tempo.ts 0.7.6 → 0.8.0

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