ox 1.7.1 → 1.7.2

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 (121) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/core/Hash.js +1 -1
  3. package/dist/core/Hash.js.map +1 -1
  4. package/dist/tempo/KeyAuthorization.d.ts +1 -1
  5. package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
  6. package/dist/tempo/MultisigConfig.d.ts +151 -83
  7. package/dist/tempo/MultisigConfig.d.ts.map +1 -1
  8. package/dist/tempo/MultisigConfig.js +164 -86
  9. package/dist/tempo/MultisigConfig.js.map +1 -1
  10. package/dist/tempo/MultisigOperation.d.ts +324 -0
  11. package/dist/tempo/MultisigOperation.d.ts.map +1 -0
  12. package/dist/tempo/MultisigOperation.js +809 -0
  13. package/dist/tempo/MultisigOperation.js.map +1 -0
  14. package/dist/tempo/MultisigWitness.d.ts +106 -0
  15. package/dist/tempo/MultisigWitness.d.ts.map +1 -0
  16. package/dist/tempo/MultisigWitness.js +118 -0
  17. package/dist/tempo/MultisigWitness.js.map +1 -0
  18. package/dist/tempo/RpcSchemaTempo.d.ts +35 -0
  19. package/dist/tempo/RpcSchemaTempo.d.ts.map +1 -1
  20. package/dist/tempo/SignatureEnvelope.d.ts +60 -80
  21. package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
  22. package/dist/tempo/SignatureEnvelope.js +87 -146
  23. package/dist/tempo/SignatureEnvelope.js.map +1 -1
  24. package/dist/tempo/TransactionRequest.d.ts +9 -17
  25. package/dist/tempo/TransactionRequest.d.ts.map +1 -1
  26. package/dist/tempo/TransactionRequest.js +7 -7
  27. package/dist/tempo/TransactionRequest.js.map +1 -1
  28. package/dist/tempo/TxEnvelopeTempo.d.ts +3 -2
  29. package/dist/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  30. package/dist/tempo/TxEnvelopeTempo.js +3 -2
  31. package/dist/tempo/TxEnvelopeTempo.js.map +1 -1
  32. package/dist/tempo/index.d.ts +22 -2
  33. package/dist/tempo/index.d.ts.map +1 -1
  34. package/dist/tempo/index.js +22 -2
  35. package/dist/tempo/index.js.map +1 -1
  36. package/dist/zod/tempo/AuthorizationTempo.d.ts +110 -110
  37. package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
  38. package/dist/zod/tempo/KeyAuthorization.d.ts +90 -83
  39. package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
  40. package/dist/zod/tempo/MultisigConfig.d.ts +31 -2
  41. package/dist/zod/tempo/MultisigConfig.d.ts.map +1 -1
  42. package/dist/zod/tempo/MultisigConfig.js +26 -3
  43. package/dist/zod/tempo/MultisigConfig.js.map +1 -1
  44. package/dist/zod/tempo/MultisigOperation.d.ts +168 -0
  45. package/dist/zod/tempo/MultisigOperation.d.ts.map +1 -0
  46. package/dist/zod/tempo/MultisigOperation.js +65 -0
  47. package/dist/zod/tempo/MultisigOperation.js.map +1 -0
  48. package/dist/zod/tempo/MultisigWitness.d.ts +152 -0
  49. package/dist/zod/tempo/MultisigWitness.d.ts.map +1 -0
  50. package/dist/zod/tempo/MultisigWitness.js +76 -0
  51. package/dist/zod/tempo/MultisigWitness.js.map +1 -0
  52. package/dist/zod/tempo/RpcSchemaTempo.d.ts +607 -102
  53. package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
  54. package/dist/zod/tempo/RpcSchemaTempo.js +38 -0
  55. package/dist/zod/tempo/RpcSchemaTempo.js.map +1 -1
  56. package/dist/zod/tempo/SignatureEnvelope.d.ts +33 -33
  57. package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
  58. package/dist/zod/tempo/SignatureEnvelope.js +9 -16
  59. package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
  60. package/dist/zod/tempo/Transaction.d.ts +228 -222
  61. package/dist/zod/tempo/Transaction.d.ts.map +1 -1
  62. package/dist/zod/tempo/TransactionRequest.d.ts +379 -176
  63. package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
  64. package/dist/zod/tempo/TransactionRequest.js +11 -22
  65. package/dist/zod/tempo/TransactionRequest.js.map +1 -1
  66. package/dist/zod/tempo/TxEnvelopeTempo.d.ts +60 -48
  67. package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  68. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +15 -12
  69. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
  70. package/dist/zod/tempo/z.d.ts +2 -0
  71. package/dist/zod/tempo/z.d.ts.map +1 -1
  72. package/dist/zod/tempo/z.js +2 -0
  73. package/dist/zod/tempo/z.js.map +1 -1
  74. package/package.json +21 -1
  75. package/src/core/Hash.ts +1 -1
  76. package/src/core/_test/Hash.test.ts +15 -0
  77. package/src/tempo/KeyAuthorization.test-d.ts +13 -1
  78. package/src/tempo/KeyAuthorization.test.ts +65 -0
  79. package/src/tempo/KeyAuthorization.ts +1 -1
  80. package/src/tempo/MultisigConfig.test-d.ts +52 -0
  81. package/src/tempo/MultisigConfig.test.ts +288 -227
  82. package/src/tempo/MultisigConfig.ts +275 -104
  83. package/src/tempo/MultisigOperation.test-d.ts +77 -0
  84. package/src/tempo/MultisigOperation.test.ts +1883 -0
  85. package/src/tempo/MultisigOperation.ts +1254 -0
  86. package/src/tempo/MultisigWitness.test-d.ts +42 -0
  87. package/src/tempo/MultisigWitness.test.ts +288 -0
  88. package/src/tempo/MultisigWitness.ts +210 -0
  89. package/src/tempo/RpcSchemaTempo.test-d.ts +56 -0
  90. package/src/tempo/RpcSchemaTempo.ts +37 -0
  91. package/src/tempo/SignatureEnvelope.test-d.ts +63 -46
  92. package/src/tempo/SignatureEnvelope.test.ts +523 -500
  93. package/src/tempo/SignatureEnvelope.ts +172 -242
  94. package/src/tempo/TransactionRequest.test-d.ts +11 -0
  95. package/src/tempo/TransactionRequest.test.ts +285 -33
  96. package/src/tempo/TransactionRequest.ts +15 -20
  97. package/src/tempo/TxEnvelopeTempo.test-d.ts +7 -0
  98. package/src/tempo/TxEnvelopeTempo.test.ts +25 -0
  99. package/src/tempo/TxEnvelopeTempo.ts +5 -3
  100. package/src/tempo/index.ts +22 -2
  101. package/src/tempo/multisig.e2e.test.ts +113 -86
  102. package/src/version.ts +1 -1
  103. package/src/zod/tempo/MultisigConfig.ts +29 -3
  104. package/src/zod/tempo/MultisigOperation.ts +69 -0
  105. package/src/zod/tempo/MultisigWitness.ts +101 -0
  106. package/src/zod/tempo/RpcSchemaTempo.ts +43 -0
  107. package/src/zod/tempo/SignatureEnvelope.ts +20 -38
  108. package/src/zod/tempo/TransactionRequest.ts +17 -26
  109. package/src/zod/tempo/_test/KeyAuthorization.test.ts +11 -0
  110. package/src/zod/tempo/_test/MultisigConfig.test-d.ts +13 -0
  111. package/src/zod/tempo/_test/MultisigConfig.test.ts +13 -2
  112. package/src/zod/tempo/_test/MultisigOperation.test-d.ts +27 -0
  113. package/src/zod/tempo/_test/MultisigOperation.test.ts +68 -0
  114. package/src/zod/tempo/_test/MultisigWitness.test-d.ts +13 -0
  115. package/src/zod/tempo/_test/MultisigWitness.test.ts +149 -0
  116. package/src/zod/tempo/_test/RpcSchemaTempo.test-d.ts +31 -0
  117. package/src/zod/tempo/_test/RpcSchemaTempo.test.ts +41 -0
  118. package/src/zod/tempo/_test/SignatureEnvelope.test-d.ts +1 -1
  119. package/src/zod/tempo/_test/SignatureEnvelope.test.ts +25 -34
  120. package/src/zod/tempo/_test/TransactionRequest.test.ts +176 -8
  121. package/src/zod/tempo/z.ts +2 -0
