tempo.ts 0.0.6 → 0.1.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.
Files changed (195) hide show
  1. package/dist/chains.d.ts +244 -541
  2. package/dist/chains.d.ts.map +1 -1
  3. package/dist/chains.js +10 -23
  4. package/dist/chains.js.map +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/ox/SignatureEnvelope.d.ts +245 -0
  7. package/dist/ox/SignatureEnvelope.d.ts.map +1 -0
  8. package/dist/ox/SignatureEnvelope.js +437 -0
  9. package/dist/ox/SignatureEnvelope.js.map +1 -0
  10. package/dist/ox/Transaction.d.ts +61 -24
  11. package/dist/ox/Transaction.d.ts.map +1 -1
  12. package/dist/ox/Transaction.js +63 -18
  13. package/dist/ox/Transaction.js.map +1 -1
  14. package/dist/ox/TransactionEnvelopeAA.d.ts +461 -0
  15. package/dist/ox/TransactionEnvelopeAA.d.ts.map +1 -0
  16. package/dist/ox/TransactionEnvelopeAA.js +528 -0
  17. package/dist/ox/TransactionEnvelopeAA.js.map +1 -0
  18. package/dist/ox/TransactionRequest.d.ts +7 -5
  19. package/dist/ox/TransactionRequest.d.ts.map +1 -1
  20. package/dist/ox/TransactionRequest.js +21 -12
  21. package/dist/ox/TransactionRequest.js.map +1 -1
  22. package/dist/ox/index.d.ts +5 -4
  23. package/dist/ox/index.d.ts.map +1 -1
  24. package/dist/ox/index.js +5 -4
  25. package/dist/ox/index.js.map +1 -1
  26. package/dist/prool/Instance.d.ts +0 -4
  27. package/dist/prool/Instance.d.ts.map +1 -1
  28. package/dist/prool/Instance.js +7 -7
  29. package/dist/prool/Instance.js.map +1 -1
  30. package/dist/prool/index.d.ts +1 -1
  31. package/dist/prool/index.d.ts.map +1 -1
  32. package/dist/prool/index.js +1 -1
  33. package/dist/prool/index.js.map +1 -1
  34. package/dist/viem/{abis.d.ts → Abis.d.ts} +523 -9
  35. package/dist/viem/Abis.d.ts.map +1 -0
  36. package/dist/viem/{abis.js → Abis.js} +321 -9
  37. package/dist/viem/Abis.js.map +1 -0
  38. package/dist/viem/{actions → Actions}/amm.d.ts +21 -21
  39. package/dist/viem/Actions/amm.d.ts.map +1 -0
  40. package/dist/viem/{actions → Actions}/amm.js +55 -43
  41. package/dist/viem/Actions/amm.js.map +1 -0
  42. package/dist/viem/Actions/dex.d.ts +3263 -0
  43. package/dist/viem/Actions/dex.d.ts.map +1 -0
  44. package/dist/viem/Actions/dex.js +1357 -0
  45. package/dist/viem/Actions/dex.js.map +1 -0
  46. package/dist/viem/{actions → Actions}/fee.d.ts +8 -8
  47. package/dist/viem/Actions/fee.d.ts.map +1 -0
  48. package/dist/viem/{actions → Actions}/fee.js +14 -13
  49. package/dist/viem/Actions/fee.js.map +1 -0
  50. package/dist/viem/Actions/index.d.ts +6 -0
  51. package/dist/viem/Actions/index.d.ts.map +1 -0
  52. package/dist/viem/Actions/index.js +6 -0
  53. package/dist/viem/Actions/index.js.map +1 -0
  54. package/dist/viem/{actions → Actions}/policy.d.ts +19 -19
  55. package/dist/viem/Actions/policy.d.ts.map +1 -0
  56. package/dist/viem/{actions → Actions}/policy.js +59 -46
  57. package/dist/viem/Actions/policy.js.map +1 -0
  58. package/dist/viem/{actions → Actions}/token.d.ts +3275 -698
  59. package/dist/viem/Actions/token.d.ts.map +1 -0
  60. package/dist/viem/{actions → Actions}/token.js +458 -84
  61. package/dist/viem/Actions/token.js.map +1 -0
  62. package/dist/viem/Addresses.d.ts +9 -0
  63. package/dist/viem/Addresses.d.ts.map +1 -0
  64. package/dist/viem/Addresses.js +9 -0
  65. package/dist/viem/Addresses.js.map +1 -0
  66. package/dist/viem/{chain.d.ts → Chain.d.ts} +81 -57
  67. package/dist/viem/Chain.d.ts.map +1 -0
  68. package/dist/viem/{chain.js → Chain.js} +7 -7
  69. package/dist/viem/Chain.js.map +1 -0
  70. package/dist/viem/{client.d.ts → Client.d.ts} +4 -4
  71. package/dist/viem/Client.d.ts.map +1 -0
  72. package/dist/viem/{client.js → Client.js} +3 -3
  73. package/dist/viem/Client.js.map +1 -0
  74. package/dist/viem/{decorator.d.ts → Decorator.d.ts} +507 -5
  75. package/dist/viem/Decorator.d.ts.map +1 -0
  76. package/dist/viem/{decorator.js → Decorator.js} +31 -5
  77. package/dist/viem/Decorator.js.map +1 -0
  78. package/dist/viem/{formatters.d.ts → Formatters.d.ts} +2 -2
  79. package/dist/viem/Formatters.d.ts.map +1 -0
  80. package/dist/viem/{formatters.js → Formatters.js} +24 -17
  81. package/dist/viem/Formatters.js.map +1 -0
  82. package/dist/viem/Tick.d.ts +111 -0
  83. package/dist/viem/Tick.d.ts.map +1 -0
  84. package/dist/viem/Tick.js +127 -0
  85. package/dist/viem/Tick.js.map +1 -0
  86. package/dist/viem/TokenIds.d.ts +3 -0
  87. package/dist/viem/TokenIds.d.ts.map +1 -0
  88. package/dist/viem/TokenIds.js +3 -0
  89. package/dist/viem/TokenIds.js.map +1 -0
  90. package/dist/viem/Transaction.d.ts +57 -0
  91. package/dist/viem/Transaction.d.ts.map +1 -0
  92. package/dist/viem/Transaction.js +137 -0
  93. package/dist/viem/Transaction.js.map +1 -0
  94. package/dist/viem/{transport.d.ts → Transport.d.ts} +3 -3
  95. package/dist/viem/Transport.d.ts.map +1 -0
  96. package/dist/viem/{transport.js → Transport.js} +3 -3
  97. package/dist/viem/Transport.js.map +1 -0
  98. package/dist/viem/index.d.ts +13 -9
  99. package/dist/viem/index.d.ts.map +1 -1
  100. package/dist/viem/index.js +13 -9
  101. package/dist/viem/index.js.map +1 -1
  102. package/dist/viem/{types.d.ts → internal/types.d.ts} +3 -3
  103. package/dist/viem/internal/types.d.ts.map +1 -0
  104. package/dist/viem/{types.js.map → internal/types.js.map} +1 -1
  105. package/dist/viem/internal/utils.d.ts.map +1 -0
  106. package/dist/viem/internal/utils.js.map +1 -0
  107. package/package.json +87 -101
  108. package/src/chains.ts +10 -24
  109. package/src/ox/SignatureEnvelope.test.ts +1252 -0
  110. package/src/ox/SignatureEnvelope.ts +709 -0
  111. package/src/ox/Transaction.test.ts +144 -89
  112. package/src/ox/Transaction.ts +104 -29
  113. package/src/ox/TransactionEnvelopeAA.test.ts +1533 -0
  114. package/src/ox/TransactionEnvelopeAA.ts +858 -0
  115. package/src/ox/TransactionRequest.ts +25 -17
  116. package/src/ox/index.ts +2 -1
  117. package/src/prool/Instance.ts +6 -14
  118. package/src/prool/internal/chain.json +101 -27
  119. package/src/viem/{abis.ts → Abis.ts} +322 -8
  120. package/src/viem/{actions → Actions}/amm.test.ts +65 -68
  121. package/src/viem/{actions → Actions}/amm.ts +72 -60
  122. package/src/viem/Actions/dex.test.ts +1608 -0
  123. package/src/viem/Actions/dex.ts +2026 -0
  124. package/src/viem/{actions → Actions}/fee.test.ts +34 -36
  125. package/src/viem/{actions → Actions}/fee.ts +18 -17
  126. package/src/viem/{actions → Actions}/index.ts +1 -0
  127. package/src/viem/{actions → Actions}/policy.test.ts +2 -2
  128. package/src/viem/{actions → Actions}/policy.ts +77 -64
  129. package/src/viem/{actions → Actions}/token.test.ts +419 -64
  130. package/src/viem/{actions → Actions}/token.ts +751 -145
  131. package/src/viem/Addresses.ts +9 -0
  132. package/src/viem/{chain.ts → Chain.ts} +6 -6
  133. package/src/viem/{client.bench-d.ts → Client.bench-d.ts} +2 -2
  134. package/src/viem/{client.test.ts → Client.test.ts} +31 -6
  135. package/src/viem/{client.ts → Client.ts} +1 -1
  136. package/src/viem/{decorator.bench-d.ts → Decorator.bench-d.ts} +2 -2
  137. package/src/viem/{decorator.test.ts → Decorator.test.ts} +1 -0
  138. package/src/viem/{decorator.ts → Decorator.ts} +586 -4
  139. package/src/viem/{formatters.ts → Formatters.ts} +31 -20
  140. package/src/viem/Tick.test.ts +281 -0
  141. package/src/viem/Tick.ts +176 -0
  142. package/src/viem/TokenIds.ts +2 -0
  143. package/src/viem/Transaction.ts +303 -0
  144. package/src/viem/{transport.ts → Transport.ts} +5 -5
  145. package/src/viem/e2e.test.ts +153 -78
  146. package/src/viem/index.ts +13 -9
  147. package/src/viem/{types.ts → internal/types.ts} +3 -3
  148. package/dist/ox/TransactionEnvelopeFeeToken.d.ts +0 -393
  149. package/dist/ox/TransactionEnvelopeFeeToken.d.ts.map +0 -1
  150. package/dist/ox/TransactionEnvelopeFeeToken.js +0 -452
  151. package/dist/ox/TransactionEnvelopeFeeToken.js.map +0 -1
  152. package/dist/viem/abis.d.ts.map +0 -1
  153. package/dist/viem/abis.js.map +0 -1
  154. package/dist/viem/actions/amm.d.ts.map +0 -1
  155. package/dist/viem/actions/amm.js.map +0 -1
  156. package/dist/viem/actions/fee.d.ts.map +0 -1
  157. package/dist/viem/actions/fee.js.map +0 -1
  158. package/dist/viem/actions/index.d.ts +0 -5
  159. package/dist/viem/actions/index.d.ts.map +0 -1
  160. package/dist/viem/actions/index.js +0 -5
  161. package/dist/viem/actions/index.js.map +0 -1
  162. package/dist/viem/actions/policy.d.ts.map +0 -1
  163. package/dist/viem/actions/policy.js.map +0 -1
  164. package/dist/viem/actions/token.d.ts.map +0 -1
  165. package/dist/viem/actions/token.js.map +0 -1
  166. package/dist/viem/addresses.d.ts +0 -8
  167. package/dist/viem/addresses.d.ts.map +0 -1
  168. package/dist/viem/addresses.js +0 -8
  169. package/dist/viem/addresses.js.map +0 -1
  170. package/dist/viem/chain.d.ts.map +0 -1
  171. package/dist/viem/chain.js.map +0 -1
  172. package/dist/viem/client.d.ts.map +0 -1
  173. package/dist/viem/client.js.map +0 -1
  174. package/dist/viem/decorator.d.ts.map +0 -1
  175. package/dist/viem/decorator.js.map +0 -1
  176. package/dist/viem/formatters.d.ts.map +0 -1
  177. package/dist/viem/formatters.js.map +0 -1
  178. package/dist/viem/transaction.d.ts +0 -54
  179. package/dist/viem/transaction.d.ts.map +0 -1
  180. package/dist/viem/transaction.js +0 -108
  181. package/dist/viem/transaction.js.map +0 -1
  182. package/dist/viem/transport.d.ts.map +0 -1
  183. package/dist/viem/transport.js.map +0 -1
  184. package/dist/viem/types.d.ts.map +0 -1
  185. package/dist/viem/utils.d.ts.map +0 -1
  186. package/dist/viem/utils.js.map +0 -1
  187. package/src/ox/TransactionEnvelopeFeeToken.test.ts +0 -1119
  188. package/src/ox/TransactionEnvelopeFeeToken.ts +0 -717
  189. package/src/prool/internal/consensus.toml +0 -32
  190. package/src/viem/addresses.ts +0 -10
  191. package/src/viem/transaction.ts +0 -253
  192. /package/dist/viem/{types.js → internal/types.js} +0 -0
  193. /package/dist/viem/{utils.d.ts → internal/utils.d.ts} +0 -0
  194. /package/dist/viem/{utils.js → internal/utils.js} +0 -0
  195. /package/src/viem/{utils.ts → internal/utils.ts} +0 -0
