Skip to content

Commit 1530e2d

Browse files
committed
chore: add optimism and arbitrum sig types
1 parent 4a21042 commit 1530e2d

File tree

6 files changed

+158
-1
lines changed

6 files changed

+158
-1
lines changed

src/chains/arbitrum/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { arbitrum as arbitrumMetadata } from '@wagmi/chains';
22
import { Chain } from '@/chains';
3+
import { sortedArrayByField } from '@/lib/utils';
4+
import { signatureTypes } from './signatureTypes';
35
import { precompiles } from './vm/precompiles';
46

57
export const arbitrum: Chain = {
68
metadata: arbitrumMetadata,
79
precompiles,
10+
signatureTypes: sortedArrayByField(signatureTypes, 'prefixByte'),
811
};

src/chains/arbitrum/signatureTypes.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { SignatureType } from '@/chains';
2+
import { signatureTypes as mainnetSignatureTypes } from '@/chains/mainnet/signatureTypes';
3+
4+
const txTypeDocs = 'https://developer.arbitrum.io/arbos/geth#transaction-types';
5+
6+
const arbitrumDepositTx: SignatureType = {
7+
prefixByte: 0x64,
8+
description:
9+
"Represents a user deposit from L1 to L2. This increases the user's balance by the amount deposited on L1.",
10+
signedData: ['keccak256(0x64 || rlp([chainId, l1RequestId, from, to, value]))'],
11+
signs: 'transaction',
12+
references: [
13+
txTypeDocs,
14+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/transaction.go#L48',
15+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/arb_types.go#L338-L344',
16+
],
17+
};
18+
19+
const arbitrumUnsignedTx: SignatureType = {
20+
prefixByte: 0x65,
21+
description:
22+
"A message from a user on L1 to a contract on L2 that uses the bridge for authentication instead of requiring the user's signature.",
23+
signedData: [
24+
'keccak256(0x65 || rlp([chainId, from, nonce, maxFeePerGas, gasLimit, to, value, data]))',
25+
],
26+
signs: 'transaction',
27+
references: [
28+
txTypeDocs,
29+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/transaction.go#L49',
30+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/arb_types.go#L43-L53',
31+
],
32+
};
33+
34+
const arbitrumContractTx: SignatureType = {
35+
prefixByte: 0x66,
36+
description:
37+
"Similar to an `ArbitrumUnsignedTx` but intended for smart contracts. Uses the bridge's unique, sequential nonce rather than requiring the caller specify their own.",
38+
signedData: [
39+
'keccak256(0x66 || rlp([chainId, requestId, from, maxFeePerGas, gasLimit, to, value, data]))',
40+
],
41+
signs: 'transaction',
42+
references: [
43+
txTypeDocs,
44+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/transaction.go#L50',
45+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/arb_types.go#L104-L114',
46+
],
47+
};
48+
49+
const arbitrumSubmitRetryableTx: SignatureType = {
50+
prefixByte: 0x69,
51+
description: 'A retryable submission and may schedule an ArbitrumRetryTx if provided enough gas.',
52+
signedData: [
53+
'keccak256(0x69 || rlp([chainId, requestId, from, l1BaseFee, depositValue, maxFeePerGas, gasLimit, retryTo, retryValue, beneficiary, maxSubmissionFee, feeRefundAddress, retryData]))',
54+
],
55+
signs: 'transaction',
56+
references: [
57+
txTypeDocs,
58+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/transaction.go#L52',
59+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/arb_types.go#L232-L247',
60+
],
61+
};
62+
63+
const arbitrumRetryTx: SignatureType = {
64+
prefixByte: 0x68,
65+
description:
66+
'Transactions scheduled by calls to the redeem precompile method and via retryable auto-redemption.',
67+
signedData: [
68+
'keccak256(0x68 || rlp([chainId, nonce, from, maxFeePerGas, gasLimit, to, value, data, ticketId, refundTo, maxRefund, submissionFeeRefund]))',
69+
],
70+
signs: 'transaction',
71+
references: [
72+
txTypeDocs,
73+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/transaction.go#L51',
74+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/arb_types.go#L161-L176',
75+
],
76+
};
77+
78+
const arbitrumInternalTx: SignatureType = {
79+
prefixByte: 0x6a,
80+
description: 'ArbOS-created transaction to update state between user-generated transactions.',
81+
signedData: ['keccak256(0x6a || rlp([chainId, data]))'],
82+
signs: 'transaction',
83+
references: [
84+
txTypeDocs,
85+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/transaction.go#L53',
86+
'https://github.com/OffchainLabs/go-ethereum/blob/master/core/types/arb_types.go#L387-L390',
87+
],
88+
};
89+
90+
const arbitrumLegacyTx: SignatureType = {
91+
prefixByte: 0x78,
92+
description: 'A legacy transaction',
93+
signedData: mainnetSignatureTypes[0x00].signedData,
94+
signs: 'transaction',
95+
references: [
96+
'https://github.com/OffchainLabs/go-ethereum/blob/a2132df21812259f604855f8ae399745fa9b6de6/core/types/transaction.go#L54',
97+
...mainnetSignatureTypes[0x00].references,
98+
],
99+
};
100+
101+
export const signatureTypes = {
102+
...mainnetSignatureTypes,
103+
...{ [arbitrumDepositTx.prefixByte]: arbitrumDepositTx },
104+
...{ [arbitrumUnsignedTx.prefixByte]: arbitrumUnsignedTx },
105+
...{ [arbitrumContractTx.prefixByte]: arbitrumContractTx },
106+
...{ [arbitrumSubmitRetryableTx.prefixByte]: arbitrumSubmitRetryableTx },
107+
...{ [arbitrumRetryTx.prefixByte]: arbitrumRetryTx },
108+
...{ [arbitrumInternalTx.prefixByte]: arbitrumInternalTx },
109+
...{ [arbitrumLegacyTx.prefixByte]: arbitrumLegacyTx },
110+
};

