tempo.ts 0.10.5 → 0.11.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 (203) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +0 -41
  3. package/dist/viem/Account.d.ts +8 -3
  4. package/dist/viem/Account.d.ts.map +1 -1
  5. package/dist/viem/Account.js +9 -2
  6. package/dist/viem/Account.js.map +1 -1
  7. package/dist/viem/Actions/account.d.ts.map +1 -1
  8. package/dist/viem/Actions/account.js +1 -1
  9. package/dist/viem/Actions/account.js.map +1 -1
  10. package/dist/viem/Actions/amm.d.ts +1 -1
  11. package/dist/viem/Actions/amm.d.ts.map +1 -1
  12. package/dist/viem/Actions/amm.js +1 -2
  13. package/dist/viem/Actions/amm.js.map +1 -1
  14. package/dist/viem/Actions/dex.d.ts +0 -35
  15. package/dist/viem/Actions/dex.d.ts.map +1 -1
  16. package/dist/viem/Actions/dex.js +0 -43
  17. package/dist/viem/Actions/dex.js.map +1 -1
  18. package/dist/viem/Actions/fee.d.ts +1 -1
  19. package/dist/viem/Actions/fee.d.ts.map +1 -1
  20. package/dist/viem/Actions/fee.js +1 -1
  21. package/dist/viem/Actions/fee.js.map +1 -1
  22. package/dist/viem/Actions/nonce.d.ts.map +1 -1
  23. package/dist/viem/Actions/nonce.js +6 -4
  24. package/dist/viem/Actions/nonce.js.map +1 -1
  25. package/dist/viem/Actions/token.d.ts +1 -2
  26. package/dist/viem/Actions/token.d.ts.map +1 -1
  27. package/dist/viem/Actions/token.js +1 -2
  28. package/dist/viem/Actions/token.js.map +1 -1
  29. package/dist/viem/Chain.d.ts +34 -34
  30. package/dist/viem/Chain.d.ts.map +1 -1
  31. package/dist/viem/Chain.js +2 -0
  32. package/dist/viem/Chain.js.map +1 -1
  33. package/dist/viem/Decorator.d.ts +0 -27
  34. package/dist/viem/Decorator.d.ts.map +1 -1
  35. package/dist/viem/Decorator.js +0 -1
  36. package/dist/viem/Decorator.js.map +1 -1
  37. package/dist/viem/Formatters.d.ts.map +1 -1
  38. package/dist/viem/Formatters.js +5 -3
  39. package/dist/viem/Formatters.js.map +1 -1
  40. package/dist/viem/Transaction.d.ts +8 -5
  41. package/dist/viem/Transaction.d.ts.map +1 -1
  42. package/dist/viem/Transaction.js +13 -3
  43. package/dist/viem/Transaction.js.map +1 -1
  44. package/dist/viem/index.d.ts +10 -1
  45. package/dist/viem/index.d.ts.map +1 -1
  46. package/dist/viem/index.js +1 -1
  47. package/dist/viem/index.js.map +1 -1
  48. package/dist/viem/internal/types.d.ts +1 -1
  49. package/dist/viem/internal/types.d.ts.map +1 -1
  50. package/dist/wagmi/Actions/dex.d.ts +1 -45
  51. package/dist/wagmi/Actions/dex.d.ts.map +1 -1
  52. package/dist/wagmi/Actions/dex.js +0 -55
  53. package/dist/wagmi/Actions/dex.js.map +1 -1
  54. package/dist/wagmi/Connector.d.ts +1 -1
  55. package/dist/wagmi/Connector.d.ts.map +1 -1
  56. package/dist/wagmi/Connector.js +1 -2
  57. package/dist/wagmi/Connector.js.map +1 -1
  58. package/dist/wagmi/Hooks/dex.d.ts +3 -46
  59. package/dist/wagmi/Hooks/dex.d.ts.map +1 -1
  60. package/dist/wagmi/Hooks/dex.js +2 -54
  61. package/dist/wagmi/Hooks/dex.js.map +1 -1
  62. package/dist/wagmi/index.d.ts +1 -1
  63. package/dist/wagmi/index.d.ts.map +1 -1
  64. package/dist/wagmi/index.js +1 -1
  65. package/dist/wagmi/index.js.map +1 -1
  66. package/package.json +5 -13
  67. package/src/viem/Account.test.ts +1 -1
  68. package/src/viem/Account.ts +11 -2
  69. package/src/viem/Actions/account.ts +1 -1
  70. package/src/viem/Actions/amm.ts +1 -2
  71. package/src/viem/Actions/dex.test.ts +1 -195
  72. package/src/viem/Actions/dex.ts +0 -53
  73. package/src/viem/Actions/fee.test.ts +2 -2
  74. package/src/viem/Actions/fee.ts +1 -1
  75. package/src/viem/Actions/nonce.test.ts +27 -14
  76. package/src/viem/Actions/nonce.ts +6 -4
  77. package/src/viem/Actions/token.test.ts +18 -52
  78. package/src/viem/Actions/token.ts +1 -2
  79. package/src/viem/Chain.ts +3 -1
  80. package/src/viem/Decorator.ts +0 -30
  81. package/src/viem/Formatters.ts +9 -3
  82. package/src/viem/Transaction.ts +23 -7
  83. package/src/viem/e2e.test.ts +19 -0
  84. package/src/viem/index.ts +12 -1
  85. package/src/viem/internal/types.ts +1 -1
  86. package/src/wagmi/Actions/dex.test.ts +0 -26
  87. package/src/wagmi/Actions/dex.ts +1 -111
  88. package/src/wagmi/Actions/nonce.test.ts +8 -4
  89. package/src/wagmi/Actions/token.test.ts +2 -2
  90. package/src/wagmi/Connector.ts +1 -2
  91. package/src/wagmi/Hooks/dex.test.ts +0 -26
  92. package/src/wagmi/Hooks/dex.ts +1 -88
  93. package/src/wagmi/Hooks/nonce.test.ts +3 -3
  94. package/src/wagmi/index.ts +4 -1
  95. package/dist/ox/AuthorizationTempo.d.ts +0 -450
  96. package/dist/ox/AuthorizationTempo.d.ts.map +0 -1
  97. package/dist/ox/AuthorizationTempo.js +0 -433
  98. package/dist/ox/AuthorizationTempo.js.map +0 -1
  99. package/dist/ox/KeyAuthorization.d.ts +0 -356
  100. package/dist/ox/KeyAuthorization.d.ts.map +0 -1
  101. package/dist/ox/KeyAuthorization.js +0 -359
  102. package/dist/ox/KeyAuthorization.js.map +0 -1
  103. package/dist/ox/Order.d.ts +0 -92
  104. package/dist/ox/Order.d.ts.map +0 -1
  105. package/dist/ox/Order.js +0 -88
  106. package/dist/ox/Order.js.map +0 -1
  107. package/dist/ox/OrdersFilters.d.ts +0 -72
  108. package/dist/ox/OrdersFilters.d.ts.map +0 -1
  109. package/dist/ox/OrdersFilters.js +0 -100
  110. package/dist/ox/OrdersFilters.js.map +0 -1
  111. package/dist/ox/Pagination.d.ts +0 -128
  112. package/dist/ox/Pagination.d.ts.map +0 -1
  113. package/dist/ox/Pagination.js +0 -78
  114. package/dist/ox/Pagination.js.map +0 -1
  115. package/dist/ox/PoolId.d.ts +0 -18
  116. package/dist/ox/PoolId.d.ts.map +0 -1
  117. package/dist/ox/PoolId.js +0 -13
  118. package/dist/ox/PoolId.js.map +0 -1
  119. package/dist/ox/RpcSchema.d.ts +0 -32
  120. package/dist/ox/RpcSchema.d.ts.map +0 -1
  121. package/dist/ox/RpcSchema.js +0 -2
  122. package/dist/ox/RpcSchema.js.map +0 -1
  123. package/dist/ox/SignatureEnvelope.d.ts +0 -260
  124. package/dist/ox/SignatureEnvelope.d.ts.map +0 -1
  125. package/dist/ox/SignatureEnvelope.js +0 -477
  126. package/dist/ox/SignatureEnvelope.js.map +0 -1
  127. package/dist/ox/Tick.d.ts +0 -115
  128. package/dist/ox/Tick.d.ts.map +0 -1
  129. package/dist/ox/Tick.js +0 -127
  130. package/dist/ox/Tick.js.map +0 -1
  131. package/dist/ox/TokenId.d.ts +0 -25
  132. package/dist/ox/TokenId.d.ts.map +0 -1
  133. package/dist/ox/TokenId.js +0 -41
  134. package/dist/ox/TokenId.js.map +0 -1
  135. package/dist/ox/TokenRole.d.ts +0 -11
  136. package/dist/ox/TokenRole.d.ts.map +0 -1
  137. package/dist/ox/TokenRole.js +0 -22
  138. package/dist/ox/TokenRole.js.map +0 -1
  139. package/dist/ox/Transaction.d.ts +0 -201
  140. package/dist/ox/Transaction.d.ts.map +0 -1
  141. package/dist/ox/Transaction.js +0 -167
  142. package/dist/ox/Transaction.js.map +0 -1
  143. package/dist/ox/TransactionEnvelopeTempo.d.ts +0 -470
  144. package/dist/ox/TransactionEnvelopeTempo.d.ts.map +0 -1
  145. package/dist/ox/TransactionEnvelopeTempo.js +0 -547
  146. package/dist/ox/TransactionEnvelopeTempo.js.map +0 -1
  147. package/dist/ox/TransactionReceipt.d.ts +0 -155
  148. package/dist/ox/TransactionReceipt.d.ts.map +0 -1
  149. package/dist/ox/TransactionReceipt.js +0 -136
  150. package/dist/ox/TransactionReceipt.js.map +0 -1
  151. package/dist/ox/TransactionRequest.d.ts +0 -76
  152. package/dist/ox/TransactionRequest.d.ts.map +0 -1
  153. package/dist/ox/TransactionRequest.js +0 -93
  154. package/dist/ox/TransactionRequest.js.map +0 -1
  155. package/dist/ox/index.d.ts +0 -14
  156. package/dist/ox/index.d.ts.map +0 -1
  157. package/dist/ox/index.js +0 -14
  158. package/dist/ox/index.js.map +0 -1
  159. package/dist/prool/Instance.d.ts +0 -101
  160. package/dist/prool/Instance.d.ts.map +0 -1
  161. package/dist/prool/Instance.js +0 -136
  162. package/dist/prool/Instance.js.map +0 -1
  163. package/dist/prool/chain.json +0 -238
  164. package/dist/prool/index.d.ts +0 -2
  165. package/dist/prool/index.d.ts.map +0 -1
  166. package/dist/prool/index.js +0 -2
  167. package/dist/prool/index.js.map +0 -1
  168. package/src/ox/AuthorizationTempo.test.ts +0 -1256
  169. package/src/ox/AuthorizationTempo.ts +0 -648
  170. package/src/ox/KeyAuthorization.test.ts +0 -1332
  171. package/src/ox/KeyAuthorization.ts +0 -540
  172. package/src/ox/Order.test.ts +0 -78
  173. package/src/ox/Order.ts +0 -125
  174. package/src/ox/OrdersFilters.test.ts +0 -182
  175. package/src/ox/OrdersFilters.ts +0 -125
  176. package/src/ox/Pagination.test.ts +0 -162
  177. package/src/ox/Pagination.ts +0 -164
  178. package/src/ox/PoolId.test.ts +0 -33
  179. package/src/ox/PoolId.ts +0 -27
  180. package/src/ox/RpcSchema.ts +0 -35
  181. package/src/ox/SignatureEnvelope.test.ts +0 -1876
  182. package/src/ox/SignatureEnvelope.ts +0 -791
  183. package/src/ox/Tick.test.ts +0 -281
  184. package/src/ox/Tick.ts +0 -181
  185. package/src/ox/TokenId.test.ts +0 -40
  186. package/src/ox/TokenId.ts +0 -50
  187. package/src/ox/TokenRole.test.ts +0 -16
  188. package/src/ox/TokenRole.ts +0 -27
  189. package/src/ox/Transaction.test.ts +0 -523
  190. package/src/ox/Transaction.ts +0 -332
  191. package/src/ox/TransactionEnvelopeTempo.test.ts +0 -1352
  192. package/src/ox/TransactionEnvelopeTempo.ts +0 -905
  193. package/src/ox/TransactionReceipt.ts +0 -190
  194. package/src/ox/TransactionRequest.ts +0 -147
  195. package/src/ox/e2e.test.ts +0 -1393
  196. package/src/ox/index.ts +0 -13
  197. package/src/prool/Instance.test.ts +0 -43
  198. package/src/prool/Instance.ts +0 -247
  199. package/src/prool/chain.json +0 -238
  200. package/src/prool/index.ts +0 -1
  201. package/src/viem/Actions/__snapshots__/dex.test.ts.snap +0 -850
  202. package/src/wagmi/Actions/__snapshots__/dex.test.ts.snap +0 -310
  203. package/src/wagmi/Hooks/__snapshots__/dex.test.ts.snap +0 -457