@@ -0,0 +1,858 @@
1
+ import * as AccessList from 'ox/AccessList'
2
+ import * as Address from 'ox/Address'
3
+ import type * as Authorization from 'ox/Authorization'
4
+ import * 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 type { OneOf } from 'viem'
11
+ import type {
12
+ Assign,
13
+ Compute,
14
+ PartialBy,
15
+ UnionPartialBy,
16
+ } from '../internal/types.js'
17
+ import * as SignatureEnvelope from './SignatureEnvelope.js'
18
+ import * as TokenId from './TokenId.js'
19
+
20
+ /**
21
+ * Represents a single call within an AA transaction.
22
+ */
23
+ export type Call<bigintType = bigint> = {
24
+ /** Call data. */
25
+ data?: Hex.Hex | undefined
26
+ /** The target address or contract creation. */
27
+ to?: Address.Address | undefined
28
+ /** Value to send (in wei). */
29
+ value?: bigintType | undefined
30
+ }
31
+
32
+ export type TransactionEnvelopeAA<
33
+ signed extends boolean = boolean,
34
+ bigintType = bigint,
35
+ numberType = number,
36
+ type extends string = Type,
37
+ > = Compute<
38
+ {
39
+ /** EIP-2930 Access List. */
40
+ accessList?: AccessList.AccessList | undefined
41
+ /** EIP-7702 Authorization list for the transaction. */
42
+ authorizationList?:
43
+ | Authorization.ListSigned<bigintType, numberType>
44
+ | undefined
45
+ /** EIP-155 Chain ID. */
46
+ chainId: numberType
47
+ /** Sender of the transaction. */
48
+ from?: Address.Address | undefined
49
+ /** Gas provided for transaction execution */
50
+ gas?: bigintType | undefined
51
+ /** Unique number identifying this transaction */
52
+ nonce?: bigintType | undefined
53
+ /** Transaction type */
54
+ type: type
55
+ /** Array of calls to execute. */
56
+ calls: readonly Call<bigintType>[]
57
+ /** Fee payer signature. */
58
+ feePayerSignature?:
59
+ | Signature.Signature<true, bigintType, numberType>
60
+ | null
61
+ | undefined
62
+ /** Fee token preference. Address or ID of the TIP-20 token. */
63
+ feeToken?: TokenId.TokenIdOrAddress | undefined
64
+ /** Total fee per gas in wei (gasPrice/baseFeePerGas + maxPriorityFeePerGas). */
65
+ maxFeePerGas?: bigintType | undefined
66
+ /** Max priority fee per gas (in wei). */
67
+ maxPriorityFeePerGas?: bigintType | undefined
68
+ /** Nonce key for 2D nonce system (192 bits). */
69
+ nonceKey?: bigintType | undefined
70
+ /** Transaction can only be included in a block before this timestamp. */
71
+ validBefore?: numberType | undefined
72
+ /** Transaction can only be included in a block after this timestamp. */
73
+ validAfter?: numberType | undefined
74
+ } & (signed extends true
75
+ ? {
76
+ signature: SignatureEnvelope.SignatureEnvelope<bigintType, numberType>
77
+ }
78
+ : {
79
+ signature?:
80
+ | SignatureEnvelope.SignatureEnvelope<bigintType, numberType>
81
+ | undefined
82
+ })
83
+ >
84
+
85
+ export type Rpc<signed extends boolean = boolean> = TransactionEnvelopeAA<
86
+ signed,
87
+ Hex.Hex,
88
+ Hex.Hex,
89
+ '0x76'
90
+ >
91
+
92
+ export const feePayerMagic = '0x78' as const
93
+ export type FeePayerMagic = typeof feePayerMagic
94
+
95
+ export type Serialized = `${SerializedType}${string}`
96
+
97
+ export type Signed = TransactionEnvelopeAA<true>
98
+
99
+ export const serializedType = '0x76' as const
100
+ export type SerializedType = typeof serializedType
101
+
102
+ export const type = 'aa' as const
103
+ export type Type = typeof type
104
+
105
+ /**
106
+ * Asserts a {@link ox#TransactionEnvelopeAA.TransactionEnvelopeAA} is valid.
107
+ *
108
+ * @example
109
+ * ```ts twoslash
110
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
111
+ *
112
+ * TransactionEnvelopeAA.assert({
113
+ * calls: [{ to: '0x0000000000000000000000000000000000000000', value: 0n }],
114
+ * chainId: 1,
115
+ * maxFeePerGas: 1000000000n,
116
+ * })
117
+ * ```
118
+ *
119
+ * @param envelope - The transaction envelope to assert.
120
+ */
121
+ export function assert(envelope: PartialBy<TransactionEnvelopeAA, 'type'>) {
122
+ const {
123
+ calls,
124
+ chainId,
125
+ maxFeePerGas,
126
+ maxPriorityFeePerGas,
127
+ validBefore,
128
+ validAfter,
129
+ } = envelope
130
+
131
+ // Calls must not be empty
132
+ if (!calls || calls.length === 0) throw new CallsEmptyError()
133
+
134
+ // validBefore must be greater than validAfter if both are set
135
+ if (
136
+ typeof validBefore === 'number' &&
137
+ typeof validAfter === 'number' &&
138
+ validBefore <= validAfter
139
+ ) {
140
+ throw new InvalidValidityWindowError({
141
+ validBefore: validBefore,
142
+ validAfter: validAfter,
143
+ })
144
+ }
145
+
146
+ // Validate each call
147
+ if (calls)
148
+ for (const call of calls)
149
+ if (call.to) Address.assert(call.to, { strict: false })
150
+
151
+ // Validate chain ID
152
+ if (chainId <= 0)
153
+ throw new TransactionEnvelope.InvalidChainIdError({ chainId })
154
+
155
+ // Validate max fee per gas
156
+ if (maxFeePerGas && BigInt(maxFeePerGas) > 2n ** 256n - 1n)
157
+ throw new TransactionEnvelope.FeeCapTooHighError({
158
+ feeCap: maxFeePerGas,
159
+ })
160
+
161
+ if (
162
+ maxPriorityFeePerGas &&
163
+ maxFeePerGas &&
164
+ maxPriorityFeePerGas > maxFeePerGas
165
+ )
166
+ throw new TransactionEnvelope.TipAboveFeeCapError({
167
+ maxFeePerGas,
168
+ maxPriorityFeePerGas,
169
+ })
170
+ }
171
+
172
+ export declare namespace assert {
173
+ type ErrorType =
174
+ | Address.assert.ErrorType
175
+ | CallsEmptyError
176
+ | InvalidValidityWindowError
177
+ | Errors.GlobalErrorType
178
+ }
179
+
180
+ /**
181
+ * Deserializes a {@link ox#TransactionEnvelopeAA.TransactionEnvelopeAA} from its serialized form.
182
+ *
183
+ * @example
184
+ * ```ts twoslash
185
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
186
+ *
187
+ * const envelope = TransactionEnvelopeAA.deserialize('0x76f84a0182031184773594008477359400809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c0808080')
188
+ * // @log: {
189
+ * // @log: type: 'aa',
190
+ * // @log: nonce: 785n,
191
+ * // @log: maxFeePerGas: 2000000000n,
192
+ * // @log: gas: 1000000n,
193
+ * // @log: calls: [{ to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', value: 1000000000000000000n }],
194
+ * // @log: }
195
+ * ```
196
+ *
197
+ * @param serialized - The serialized transaction.
198
+ * @returns Deserialized Transaction Envelope.
199
+ */
200
+ export function deserialize(
201
+ serialized: Serialized,
202
+ ): Compute<TransactionEnvelopeAA> {
203
+ const transactionArray = Rlp.toHex(Hex.slice(serialized, 1))
204
+
205
+ const [
206
+ chainId,
207
+ maxPriorityFeePerGas,
208
+ maxFeePerGas,
209
+ gas,
210
+ calls,
211
+ accessList,
212
+ nonceKey,
213
+ nonce,
214
+ validBefore,
215
+ validAfter,
216
+ feeToken,
217
+ feePayerSignatureOrSender,
218
+ signature,
219
+ ] = transactionArray as readonly Hex.Hex[]
220
+
221
+ if (!(transactionArray.length === 12 || transactionArray.length === 13))
222
+ throw new TransactionEnvelope.InvalidSerializedError({
223
+ attributes: {
224
+ chainId,
225
+ maxPriorityFeePerGas,
226
+ maxFeePerGas,
227
+ gas,
228
+ calls,
229
+ accessList,
230
+ nonceKey,
231
+ nonce,
232
+ validBefore,
233
+ validAfter,
234
+ feeToken,
235
+ feePayerSignatureOrSender,
236
+ ...(transactionArray.length > 12
237
+ ? {
238
+ signature,
239
+ }
240
+ : {}),
241
+ },
242
+ serialized,
243
+ type,
244
+ })
245
+
246
+ let transaction = {
247
+ chainId: Number(chainId),
248
+ type,
249
+ } as TransactionEnvelopeAA
250
+
251
+ if (Hex.validate(gas) && gas !== '0x') transaction.gas = BigInt(gas)
252
+ if (Hex.validate(nonce))
253
+ transaction.nonce = nonce === '0x' ? 0n : BigInt(nonce)
254
+ if (Hex.validate(maxFeePerGas) && maxFeePerGas !== '0x')
255
+ transaction.maxFeePerGas = BigInt(maxFeePerGas)
256
+ if (Hex.validate(maxPriorityFeePerGas) && maxPriorityFeePerGas !== '0x')
257
+ transaction.maxPriorityFeePerGas = BigInt(maxPriorityFeePerGas)
258
+ if (Hex.validate(nonceKey))
259
+ transaction.nonceKey = nonceKey === '0x' ? 0n : BigInt(nonceKey)
260
+ if (Hex.validate(validBefore) && validBefore !== '0x')
261
+ transaction.validBefore = Number(validBefore)
262
+ if (Hex.validate(validAfter) && validAfter !== '0x')
263
+ transaction.validAfter = Number(validAfter)
264
+ if (Hex.validate(feeToken) && feeToken !== '0x')
265
+ transaction.feeToken = feeToken
266
+
267
+ // Parse calls array
268
+ if (calls && calls !== '0x') {
269
+ const callsArray = calls as unknown as readonly Hex.Hex[][]
270
+ transaction.calls = callsArray.map((callTuple) => {
271
+ const [to, value, data] = callTuple
272
+ const call: Call = {}
273
+ if (to && to !== '0x') call.to = to
274
+ if (value && value !== '0x') call.value = BigInt(value)
275
+ if (data && data !== '0x') call.data = data
276
+ return call
277
+ })
278
+ }
279
+
280
+ if (accessList?.length !== 0 && accessList !== '0x')
281
+ transaction.accessList = AccessList.fromTupleList(accessList as never)
282
+
283
+ if (
284
+ feePayerSignatureOrSender !== '0x' &&
285
+ feePayerSignatureOrSender !== undefined
286
+ ) {
287
+ if (
288
+ feePayerSignatureOrSender === '0x00' ||
289
+ Address.validate(feePayerSignatureOrSender)
290
+ )
291
+ transaction.feePayerSignature = null
292
+ else
293
+ transaction.feePayerSignature = Signature.fromTuple(
294
+ feePayerSignatureOrSender as never,
295
+ )
296
+ }
297
+
298
+ const signatureEnvelope = signature
299
+ ? SignatureEnvelope.deserialize(signature)
300
+ : undefined
301
+ if (signatureEnvelope)
302
+ transaction = {
303
+ ...transaction,
304
+ signature: signatureEnvelope,
305
+ }
306
+
307
+ assert(transaction)
308
+
309
+ return transaction
310
+ }
311
+
312
+ export declare namespace deserialize {
313
+ type ErrorType = Errors.GlobalErrorType
314
+ }
315
+
316
+ /**
317
+ * Converts an arbitrary transaction object into an AA Transaction Envelope.
318
+ *
319
+ * @example
320
+ * ```ts twoslash
321
+ * import { Value } from 'ox'
322
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
323
+ *
324
+ * const envelope = TransactionEnvelopeAA.from({ // [!code focus]
325
+ * chainId: 1, // [!code focus]
326
+ * calls: [{ to: '0x0000000000000000000000000000000000000000', value: Value.fromEther('1') }], // [!code focus]
327
+ * maxFeePerGas: Value.fromGwei('10'), // [!code focus]
328
+ * maxPriorityFeePerGas: Value.fromGwei('1'), // [!code focus]
329
+ * }) // [!code focus]
330
+ * ```
331
+ *
332
+ * @example
333
+ * ### Attaching Signatures
334
+ *
335
+ * It is possible to attach a `signature` to the transaction envelope.
336
+ *
337
+ * ```ts twoslash
338
+ * // @noErrors
339
+ * import { Secp256k1, Value } from 'ox'
340
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
341
+ *
342
+ * const envelope = TransactionEnvelopeAA.from({
343
+ * chainId: 1,
344
+ * calls: [{ to: '0x0000000000000000000000000000000000000000', value: Value.fromEther('1') }],
345
+ * maxFeePerGas: Value.fromGwei('10'),
346
+ * maxPriorityFeePerGas: Value.fromGwei('1'),
347
+ * })
348
+ *
349
+ * const signature = Secp256k1.sign({
350
+ * payload: TransactionEnvelopeAA.getSignPayload(envelope),
351
+ * privateKey: '0x...',
352
+ * })
353
+ *
354
+ * const envelope_signed = TransactionEnvelopeAA.from(envelope, { // [!code focus]
355
+ * signature, // [!code focus]
356
+ * }) // [!code focus]
357
+ * // @log: {
358
+ * // @log: chainId: 1,
359
+ * // @log: calls: [{ to: '0x0000000000000000000000000000000000000000', value: 1000000000000000000n }],
360
+ * // @log: maxFeePerGas: 10000000000n,
361
+ * // @log: maxPriorityFeePerGas: 1000000000n,
362
+ * // @log: type: 'aa',
363
+ * // @log: r: 125...n,
364
+ * // @log: s: 642...n,
365
+ * // @log: yParity: 0,
366
+ * // @log: }
367
+ * ```
368
+ *
369
+ * @example
370
+ * ### From Serialized
371
+ *
372
+ * It is possible to instantiate an AA Transaction Envelope from a {@link ox#TransactionEnvelopeAA.Serialized} value.
373
+ *
374
+ * ```ts twoslash
375
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
376
+ *
377
+ * const envelope = TransactionEnvelopeAA.from('0x76f84a0182031184773594008477359400809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c0808080')
378
+ * // @log: {
379
+ * // @log: chainId: 1,
380
+ * // @log: calls: [{ to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', value: 1000000000000000000n }],
381
+ * // @log: maxFeePerGas: 10000000000n,
382
+ * // @log: type: 'aa',
383
+ * // @log: }
384
+ * ```
385
+ *
386
+ * @param envelope - The transaction object to convert.
387
+ * @param options - Options.
388
+ * @returns An AA Transaction Envelope.
389
+ */
390
+ export function from<
391
+ const envelope extends
392
+ | UnionPartialBy<TransactionEnvelopeAA, 'type'>
393
+ | Serialized,
394
+ const signature extends
395
+ | SignatureEnvelope.SignatureEnvelope
396
+ | undefined = undefined,
397
+ >(
398
+ envelope:
399
+ | envelope
400
+ | UnionPartialBy<TransactionEnvelopeAA, 'type'>
401
+ | Serialized,
402
+ options: from.Options<signature> = {},
403
+ ): from.ReturnValue<envelope, signature> {
404
+ const { feePayerSignature, signature } = options
405
+
406
+ const envelope_ = (
407
+ typeof envelope === 'string' ? deserialize(envelope) : envelope
408
+ ) as TransactionEnvelopeAA
409
+
410
+ assert(envelope_)
411
+
412
+ return {
413
+ ...envelope_,
414
+ ...(signature ? { signature: SignatureEnvelope.from(signature) } : {}),
415
+ ...(feePayerSignature
416
+ ? { feePayerSignature: Signature.from(feePayerSignature) }
417
+ : {}),
418
+ type: 'aa',
419
+ } as never
420
+ }
421
+
422
+ export declare namespace from {
423
+ type Options<
424
+ signature extends
425
+ | SignatureEnvelope.SignatureEnvelope
426
+ | undefined = undefined,
427
+ > = {
428
+ feePayerSignature?: Signature.Signature | null | undefined
429
+ signature?: signature | SignatureEnvelope.SignatureEnvelope | undefined
430
+ }
431
+
432
+ type ReturnValue<
433
+ envelope extends UnionPartialBy<TransactionEnvelopeAA, 'type'> | Hex.Hex =
434
+ | TransactionEnvelopeAA
435
+ | Hex.Hex,
436
+ signature extends
437
+ | SignatureEnvelope.SignatureEnvelope
438
+ | undefined = undefined,
439
+ > = Compute<
440
+ envelope extends Hex.Hex
441
+ ? TransactionEnvelopeAA
442
+ : Assign<
443
+ envelope,
444
+ (signature extends SignatureEnvelope.SignatureEnvelope
445
+ ? { signature: SignatureEnvelope.from.ReturnValue<signature> }
446
+ : {}) & {
447
+ readonly type: 'aa'
448
+ }
449
+ >
450
+ >
451
+
452
+ type ErrorType =
453
+ | deserialize.ErrorType
454
+ | assert.ErrorType
455
+ | Errors.GlobalErrorType
456
+ }
457
+
458
+ /**
459
+ * Serializes a {@link ox#TransactionEnvelopeAA.TransactionEnvelopeAA}.
460
+ *
461
+ * @example
462
+ * ```ts twoslash
463
+ * // @noErrors
464
+ * import { Value } from 'ox'
465
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
466
+ *
467
+ * const envelope = TransactionEnvelopeAA.from({
468
+ * chainId: 1,
469
+ * calls: [{ to: '0x0000000000000000000000000000000000000000', value: Value.fromEther('1') }],
470
+ * maxFeePerGas: Value.fromGwei('10'),
471
+ * })
472
+ *
473
+ * const serialized = TransactionEnvelopeAA.serialize(envelope) // [!code focus]
474
+ * ```
475
+ *
476
+ * @example
477
+ * ### Attaching Signatures
478
+ *
479
+ * It is possible to attach a `signature` to the serialized Transaction Envelope.
480
+ *
481
+ * ```ts twoslash
482
+ * // @noErrors
483
+ * import { Secp256k1, Value } from 'ox'
484
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
485
+ *
486
+ * const envelope = TransactionEnvelopeAA.from({
487
+ * chainId: 1,
488
+ * calls: [{ to: '0x0000000000000000000000000000000000000000', value: Value.fromEther('1') }],
489
+ * maxFeePerGas: Value.fromGwei('10'),
490
+ * })
491
+ *
492
+ * const signature = Secp256k1.sign({
493
+ * payload: TransactionEnvelopeAA.getSignPayload(envelope),
494
+ * privateKey: '0x...',
495
+ * })
496
+ *
497
+ * const serialized = TransactionEnvelopeAA.serialize(envelope, { // [!code focus]
498
+ * signature, // [!code focus]
499
+ * }) // [!code focus]
500
+ *
501
+ * // ... send `serialized` transaction to JSON-RPC `eth_sendRawTransaction`
502
+ * ```
503
+ *
504
+ * @param envelope - The Transaction Envelope to serialize.
505
+ * @param options - Options.
506
+ * @returns The serialized Transaction Envelope.
507
+ */
508
+ export function serialize(
509
+ envelope: PartialBy<TransactionEnvelopeAA, 'type'>,
510
+ options: serialize.Options = {},
511
+ ): Serialized {
512
+ const {
513
+ accessList,
514
+ calls,
515
+ chainId,
516
+ feeToken,
517
+ gas,
518
+ nonce,
519
+ nonceKey,
520
+ maxFeePerGas,
521
+ maxPriorityFeePerGas,
522
+ validBefore,
523
+ validAfter,
524
+ } = envelope
525
+
526
+ assert(envelope)
527
+
528
+ const accessTupleList = AccessList.toTupleList(accessList)
529
+ const signature = options.signature || envelope.signature
530
+
531
+ // Encode calls as RLP list of [to, value, data] tuples
532
+ const callsTupleList = calls.map((call) => [
533
+ call.to ?? '0x',
534
+ call.value ? Hex.fromNumber(call.value) : '0x',
535
+ call.data ?? '0x',
536
+ ])
537
+
538
+ const feePayerSignatureOrSender = (() => {
539
+ if (options.sender) return options.sender
540
+ const feePayerSignature =
541
+ typeof options.feePayerSignature !== 'undefined'
542
+ ? options.feePayerSignature
543
+ : envelope.feePayerSignature
544
+ if (feePayerSignature === null) return '0x00'
545
+ if (!feePayerSignature) return '0x'
546
+ return Signature.toTuple(feePayerSignature)
547
+ })()
548
+
549
+ const serialized = [
550
+ Hex.fromNumber(chainId),
551
+ maxPriorityFeePerGas ? Hex.fromNumber(maxPriorityFeePerGas) : '0x',
552
+ maxFeePerGas ? Hex.fromNumber(maxFeePerGas) : '0x',
553
+ gas ? Hex.fromNumber(gas) : '0x',
554
+ callsTupleList,
555
+ accessTupleList,
556
+ nonceKey ? Hex.fromNumber(nonceKey) : '0x',
557
+ nonce ? Hex.fromNumber(nonce) : '0x',
558
+ typeof validBefore === 'number' ? Hex.fromNumber(validBefore) : '0x',
559
+ typeof validAfter === 'number' ? Hex.fromNumber(validAfter) : '0x',
560
+ typeof feeToken === 'bigint' || typeof feeToken === 'string'
561
+ ? TokenId.toAddress(feeToken)
562
+ : '0x',
563
+ feePayerSignatureOrSender,
564
+ ...(signature
565
+ ? [SignatureEnvelope.serialize(SignatureEnvelope.from(signature))]
566
+ : []),
567
+ ] as const
568
+
569
+ return Hex.concat(
570
+ options.format === 'feePayer' ? feePayerMagic : serializedType,
571
+ Rlp.fromHex(serialized),
572
+ ) as Serialized
573
+ }
574
+
575
+ export declare namespace serialize {
576
+ type Options = {
577
+ /**
578
+ * Sender signature to append to the serialized envelope.
579
+ */
580
+ signature?: SignatureEnvelope.SignatureEnvelope | undefined
581
+ } & OneOf<
582
+ | {
583
+ /**
584
+ * Sender address to cover the fee of.
585
+ */
586
+ sender: Address.Address
587
+ /**
588
+ * Whether to serialize the transaction in the fee payer format.
589
+ *
590
+ * - If `'feePayer'`, then the transaction will be serialized in the fee payer format.
591
+ * - If `undefined` (default), then the transaction will be serialized in the normal format.
592
+ */
593
+ format: 'feePayer'
594
+ }
595
+ | {
596
+ /**
597
+ * Fee payer signature or the sender to cover the fee of.
598
+ *
599
+ * - If `Signature.Signature`, then this is the fee payer signature.
600
+ * - If `null`, then this indicates the envelope is intended to be signed by a fee payer.
601
+ */
602
+ feePayerSignature?: Signature.Signature | null | undefined
603
+ format?: undefined
604
+ }
605
+ >
606
+
607
+ type ErrorType =
608
+ | assert.ErrorType
609
+ | Hex.fromNumber.ErrorType
610
+ | Signature.toTuple.ErrorType
611
+ | Hex.concat.ErrorType
612
+ | Rlp.fromHex.ErrorType
613
+ | Errors.GlobalErrorType
614
+ }
615
+
616
+ /**
617
+ * Returns the payload to sign for a {@link ox#TransactionEnvelopeAA.TransactionEnvelopeAA}.
618
+ *
619
+ * @example
620
+ * The example below demonstrates how to compute the sign payload which can be used
621
+ * with ECDSA signing utilities like {@link ox#Secp256k1.(sign:function)}.
622
+ *
623
+ * ```ts twoslash
624
+ * // @noErrors
625
+ * import { Secp256k1 } from 'ox'
626
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
627
+ *
628
+ * const envelope = TransactionEnvelopeAA.from({
629
+ * chainId: 1,
630
+ * calls: [{ to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', value: 1000000000000000000n }],
631
+ * nonce: 0n,
632
+ * maxFeePerGas: 1000000000n,
633
+ * gas: 21000n,
634
+ * })
635
+ *
636
+ * const payload = TransactionEnvelopeAA.getSignPayload(envelope) // [!code focus]
637
+ * // @log: '0x...'
638
+ *
639
+ * const signature = Secp256k1.sign({ payload, privateKey: '0x...' })
640
+ * ```
641
+ *
642
+ * @param envelope - The transaction envelope to get the sign payload for.
643
+ * @returns The sign payload.
644
+ */
645
+ export function getSignPayload(
646
+ envelope: TransactionEnvelopeAA,
647
+ ): getSignPayload.ReturnValue {
648
+ return hash(envelope, { presign: true })
649
+ }
650
+
651
+ export declare namespace getSignPayload {
652
+ type ReturnValue = Hex.Hex
653
+
654
+ type ErrorType = hash.ErrorType | Errors.GlobalErrorType
655
+ }
656
+
657
+ /**
658
+ * Hashes a {@link ox#TransactionEnvelopeAA.TransactionEnvelopeAA}. This is the "transaction hash".
659
+ *
660
+ * @example
661
+ * ```ts twoslash
662
+ * // @noErrors
663
+ * import { Secp256k1 } from 'ox'
664
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
665
+ *
666
+ * const envelope = TransactionEnvelopeAA.from({
667
+ * chainId: 1,
668
+ * calls: [{ to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', value: 1000000000000000000n }],
669
+ * nonce: 0n,
670
+ * maxFeePerGas: 1000000000n,
671
+ * gas: 21000n,
672
+ * })
673
+ *
674
+ * const signature = Secp256k1.sign({
675
+ * payload: TransactionEnvelopeAA.getSignPayload(envelope),
676
+ * privateKey: '0x...'
677
+ * })
678
+ *
679
+ * const envelope_signed = TransactionEnvelopeAA.from(envelope, { signature })
680
+ *
681
+ * const hash = TransactionEnvelopeAA.hash(envelope_signed) // [!code focus]
682
+ * ```
683
+ *
684
+ * @param envelope - The AA Transaction Envelope to hash.
685
+ * @param options - Options.
686
+ * @returns The hash of the transaction envelope.
687
+ */
688
+ export function hash<presign extends boolean = false>(
689
+ envelope: TransactionEnvelopeAA<presign extends true ? false : true>,
690
+ options: hash.Options<presign> = {},
691
+ ): hash.ReturnValue {
692
+ const serialized = serialize({
693
+ ...envelope,
694
+ ...(options.presign
695
+ ? {
696
+ signature: undefined,
697
+ }
698
+ : {}),
699
+ })
700
+ return Hash.keccak256(serialized)
701
+ }
702
+
703
+ export declare namespace hash {
704
+ type Options<presign extends boolean = false> = {
705
+ /**
706
+ * Whether to hash this transaction for signing.
707
+ *
708
+ * @default false
709
+ */
710
+ presign?: presign | boolean | undefined
711
+ }
712
+
713
+ type ReturnValue = Hex.Hex
714
+
715
+ type ErrorType =
716
+ | Hash.keccak256.ErrorType
717
+ | serialize.ErrorType
718
+ | Errors.GlobalErrorType
719
+ }
720
+
721
+ /**
722
+ * Returns the fee payer payload to sign for a {@link ox#TransactionEnvelopeAA.TransactionEnvelopeAA}.
723
+ *
724
+ * @example
725
+ * ```ts twoslash
726
+ * // @noErrors
727
+ * import { Secp256k1 } from 'ox'
728
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
729
+ *
730
+ * const envelope = TransactionEnvelopeAA.from({
731
+ * chainId: 1,
732
+ * calls: [{ to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', value: 1000000000000000000n }],
733
+ * nonce: 0n,
734
+ * maxFeePerGas: 1000000000n,
735
+ * gas: 21000n,
736
+ * })
737
+ *
738
+ * const payload = TransactionEnvelopeAA.getFeePayerSignPayload(envelope, {
739
+ * sender: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045'
740
+ * }) // [!code focus]
741
+ * // @log: '0x...'
742
+ *
743
+ * const signature = Secp256k1.sign({ payload, privateKey: '0x...' })
744
+ * ```
745
+ *
746
+ * @param envelope - The transaction envelope to get the fee payer sign payload for.
747
+ * @param options - Options.
748
+ * @returns The fee payer sign payload.
749
+ */
750
+ export function getFeePayerSignPayload(
751
+ envelope: TransactionEnvelopeAA,
752
+ options: getFeePayerSignPayload.Options,
753
+ ): getFeePayerSignPayload.ReturnValue {
754
+ const { sender } = options
755
+ const serialized = serialize(
756
+ { ...envelope, signature: undefined },
757
+ {
758
+ sender,
759
+ format: 'feePayer',
760
+ },
761
+ )
762
+ return Hash.keccak256(serialized)
763
+ }
764
+
765
+ export declare namespace getFeePayerSignPayload {
766
+ type Options = {
767
+ /**
768
+ * Sender address to cover the fee of.
769
+ */
770
+ sender: Address.Address
771
+ }
772
+
773
+ type ReturnValue = Hex.Hex
774
+
775
+ type ErrorType = hash.ErrorType | Errors.GlobalErrorType
776
+ }
777
+
778
+ /**
779
+ * Validates a {@link ox#TransactionEnvelopeAA.TransactionEnvelopeAA}. Returns `true` if the envelope is valid, `false` otherwise.
780
+ *
781
+ * @example
782
+ * ```ts twoslash
783
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
784
+ *
785
+ * const valid = TransactionEnvelopeAA.validate({
786
+ * calls: [{ to: '0x0000000000000000000000000000000000000000', value: 0n }],
787
+ * chainId: 1,
788
+ * maxFeePerGas: 1000000000n,
789
+ * })
790
+ * // @log: true
791
+ * ```
792
+ *
793
+ * @param envelope - The transaction envelope to validate.
794
+ */
795
+ export function validate(envelope: PartialBy<TransactionEnvelopeAA, 'type'>) {
796
+ try {
797
+ assert(envelope)
798
+ return true
799
+ } catch {
800
+ return false
801
+ }
802
+ }
803
+
804
+ export declare namespace validate {
805
+ type ErrorType = Errors.GlobalErrorType
806
+ }
807
+
808
+ /**
809
+ * Thrown when a transaction's calls list is empty.
810
+ *
811
+ * @example
812
+ * ```ts twoslash
813
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
814
+ *
815
+ * TransactionEnvelopeAA.assert({
816
+ * calls: [],
817
+ * chainId: 1,
818
+ * })
819
+ * // @error: TransactionEnvelopeAA.CallsEmptyError: Calls list cannot be empty.
820
+ * ```
821
+ */
822
+ export class CallsEmptyError extends Errors.BaseError {
823
+ override readonly name = 'TransactionEnvelopeAA.CallsEmptyError'
824
+ constructor() {
825
+ super('Calls list cannot be empty.')
826
+ }
827
+ }
828
+
829
+ /**
830
+ * Thrown when validBefore is not greater than validAfter.
831
+ *
832
+ * @example
833
+ * ```ts twoslash
834
+ * import { TransactionEnvelopeAA } from 'ox/tempo'
835
+ *
836
+ * TransactionEnvelopeAA.assert({
837
+ * calls: [{ to: '0x0000000000000000000000000000000000000000' }],
838
+ * chainId: 1,
839
+ * validBefore: 100n,
840
+ * validAfter: 200n,
841
+ * })
842
+ * // @error: TransactionEnvelopeAA.InvalidValidityWindowError: validBefore (100) must be greater than validAfter (200).
843
+ * ```
844
+ */
845
+ export class InvalidValidityWindowError extends Errors.BaseError {
846
+ override readonly name = 'TransactionEnvelopeAA.InvalidValidityWindowError'
847
+ constructor({
848
+ validBefore,
849
+ validAfter,
850
+ }: {
851
+ validBefore: number
852
+ validAfter: number
853
+ }) {
854
+ super(
855
+ `validBefore (${validBefore}) must be greater than validAfter (${validAfter}).`,
856
+ )
857
+ }
858
+ }