tempo.ts 0.0.0 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -0
- package/dist/chains.d.ts +1477 -0
- package/dist/chains.d.ts.map +1 -0
- package/dist/chains.js +43 -0
- package/dist/chains.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/types.d.ts +284 -0
- package/dist/internal/types.d.ts.map +1 -0
- package/dist/internal/types.js +2 -0
- package/dist/internal/types.js.map +1 -0
- package/dist/ox/TokenId.d.ts +18 -0
- package/dist/ox/TokenId.d.ts.map +1 -0
- package/dist/ox/TokenId.js +29 -0
- package/dist/ox/TokenId.js.map +1 -0
- package/dist/ox/TokenRole.d.ts +11 -0
- package/dist/ox/TokenRole.d.ts.map +1 -0
- package/dist/ox/TokenRole.js +22 -0
- package/dist/ox/TokenRole.js.map +1 -0
- package/dist/ox/Transaction.d.ts +161 -0
- package/dist/ox/Transaction.d.ts.map +1 -0
- package/dist/ox/Transaction.js +117 -0
- package/dist/ox/Transaction.js.map +1 -0
- package/dist/ox/TransactionEnvelopeFeeToken.d.ts +393 -0
- package/dist/ox/TransactionEnvelopeFeeToken.d.ts.map +1 -0
- package/dist/ox/TransactionEnvelopeFeeToken.js +452 -0
- package/dist/ox/TransactionEnvelopeFeeToken.js.map +1 -0
- package/dist/ox/TransactionRequest.d.ts +62 -0
- package/dist/ox/TransactionRequest.d.ts.map +1 -0
- package/dist/ox/TransactionRequest.js +66 -0
- package/dist/ox/TransactionRequest.js.map +1 -0
- package/dist/ox/index.d.ts +5 -0
- package/dist/ox/index.d.ts.map +1 -0
- package/dist/ox/index.js +5 -0
- package/dist/ox/index.js.map +1 -0
- package/dist/prool/Instance.d.ts +92 -0
- package/dist/prool/Instance.d.ts.map +1 -0
- package/dist/prool/Instance.js +96 -0
- package/dist/prool/Instance.js.map +1 -0
- package/dist/prool/index.d.ts +2 -0
- package/dist/prool/index.d.ts.map +1 -0
- package/dist/prool/index.js +2 -0
- package/dist/prool/index.js.map +1 -0
- package/dist/viem/abis.d.ts +2058 -0
- package/dist/viem/abis.d.ts.map +1 -0
- package/dist/viem/abis.js +1599 -0
- package/dist/viem/abis.js.map +1 -0
- package/dist/viem/actions/amm.d.ts +2091 -0
- package/dist/viem/actions/amm.d.ts.map +1 -0
- package/dist/viem/actions/amm.js +876 -0
- package/dist/viem/actions/amm.js.map +1 -0
- package/dist/viem/actions/fee.d.ts +727 -0
- package/dist/viem/actions/fee.d.ts.map +1 -0
- package/dist/viem/actions/fee.js +230 -0
- package/dist/viem/actions/fee.js.map +1 -0
- package/dist/viem/actions/index.d.ts +5 -0
- package/dist/viem/actions/index.d.ts.map +1 -0
- package/dist/viem/actions/index.js +5 -0
- package/dist/viem/actions/index.js.map +1 -0
- package/dist/viem/actions/policy.d.ts +1900 -0
- package/dist/viem/actions/policy.d.ts.map +1 -0
- package/dist/viem/actions/policy.js +841 -0
- package/dist/viem/actions/policy.js.map +1 -0
- package/dist/viem/actions/token.d.ts +13759 -0
- package/dist/viem/actions/token.d.ts.map +1 -0
- package/dist/viem/actions/token.js +2579 -0
- package/dist/viem/actions/token.js.map +1 -0
- package/dist/viem/addresses.d.ts +8 -0
- package/dist/viem/addresses.d.ts.map +1 -0
- package/dist/viem/addresses.js +8 -0
- package/dist/viem/addresses.js.map +1 -0
- package/dist/viem/chain.d.ts +341 -0
- package/dist/viem/chain.d.ts.map +1 -0
- package/dist/viem/chain.js +22 -0
- package/dist/viem/chain.js.map +1 -0
- package/dist/viem/client.d.ts +27 -0
- package/dist/viem/client.d.ts.map +1 -0
- package/dist/viem/client.js +28 -0
- package/dist/viem/client.js.map +1 -0
- package/dist/viem/decorator.d.ts +1636 -0
- package/dist/viem/decorator.d.ts.map +1 -0
- package/dist/viem/decorator.js +95 -0
- package/dist/viem/decorator.js.map +1 -0
- package/dist/viem/formatters.d.ts +4 -0
- package/dist/viem/formatters.d.ts.map +1 -0
- package/dist/viem/formatters.js +69 -0
- package/dist/viem/formatters.js.map +1 -0
- package/dist/viem/index.d.ts +9 -0
- package/dist/viem/index.d.ts.map +1 -0
- package/dist/viem/index.js +9 -0
- package/dist/viem/index.js.map +1 -0
- package/dist/viem/transaction.d.ts +54 -0
- package/dist/viem/transaction.d.ts.map +1 -0
- package/dist/viem/transaction.js +108 -0
- package/dist/viem/transaction.js.map +1 -0
- package/dist/viem/transport.d.ts +16 -0
- package/dist/viem/transport.d.ts.map +1 -0
- package/dist/viem/transport.js +33 -0
- package/dist/viem/transport.js.map +1 -0
- package/dist/viem/types.d.ts +10 -0
- package/dist/viem/types.d.ts.map +1 -0
- package/dist/viem/types.js +2 -0
- package/dist/viem/types.js.map +1 -0
- package/dist/viem/utils.d.ts +8 -0
- package/dist/viem/utils.d.ts.map +1 -0
- package/dist/viem/utils.js +9 -0
- package/dist/viem/utils.js.map +1 -0
- package/package.json +100 -2
- package/src/chains.ts +46 -0
- package/src/index.ts +1 -0
- package/src/internal/types.ts +414 -0
- package/src/ox/TokenId.test.ts +29 -0
- package/src/ox/TokenId.ts +35 -0
- package/src/ox/TokenRole.test.ts +20 -0
- package/src/ox/TokenRole.ts +27 -0
- package/src/ox/Transaction.test.ts +257 -0
- package/src/ox/Transaction.ts +247 -0
- package/src/ox/TransactionEnvelopeFeeToken.test.ts +1215 -0
- package/src/ox/TransactionEnvelopeFeeToken.ts +717 -0
- package/src/ox/TransactionRequest.ts +100 -0
- package/src/ox/index.ts +4 -0
- package/src/prool/Instance.test.ts +43 -0
- package/src/prool/Instance.ts +190 -0
- package/src/prool/index.ts +1 -0
- package/src/prool/internal/chain.json +106 -0
- package/src/prool/internal/consensus.toml +32 -0
- package/src/viem/abis.ts +1606 -0
- package/src/viem/actions/amm.test.ts +425 -0
- package/src/viem/actions/amm.ts +1308 -0
- package/src/viem/actions/fee.test.ts +281 -0
- package/src/viem/actions/fee.ts +362 -0
- package/src/viem/actions/index.ts +4 -0
- package/src/viem/actions/policy.test.ts +514 -0
- package/src/viem/actions/policy.ts +1284 -0
- package/src/viem/actions/token.test.ts +2172 -0
- package/src/viem/actions/token.ts +3830 -0
- package/src/viem/addresses.ts +10 -0
- package/src/viem/chain.ts +27 -0
- package/src/viem/client.bench-d.ts +8 -0
- package/src/viem/client.test.ts +152 -0
- package/src/viem/client.ts +91 -0
- package/src/viem/decorator.bench-d.ts +11 -0
- package/src/viem/decorator.test.ts +35 -0
- package/src/viem/decorator.ts +1914 -0
- package/src/viem/e2e.test.ts +410 -0
- package/src/viem/formatters.ts +100 -0
- package/src/viem/index.ts +8 -0
- package/src/viem/transaction.ts +253 -0
- package/src/viem/transport.ts +47 -0
- package/src/viem/types.ts +55 -0
- package/src/viem/utils.ts +37 -0
|
@@ -0,0 +1,717 @@
|
|
|
1
|
+
import * as AccessList from 'ox/AccessList'
|
|
2
|
+
import * as Address from 'ox/Address'
|
|
3
|
+
import * as Authorization from 'ox/Authorization'
|
|
4
|
+
import type * as Errors from 'ox/Errors'
|
|
5
|
+
import * as Hash from 'ox/Hash'
|
|
6
|
+
import * as Hex from 'ox/Hex'
|
|
7
|
+
import * as Rlp from 'ox/Rlp'
|
|
8
|
+
import * as Signature from 'ox/Signature'
|
|
9
|
+
import * as TransactionEnvelope from 'ox/TransactionEnvelope'
|
|
10
|
+
import * as TransactionEnvelopeEip1559 from 'ox/TransactionEnvelopeEip1559'
|
|
11
|
+
import type { OneOf } from 'viem'
|
|
12
|
+
import type {
|
|
13
|
+
Assign,
|
|
14
|
+
Compute,
|
|
15
|
+
PartialBy,
|
|
16
|
+
UnionPartialBy,
|
|
17
|
+
} from '../internal/types.js'
|
|
18
|
+
import * as TokenId from './TokenId.js'
|
|
19
|
+
|
|
20
|
+
export type TransactionEnvelopeFeeToken<
|
|
21
|
+
signed extends boolean = boolean,
|
|
22
|
+
bigintType = bigint,
|
|
23
|
+
numberType = number,
|
|
24
|
+
type extends string = Type,
|
|
25
|
+
> = Compute<
|
|
26
|
+
TransactionEnvelope.Base<type, signed, bigintType, numberType> & {
|
|
27
|
+
/** EIP-2930 Access List. */
|
|
28
|
+
accessList?: AccessList.AccessList | undefined
|
|
29
|
+
/** EIP-7702 Authorization List. */
|
|
30
|
+
authorizationList?:
|
|
31
|
+
| Authorization.ListSigned<bigintType, numberType>
|
|
32
|
+
| undefined
|
|
33
|
+
/** Fee payer signature. */
|
|
34
|
+
feePayerSignature?:
|
|
35
|
+
| Signature.Signature<true, bigintType, numberType>
|
|
36
|
+
| null
|
|
37
|
+
| undefined
|
|
38
|
+
/** Fee token preference. Address or ID of the TIP-20 token. */
|
|
39
|
+
feeToken?: TokenId.TokenIdOrAddress | undefined
|
|
40
|
+
/** Total fee per gas in wei (gasPrice/baseFeePerGas + maxPriorityFeePerGas). */
|
|
41
|
+
maxFeePerGas?: bigintType | undefined
|
|
42
|
+
/** Max priority fee per gas (in wei). */
|
|
43
|
+
maxPriorityFeePerGas?: bigintType | undefined
|
|
44
|
+
}
|
|
45
|
+
>
|
|
46
|
+
|
|
47
|
+
export type Rpc<signed extends boolean = boolean> = TransactionEnvelopeFeeToken<
|
|
48
|
+
signed,
|
|
49
|
+
Hex.Hex,
|
|
50
|
+
Hex.Hex,
|
|
51
|
+
'0x77'
|
|
52
|
+
>
|
|
53
|
+
|
|
54
|
+
export const feePayerMagic = '0x78' as const
|
|
55
|
+
export type FeePayerMagic = typeof feePayerMagic
|
|
56
|
+
|
|
57
|
+
export type Serialized = `${SerializedType}${string}`
|
|
58
|
+
|
|
59
|
+
export type Signed = TransactionEnvelopeFeeToken<true>
|
|
60
|
+
|
|
61
|
+
export const serializedType = '0x77' as const
|
|
62
|
+
export type SerializedType = typeof serializedType
|
|
63
|
+
|
|
64
|
+
export const type = 'feeToken' as const
|
|
65
|
+
export type Type = typeof type
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Asserts a {@link ox#TransactionEnvelopeFeeToken.TransactionEnvelopeFeeToken} is valid.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts twoslash
|
|
72
|
+
* import { Value } from 'ox'
|
|
73
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
74
|
+
*
|
|
75
|
+
* TransactionEnvelopeFeeToken.assert({
|
|
76
|
+
* feeToken: '0x20c0000000000000000000000000000000000000',
|
|
77
|
+
* maxFeePerGas: 2n ** 256n - 1n + 1n,
|
|
78
|
+
* chainId: 1,
|
|
79
|
+
* to: '0x0000000000000000000000000000000000000000',
|
|
80
|
+
* value: Value.fromEther('1'),
|
|
81
|
+
* })
|
|
82
|
+
* // @error: FeeCapTooHighError:
|
|
83
|
+
* // @error: The fee cap (`masFeePerGas` = 115792089237316195423570985008687907853269984665640564039457584007913 gwei) cannot be
|
|
84
|
+
* // @error: higher than the maximum allowed value (2^256-1).
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* @param envelope - The transaction envelope to assert.
|
|
88
|
+
*/
|
|
89
|
+
export function assert(
|
|
90
|
+
envelope: PartialBy<TransactionEnvelopeFeeToken, 'type'>,
|
|
91
|
+
) {
|
|
92
|
+
const { authorizationList } = envelope
|
|
93
|
+
if (authorizationList) {
|
|
94
|
+
for (const authorization of authorizationList) {
|
|
95
|
+
const { address, chainId } = authorization
|
|
96
|
+
if (address) Address.assert(address, { strict: false })
|
|
97
|
+
if (Number(chainId) < 0)
|
|
98
|
+
throw new TransactionEnvelope.InvalidChainIdError({ chainId })
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
TransactionEnvelopeEip1559.assert(
|
|
102
|
+
envelope as {} as TransactionEnvelopeEip1559.TransactionEnvelopeEip1559,
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export declare namespace assert {
|
|
107
|
+
type ErrorType =
|
|
108
|
+
| Address.assert.ErrorType
|
|
109
|
+
| TransactionEnvelope.InvalidChainIdError
|
|
110
|
+
| Errors.GlobalErrorType
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Deserializes a {@link ox#TransactionEnvelopeFeeToken.TransactionEnvelopeFeeToken} from its serialized form.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts twoslash
|
|
118
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
119
|
+
*
|
|
120
|
+
* const envelope = TransactionEnvelopeFeeToken.deserialize('0x77ef0182031184773594008477359400809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c0')
|
|
121
|
+
* // @log: {
|
|
122
|
+
* // @log: type: 'feeToken',
|
|
123
|
+
* // @log: nonce: 785n,
|
|
124
|
+
* // @log: maxFeePerGas: 2000000000n,
|
|
125
|
+
* // @log: gas: 1000000n,
|
|
126
|
+
* // @log: to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
|
|
127
|
+
* // @log: value: 1000000000000000000n,
|
|
128
|
+
* // @log: }
|
|
129
|
+
* ```
|
|
130
|
+
*
|
|
131
|
+
* @param serialized - The serialized transaction.
|
|
132
|
+
* @returns Deserialized Transaction Envelope.
|
|
133
|
+
*/
|
|
134
|
+
export function deserialize(
|
|
135
|
+
serialized: Serialized,
|
|
136
|
+
): Compute<TransactionEnvelopeFeeToken> {
|
|
137
|
+
const transactionArray = Rlp.toHex(Hex.slice(serialized, 1))
|
|
138
|
+
|
|
139
|
+
const [
|
|
140
|
+
chainId,
|
|
141
|
+
nonce,
|
|
142
|
+
maxPriorityFeePerGas,
|
|
143
|
+
maxFeePerGas,
|
|
144
|
+
gas,
|
|
145
|
+
to,
|
|
146
|
+
value,
|
|
147
|
+
data,
|
|
148
|
+
accessList,
|
|
149
|
+
authorizationList,
|
|
150
|
+
feeToken,
|
|
151
|
+
feePayerSignatureOrSender,
|
|
152
|
+
yParity,
|
|
153
|
+
r,
|
|
154
|
+
s,
|
|
155
|
+
] = transactionArray as readonly Hex.Hex[]
|
|
156
|
+
|
|
157
|
+
if (!(transactionArray.length === 12 || transactionArray.length === 15))
|
|
158
|
+
throw new TransactionEnvelope.InvalidSerializedError({
|
|
159
|
+
attributes: {
|
|
160
|
+
chainId,
|
|
161
|
+
nonce,
|
|
162
|
+
feeToken,
|
|
163
|
+
maxPriorityFeePerGas,
|
|
164
|
+
maxFeePerGas,
|
|
165
|
+
gas,
|
|
166
|
+
to,
|
|
167
|
+
value,
|
|
168
|
+
data,
|
|
169
|
+
accessList,
|
|
170
|
+
authorizationList,
|
|
171
|
+
feePayerSignatureOrSender,
|
|
172
|
+
...(transactionArray.length > 9
|
|
173
|
+
? {
|
|
174
|
+
yParity,
|
|
175
|
+
r,
|
|
176
|
+
s,
|
|
177
|
+
}
|
|
178
|
+
: {}),
|
|
179
|
+
},
|
|
180
|
+
serialized,
|
|
181
|
+
type,
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
let transaction = {
|
|
185
|
+
chainId: Number(chainId),
|
|
186
|
+
type,
|
|
187
|
+
} as TransactionEnvelopeFeeToken
|
|
188
|
+
if (Hex.validate(to) && to !== '0x') transaction.to = to
|
|
189
|
+
if (Hex.validate(feeToken) && feeToken !== '0x')
|
|
190
|
+
transaction.feeToken = feeToken
|
|
191
|
+
if (Hex.validate(gas) && gas !== '0x') transaction.gas = BigInt(gas)
|
|
192
|
+
if (Hex.validate(data) && data !== '0x') transaction.data = data
|
|
193
|
+
if (Hex.validate(nonce))
|
|
194
|
+
transaction.nonce = nonce === '0x' ? 0n : BigInt(nonce)
|
|
195
|
+
if (Hex.validate(value) && value !== '0x') transaction.value = BigInt(value)
|
|
196
|
+
if (Hex.validate(maxFeePerGas) && maxFeePerGas !== '0x')
|
|
197
|
+
transaction.maxFeePerGas = BigInt(maxFeePerGas)
|
|
198
|
+
if (Hex.validate(maxPriorityFeePerGas) && maxPriorityFeePerGas !== '0x')
|
|
199
|
+
transaction.maxPriorityFeePerGas = BigInt(maxPriorityFeePerGas)
|
|
200
|
+
if (accessList?.length !== 0 && accessList !== '0x')
|
|
201
|
+
transaction.accessList = AccessList.fromTupleList(accessList as never)
|
|
202
|
+
if (authorizationList !== '0x' && (authorizationList?.length ?? 0) > 0)
|
|
203
|
+
transaction.authorizationList = Authorization.fromTupleList(
|
|
204
|
+
authorizationList as never,
|
|
205
|
+
)
|
|
206
|
+
if (
|
|
207
|
+
feePayerSignatureOrSender !== '0x' &&
|
|
208
|
+
feePayerSignatureOrSender !== undefined
|
|
209
|
+
) {
|
|
210
|
+
if (
|
|
211
|
+
feePayerSignatureOrSender === '0x00' ||
|
|
212
|
+
Address.validate(feePayerSignatureOrSender)
|
|
213
|
+
)
|
|
214
|
+
transaction.feePayerSignature = null
|
|
215
|
+
else
|
|
216
|
+
transaction.feePayerSignature = Signature.fromTuple(
|
|
217
|
+
feePayerSignatureOrSender as never,
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const signature =
|
|
222
|
+
r && s && yParity ? Signature.fromTuple([yParity, r, s]) : undefined
|
|
223
|
+
if (signature)
|
|
224
|
+
transaction = {
|
|
225
|
+
...transaction,
|
|
226
|
+
...signature,
|
|
227
|
+
} as TransactionEnvelopeFeeToken
|
|
228
|
+
|
|
229
|
+
assert(transaction)
|
|
230
|
+
|
|
231
|
+
return transaction
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export declare namespace deserialize {
|
|
235
|
+
type ErrorType = Errors.GlobalErrorType
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Converts an arbitrary transaction object into an Fee Token Transaction Envelope.
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```ts twoslash
|
|
243
|
+
* import { Value } from 'ox'
|
|
244
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
245
|
+
*
|
|
246
|
+
* const envelope = TransactionEnvelopeFeeToken.from({ // [!code focus]
|
|
247
|
+
* chainId: 1, // [!code focus]
|
|
248
|
+
* feeToken: '0x20c0000000000000000000000000000000000000', // [!code focus]
|
|
249
|
+
* maxFeePerGas: Value.fromGwei('10'), // [!code focus]
|
|
250
|
+
* maxPriorityFeePerGas: Value.fromGwei('1'), // [!code focus]
|
|
251
|
+
* to: '0x0000000000000000000000000000000000000000', // [!code focus]
|
|
252
|
+
* value: Value.fromEther('1'), // [!code focus]
|
|
253
|
+
* }) // [!code focus]
|
|
254
|
+
* ```
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ### Attaching Signatures
|
|
258
|
+
*
|
|
259
|
+
* It is possible to attach a `signature` to the transaction envelope.
|
|
260
|
+
*
|
|
261
|
+
* ```ts twoslash
|
|
262
|
+
* // @noErrors
|
|
263
|
+
* import { Secp256k1, Value } from 'ox'
|
|
264
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
265
|
+
*
|
|
266
|
+
* const envelope = TransactionEnvelopeFeeToken.from({
|
|
267
|
+
* chainId: 1,
|
|
268
|
+
* feeToken: '0x20c0000000000000000000000000000000000000',
|
|
269
|
+
* maxFeePerGas: Value.fromGwei('10'),
|
|
270
|
+
* maxPriorityFeePerGas: Value.fromGwei('1'),
|
|
271
|
+
* to: '0x0000000000000000000000000000000000000000',
|
|
272
|
+
* value: Value.fromEther('1'),
|
|
273
|
+
* })
|
|
274
|
+
*
|
|
275
|
+
* const signature = Secp256k1.sign({
|
|
276
|
+
* payload: TransactionEnvelopeFeeToken.getSignPayload(envelope),
|
|
277
|
+
* privateKey: '0x...',
|
|
278
|
+
* })
|
|
279
|
+
*
|
|
280
|
+
* const envelope_signed = TransactionEnvelopeFeeToken.from(envelope, { // [!code focus]
|
|
281
|
+
* signature, // [!code focus]
|
|
282
|
+
* }) // [!code focus]
|
|
283
|
+
* // @log: {
|
|
284
|
+
* // @log: chainId: 1,
|
|
285
|
+
* // @log: feeToken: '0x20c0000000000000000000000000000000000000',
|
|
286
|
+
* // @log: maxFeePerGas: 10000000000n,
|
|
287
|
+
* // @log: maxPriorityFeePerGas: 1000000000n,
|
|
288
|
+
* // @log: to: '0x0000000000000000000000000000000000000000',
|
|
289
|
+
* // @log: type: 'feeToken',
|
|
290
|
+
* // @log: value: 1000000000000000000n,
|
|
291
|
+
* // @log: r: 125...n,
|
|
292
|
+
* // @log: s: 642...n,
|
|
293
|
+
* // @log: yParity: 0,
|
|
294
|
+
* // @log: }
|
|
295
|
+
* ```
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ### From Serialized
|
|
299
|
+
*
|
|
300
|
+
* It is possible to instantiate an Fee Token Transaction Envelope from a {@link ox#TransactionEnvelopeFeeToken.Serialized} value.
|
|
301
|
+
*
|
|
302
|
+
* ```ts twoslash
|
|
303
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
304
|
+
*
|
|
305
|
+
* const envelope = TransactionEnvelopeFeeToken.from('0x77f858018203118502540be4008504a817c800809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c08477359400e1a001627c687261b0e7f8638af1112efa8a77e23656f6e7945275b19e9deed80261')
|
|
306
|
+
* // @log: {
|
|
307
|
+
* // @log: chainId: 1,
|
|
308
|
+
* // @log: feeToken: '0x20c0000000000000000000000000000000000000',
|
|
309
|
+
* // @log: maxFeePerGas: 10000000000n,
|
|
310
|
+
* // @log: to: '0x0000000000000000000000000000000000000000',
|
|
311
|
+
* // @log: type: 'feeToken',
|
|
312
|
+
* // @log: value: 1000000000000000000n,
|
|
313
|
+
* // @log: }
|
|
314
|
+
* ```
|
|
315
|
+
*
|
|
316
|
+
* @param envelope - The transaction object to convert.
|
|
317
|
+
* @param options - Options.
|
|
318
|
+
* @returns An Fee Token Transaction Envelope.
|
|
319
|
+
*/
|
|
320
|
+
export function from<
|
|
321
|
+
const envelope extends
|
|
322
|
+
| UnionPartialBy<TransactionEnvelopeFeeToken, 'type'>
|
|
323
|
+
| Serialized,
|
|
324
|
+
const signature extends Signature.Signature | undefined = undefined,
|
|
325
|
+
>(
|
|
326
|
+
envelope:
|
|
327
|
+
| envelope
|
|
328
|
+
| UnionPartialBy<TransactionEnvelopeFeeToken, 'type'>
|
|
329
|
+
| Serialized,
|
|
330
|
+
options: from.Options<signature> = {},
|
|
331
|
+
): from.ReturnValue<envelope, signature> {
|
|
332
|
+
const { feePayerSignature, signature } = options
|
|
333
|
+
|
|
334
|
+
const envelope_ = (
|
|
335
|
+
typeof envelope === 'string' ? deserialize(envelope) : envelope
|
|
336
|
+
) as TransactionEnvelopeFeeToken
|
|
337
|
+
|
|
338
|
+
assert(envelope_)
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
...envelope_,
|
|
342
|
+
...(signature ? Signature.from(signature) : {}),
|
|
343
|
+
...(feePayerSignature
|
|
344
|
+
? { feePayerSignature: Signature.from(feePayerSignature) }
|
|
345
|
+
: {}),
|
|
346
|
+
type: 'feeToken',
|
|
347
|
+
} as never
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export declare namespace from {
|
|
351
|
+
type Options<signature extends Signature.Signature | undefined = undefined> =
|
|
352
|
+
{
|
|
353
|
+
feePayerSignature?: Signature.Signature | null | undefined
|
|
354
|
+
signature?: signature | Signature.Signature | undefined
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
type ReturnValue<
|
|
358
|
+
envelope extends
|
|
359
|
+
| UnionPartialBy<TransactionEnvelopeFeeToken, 'type'>
|
|
360
|
+
| Hex.Hex = TransactionEnvelopeFeeToken | Hex.Hex,
|
|
361
|
+
signature extends Signature.Signature | undefined = undefined,
|
|
362
|
+
> = Compute<
|
|
363
|
+
envelope extends Hex.Hex
|
|
364
|
+
? TransactionEnvelopeFeeToken
|
|
365
|
+
: Assign<
|
|
366
|
+
envelope,
|
|
367
|
+
(signature extends Signature.Signature ? Readonly<signature> : {}) & {
|
|
368
|
+
readonly type: 'feeToken'
|
|
369
|
+
}
|
|
370
|
+
>
|
|
371
|
+
>
|
|
372
|
+
|
|
373
|
+
type ErrorType =
|
|
374
|
+
| deserialize.ErrorType
|
|
375
|
+
| assert.ErrorType
|
|
376
|
+
| Errors.GlobalErrorType
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Returns the fee payer payload to sign for a {@link ox#TransactionEnvelopeFeeToken.TransactionEnvelopeFeeToken}.
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* TODO
|
|
384
|
+
*
|
|
385
|
+
* @param envelope - The transaction envelope to get the fee payer sign payload for.
|
|
386
|
+
* @returns The fee payer sign payload.
|
|
387
|
+
*/
|
|
388
|
+
export function getFeePayerSignPayload(
|
|
389
|
+
envelope: TransactionEnvelopeFeeToken,
|
|
390
|
+
options: getFeePayerSignPayload.Options,
|
|
391
|
+
): getFeePayerSignPayload.ReturnValue {
|
|
392
|
+
const { sender } = options
|
|
393
|
+
const serialized = serialize(
|
|
394
|
+
{ ...envelope, r: undefined, s: undefined, yParity: undefined },
|
|
395
|
+
{
|
|
396
|
+
sender,
|
|
397
|
+
format: 'feePayer',
|
|
398
|
+
},
|
|
399
|
+
)
|
|
400
|
+
return Hash.keccak256(serialized)
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export declare namespace getFeePayerSignPayload {
|
|
404
|
+
type Options = {
|
|
405
|
+
/**
|
|
406
|
+
* Whether to get the fee payer sign payload for the **sender** to sign.
|
|
407
|
+
*
|
|
408
|
+
* @default false
|
|
409
|
+
*/
|
|
410
|
+
sender: Address.Address
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
type ReturnValue = Hex.Hex
|
|
414
|
+
|
|
415
|
+
type ErrorType = hash.ErrorType | Errors.GlobalErrorType
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Returns the payload to sign for a {@link ox#TransactionEnvelopeFeeToken.TransactionEnvelopeFeeToken}.
|
|
420
|
+
*
|
|
421
|
+
* @example
|
|
422
|
+
* The example below demonstrates how to compute the sign payload which can be used
|
|
423
|
+
* with ECDSA signing utilities like {@link ox#Secp256k1.(sign:function)}.
|
|
424
|
+
*
|
|
425
|
+
* ```ts twoslash
|
|
426
|
+
* // @noErrors
|
|
427
|
+
* import { Secp256k1 } from 'ox'
|
|
428
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
429
|
+
*
|
|
430
|
+
* const envelope = TransactionEnvelopeFeeToken.from({
|
|
431
|
+
* chainId: 1,
|
|
432
|
+
* feeToken: '0x20c0000000000000000000000000000000000000',
|
|
433
|
+
* nonce: 0n,
|
|
434
|
+
* maxFeePerGas: 1000000000n,
|
|
435
|
+
* gas: 21000n,
|
|
436
|
+
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
|
|
437
|
+
* value: 1000000000000000000n,
|
|
438
|
+
* })
|
|
439
|
+
*
|
|
440
|
+
* const payload = TransactionEnvelopeFeeToken.getSignPayload(envelope) // [!code focus]
|
|
441
|
+
* // @log: '0x...'
|
|
442
|
+
*
|
|
443
|
+
* const signature = Secp256k1.sign({ payload, privateKey: '0x...' })
|
|
444
|
+
* ```
|
|
445
|
+
*
|
|
446
|
+
* @param envelope - The transaction envelope to get the sign payload for.
|
|
447
|
+
* @returns The sign payload.
|
|
448
|
+
*/
|
|
449
|
+
export function getSignPayload(
|
|
450
|
+
envelope: TransactionEnvelopeFeeToken,
|
|
451
|
+
): getSignPayload.ReturnValue {
|
|
452
|
+
return hash(envelope, { presign: true })
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export declare namespace getSignPayload {
|
|
456
|
+
type ReturnValue = Hex.Hex
|
|
457
|
+
|
|
458
|
+
type ErrorType = hash.ErrorType | Errors.GlobalErrorType
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Hashes a {@link ox#TransactionEnvelopeFeeToken.TransactionEnvelopeFeeToken}. This is the "transaction hash".
|
|
463
|
+
*
|
|
464
|
+
* @example
|
|
465
|
+
* ```ts twoslash
|
|
466
|
+
* // @noErrors
|
|
467
|
+
* import { Secp256k1 } from 'ox'
|
|
468
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
469
|
+
*
|
|
470
|
+
* const envelope = TransactionEnvelopeFeeToken.from({
|
|
471
|
+
* chainId: 1,
|
|
472
|
+
* feeToken: '0x20c0000000000000000000000000000000000000',
|
|
473
|
+
* nonce: 0n,
|
|
474
|
+
* maxFeePerGas: 1000000000n,
|
|
475
|
+
* gas: 21000n,
|
|
476
|
+
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
|
|
477
|
+
* value: 1000000000000000000n,
|
|
478
|
+
* })
|
|
479
|
+
*
|
|
480
|
+
* const signature = Secp256k1.sign({
|
|
481
|
+
* payload: TransactionEnvelopeFeeToken.getSignPayload(envelope),
|
|
482
|
+
* privateKey: '0x...'
|
|
483
|
+
* })
|
|
484
|
+
*
|
|
485
|
+
* const envelope_signed = TransactionEnvelopeFeeToken.from(envelope, { signature })
|
|
486
|
+
*
|
|
487
|
+
* const hash = TransactionEnvelopeFeeToken.hash(envelope_signed) // [!code focus]
|
|
488
|
+
* ```
|
|
489
|
+
*
|
|
490
|
+
* @param envelope - The Fee Token Transaction Envelope to hash.
|
|
491
|
+
* @param options - Options.
|
|
492
|
+
* @returns The hash of the transaction envelope.
|
|
493
|
+
*/
|
|
494
|
+
export function hash<presign extends boolean = false>(
|
|
495
|
+
envelope: TransactionEnvelopeFeeToken<presign extends true ? false : true>,
|
|
496
|
+
options: hash.Options<presign> = {},
|
|
497
|
+
): hash.ReturnValue {
|
|
498
|
+
const serialized = serialize({
|
|
499
|
+
...envelope,
|
|
500
|
+
...(options.presign
|
|
501
|
+
? {
|
|
502
|
+
r: undefined,
|
|
503
|
+
s: undefined,
|
|
504
|
+
yParity: undefined,
|
|
505
|
+
}
|
|
506
|
+
: {}),
|
|
507
|
+
})
|
|
508
|
+
return Hash.keccak256(serialized)
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
export declare namespace hash {
|
|
512
|
+
type Options<presign extends boolean = false> = {
|
|
513
|
+
/**
|
|
514
|
+
* Whether to hash this transaction for signing.
|
|
515
|
+
*
|
|
516
|
+
* @default false
|
|
517
|
+
*/
|
|
518
|
+
presign?: presign | boolean | undefined
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
type ReturnValue = Hex.Hex
|
|
522
|
+
|
|
523
|
+
type ErrorType =
|
|
524
|
+
| Hash.keccak256.ErrorType
|
|
525
|
+
| serialize.ErrorType
|
|
526
|
+
| Errors.GlobalErrorType
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Serializes a {@link ox#TransactionEnvelopeFeeToken.TransactionEnvelopeFeeToken}.
|
|
531
|
+
*
|
|
532
|
+
* @example
|
|
533
|
+
* ```ts twoslash
|
|
534
|
+
* // @noErrors
|
|
535
|
+
* import { Value } from 'ox'
|
|
536
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
537
|
+
*
|
|
538
|
+
* const envelope = TransactionEnvelopeFeeToken.from({
|
|
539
|
+
* chainId: 1,
|
|
540
|
+
* feeToken: '0x20c0000000000000000000000000000000000000',
|
|
541
|
+
* maxFeePerGas: Value.fromGwei('10'),
|
|
542
|
+
* to: '0x0000000000000000000000000000000000000000',
|
|
543
|
+
* value: Value.fromEther('1'),
|
|
544
|
+
* })
|
|
545
|
+
*
|
|
546
|
+
* const serialized = TransactionEnvelopeFeeToken.serialize(envelope) // [!code focus]
|
|
547
|
+
* ```
|
|
548
|
+
*
|
|
549
|
+
* @example
|
|
550
|
+
* ### Attaching Signatures
|
|
551
|
+
*
|
|
552
|
+
* It is possible to attach a `signature` to the serialized Transaction Envelope.
|
|
553
|
+
*
|
|
554
|
+
* ```ts twoslash
|
|
555
|
+
* // @noErrors
|
|
556
|
+
* import { Secp256k1, Value } from 'ox'
|
|
557
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
558
|
+
*
|
|
559
|
+
* const envelope = TransactionEnvelopeFeeToken.from({
|
|
560
|
+
* chainId: 1,
|
|
561
|
+
* feeToken: '0x20c0000000000000000000000000000000000000',
|
|
562
|
+
* maxFeePerGas: Value.fromGwei('10'),
|
|
563
|
+
* to: '0x0000000000000000000000000000000000000000',
|
|
564
|
+
* value: Value.fromEther('1'),
|
|
565
|
+
* })
|
|
566
|
+
*
|
|
567
|
+
* const signature = Secp256k1.sign({
|
|
568
|
+
* payload: TransactionEnvelopeFeeToken.getSignPayload(envelope),
|
|
569
|
+
* privateKey: '0x...',
|
|
570
|
+
* })
|
|
571
|
+
*
|
|
572
|
+
* const serialized = TransactionEnvelopeFeeToken.serialize(envelope, { // [!code focus]
|
|
573
|
+
* signature, // [!code focus]
|
|
574
|
+
* }) // [!code focus]
|
|
575
|
+
*
|
|
576
|
+
* // ... send `serialized` transaction to JSON-RPC `eth_sendRawTransaction`
|
|
577
|
+
* ```
|
|
578
|
+
*
|
|
579
|
+
* @param envelope - The Transaction Envelope to serialize.
|
|
580
|
+
* @param options - Options.
|
|
581
|
+
* @returns The serialized Transaction Envelope.
|
|
582
|
+
*/
|
|
583
|
+
export function serialize(
|
|
584
|
+
envelope: PartialBy<TransactionEnvelopeFeeToken, 'type'>,
|
|
585
|
+
options: serialize.Options = {},
|
|
586
|
+
): Serialized {
|
|
587
|
+
const {
|
|
588
|
+
authorizationList,
|
|
589
|
+
chainId,
|
|
590
|
+
feeToken,
|
|
591
|
+
gas,
|
|
592
|
+
nonce,
|
|
593
|
+
to,
|
|
594
|
+
value,
|
|
595
|
+
maxFeePerGas,
|
|
596
|
+
maxPriorityFeePerGas,
|
|
597
|
+
accessList,
|
|
598
|
+
data,
|
|
599
|
+
input,
|
|
600
|
+
} = envelope
|
|
601
|
+
|
|
602
|
+
assert(envelope)
|
|
603
|
+
|
|
604
|
+
const accessTupleList = AccessList.toTupleList(accessList)
|
|
605
|
+
const authorizationTupleList = Authorization.toTupleList(authorizationList)
|
|
606
|
+
const signature = Signature.extract(options.signature || envelope)
|
|
607
|
+
|
|
608
|
+
const feePayerSignatureOrSender = (() => {
|
|
609
|
+
if (options.sender) return options.sender
|
|
610
|
+
const feePayerSignature =
|
|
611
|
+
typeof options.feePayerSignature !== 'undefined'
|
|
612
|
+
? options.feePayerSignature
|
|
613
|
+
: envelope.feePayerSignature
|
|
614
|
+
if (feePayerSignature === null) return '0x00'
|
|
615
|
+
if (!feePayerSignature) return '0x'
|
|
616
|
+
return Signature.toTuple(feePayerSignature)
|
|
617
|
+
})()
|
|
618
|
+
|
|
619
|
+
const serialized = [
|
|
620
|
+
Hex.fromNumber(chainId),
|
|
621
|
+
nonce ? Hex.fromNumber(nonce) : '0x',
|
|
622
|
+
maxPriorityFeePerGas ? Hex.fromNumber(maxPriorityFeePerGas) : '0x',
|
|
623
|
+
maxFeePerGas ? Hex.fromNumber(maxFeePerGas) : '0x',
|
|
624
|
+
gas ? Hex.fromNumber(gas) : '0x',
|
|
625
|
+
to ?? '0x',
|
|
626
|
+
value ? Hex.fromNumber(value) : '0x',
|
|
627
|
+
data ?? input ?? '0x',
|
|
628
|
+
accessTupleList,
|
|
629
|
+
authorizationTupleList,
|
|
630
|
+
typeof feeToken === 'bigint' || typeof feeToken === 'string'
|
|
631
|
+
? TokenId.toAddress(feeToken)
|
|
632
|
+
: '0x',
|
|
633
|
+
feePayerSignatureOrSender,
|
|
634
|
+
...(signature ? Signature.toTuple(signature) : []),
|
|
635
|
+
] as const
|
|
636
|
+
|
|
637
|
+
return Hex.concat(
|
|
638
|
+
options.format === 'feePayer' ? feePayerMagic : serializedType,
|
|
639
|
+
Rlp.fromHex(serialized),
|
|
640
|
+
) as Serialized
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
export declare namespace serialize {
|
|
644
|
+
type Options = {
|
|
645
|
+
/**
|
|
646
|
+
* Sender signature to append to the serialized envelope.
|
|
647
|
+
*/
|
|
648
|
+
signature?: Signature.Signature | undefined
|
|
649
|
+
} & OneOf<
|
|
650
|
+
| {
|
|
651
|
+
/**
|
|
652
|
+
* Sender address to cover the fee of.
|
|
653
|
+
*/
|
|
654
|
+
sender: Address.Address
|
|
655
|
+
/**
|
|
656
|
+
* Whether to serialize the transaction in the fee payer format.
|
|
657
|
+
*
|
|
658
|
+
* - If `'feePayer'`, then the transaction will be serialized in the fee payer format.
|
|
659
|
+
* - If `undefined` (default), then the transaction will be serialized in the normal format.
|
|
660
|
+
*/
|
|
661
|
+
format: 'feePayer'
|
|
662
|
+
}
|
|
663
|
+
| {
|
|
664
|
+
/**
|
|
665
|
+
* Fee payer signature or the sender to cover the fee of.
|
|
666
|
+
*
|
|
667
|
+
* - If `Signature.Signature`, then this is the fee payer signature.
|
|
668
|
+
* - If `null`, then this indicates the envelope is intended to be signed by a fee payer.
|
|
669
|
+
*/
|
|
670
|
+
feePayerSignature?: Signature.Signature | null | undefined
|
|
671
|
+
format?: undefined
|
|
672
|
+
}
|
|
673
|
+
>
|
|
674
|
+
|
|
675
|
+
type ErrorType =
|
|
676
|
+
| assert.ErrorType
|
|
677
|
+
| Hex.fromNumber.ErrorType
|
|
678
|
+
| Signature.toTuple.ErrorType
|
|
679
|
+
| Hex.concat.ErrorType
|
|
680
|
+
| Rlp.fromHex.ErrorType
|
|
681
|
+
| Errors.GlobalErrorType
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Validates a {@link ox#TransactionEnvelopeFeeToken.TransactionEnvelopeFeeToken}. Returns `true` if the envelope is valid, `false` otherwise.
|
|
686
|
+
*
|
|
687
|
+
* @example
|
|
688
|
+
* ```ts twoslash
|
|
689
|
+
* import { Value } from 'ox'
|
|
690
|
+
* import { TransactionEnvelopeFeeToken } from 'ox/tempo'
|
|
691
|
+
*
|
|
692
|
+
* const valid = TransactionEnvelopeFeeToken.validate({
|
|
693
|
+
* feeToken: '0x20c0000000000000000000000000000000000000',
|
|
694
|
+
* maxFeePerGas: 2n ** 256n - 1n + 1n,
|
|
695
|
+
* chainId: 1,
|
|
696
|
+
* to: '0x0000000000000000000000000000000000000000',
|
|
697
|
+
* value: Value.fromEther('1'),
|
|
698
|
+
* })
|
|
699
|
+
* // @log: false
|
|
700
|
+
* ```
|
|
701
|
+
*
|
|
702
|
+
* @param envelope - The transaction envelope to validate.
|
|
703
|
+
*/
|
|
704
|
+
export function validate(
|
|
705
|
+
envelope: PartialBy<TransactionEnvelopeFeeToken, 'type'>,
|
|
706
|
+
) {
|
|
707
|
+
try {
|
|
708
|
+
assert(envelope)
|
|
709
|
+
return true
|
|
710
|
+
} catch {
|
|
711
|
+
return false
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
export declare namespace validate {
|
|
716
|
+
type ErrorType = Errors.GlobalErrorType
|
|
717
|
+
}
|