@@ -1,1393 +0,0 @@
1
- import {
2
- Address,
3
- Hex,
4
- P256,
5
- Secp256k1,
6
- Value,
7
- WebAuthnP256,
8
- WebCryptoP256,
9
- } from 'ox'
10
- import { getTransactionCount } from 'viem/actions'
11
- import { beforeEach, describe, expect, test } from 'vitest'
12
- import { chainId } from '../../test/config.js'
13
- import { client, fundAddress } from '../../test/viem/config.js'
14
- import {
15
- AuthorizationTempo,
16
- KeyAuthorization,
17
- SignatureEnvelope,
18
- } from './index.js'
19
- import * as Transaction from './Transaction.js'
20
- import * as TransactionEnvelopeTempo from './TransactionEnvelopeTempo.js'
21
- import * as TransactionReceipt from './TransactionReceipt.js'
22
-
23
- test('behavior: default (secp256k1)', async () => {
24
- const privateKey = Secp256k1.randomPrivateKey()
25
- const address = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey }))
26
-
27
- await fundAddress(client, {
28
- address,
29
- })
30
-
31
- const nonce = await getTransactionCount(client, {
32
- address,
33
- blockTag: 'pending',
34
- })
35
-
36
- const transaction = TransactionEnvelopeTempo.from({
37
- calls: [
38
- {
39
- to: '0x0000000000000000000000000000000000000000',
40
- },
41
- ],
42
- chainId,
43
- feeToken: '0x20c0000000000000000000000000000000000001',
44
- nonce: BigInt(nonce),
45
- gas: 100_000n,
46
- maxFeePerGas: Value.fromGwei('20'),
47
- maxPriorityFeePerGas: Value.fromGwei('10'),
48
- })
49
-
50
- const signature = Secp256k1.sign({
51
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
52
- privateKey,
53
- })
54
-
55
- const serialized_signed = TransactionEnvelopeTempo.serialize(transaction, {
56
- signature: SignatureEnvelope.from(signature),
57
- })
58
-
59
- const receipt = (await client
60
- .request({
61
- method: 'eth_sendRawTransactionSync',
62
- params: [serialized_signed],
63
- })
64
- .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
65
- expect(receipt).toBeDefined()
66
-
67
- {
68
- const response = await client
69
- .request({
70
- method: 'eth_getTransactionByHash',
71
- params: [receipt.transactionHash],
72
- })
73
- .then((tx) => Transaction.fromRpc(tx as any))
74
- if (!response) throw new Error()
75
-
76
- const {
77
- blockNumber,
78
- blockHash,
79
- chainId,
80
- hash,
81
- feeToken: _,
82
- from,
83
- keyAuthorization: __,
84
- nonce,
85
- maxFeePerGas,
86
- maxPriorityFeePerGas,
87
- signature,
88
- transactionIndex,
89
- ...rest
90
- } = response
91
-
92
- expect(blockNumber).toBeDefined()
93
- expect(blockHash).toBeDefined()
94
- expect(chainId).toBe(chainId)
95
- expect(hash).toBe(receipt.transactionHash)
96
- expect(from).toBe(address)
97
- expect(maxFeePerGas).toBeDefined()
98
- expect(maxPriorityFeePerGas).toBeDefined()
99
- expect(nonce).toBeDefined()
100
- expect(signature).toBeDefined()
101
- expect(transactionIndex).toBeDefined()
102
- expect(rest).toMatchInlineSnapshot(`
103
- {
104
- "accessList": [],
105
- "authorizationList": [],
106
- "calls": [
107
- {
108
- "data": "0x",
109
- "to": "0x0000000000000000000000000000000000000000",
110
- "value": 0n,
111
- },
112
- ],
113
- "data": undefined,
114
- "feePayerSignature": null,
115
- "gas": 100000n,
116
- "gasPrice": 20000000000n,
117
- "nonceKey": 0n,
118
- "type": "tempo",
119
- "validAfter": null,
120
- "validBefore": null,
121
- "value": 0n,
122
- }
123
- `)
124
- }
125
-
126
- const {
127
- blockNumber,
128
- blockHash,
129
- feePayer,
130
- feeToken: _,
131
- from,
132
- logs,
133
- logsBloom,
134
- transactionHash,
135
- transactionIndex,
136
- ...rest
137
- } = receipt
138
-
139
- expect(blockNumber).toBeDefined()
140
- expect(blockHash).toBeDefined()
141
- expect(feePayer).toBeDefined()
142
- expect(from).toBe(address)
143
- expect(logs).toBeDefined()
144
- expect(logsBloom).toBeDefined()
145
- expect(transactionHash).toBe(receipt.transactionHash)
146
- expect(transactionIndex).toBeDefined()
147
- expect(rest).toMatchInlineSnapshot(`
148
- {
149
- "blobGasPrice": undefined,
150
- "blobGasUsed": undefined,
151
- "contractAddress": null,
152
- "cumulativeGasUsed": 23600n,
153
- "effectiveGasPrice": 20000000000n,
154
- "gasUsed": 23600n,
155
- "status": "success",
156
- "to": "0x0000000000000000000000000000000000000000",
157
- "type": "0x76",
158
- }
159
- `)
160
- })
161
-
162
- test('behavior: authorizationList (secp256k1)', async () => {
163
- const privateKey = Secp256k1.randomPrivateKey()
164
- const address = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey }))
165
-
166
- await fundAddress(client, {
167
- address,
168
- })
169
-
170
- const nonce = await getTransactionCount(client, {
171
- address,
172
- blockTag: 'pending',
173
- })
174
-
175
- const authorization = AuthorizationTempo.from({
176
- address: '0x0000000000000000000000000000000000000001',
177
- chainId: 0,
178
- nonce: BigInt(nonce + 1),
179
- })
180
-
181
- const authorizationSigned = AuthorizationTempo.from(authorization, {
182
- signature: SignatureEnvelope.from(
183
- Secp256k1.sign({
184
- payload: AuthorizationTempo.getSignPayload(authorization),
185
- privateKey,
186
- }),
187
- ),
188
- })
189
-
190
- const transaction = TransactionEnvelopeTempo.from({
191
- authorizationList: [authorizationSigned],
192
- calls: [
193
- {
194
- to: '0x0000000000000000000000000000000000000000',
195
- },
196
- ],
197
- chainId,
198
- feeToken: '0x20c0000000000000000000000000000000000001',
199
- nonce: BigInt(nonce),
200
- gas: 100_000n,
201
- maxFeePerGas: Value.fromGwei('20'),
202
- maxPriorityFeePerGas: Value.fromGwei('10'),
203
- })
204
-
205
- const signature = Secp256k1.sign({
206
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
207
- privateKey,
208
- })
209
-
210
- const serialized_signed = TransactionEnvelopeTempo.serialize(transaction, {
211
- signature: SignatureEnvelope.from(signature),
212
- })
213
-
214
- const receipt = (await client
215
- .request({
216
- method: 'eth_sendRawTransactionSync',
217
- params: [serialized_signed],
218
- })
219
- .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
220
- expect(receipt).toBeDefined()
221
-
222
- const code = await client.request({
223
- method: 'eth_getCode',
224
- params: [address, 'latest'],
225
- })
226
- expect(Hex.slice(code, 3)).toBe('0x0000000000000000000000000000000000000001')
227
- })
228
-
229
- test('behavior: default (p256)', async () => {
230
- const privateKey = P256.randomPrivateKey()
231
- const publicKey = P256.getPublicKey({ privateKey })
232
- const address = Address.fromPublicKey(publicKey)
233
-
234
- await fundAddress(client, {
235
- address,
236
- })
237
-
238
- const transaction = TransactionEnvelopeTempo.from({
239
- calls: [
240
- {
241
- to: '0x0000000000000000000000000000000000000000',
242
- },
243
- ],
244
- chainId,
245
- feeToken: '0x20c0000000000000000000000000000000000001',
246
- gas: 100_000n,
247
- maxFeePerGas: Value.fromGwei('20'),
248
- maxPriorityFeePerGas: Value.fromGwei('10'),
249
- })
250
-
251
- const signature = P256.sign({
252
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
253
- privateKey,
254
- hash: false,
255
- })
256
-
257
- const serialized_signed = TransactionEnvelopeTempo.serialize(transaction, {
258
- signature: SignatureEnvelope.from({
259
- signature,
260
- publicKey,
261
- prehash: false,
262
- }),
263
- })
264
-
265
- const receipt = (await client
266
- .request({
267
- method: 'eth_sendRawTransactionSync',
268
- params: [serialized_signed],
269
- })
270
- .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
271
-
272
- expect(receipt).toBeDefined()
273
-
274
- {
275
- const response = await client
276
- .request({
277
- method: 'eth_getTransactionByHash',
278
- params: [receipt.transactionHash],
279
- })
280
- .then((tx) => Transaction.fromRpc(tx as any))
281
- if (!response) throw new Error()
282
-
283
- const {
284
- blockNumber,
285
- blockHash,
286
- chainId,
287
- feeToken: _,
288
- from,
289
- keyAuthorization: __,
290
- hash,
291
- nonce,
292
- maxFeePerGas,
293
- maxPriorityFeePerGas,
294
- signature,
295
- transactionIndex,
296
- ...rest
297
- } = response
298
-
299
- expect(blockNumber).toBeDefined()
300
- expect(blockHash).toBeDefined()
301
- expect(chainId).toBe(chainId)
302
- expect(from).toBe(address)
303
- expect(hash).toBe(receipt.transactionHash)
304
- expect(nonce).toBeDefined()
305
- expect(maxFeePerGas).toBeDefined()
306
- expect(maxPriorityFeePerGas).toBeDefined()
307
- expect(signature).toBeDefined()
308
- expect(transactionIndex).toBeDefined()
309
- expect(rest).toMatchInlineSnapshot(`
310
- {
311
- "accessList": [],
312
- "authorizationList": [],
313
- "calls": [
314
- {
315
- "data": "0x",
316
- "to": "0x0000000000000000000000000000000000000000",
317
- "value": 0n,
318
- },
319
- ],
320
- "data": undefined,
321
- "feePayerSignature": null,
322
- "gas": 100000n,
323
- "gasPrice": 20000000000n,
324
- "nonceKey": 0n,
325
- "type": "tempo",
326
- "validAfter": null,
327
- "validBefore": null,
328
- "value": 0n,
329
- }
330
- `)
331
- }
332
-
333
- const {
334
- blockNumber,
335
- blockHash,
336
- feePayer,
337
- feeToken: _,
338
- from,
339
- logs,
340
- logsBloom,
341
- transactionHash,
342
- transactionIndex,
343
- ...rest
344
- } = receipt
345
-
346
- expect(blockNumber).toBeDefined()
347
- expect(blockHash).toBeDefined()
348
- expect(feePayer).toBeDefined()
349
- expect(from).toBe(address)
350
- expect(logs).toBeDefined()
351
- expect(logsBloom).toBeDefined()
352
- expect(transactionHash).toBe(receipt.transactionHash)
353
- expect(transactionIndex).toBeDefined()
354
- expect(rest).toMatchInlineSnapshot(`
355
- {
356
- "blobGasPrice": undefined,
357
- "blobGasUsed": undefined,
358
- "contractAddress": null,
359
- "cumulativeGasUsed": 28600n,
360
- "effectiveGasPrice": 20000000000n,
361
- "gasUsed": 28600n,
362
- "status": "success",
363
- "to": "0x0000000000000000000000000000000000000000",
364
- "type": "0x76",
365
- }
366
- `)
367
- })
368
-
369
- test('behavior: default (p256 - webcrypto)', async () => {
370
- const keyPair = await WebCryptoP256.createKeyPair()
371
- const address = Address.fromPublicKey(keyPair.publicKey)
372
-
373
- await fundAddress(client, {
374
- address,
375
- })
376
-
377
- const transaction = TransactionEnvelopeTempo.from({
378
- calls: [
379
- {
380
- to: '0x0000000000000000000000000000000000000000',
381
- },
382
- ],
383
- chainId,
384
- feeToken: '0x20c0000000000000000000000000000000000001',
385
- gas: 100_000n,
386
- maxFeePerGas: Value.fromGwei('20'),
387
- maxPriorityFeePerGas: Value.fromGwei('10'),
388
- })
389
-
390
- const signature = await WebCryptoP256.sign({
391
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
392
- privateKey: keyPair.privateKey,
393
- })
394
-
395
- const serialized_signed = TransactionEnvelopeTempo.serialize(transaction, {
396
- signature: SignatureEnvelope.from({
397
- signature,
398
- publicKey: keyPair.publicKey,
399
- prehash: true,
400
- type: 'p256',
401
- }),
402
- })
403
-
404
- const receipt = (await client
405
- .request({
406
- method: 'eth_sendRawTransactionSync',
407
- params: [serialized_signed],
408
- })
409
- .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
410
-
411
- expect(receipt).toBeDefined()
412
-
413
- {
414
- const response = await client
415
- .request({
416
- method: 'eth_getTransactionByHash',
417
- params: [receipt.transactionHash],
418
- })
419
- .then((tx) => Transaction.fromRpc(tx as any))
420
- if (!response) throw new Error()
421
-
422
- const {
423
- blockNumber,
424
- blockHash,
425
- chainId,
426
- feeToken: _,
427
- from,
428
- keyAuthorization: __,
429
- hash,
430
- nonce,
431
- maxFeePerGas,
432
- maxPriorityFeePerGas,
433
- signature,
434
- transactionIndex,
435
- ...rest
436
- } = response as any
437
-
438
- expect(blockNumber).toBeDefined()
439
- expect(blockHash).toBeDefined()
440
- expect(chainId).toBeDefined()
441
- expect(from).toBeDefined()
442
- expect(hash).toBe(receipt.transactionHash)
443
- expect(nonce).toBeDefined()
444
- expect(maxFeePerGas).toBeDefined()
445
- expect(maxPriorityFeePerGas).toBeDefined()
446
- expect(signature).toBeDefined()
447
- expect(transactionIndex).toBeDefined()
448
- expect(rest).toMatchInlineSnapshot(`
449
- {
450
- "accessList": [],
451
- "authorizationList": [],
452
- "calls": [
453
- {
454
- "data": "0x",
455
- "to": "0x0000000000000000000000000000000000000000",
456
- "value": 0n,
457
- },
458
- ],
459
- "data": undefined,
460
- "feePayerSignature": null,
461
- "gas": 100000n,
462
- "gasPrice": 20000000000n,
463
- "nonceKey": 0n,
464
- "type": "tempo",
465
- "validAfter": null,
466
- "validBefore": null,
467
- "value": 0n,
468
- }
469
- `)
470
- }
471
-
472
- const {
473
- blockNumber,
474
- blockHash,
475
- feePayer,
476
- feeToken: _,
477
- from,
478
- logs,
479
- logsBloom,
480
- transactionHash,
481
- transactionIndex,
482
- ...rest
483
- } = receipt
484
-
485
- expect(blockNumber).toBeDefined()
486
- expect(blockHash).toBeDefined()
487
- expect(feePayer).toBeDefined()
488
- expect(from).toBeDefined()
489
- expect(logs).toBeDefined()
490
- expect(logsBloom).toBeDefined()
491
- expect(transactionHash).toBe(receipt.transactionHash)
492
- expect(transactionIndex).toBeDefined()
493
- expect(rest).toMatchInlineSnapshot(`
494
- {
495
- "blobGasPrice": undefined,
496
- "blobGasUsed": undefined,
497
- "contractAddress": null,
498
- "cumulativeGasUsed": 28600n,
499
- "effectiveGasPrice": 20000000000n,
500
- "gasUsed": 28600n,
501
- "status": "success",
502
- "to": "0x0000000000000000000000000000000000000000",
503
- "type": "0x76",
504
- }
505
- `)
506
- })
507
-
508
- test('behavior: default (webauthn)', async () => {
509
- const privateKey = P256.randomPrivateKey()
510
- const publicKey = P256.getPublicKey({ privateKey })
511
- const address = Address.fromPublicKey(publicKey)
512
-
513
- await fundAddress(client, {
514
- address,
515
- })
516
-
517
- const transaction = TransactionEnvelopeTempo.from({
518
- calls: [
519
- {
520
- to: '0x0000000000000000000000000000000000000000',
521
- },
522
- ],
523
- chainId,
524
- feeToken: '0x20c0000000000000000000000000000000000001',
525
- gas: 100_000n,
526
- maxFeePerGas: Value.fromGwei('20'),
527
- maxPriorityFeePerGas: Value.fromGwei('10'),
528
- })
529
-
530
- const { metadata, payload } = WebAuthnP256.getSignPayload({
531
- challenge: TransactionEnvelopeTempo.getSignPayload(transaction),
532
- rpId: 'localhost',
533
- origin: 'http://localhost',
534
- })
535
-
536
- const signature = P256.sign({
537
- payload,
538
- privateKey,
539
- hash: true,
540
- })
541
-
542
- const serialized_signed = TransactionEnvelopeTempo.serialize(transaction, {
543
- signature: SignatureEnvelope.from({
544
- signature,
545
- publicKey,
546
- metadata,
547
- }),
548
- })
549
-
550
- const receipt = (await client
551
- .request({
552
- method: 'eth_sendRawTransactionSync',
553
- params: [serialized_signed],
554
- })
555
- .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
556
-
557
- expect(receipt).toBeDefined()
558
-
559
- {
560
- const response = await client
561
- .request({
562
- method: 'eth_getTransactionByHash',
563
- params: [receipt.transactionHash],
564
- })
565
- .then((tx) => Transaction.fromRpc(tx as any))
566
- if (!response) throw new Error()
567
-
568
- const {
569
- blockNumber,
570
- blockHash,
571
- chainId,
572
- feeToken: _,
573
- from,
574
- keyAuthorization: __,
575
- hash,
576
- nonce,
577
- maxFeePerGas,
578
- maxPriorityFeePerGas,
579
- transactionIndex,
580
- signature,
581
- ...rest
582
- } = response
583
-
584
- expect(blockNumber).toBeDefined()
585
- expect(blockHash).toBeDefined()
586
- expect(chainId).toBe(chainId)
587
- expect(from).toBeDefined()
588
- expect(hash).toBe(receipt.transactionHash)
589
- expect(nonce).toBeDefined()
590
- expect(maxFeePerGas).toBeDefined()
591
- expect(maxPriorityFeePerGas).toBeDefined()
592
- expect(signature).toBeDefined()
593
- expect(transactionIndex).toBeDefined()
594
- expect(rest).toMatchInlineSnapshot(`
595
- {
596
- "accessList": [],
597
- "authorizationList": [],
598
- "calls": [
599
- {
600
- "data": "0x",
601
- "to": "0x0000000000000000000000000000000000000000",
602
- "value": 0n,
603
- },
604
- ],
605
- "data": undefined,
606
- "feePayerSignature": null,
607
- "gas": 100000n,
608
- "gasPrice": 20000000000n,
609
- "nonceKey": 0n,
610
- "type": "tempo",
611
- "validAfter": null,
612
- "validBefore": null,
613
- "value": 0n,
614
- }
615
- `)
616
- }
617
-
618
- const {
619
- blockNumber,
620
- blockHash,
621
- cumulativeGasUsed,
622
- feePayer,
623
- feeToken: _,
624
- from,
625
- logs,
626
- logsBloom,
627
- transactionHash,
628
- transactionIndex,
629
- ...rest
630
- } = receipt
631
-
632
- expect(blockNumber).toBeDefined()
633
- expect(blockHash).toBeDefined()
634
- expect(cumulativeGasUsed).toBeDefined()
635
- expect(feePayer).toBeDefined()
636
- expect(from).toBe(address)
637
- expect(logs).toBeDefined()
638
- expect(logsBloom).toBeDefined()
639
- expect(transactionHash).toBe(receipt.transactionHash)
640
- expect(transactionIndex).toBeDefined()
641
- expect(rest).toMatchInlineSnapshot(`
642
- {
643
- "blobGasPrice": undefined,
644
- "blobGasUsed": undefined,
645
- "contractAddress": null,
646
- "effectiveGasPrice": 20000000000n,
647
- "gasUsed": 31208n,
648
- "status": "success",
649
- "to": "0x0000000000000000000000000000000000000000",
650
- "type": "0x76",
651
- }
652
- `)
653
- })
654
-
655
- test('behavior: feePayerSignature (user → feePayer)', async () => {
656
- const feePayerPrivateKey = Secp256k1.randomPrivateKey()
657
- const feePayerAddress = Address.fromPublicKey(
658
- Secp256k1.getPublicKey({ privateKey: feePayerPrivateKey }),
659
- )
660
-
661
- const senderPrivateKey = Secp256k1.randomPrivateKey()
662
- const senderAddress = Address.fromPublicKey(
663
- Secp256k1.getPublicKey({ privateKey: senderPrivateKey }),
664
- )
665
-
666
- await fundAddress(client, {
667
- address: feePayerAddress,
668
- })
669
-
670
- const nonce = await client.request({
671
- method: 'eth_getTransactionCount',
672
- params: [senderAddress, 'pending'],
673
- })
674
-
675
- //////////////////////////////////////////////////////////////////
676
- // Sender flow
677
-
678
- const transaction = TransactionEnvelopeTempo.from({
679
- calls: [{ to: '0x0000000000000000000000000000000000000000', value: 0n }],
680
- chainId,
681
- feePayerSignature: null,
682
- nonce: BigInt(nonce),
683
- gas: 100000n,
684
- maxFeePerGas: Value.fromGwei('20'),
685
- maxPriorityFeePerGas: Value.fromGwei('10'),
686
- })
687
-
688
- const signature = Secp256k1.sign({
689
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
690
- // unfunded PK
691
- privateKey: senderPrivateKey,
692
- })
693
-
694
- const transaction_signed = TransactionEnvelopeTempo.from(transaction, {
695
- signature: SignatureEnvelope.from(signature),
696
- })
697
-
698
- //////////////////////////////////////////////////////////////////
699
- // Fee payer flow
700
-
701
- const transaction_feePayer = TransactionEnvelopeTempo.from({
702
- ...transaction_signed,
703
- feeToken: '0x20c0000000000000000000000000000000000001',
704
- })
705
-
706
- const feePayerSignature = Secp256k1.sign({
707
- payload: TransactionEnvelopeTempo.getFeePayerSignPayload(
708
- transaction_feePayer,
709
- { sender: senderAddress },
710
- ),
711
- privateKey: feePayerPrivateKey,
712
- })
713
-
714
- const serialized_signed = TransactionEnvelopeTempo.serialize(
715
- transaction_feePayer,
716
- {
717
- feePayerSignature,
718
- },
719
- )
720
-
721
- const receipt = (await client
722
- .request({
723
- method: 'eth_sendRawTransactionSync',
724
- params: [serialized_signed],
725
- })
726
- .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
727
-
728
- {
729
- const {
730
- blockNumber,
731
- blockHash,
732
- feePayer,
733
- feeToken: _,
734
- from,
735
- logs,
736
- logsBloom,
737
- transactionHash,
738
- transactionIndex,
739
- ...rest
740
- } = receipt
741
-
742
- expect(blockNumber).toBeDefined()
743
- expect(blockHash).toBeDefined()
744
- expect(feePayer).toBe(feePayerAddress)
745
- expect(from).toBe(senderAddress)
746
- expect(logs).toBeDefined()
747
- expect(logsBloom).toBeDefined()
748
- expect(transactionHash).toBe(receipt.transactionHash)
749
- expect(transactionIndex).toBeDefined()
750
- expect(rest).toMatchInlineSnapshot(`
751
- {
752
- "blobGasPrice": undefined,
753
- "blobGasUsed": undefined,
754
- "contractAddress": null,
755
- "cumulativeGasUsed": 23600n,
756
- "effectiveGasPrice": 20000000000n,
757
- "gasUsed": 23600n,
758
- "status": "success",
759
- "to": "0x0000000000000000000000000000000000000000",
760
- "type": "0x76",
761
- }
762
- `)
763
- }
764
-
765
- const { feeToken, from } = (await client
766
- .request({
767
- method: 'eth_getTransactionByHash',
768
- params: [receipt.transactionHash],
769
- })
770
- .then((tx) => Transaction.fromRpc(tx as any))) as any
771
-
772
- expect(feeToken).toBe('0x20c0000000000000000000000000000000000001')
773
- expect(from).toBe(senderAddress)
774
- })
775
-
776
- describe('behavior: keyAuthorization', () => {
777
- const privateKey = Secp256k1.randomPrivateKey()
778
- const address = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey }))
779
- const root = {
780
- address,
781
- privateKey,
782
- } as const
783
-
784
- beforeEach(async () => {
785
- await fundAddress(client, {
786
- address,
787
- })
788
- })
789
-
790
- test('behavior: secp256k1 access key', async () => {
791
- const privateKey =
792
- '0x06a952d58c24d287245276dd8b4272d82a921d27d90874a6c27a3bc19ff4bfde'
793
- const publicKey = Secp256k1.getPublicKey({ privateKey })
794
- const address = Address.fromPublicKey(publicKey)
795
- const access = {
796
- address,
797
- publicKey,
798
- privateKey,
799
- } as const
800
-
801
- const keyAuth = KeyAuthorization.from({
802
- address: access.address,
803
- type: 'secp256k1',
804
- })
805
-
806
- const keyAuth_signature = Secp256k1.sign({
807
- payload: KeyAuthorization.getSignPayload(keyAuth),
808
- privateKey: root.privateKey,
809
- })
810
-
811
- const keyAuth_signed = KeyAuthorization.from(keyAuth, {
812
- signature: SignatureEnvelope.from(keyAuth_signature),
813
- })
814
-
815
- const nonce = await getTransactionCount(client, {
816
- address: root.address,
817
- blockTag: 'pending',
818
- })
819
-
820
- const transaction = TransactionEnvelopeTempo.from({
821
- calls: [
822
- {
823
- to: '0x0000000000000000000000000000000000000000',
824
- },
825
- ],
826
- chainId,
827
- feeToken: '0x20c0000000000000000000000000000000000001',
828
- keyAuthorization: keyAuth_signed,
829
- nonce: BigInt(nonce),
830
- gas: 100_000n,
831
- maxFeePerGas: Value.fromGwei('20'),
832
- maxPriorityFeePerGas: Value.fromGwei('10'),
833
- })
834
-
835
- const signature = Secp256k1.sign({
836
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
837
- privateKey: access.privateKey,
838
- })
839
-
840
- const serialized_signed = TransactionEnvelopeTempo.serialize(transaction, {
841
- signature: SignatureEnvelope.from({
842
- userAddress: root.address,
843
- inner: SignatureEnvelope.from(signature),
844
- type: 'keychain',
845
- }),
846
- })
847
-
848
- const receipt = (await client
849
- .request({
850
- method: 'eth_sendRawTransactionSync',
851
- params: [serialized_signed],
852
- })
853
- .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
854
-
855
- {
856
- const response = await client
857
- .request({
858
- method: 'eth_getTransactionByHash',
859
- params: [receipt.transactionHash],
860
- })
861
- .then((tx) => Transaction.fromRpc(tx as any))
862
- if (!response) throw new Error()
863
-
864
- const {
865
- blockNumber,
866
- blockHash,
867
- chainId: _,
868
- gasPrice,
869
- hash,
870
- from,
871
- keyAuthorization,
872
- maxFeePerGas,
873
- maxPriorityFeePerGas,
874
- nonce,
875
- signature,
876
- transactionIndex,
877
- ...rest
878
- } = response
879
-
880
- expect(blockNumber).toBeDefined()
881
- expect(blockHash).toBeDefined()
882
- expect(gasPrice).toBeDefined()
883
- expect(maxFeePerGas).toBeDefined()
884
- expect(maxPriorityFeePerGas).toBeDefined()
885
- expect(nonce).toBeDefined()
886
- expect(from).toBe(root.address)
887
- expect(hash).toBe(receipt.transactionHash)
888
- expect(keyAuthorization).toBeDefined()
889
- expect(signature).toBeDefined()
890
- expect(transactionIndex).toBeDefined()
891
- expect(rest).toMatchInlineSnapshot(`
892
- {
893
- "accessList": [],
894
- "authorizationList": [],
895
- "calls": [
896
- {
897
- "data": "0x",
898
- "to": "0x0000000000000000000000000000000000000000",
899
- "value": 0n,
900
- },
901
- ],
902
- "data": undefined,
903
- "feePayerSignature": null,
904
- "feeToken": "0x20c0000000000000000000000000000000000001",
905
- "gas": 100000n,
906
- "nonceKey": 0n,
907
- "type": "tempo",
908
- "validAfter": null,
909
- "validBefore": null,
910
- "value": 0n,
911
- }
912
- `)
913
- }
914
-
915
- const {
916
- blockNumber,
917
- blockHash,
918
- feePayer,
919
- feeToken,
920
- from,
921
- logs,
922
- logsBloom,
923
- transactionHash,
924
- transactionIndex,
925
- ...rest
926
- } = receipt
927
-
928
- expect(blockNumber).toBeDefined()
929
- expect(blockHash).toBeDefined()
930
- expect(feeToken).toBeDefined()
931
- expect(feePayer).toBeDefined()
932
- expect(from).toBeDefined()
933
- expect(logs).toBeDefined()
934
- expect(logsBloom).toBeDefined()
935
- expect(transactionHash).toBe(receipt.transactionHash)
936
- expect(transactionIndex).toBeDefined()
937
- expect(rest).toMatchInlineSnapshot(`
938
- {
939
- "blobGasPrice": undefined,
940
- "blobGasUsed": undefined,
941
- "contractAddress": null,
942
- "cumulativeGasUsed": 23600n,
943
- "effectiveGasPrice": 20000000000n,
944
- "gasUsed": 23600n,
945
- "status": "success",
946
- "to": "0x0000000000000000000000000000000000000000",
947
- "type": "0x76",
948
- }
949
- `)
950
-
951
- // Test a subsequent tx signed by access key with no keyAuthorization
952
- {
953
- const nonce = await getTransactionCount(client, {
954
- address: root.address,
955
- blockTag: 'pending',
956
- })
957
-
958
- const transaction = TransactionEnvelopeTempo.from({
959
- calls: [
960
- {
961
- to: '0x0000000000000000000000000000000000000000',
962
- },
963
- ],
964
- chainId,
965
- feeToken: '0x20c0000000000000000000000000000000000001',
966
- nonce: BigInt(nonce),
967
- gas: 100_000n,
968
- maxFeePerGas: Value.fromGwei('20'),
969
- maxPriorityFeePerGas: Value.fromGwei('10'),
970
- })
971
-
972
- const signature = Secp256k1.sign({
973
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
974
- privateKey: access.privateKey,
975
- })
976
-
977
- const serialized_signed = TransactionEnvelopeTempo.serialize(
978
- transaction,
979
- {
980
- signature: SignatureEnvelope.from({
981
- userAddress: root.address,
982
- inner: SignatureEnvelope.from(signature),
983
- type: 'keychain',
984
- }),
985
- },
986
- )
987
-
988
- const receipt = await client.request({
989
- method: 'eth_sendRawTransactionSync',
990
- params: [serialized_signed],
991
- })
992
-
993
- expect(receipt).toBeDefined()
994
- }
995
- })
996
-
997
- test('behavior: p256 access key', async () => {
998
- const privateKey =
999
- '0x06a952d58c24d287245276dd8b4272d82a921d27d90874a6c27a3bc19ff4bfde'
1000
- const publicKey = P256.getPublicKey({ privateKey })
1001
- const address = Address.fromPublicKey(publicKey)
1002
- const access = {
1003
- address,
1004
- publicKey,
1005
- privateKey,
1006
- } as const
1007
-
1008
- const keyAuth = KeyAuthorization.from({
1009
- address: access.address,
1010
- type: 'p256',
1011
- })
1012
-
1013
- const keyAuth_signature = Secp256k1.sign({
1014
- payload: KeyAuthorization.getSignPayload(keyAuth),
1015
- privateKey: root.privateKey,
1016
- })
1017
-
1018
- const keyAuth_signed = KeyAuthorization.from(keyAuth, {
1019
- signature: SignatureEnvelope.from(keyAuth_signature),
1020
- })
1021
-
1022
- const nonce = await getTransactionCount(client, {
1023
- address: root.address,
1024
- blockTag: 'pending',
1025
- })
1026
-
1027
- const transaction = TransactionEnvelopeTempo.from({
1028
- calls: [
1029
- {
1030
- to: '0x0000000000000000000000000000000000000000',
1031
- },
1032
- ],
1033
- chainId,
1034
- feeToken: '0x20c0000000000000000000000000000000000001',
1035
- keyAuthorization: keyAuth_signed,
1036
- nonce: BigInt(nonce),
1037
- gas: 100_000n,
1038
- maxFeePerGas: Value.fromGwei('20'),
1039
- maxPriorityFeePerGas: Value.fromGwei('10'),
1040
- })
1041
-
1042
- const signature = P256.sign({
1043
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
1044
- privateKey: access.privateKey,
1045
- })
1046
-
1047
- const serialized_signed = TransactionEnvelopeTempo.serialize(transaction, {
1048
- signature: SignatureEnvelope.from({
1049
- userAddress: root.address,
1050
- inner: SignatureEnvelope.from({
1051
- prehash: false,
1052
- publicKey: access.publicKey,
1053
- signature,
1054
- type: 'p256',
1055
- }),
1056
- type: 'keychain',
1057
- }),
1058
- })
1059
-
1060
- const receipt = (await client
1061
- .request({
1062
- method: 'eth_sendRawTransactionSync',
1063
- params: [serialized_signed],
1064
- })
1065
- .then((tx) => TransactionReceipt.fromRpc(tx as any)))!
1066
- expect(receipt).toBeDefined()
1067
-
1068
- {
1069
- const response = await client
1070
- .request({
1071
- method: 'eth_getTransactionByHash',
1072
- params: [receipt.transactionHash],
1073
- })
1074
- .then((tx) => Transaction.fromRpc(tx as any))
1075
- if (!response) throw new Error()
1076
-
1077
- const {
1078
- blockNumber,
1079
- blockHash,
1080
- chainId: _,
1081
- gasPrice,
1082
- hash,
1083
- from,
1084
- keyAuthorization,
1085
- maxFeePerGas,
1086
- maxPriorityFeePerGas,
1087
- nonce,
1088
- signature,
1089
- transactionIndex,
1090
- ...rest
1091
- } = response
1092
-
1093
- expect(blockNumber).toBeDefined()
1094
- expect(blockHash).toBeDefined()
1095
- expect(gasPrice).toBeDefined()
1096
- expect(hash).toBe(receipt.transactionHash)
1097
- expect(from).toBe(root.address)
1098
- expect(keyAuthorization).toBeDefined()
1099
- expect(maxFeePerGas).toBeDefined()
1100
- expect(maxPriorityFeePerGas).toBeDefined()
1101
- expect(nonce).toBeDefined()
1102
- expect(signature).toBeDefined()
1103
- expect(transactionIndex).toBeDefined()
1104
- expect(rest).toMatchInlineSnapshot(`
1105
- {
1106
- "accessList": [],
1107
- "authorizationList": [],
1108
- "calls": [
1109
- {
1110
- "data": "0x",
1111
- "to": "0x0000000000000000000000000000000000000000",
1112
- "value": 0n,
1113
- },
1114
- ],
1115
- "data": undefined,
1116
- "feePayerSignature": null,
1117
- "feeToken": "0x20c0000000000000000000000000000000000001",
1118
- "gas": 100000n,
1119
- "nonceKey": 0n,
1120
- "type": "tempo",
1121
- "validAfter": null,
1122
- "validBefore": null,
1123
- "value": 0n,
1124
- }
1125
- `)
1126
- }
1127
-
1128
- const {
1129
- blockNumber,
1130
- blockHash,
1131
- feePayer,
1132
- feeToken,
1133
- from,
1134
- logs,
1135
- logsBloom,
1136
- transactionHash,
1137
- transactionIndex,
1138
- ...rest
1139
- } = receipt
1140
-
1141
- expect(blockNumber).toBeDefined()
1142
- expect(blockHash).toBeDefined()
1143
- expect(feePayer).toBeDefined()
1144
- expect(feeToken).toBeDefined()
1145
- expect(from).toBeDefined()
1146
- expect(logs).toBeDefined()
1147
- expect(logsBloom).toBeDefined()
1148
- expect(transactionHash).toBe(receipt.transactionHash)
1149
- expect(transactionIndex).toBeDefined()
1150
- expect(rest).toMatchInlineSnapshot(`
1151
- {
1152
- "blobGasPrice": undefined,
1153
- "blobGasUsed": undefined,
1154
- "contractAddress": null,
1155
- "cumulativeGasUsed": 28600n,
1156
- "effectiveGasPrice": 20000000000n,
1157
- "gasUsed": 28600n,
1158
- "status": "success",
1159
- "to": "0x0000000000000000000000000000000000000000",
1160
- "type": "0x76",
1161
- }
1162
- `)
1163
-
1164
- // Test a subsequent tx signed by access key with no keyAuthorization
1165
- {
1166
- const nonce = await getTransactionCount(client, {
1167
- address: root.address,
1168
- blockTag: 'pending',
1169
- })
1170
-
1171
- const transaction = TransactionEnvelopeTempo.from({
1172
- calls: [
1173
- {
1174
- to: '0x0000000000000000000000000000000000000000',
1175
- },
1176
- ],
1177
- chainId,
1178
- feeToken: '0x20c0000000000000000000000000000000000001',
1179
- nonce: BigInt(nonce),
1180
- gas: 100_000n,
1181
- maxFeePerGas: Value.fromGwei('20'),
1182
- maxPriorityFeePerGas: Value.fromGwei('10'),
1183
- })
1184
-
1185
- const signature = P256.sign({
1186
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
1187
- privateKey: access.privateKey,
1188
- })
1189
-
1190
- const serialized_signed = TransactionEnvelopeTempo.serialize(
1191
- transaction,
1192
- {
1193
- signature: SignatureEnvelope.from({
1194
- userAddress: root.address,
1195
- inner: SignatureEnvelope.from({
1196
- prehash: false,
1197
- publicKey: access.publicKey,
1198
- signature,
1199
- type: 'p256',
1200
- }),
1201
- type: 'keychain',
1202
- }),
1203
- },
1204
- )
1205
-
1206
- const receipt = await client.request({
1207
- method: 'eth_sendRawTransactionSync',
1208
- params: [serialized_signed],
1209
- })
1210
-
1211
- expect(receipt).toBeDefined()
1212
- }
1213
- })
1214
-
1215
- test('behavior: webcrypto access key', async () => {
1216
- const keyPair = await WebCryptoP256.createKeyPair()
1217
- const address = Address.fromPublicKey(keyPair.publicKey)
1218
- const access = {
1219
- address,
1220
- publicKey: keyPair.publicKey,
1221
- privateKey: keyPair.privateKey,
1222
- } as const
1223
-
1224
- const keyAuth = KeyAuthorization.from({
1225
- address: access.address,
1226
- type: 'p256',
1227
- })
1228
-
1229
- const keyAuth_signature = Secp256k1.sign({
1230
- payload: KeyAuthorization.getSignPayload(keyAuth),
1231
- privateKey: root.privateKey,
1232
- })
1233
-
1234
- const keyAuth_signed = KeyAuthorization.from(keyAuth, {
1235
- signature: SignatureEnvelope.from(keyAuth_signature),
1236
- })
1237
-
1238
- const nonce = await getTransactionCount(client, {
1239
- address: root.address,
1240
- blockTag: 'pending',
1241
- })
1242
-
1243
- const transaction = TransactionEnvelopeTempo.from({
1244
- calls: [
1245
- {
1246
- to: '0x0000000000000000000000000000000000000000',
1247
- },
1248
- ],
1249
- chainId,
1250
- feeToken: '0x20c0000000000000000000000000000000000001',
1251
- keyAuthorization: keyAuth_signed,
1252
- nonce: BigInt(nonce),
1253
- gas: 100_000n,
1254
- maxFeePerGas: Value.fromGwei('20'),
1255
- maxPriorityFeePerGas: Value.fromGwei('10'),
1256
- })
1257
-
1258
- const signature = await WebCryptoP256.sign({
1259
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
1260
- privateKey: keyPair.privateKey,
1261
- })
1262
-
1263
- const serialized_signed = TransactionEnvelopeTempo.serialize(transaction, {
1264
- signature: SignatureEnvelope.from({
1265
- userAddress: root.address,
1266
- inner: SignatureEnvelope.from({
1267
- prehash: true,
1268
- publicKey: access.publicKey,
1269
- signature,
1270
- type: 'p256',
1271
- }),
1272
- type: 'keychain',
1273
- }),
1274
- })
1275
-
1276
- const receipt = await client.request({
1277
- method: 'eth_sendRawTransactionSync',
1278
- params: [serialized_signed],
1279
- })
1280
-
1281
- expect(receipt).toBeDefined()
1282
-
1283
- {
1284
- const response = await client
1285
- .request({
1286
- method: 'eth_getTransactionByHash',
1287
- params: [receipt.transactionHash],
1288
- })
1289
- .then((tx) => Transaction.fromRpc(tx as any))
1290
- if (!response) throw new Error()
1291
-
1292
- const {
1293
- blockNumber,
1294
- blockHash,
1295
- chainId: _,
1296
- gasPrice,
1297
- hash,
1298
- from,
1299
- keyAuthorization,
1300
- maxFeePerGas,
1301
- maxPriorityFeePerGas,
1302
- nonce,
1303
- signature,
1304
- transactionIndex,
1305
- ...rest
1306
- } = response
1307
-
1308
- expect(blockNumber).toBeDefined()
1309
- expect(blockHash).toBeDefined()
1310
- expect(gasPrice).toBeDefined()
1311
- expect(hash).toBe(receipt.transactionHash)
1312
- expect(from).toBe(root.address)
1313
- expect(keyAuthorization).toBeDefined()
1314
- expect(maxFeePerGas).toBeDefined()
1315
- expect(maxPriorityFeePerGas).toBeDefined()
1316
- expect(nonce).toBeDefined()
1317
- expect(signature).toBeDefined()
1318
- expect(transactionIndex).toBeDefined()
1319
- expect(rest).toMatchInlineSnapshot(`
1320
- {
1321
- "accessList": [],
1322
- "authorizationList": [],
1323
- "calls": [
1324
- {
1325
- "data": "0x",
1326
- "to": "0x0000000000000000000000000000000000000000",
1327
- "value": 0n,
1328
- },
1329
- ],
1330
- "data": undefined,
1331
- "feePayerSignature": null,
1332
- "feeToken": "0x20c0000000000000000000000000000000000001",
1333
- "gas": 100000n,
1334
- "nonceKey": 0n,
1335
- "type": "tempo",
1336
- "validAfter": null,
1337
- "validBefore": null,
1338
- "value": 0n,
1339
- }
1340
- `)
1341
- }
1342
-
1343
- // Test a subsequent tx signed by access key with no keyAuthorization
1344
- {
1345
- const nonce = await getTransactionCount(client, {
1346
- address: root.address,
1347
- blockTag: 'pending',
1348
- })
1349
-
1350
- const transaction = TransactionEnvelopeTempo.from({
1351
- calls: [
1352
- {
1353
- to: '0x0000000000000000000000000000000000000000',
1354
- },
1355
- ],
1356
- chainId,
1357
- feeToken: '0x20c0000000000000000000000000000000000001',
1358
- nonce: BigInt(nonce),
1359
- gas: 100_000n,
1360
- maxFeePerGas: Value.fromGwei('20'),
1361
- maxPriorityFeePerGas: Value.fromGwei('10'),
1362
- })
1363
-
1364
- const signature = await WebCryptoP256.sign({
1365
- payload: TransactionEnvelopeTempo.getSignPayload(transaction),
1366
- privateKey: keyPair.privateKey,
1367
- })
1368
-
1369
- const serialized_signed = TransactionEnvelopeTempo.serialize(
1370
- transaction,
1371
- {
1372
- signature: SignatureEnvelope.from({
1373
- userAddress: root.address,
1374
- inner: SignatureEnvelope.from({
1375
- prehash: true,
1376
- publicKey: access.publicKey,
1377
- signature,
1378
- type: 'p256',
1379
- }),
1380
- type: 'keychain',
1381
- }),
1382
- },
1383
- )
1384
-
1385
- const receipt = await client.request({
1386
- method: 'eth_sendRawTransactionSync',
1387
- params: [serialized_signed],
1388
- })
1389
-
1390
- expect(receipt).toBeDefined()
1391
- }
1392
- })
1393
- })