src/chains/mainnet/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { mainnet as mainnetMetadata } from '@wagmi/chains';
22
import { Chain } from '@/chains';
3+
import { sortedArrayByField } from '@/lib/utils';
34
import { signatureTypes } from './signatureTypes';
45
import { precompiles } from './vm/precompiles';
56

67
export const mainnet: Chain = {
78
metadata: mainnetMetadata,
89
precompiles,
9-
signatureTypes,
10+
signatureTypes: sortedArrayByField(signatureTypes, 'prefixByte'),
1011
};

src/chains/optimism/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { optimism as optimismMetadata } from '@wagmi/chains';
22
import { Chain } from '@/chains';
3+
import { sortedArrayByField } from '@/lib/utils';
4+
import { signatureTypes } from './signatureTypes';
35
import { precompiles } from './vm/precompiles';
46

57
export const optimism: Chain = {
68
metadata: optimismMetadata,
79
precompiles,
10+
signatureTypes: sortedArrayByField(signatureTypes, 'prefixByte'),
811
};

src/chains/optimism/signatureTypes.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { SignatureType } from '@/chains';
2+
import { signatureTypes as mainnetSignatureTypes } from '@/chains/mainnet/signatureTypes';
3+
4+
const depositTx: SignatureType = {
5+
prefixByte: 0x7e,
6+
description: 'An L2 transaction that was derived from L1 and included in a L2 block',
7+
signedData: [
8+
'keccak256(0x7E || rlp([sourceHash, from, to, mint, value, gas, isSystemTx, data]))',
9+
],
10+
signs: 'transaction',
11+
references: [
12+
'https://github.com/ethereum-optimism/optimism/blob/develop/specs/deposits.md#the-deposited-transaction-type',
13+
'https://github.com/ethereum-optimism/optimism/blob/develop/specs/glossary.md#deposited-transaction',
14+
],
15+
notes: [
16+
`There are two kinds of deposited transactions:
17+
- [L1 attributes deposited transaction][l1-attr-deposit], which submits the L1 block's attributes to the [L1 Attributes Predeployed Contract][l1-attr-predeploy].
18+
- [User-deposited transactions][user-deposited], which are transactions derived from an L1 call to the [deposit contract][deposit-contract].`,
19+
],
20+
};
21+
22+
export const signatureTypes = {
23+
...mainnetSignatureTypes,
24+
...{ [depositTx.prefixByte]: depositTx },
25+
};

src/lib/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,16 @@
1+
// Takes an arbitrary number of class names, filtering out any falsey values.
12
export const classNames = (...classes: (string | boolean)[]) => classes.filter(Boolean).join(' ');
3+
4+
// Given a `record` (i.e. an object), return an array of its values sorted by the given `field`.
5+
// Make sure the field is a number or string or the sort behavior based on `>` and `<` may be
6+
// undefined.
7+
export const sortedArrayByField = <T extends number | string | symbol, U, K extends keyof U>(
8+
record: Record<T, U>,
9+
field: K
10+
): U[] => {
11+
return (Object.values(record) as U[]).sort((a, b) => {
12+
if (a[field] > b[field]) return 1;
13+
if (a[field] < b[field]) return -1;
14+
return 0;
15+
});
16+
};

0 commit comments

Comments
 (0)