@@ -1,6 +1,7 @@
1
1
  import type * as ox_TransactionRequest from '../core/TransactionRequest.js'
2
2
  import * as Signature from '../core/Signature.js'
3
3
  import { describe, expectTypeOf, test } from 'vp/test'
4
+ import * as MultisigWitness from './MultisigWitness.js'
4
5
  import * as SignatureEnvelope from './SignatureEnvelope.js'
5
6
  import * as TransactionRequest from './TransactionRequest.js'
6
7
  import * as TxEnvelopeTempo from './TxEnvelopeTempo.js'
@@ -47,6 +48,15 @@ describe('TransactionRequest type', () => {
47
48
  Signature.Rpc | null | undefined
48
49
  >()
49
50
  })
51
+
52
+ test('carries domain and RPC multisig witnesses', () => {
53
+ expectTypeOf<
54
+ TransactionRequest.TransactionRequest['multisigWitness']
55
+ >().toEqualTypeOf<MultisigWitness.MultisigWitness | undefined>()
56
+ expectTypeOf<TransactionRequest.Rpc['multisigWitness']>().toEqualTypeOf<
57
+ MultisigWitness.Rpc | undefined
58
+ >()
59
+ })
50
60
  })
51
61
 
52
62
  describe('toEnvelope', () => {
@@ -77,6 +87,7 @@ describe('toEnvelope', () => {
77
87
  keyType: 'secp256k1',
78
88
  maxFeePerGas: 1n,
79
89
  maxPriorityFeePerGas: 1n,
90
+ multisigWitness: undefined,
80
91
  nonce: 0n,
81
92
  nonceKey: 'random',
82
93
  signature: undefined,
@@ -69,7 +69,7 @@ describe('fromRpc', () => {
69
69
  expect(request.nonceKey).toBe(255n)
70
70
  })
71
71
 
72
- test('behavior: gas-model hints and capabilities pass through', () => {
72
+ test('behavior: capabilities and key hints pass through', () => {
73
73
  const request = TransactionRequest.fromRpc({
74
74
  calls: [{ to: '0xcafebabecafebabecafebabecafebabecafebabe' }],
75
75
  capabilities: { balanceDiffs: true },
@@ -77,30 +77,156 @@ describe('fromRpc', () => {
77
77
  keyData: '0x0578',
78
78
  keyId: '0xcccccccccccccccccccccccccccccccccccccccc',
79
79
  keyType: 'webAuthn',
80
- multisigInit: {
81
- salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
82
- threshold: 2,
83
- owners: [
80
+ type: '0x76',
81
+ })
82
+ expect(request).toMatchInlineSnapshot(`
83
+ {
84
+ "calls": [
85
+ {
86
+ "data": undefined,
87
+ "to": "0xcafebabecafebabecafebabecafebabecafebabe",
88
+ },
89
+ ],
90
+ "capabilities": {
91
+ "balanceDiffs": true,
92
+ },
93
+ "feePayer": true,
94
+ "keyData": "0x0578",
95
+ "keyId": "0xcccccccccccccccccccccccccccccccccccccccc",
96
+ "keyType": "webAuthn",
97
+ "type": "tempo",
98
+ }
99
+ `)
100
+ })
101
+
102
+ test('behavior: multisig witness configs decode from RPC numbers', () => {
103
+ const request = TransactionRequest.fromRpc({
104
+ calls: [{ to: '0xcafebabecafebabecafebabecafebabecafebabe' }],
105
+ multisigWitness: {
106
+ account: '0xcccccccccccccccccccccccccccccccccccccccc',
107
+ approvals: [
84
108
  {
109
+ keyData: '0x0578',
110
+ keyType: 'webAuthn',
85
111
  owner: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
86
- weight: 1,
112
+ type: 'primitive',
87
113
  },
88
114
  {
89
- owner: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
90
- weight: 1,
115
+ type: 'multisig',
116
+ witness: {
117
+ account: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
118
+ approvals: [
119
+ {
120
+ keyType: 'secp256k1',
121
+ owner: '0xdddddddddddddddddddddddddddddddddddddddd',
122
+ },
123
+ {
124
+ owner: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
125
+ },
126
+ ],
127
+ config: {
128
+ owners: [
129
+ {
130
+ owner: '0xdddddddddddddddddddddddddddddddddddddddd',
131
+ weight: 1,
132
+ },
133
+ {
134
+ owner: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
135
+ weight: 1,
136
+ },
137
+ ],
138
+ salt: '0x2222222222222222222222222222222222222222222222222222222222222222',
139
+ threshold: 2,
140
+ version: 2,
141
+ },
142
+ },
91
143
  },
92
144
  ],
145
+ config: {
146
+ owners: [
147
+ {
148
+ owner: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
149
+ weight: 1,
150
+ },
151
+ {
152
+ owner: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
153
+ weight: 1,
154
+ },
155
+ ],
156
+ salt: '0x1111111111111111111111111111111111111111111111111111111111111111',
157
+ threshold: 2,
158
+ version: 1,
159
+ },
93
160
  },
94
- multisigSignatureCount: 2,
95
161
  type: '0x76',
96
162
  })
97
- expect(request.capabilities).toEqual({ balanceDiffs: true })
98
- expect(request.feePayer).toBe(true)
99
- expect(request.keyData).toBe('0x0578')
100
- expect(request.keyId).toBe('0xcccccccccccccccccccccccccccccccccccccccc')
101
- expect(request.keyType).toBe('webAuthn')
102
- expect(request.multisigInit).toMatchObject({ threshold: 2 })
103
- expect(request.multisigSignatureCount).toBe(2)
163
+ expect(request).toMatchInlineSnapshot(`
164
+ {
165
+ "calls": [
166
+ {
167
+ "data": undefined,
168
+ "to": "0xcafebabecafebabecafebabecafebabecafebabe",
169
+ },
170
+ ],
171
+ "multisigWitness": {
172
+ "account": "0xcccccccccccccccccccccccccccccccccccccccc",
173
+ "approvals": [
174
+ {
175
+ "keyData": "0x0578",
176
+ "keyType": "webAuthn",
177
+ "owner": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
178
+ "type": "primitive",
179
+ },
180
+ {
181
+ "type": "multisig",
182
+ "witness": {
183
+ "account": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
184
+ "approvals": [
185
+ {
186
+ "keyType": "secp256k1",
187
+ "owner": "0xdddddddddddddddddddddddddddddddddddddddd",
188
+ },
189
+ {
190
+ "owner": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
191
+ },
192
+ ],
193
+ "config": {
194
+ "owners": [
195
+ {
196
+ "owner": "0xdddddddddddddddddddddddddddddddddddddddd",
197
+ "weight": 1,
198
+ },
199
+ {
200
+ "owner": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
201
+ "weight": 1,
202
+ },
203
+ ],
204
+ "salt": "0x2222222222222222222222222222222222222222222222222222222222222222",
205
+ "threshold": 2,
206
+ "version": 2n,
207
+ },
208
+ },
209
+ },
210
+ ],
211
+ "config": {
212
+ "owners": [
213
+ {
214
+ "owner": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
215
+ "weight": 1,
216
+ },
217
+ {
218
+ "owner": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
219
+ "weight": 1,
220
+ },
221
+ ],
222
+ "salt": "0x1111111111111111111111111111111111111111111111111111111111111111",
223
+ "threshold": 2,
224
+ "version": 1n,
225
+ },
226
+ },
227
+ "type": "tempo",
228
+ }
229
+ `)
104
230
  })
105
231
 
106
232
  test('behavior: empty', () => {
@@ -157,7 +283,7 @@ describe('toRpc', () => {
157
283
  `)
158
284
  })
159
285
 
160
- test('behavior: gas-model hints and capabilities are carried', () => {
286
+ test('behavior: capabilities and key hints are carried', () => {
161
287
  const request = TransactionRequest.toRpc({
162
288
  calls: [{ to: '0xcafebabecafebabecafebabecafebabecafebabe' }],
163
289
  capabilities: { balanceDiffs: true },
@@ -165,30 +291,156 @@ describe('toRpc', () => {
165
291
  keyData: '0x0578',
166
292
  keyId: '0xcccccccccccccccccccccccccccccccccccccccc',
167
293
  keyType: 'webAuthn',
168
- multisigInit: {
169
- salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
170
- threshold: 2,
171
- owners: [
294
+ })
295
+ expect(request).toMatchInlineSnapshot(`
296
+ {
297
+ "calls": [
298
+ {
299
+ "data": "0x",
300
+ "to": "0xcafebabecafebabecafebabecafebabecafebabe",
301
+ "value": "0x",
302
+ },
303
+ ],
304
+ "capabilities": {
305
+ "balanceDiffs": true,
306
+ },
307
+ "feePayer": false,
308
+ "keyData": "0x0578",
309
+ "keyId": "0xcccccccccccccccccccccccccccccccccccccccc",
310
+ "keyType": "webAuthn",
311
+ "type": "0x76",
312
+ }
313
+ `)
314
+ })
315
+
316
+ test('behavior: multisig witness configs encode as RPC numbers', () => {
317
+ const request = TransactionRequest.toRpc({
318
+ calls: [{ to: '0xcafebabecafebabecafebabecafebabecafebabe' }],
319
+ multisigWitness: {
320
+ account: '0xcccccccccccccccccccccccccccccccccccccccc',
321
+ approvals: [
172
322
  {
323
+ keyData: '0x0578',
324
+ keyType: 'webAuthn',
173
325
  owner: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
174
- weight: 1,
326
+ type: 'primitive',
175
327
  },
176
328
  {
177
- owner: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
178
- weight: 1,
329
+ type: 'multisig',
330
+ witness: {
331
+ account: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
332
+ approvals: [
333
+ {
334
+ keyType: 'secp256k1',
335
+ owner: '0xdddddddddddddddddddddddddddddddddddddddd',
336
+ },
337
+ {
338
+ owner: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
339
+ },
340
+ ],
341
+ config: {
342
+ owners: [
343
+ {
344
+ owner: '0xdddddddddddddddddddddddddddddddddddddddd',
345
+ weight: 1,
346
+ },
347
+ {
348
+ owner: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
349
+ weight: 1,
350
+ },
351
+ ],
352
+ salt: '0x2222222222222222222222222222222222222222222222222222222222222222',
353
+ threshold: 2,
354
+ version: 2n,
355
+ },
356
+ },
179
357
  },
180
358
  ],
359
+ config: {
360
+ owners: [
361
+ {
362
+ owner: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
363
+ weight: 1,
364
+ },
365
+ {
366
+ owner: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
367
+ weight: 1,
368
+ },
369
+ ],
370
+ salt: '0x1111111111111111111111111111111111111111111111111111111111111111',
371
+ threshold: 2,
372
+ version: 1n,
373
+ },
181
374
  },
182
- multisigSignatureCount: 2,
183
375
  })
184
- expect(request.capabilities).toEqual({ balanceDiffs: true })
185
- expect(request.feePayer).toBe(false)
186
- expect(request.keyData).toBe('0x0578')
187
- expect(request.keyId).toBe('0xcccccccccccccccccccccccccccccccccccccccc')
188
- expect(request.keyType).toBe('webAuthn')
189
- expect(request.multisigInit).toMatchObject({ threshold: 2 })
190
- expect(request.multisigSignatureCount).toBe(2)
191
- expect(request.type).toBe('0x76')
376
+ expect(request).toMatchInlineSnapshot(`
377
+ {
378
+ "calls": [
379
+ {
380
+ "data": "0x",
381
+ "to": "0xcafebabecafebabecafebabecafebabecafebabe",
382
+ "value": "0x",
383
+ },
384
+ ],
385
+ "multisigWitness": {
386
+ "account": "0xcccccccccccccccccccccccccccccccccccccccc",
387
+ "approvals": [
388
+ {
389
+ "keyData": "0x0578",
390
+ "keyType": "webAuthn",
391
+ "owner": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
392
+ "type": "primitive",
393
+ },
394
+ {
395
+ "type": "multisig",
396
+ "witness": {
397
+ "account": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
398
+ "approvals": [
399
+ {
400
+ "keyType": "secp256k1",
401
+ "owner": "0xdddddddddddddddddddddddddddddddddddddddd",
402
+ },
403
+ {
404
+ "owner": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
405
+ },
406
+ ],
407
+ "config": {
408
+ "owners": [
409
+ {
410
+ "owner": "0xdddddddddddddddddddddddddddddddddddddddd",
411
+ "weight": 1,
412
+ },
413
+ {
414
+ "owner": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
415
+ "weight": 1,
416
+ },
417
+ ],
418
+ "salt": "0x2222222222222222222222222222222222222222222222222222222222222222",
419
+ "threshold": 2,
420
+ "version": 2,
421
+ },
422
+ },
423
+ },
424
+ ],
425
+ "config": {
426
+ "owners": [
427
+ {
428
+ "owner": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
429
+ "weight": 1,
430
+ },
431
+ {
432
+ "owner": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
433
+ "weight": 1,
434
+ },
435
+ ],
436
+ "salt": "0x1111111111111111111111111111111111111111111111111111111111111111",
437
+ "threshold": 2,
438
+ "version": 1,
439
+ },
440
+ },
441
+ "type": "0x76",
442
+ }
443
+ `)
192
444
  })
193
445
 
194
446
  test('behavior: key data longer than 4 bytes shims into a length hint', () => {
@@ -7,7 +7,7 @@ import * as Signature from '../core/Signature.js'
7
7
  import * as ox_TransactionRequest from '../core/TransactionRequest.js'
8
8
  import * as AuthorizationTempo from './AuthorizationTempo.js'
9
9
  import * as KeyAuthorization from './KeyAuthorization.js'
10
- import type * as MultisigConfig from './MultisigConfig.js'
10
+ import * as MultisigWitness from './MultisigWitness.js'
11
11
  import * as SignatureEnvelope from './SignatureEnvelope.js'
12
12
  import * as Transaction from './Transaction.js'
13
13
  import * as TxEnvelopeTempo from './TxEnvelopeTempo.js'
@@ -15,13 +15,6 @@ import type { Call } from './TxEnvelopeTempo.js'
15
15
 
16
16
  type KeyType = 'secp256k1' | 'p256' | 'webAuthn'
17
17
 
18
- /**
19
- * Bootstrap multisig config hint for node-side gas modeling (TIP-1061).
20
- * The node prices multisig gas from it during simulation, and ignores it
21
- * for registered senders.
22
- */
23
- export type MultisigInit = Compute<MultisigConfig.Config & { salt: Hex.Hex }>
24
-
25
18
  /**
26
19
  * A Transaction Request that is generic to all transaction types.
27
20
  *
@@ -44,19 +37,18 @@ export type TransactionRequest<
44
37
  | undefined
45
38
  calls?: readonly Call<bigintType>[] | undefined
46
39
  capabilities?: Record<string, unknown> | undefined
40
+ feePayer?: boolean | undefined
47
41
  feePayerSignature?: Signature.Signature<true, numberType> | null | undefined
42
+ feeToken?: Address.Address | undefined
48
43
  keyAuthorization?: KeyAuthorization.KeyAuthorization<true> | undefined
49
44
  keyData?: Hex.Hex | undefined
50
45
  keyId?: Address.Address | undefined
51
46
  keyType?: KeyType | undefined
52
- feePayer?: boolean | undefined
53
- feeToken?: Address.Address | undefined
54
- multisigInit?: MultisigInit | undefined
55
- multisigSignatureCount?: number | undefined
47
+ multisigWitness?: MultisigWitness.MultisigWitness | undefined
56
48
  nonceKey?: 'random' | bigintType | undefined
57
49
  signature?: SignatureEnvelope.SignatureEnvelope<numberType> | undefined
58
- validBefore?: numberType | undefined
59
50
  validAfter?: numberType | undefined
51
+ validBefore?: numberType | undefined
60
52
  }
61
53
  >
62
54
 
@@ -67,12 +59,14 @@ export type Rpc = Omit<
67
59
  | 'feePayerSignature'
68
60
  | 'feeToken'
69
61
  | 'keyAuthorization'
62
+ | 'multisigWitness'
70
63
  | 'signature'
71
64
  > & {
72
65
  authorizationList?: AuthorizationTempo.ListRpc | undefined
73
66
  feePayerSignature?: Signature.Rpc | null | undefined
74
67
  feeToken?: Hex.Hex | undefined
75
68
  keyAuthorization?: KeyAuthorization.Rpc | undefined
69
+ multisigWitness?: MultisigWitness.Rpc | undefined
76
70
  nonceKey?: Hex.Hex | undefined
77
71
  signature?: SignatureEnvelope.SignatureEnvelopeRpc | undefined
78
72
  }
@@ -100,7 +94,7 @@ export type Rpc = Omit<
100
94
  * @returns A transaction request.
101
95
  */
102
96
  export function fromRpc(request: Rpc): TransactionRequest {
103
- const { authorizationList: _, ...rest } = request
97
+ const { authorizationList: _, multisigWitness: __, ...rest } = request
104
98
  const request_ = ox_TransactionRequest.fromRpc(
105
99
  rest as any,
106
100
  ) as TransactionRequest
@@ -135,6 +129,8 @@ export function fromRpc(request: Rpc): TransactionRequest {
135
129
  request_.keyAuthorization = KeyAuthorization.fromRpc(
136
130
  request.keyAuthorization,
137
131
  )
132
+ if (request.multisigWitness)
133
+ request_.multisigWitness = MultisigWitness.fromRpc(request.multisigWitness)
138
134
  if (typeof request.validBefore !== 'undefined')
139
135
  request_.validBefore = Hex.toNumber(request.validBefore as Hex.Hex)
140
136
  if (typeof request.validAfter !== 'undefined')
@@ -150,6 +146,7 @@ export declare namespace fromRpc {
150
146
  | AuthorizationTempo.fromRpcList.ErrorType
151
147
  | Hex.toNumber.ErrorType
152
148
  | Hex.toBigInt.ErrorType
149
+ | MultisigWitness.fromRpc.ErrorType
153
150
  | Errors.GlobalErrorType
154
151
  }
155
152
 
@@ -223,8 +220,7 @@ export function toRpc(request: toRpc.Input): Rpc {
223
220
  typeof request.keyData !== 'undefined' ||
224
221
  typeof request.keyId !== 'undefined' ||
225
222
  typeof request.keyType !== 'undefined' ||
226
- typeof request.multisigInit !== 'undefined' ||
227
- typeof request.multisigSignatureCount !== 'undefined' ||
223
+ typeof request.multisigWitness !== 'undefined' ||
228
224
  typeof request.nonceKey !== 'undefined' ||
229
225
  typeof request.validBefore !== 'undefined' ||
230
226
  typeof request.validAfter !== 'undefined' ||
@@ -274,10 +270,8 @@ export function toRpc(request: toRpc.Input): Rpc {
274
270
  if (typeof request.keyId !== 'undefined') request_rpc.keyId = request.keyId
275
271
  if (typeof request.keyType !== 'undefined')
276
272
  request_rpc.keyType = request.keyType
277
- if (typeof request.multisigInit !== 'undefined')
278
- request_rpc.multisigInit = request.multisigInit
279
- if (typeof request.multisigSignatureCount !== 'undefined')
280
- request_rpc.multisigSignatureCount = request.multisigSignatureCount
273
+ if (typeof request.multisigWitness !== 'undefined')
274
+ request_rpc.multisigWitness = MultisigWitness.toRpc(request.multisigWitness)
281
275
  if (typeof request.validBefore !== 'undefined')
282
276
  request_rpc.validBefore = Quantity.fromNumberish(request.validBefore)
283
277
  if (typeof request.validAfter !== 'undefined')
@@ -312,6 +306,7 @@ export declare namespace toRpc {
312
306
  export type ErrorType =
313
307
  | AuthorizationTempo.toRpcList.ErrorType
314
308
  | Hex.fromNumber.ErrorType
309
+ | MultisigWitness.toRpc.ErrorType
315
310
  | Errors.GlobalErrorType
316
311
  }
317
312
 
@@ -0,0 +1,7 @@
1
+ import { expectTypeOf, test } from 'vp/test'
2
+ import type * as TxEnvelopeTempo from './TxEnvelopeTempo.js'
3
+
4
+ test('Serialized', () => {
5
+ expectTypeOf<'0x76'>().toExtend<TxEnvelopeTempo.Serialized>()
6
+ expectTypeOf<'0x78'>().toExtend<TxEnvelopeTempo.Serialized>()
7
+ })
@@ -138,6 +138,31 @@ describe('deserialize', () => {
138
138
  expect(deserialized).toEqual(transaction)
139
139
  })
140
140
 
141
+ test('fee payer', () => {
142
+ const serialized = TxEnvelopeTempo.serialize(transaction, {
143
+ format: 'feePayer',
144
+ sender: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
145
+ })
146
+
147
+ expect(TxEnvelopeTempo.deserialize(serialized)).toMatchInlineSnapshot(`
148
+ {
149
+ "calls": [
150
+ {
151
+ "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
152
+ },
153
+ ],
154
+ "chainId": 1,
155
+ "feePayerSignature": null,
156
+ "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
157
+ "maxFeePerGas": 2000000000n,
158
+ "maxPriorityFeePerGas": 2000000000n,
159
+ "nonce": 785n,
160
+ "nonceKey": 0n,
161
+ "type": "tempo",
162
+ }
163
+ `)
164
+ })
165
+
141
166
  test('minimal', () => {
142
167
  const transaction = TxEnvelopeTempo.from({
143
168
  chainId: 1,
@@ -134,7 +134,8 @@ export type Rpc<signed extends boolean = boolean> = TxEnvelopeTempo<
134
134
  export const feePayerMagic = '0x78' as const
135
135
  export type FeePayerMagic = typeof feePayerMagic
136
136
 
137
- export type Serialized = `${SerializedType}${string}`
137
+ /** Serialized standard or fee-payer Tempo transaction. */
138
+ export type Serialized = `${SerializedType | FeePayerMagic}${string}`
138
139
 
139
140
  export type Signed = TxEnvelopeTempo<true>
140
141
 
@@ -232,7 +233,7 @@ export declare namespace assert {
232
233
  }
233
234
 
234
235
  /**
235
- * Deserializes a {@link ox#TxEnvelopeTempo.TxEnvelopeTempo} from its serialized form.
236
+ * Deserializes a standard or fee-payer {@link ox#TxEnvelopeTempo.TxEnvelopeTempo}.
236
237
  *
237
238
  * @example
238
239
  * ```ts twoslash
@@ -254,7 +255,8 @@ export declare namespace assert {
254
255
  * @returns Deserialized Transaction Envelope.
255
256
  */
256
257
  export function deserialize(serialized: Serialized): Compute<TxEnvelopeTempo> {
257
- if (Hex.slice(serialized, 0, 1) !== serializedType)
258
+ const prefix = Hex.slice(serialized, 0, 1)
259
+ if (prefix !== serializedType && prefix !== feePayerMagic)
258
260
  throw new TransactionEnvelope.InvalidSerializedError({
259
261
  attributes: {},
260
262
  serialized,
@@ -173,6 +173,24 @@ export * as KeyAuthorization from './KeyAuthorization.js'
173
173
  * @category Reference
174
174
  */
175
175
  export * as MultisigConfig from './MultisigConfig.js'
176
+ /**
177
+ * Offchain multisig transaction and key authorization operation utilities.
178
+ *
179
+ * Derives operation hashes, selects owner approvals, serializes transactions,
180
+ * validates operation state, and converts JSON-RPC representations.
181
+ *
182
+ * @category Reference
183
+ */
184
+ export * as MultisigOperation from './MultisigOperation.js'
185
+ /**
186
+ * Native multisig RPC simulation witness utilities.
187
+ *
188
+ * Converts complete root and nested owner witnesses between their domain and
189
+ * Tempo JSON-RPC representations.
190
+ *
191
+ * @category Reference
192
+ */
193
+ export * as MultisigWitness from './MultisigWitness.js'
176
194
  /**
177
195
  * Utilities for constructing period durations (in seconds) for recurring spending limits.
178
196
  *
@@ -251,7 +269,7 @@ export * as PoolId from './PoolId.js'
251
269
  */
252
270
  export * as ReceivePolicyReceipt from './ReceivePolicyReceipt.js'
253
271
  /**
254
- * Union of all JSON-RPC Methods for the `tempo_` namespace.
272
+ * JSON-RPC schemas for the `tempo_` and `multisig_` namespaces.
255
273
  *
256
274
  * @example
257
275
  * ```ts twoslash
@@ -260,7 +278,9 @@ export * as ReceivePolicyReceipt from './ReceivePolicyReceipt.js'
260
278
  * import { RpcSchemaTempo } from 'ox/tempo'
261
279
  *
262
280
  * const schema = RpcSchema.from<
263
- * RpcSchema.Default | RpcSchemaTempo.Tempo
281
+ * | RpcSchema.Default
282
+ * | RpcSchemaTempo.Multisig
283
+ * | RpcSchemaTempo.Tempo
264
284
  * >()
265
285
  *
266
286
  * const provider = Provider.from(window.ethereum!, { schema })