ox 1.7.2 → 1.7.5

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 (142) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/core/AbiEvent.d.ts.map +1 -1
  3. package/dist/core/AbiEvent.js +10 -9
  4. package/dist/core/AbiEvent.js.map +1 -1
  5. package/dist/core/Blobs.d.ts.map +1 -1
  6. package/dist/core/Blobs.js +6 -2
  7. package/dist/core/Blobs.js.map +1 -1
  8. package/dist/core/Signature.d.ts +6 -5
  9. package/dist/core/Signature.d.ts.map +1 -1
  10. package/dist/core/Signature.js +17 -7
  11. package/dist/core/Signature.js.map +1 -1
  12. package/dist/core/Siwe.d.ts.map +1 -1
  13. package/dist/core/Siwe.js +21 -1
  14. package/dist/core/Siwe.js.map +1 -1
  15. package/dist/tempo/KeyAuthorization.d.ts +43 -39
  16. package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
  17. package/dist/tempo/KeyAuthorization.js +24 -4
  18. package/dist/tempo/KeyAuthorization.js.map +1 -1
  19. package/dist/tempo/MultisigConfig.d.ts +18 -15
  20. package/dist/tempo/MultisigConfig.d.ts.map +1 -1
  21. package/dist/tempo/MultisigConfig.js +49 -20
  22. package/dist/tempo/MultisigConfig.js.map +1 -1
  23. package/dist/tempo/MultisigOperation.d.ts +45 -28
  24. package/dist/tempo/MultisigOperation.d.ts.map +1 -1
  25. package/dist/tempo/MultisigOperation.js +81 -131
  26. package/dist/tempo/MultisigOperation.js.map +1 -1
  27. package/dist/tempo/MultisigSimulation.d.ts +85 -0
  28. package/dist/tempo/MultisigSimulation.d.ts.map +1 -0
  29. package/dist/tempo/MultisigSimulation.js +112 -0
  30. package/dist/tempo/MultisigSimulation.js.map +1 -0
  31. package/dist/tempo/RpcSchemaTempo.d.ts +20 -10
  32. package/dist/tempo/RpcSchemaTempo.d.ts.map +1 -1
  33. package/dist/tempo/SignatureEnvelope.d.ts +74 -153
  34. package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
  35. package/dist/tempo/SignatureEnvelope.js +130 -187
  36. package/dist/tempo/SignatureEnvelope.js.map +1 -1
  37. package/dist/tempo/TransactionRequest.d.ts +9 -7
  38. package/dist/tempo/TransactionRequest.d.ts.map +1 -1
  39. package/dist/tempo/TransactionRequest.js +12 -7
  40. package/dist/tempo/TransactionRequest.js.map +1 -1
  41. package/dist/tempo/index.d.ts +7 -5
  42. package/dist/tempo/index.d.ts.map +1 -1
  43. package/dist/tempo/index.js +7 -5
  44. package/dist/tempo/index.js.map +1 -1
  45. package/dist/zod/tempo/AuthorizationTempo.d.ts +360 -140
  46. package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
  47. package/dist/zod/tempo/KeyAuthorization.d.ts +247 -487
  48. package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
  49. package/dist/zod/tempo/KeyAuthorization.js +29 -31
  50. package/dist/zod/tempo/KeyAuthorization.js.map +1 -1
  51. package/dist/zod/tempo/MultisigOperation.d.ts +0 -10
  52. package/dist/zod/tempo/MultisigOperation.d.ts.map +1 -1
  53. package/dist/zod/tempo/MultisigOperation.js +0 -3
  54. package/dist/zod/tempo/MultisigOperation.js.map +1 -1
  55. package/dist/zod/tempo/MultisigSimulation.d.ts +52 -0
  56. package/dist/zod/tempo/MultisigSimulation.d.ts.map +1 -0
  57. package/dist/zod/tempo/MultisigSimulation.js +44 -0
  58. package/dist/zod/tempo/MultisigSimulation.js.map +1 -0
  59. package/dist/zod/tempo/RpcSchemaTempo.d.ts +357 -422
  60. package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
  61. package/dist/zod/tempo/RpcSchemaTempo.js +19 -10
  62. package/dist/zod/tempo/RpcSchemaTempo.js.map +1 -1
  63. package/dist/zod/tempo/SignatureEnvelope.d.ts +108 -42
  64. package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
  65. package/dist/zod/tempo/SignatureEnvelope.js +21 -19
  66. package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
  67. package/dist/zod/tempo/Transaction.d.ts +678 -666
  68. package/dist/zod/tempo/Transaction.d.ts.map +1 -1
  69. package/dist/zod/tempo/TransactionRequest.d.ts +580 -619
  70. package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
  71. package/dist/zod/tempo/TransactionRequest.js +18 -10
  72. package/dist/zod/tempo/TransactionRequest.js.map +1 -1
  73. package/dist/zod/tempo/TxEnvelopeTempo.d.ts +327 -213
  74. package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  75. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +105 -3
  76. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
  77. package/dist/zod/tempo/z.d.ts +1 -1
  78. package/dist/zod/tempo/z.d.ts.map +1 -1
  79. package/dist/zod/tempo/z.js +1 -1
  80. package/dist/zod/tempo/z.js.map +1 -1
  81. package/package.json +9 -9
  82. package/src/core/AbiEvent.ts +11 -9
  83. package/src/core/Blobs.ts +6 -2
  84. package/src/core/Signature.ts +41 -11
  85. package/src/core/Siwe.ts +20 -1
  86. package/src/core/_test/AbiEvent.test.ts +45 -0
  87. package/src/core/_test/Blobs.test.ts +22 -0
  88. package/src/core/_test/Signature.test.ts +166 -0
  89. package/src/core/_test/Siwe.test.ts +100 -1
  90. package/src/tempo/AuthorizationTempo.test.ts +8 -0
  91. package/src/tempo/KeyAuthorization.test-d.ts +16 -74
  92. package/src/tempo/KeyAuthorization.test.ts +113 -14
  93. package/src/tempo/KeyAuthorization.ts +110 -66
  94. package/src/tempo/MultisigConfig.test.ts +44 -20
  95. package/src/tempo/MultisigConfig.ts +65 -23
  96. package/src/tempo/MultisigOperation.test-d.ts +8 -6
  97. package/src/tempo/MultisigOperation.test.ts +187 -591
  98. package/src/tempo/MultisigOperation.ts +129 -205
  99. package/src/tempo/MultisigSimulation.test-d.ts +33 -0
  100. package/src/tempo/MultisigSimulation.test.ts +194 -0
  101. package/src/tempo/MultisigSimulation.ts +192 -0
  102. package/src/tempo/RpcSchemaTempo.test-d.ts +45 -10
  103. package/src/tempo/RpcSchemaTempo.ts +15 -6
  104. package/src/tempo/SignatureEnvelope.test-d.ts +27 -101
  105. package/src/tempo/SignatureEnvelope.test.ts +330 -533
  106. package/src/tempo/SignatureEnvelope.ts +198 -310
  107. package/src/tempo/Transaction.test.ts +61 -0
  108. package/src/tempo/TransactionRequest.test-d.ts +7 -7
  109. package/src/tempo/TransactionRequest.test.ts +81 -223
  110. package/src/tempo/TransactionRequest.ts +34 -13
  111. package/src/tempo/index.ts +7 -5
  112. package/src/tempo/multisig.e2e.test.ts +329 -818
  113. package/src/version.ts +1 -1
  114. package/src/zod/tempo/KeyAuthorization.ts +50 -39
  115. package/src/zod/tempo/MultisigOperation.ts +0 -3
  116. package/src/zod/tempo/MultisigSimulation.ts +53 -0
  117. package/src/zod/tempo/RpcSchemaTempo.ts +20 -10
  118. package/src/zod/tempo/SignatureEnvelope.ts +46 -59
  119. package/src/zod/tempo/TransactionRequest.ts +28 -14
  120. package/src/zod/tempo/_test/KeyAuthorization.test.ts +66 -30
  121. package/src/zod/tempo/_test/MultisigOperation.test.ts +0 -2
  122. package/src/zod/tempo/_test/MultisigSimulation.test-d.ts +13 -0
  123. package/src/zod/tempo/_test/MultisigSimulation.test.ts +53 -0
  124. package/src/zod/tempo/_test/RpcSchemaTempo.test-d.ts +19 -2
  125. package/src/zod/tempo/_test/RpcSchemaTempo.test.ts +46 -4
  126. package/src/zod/tempo/_test/SignatureEnvelope.test.ts +108 -129
  127. package/src/zod/tempo/_test/TransactionRequest.test.ts +17 -168
  128. package/src/zod/tempo/z.ts +1 -1
  129. package/dist/tempo/MultisigWitness.d.ts +0 -106
  130. package/dist/tempo/MultisigWitness.d.ts.map +0 -1
  131. package/dist/tempo/MultisigWitness.js +0 -118
  132. package/dist/tempo/MultisigWitness.js.map +0 -1
  133. package/dist/zod/tempo/MultisigWitness.d.ts +0 -152
  134. package/dist/zod/tempo/MultisigWitness.d.ts.map +0 -1
  135. package/dist/zod/tempo/MultisigWitness.js +0 -76
  136. package/dist/zod/tempo/MultisigWitness.js.map +0 -1
  137. package/src/tempo/MultisigWitness.test-d.ts +0 -42
  138. package/src/tempo/MultisigWitness.test.ts +0 -288
  139. package/src/tempo/MultisigWitness.ts +0 -210
  140. package/src/zod/tempo/MultisigWitness.ts +0 -101
  141. package/src/zod/tempo/_test/MultisigWitness.test-d.ts +0 -13
  142. package/src/zod/tempo/_test/MultisigWitness.test.ts +0 -149
@@ -1,3 +1,4 @@
1
+ import { factory } from '../../test/tempo/multisig.js'
1
2
  import { Address, Hash, Hex, P256 } from 'ox'
2
3
  import {
3
4
  KeyAuthorization,
@@ -39,8 +40,8 @@ const config = MultisigConfig.from({
39
40
  ],
40
41
  threshold: 2,
41
42
  })
42
- const initializedConfig = MultisigConfig.from({ ...config, version: 1n })
43
- const account = MultisigConfig.getAddress(config)
43
+ const currentConfig = MultisigConfig.from({ ...config, version: 1n })
44
+ const account = MultisigConfig.getAddress(config, { factory })
44
45
  const ownerSignature_1 = owners[0]!.signature
45
46
  const approval_1 = SignatureEnvelope.serialize(ownerSignature_1)
46
47
  const approval_2 = SignatureEnvelope.serialize(owners[1]!.signature)
@@ -66,14 +67,14 @@ const keyAuthorization = KeyAuthorization.serialize(
66
67
 
67
68
  const transactionHash_ = MultisigConfig.getSignPayload({
68
69
  account,
69
- config: initializedConfig,
70
+ config: currentConfig,
70
71
  payload: TxEnvelopeTempo.getSignPayload(
71
72
  TxEnvelopeTempo.deserialize(transaction),
72
73
  ),
73
74
  })
74
75
  const keyAuthorizationHash = MultisigConfig.getSignPayload({
75
76
  account,
76
- config: initializedConfig,
77
+ config: currentConfig,
77
78
  payload: KeyAuthorization.getSignPayload(
78
79
  KeyAuthorization.deserialize(keyAuthorization),
79
80
  ),
@@ -82,10 +83,8 @@ const keyAuthorizationHash = MultisigConfig.getSignPayload({
82
83
  const base = {
83
84
  account,
84
85
  approvals: [approval_1],
85
- config: initializedConfig,
86
- configVersion: 1n,
86
+ config: currentConfig,
87
87
  createdAt: 1,
88
- init: false,
89
88
  signatureCount: 1,
90
89
  threshold: 2,
91
90
  updatedAt: 2,
@@ -142,20 +141,20 @@ describe('getHash', () => {
142
141
  expect({
143
142
  keyAuthorization: MultisigOperation.getHash({
144
143
  account,
145
- configVersion: 1n,
144
+ config: currentConfig,
146
145
  keyAuthorization,
147
146
  type: 'keyAuthorization',
148
147
  }),
149
148
  transaction: MultisigOperation.getHash({
150
149
  account,
151
- configVersion: 1n,
150
+ config: currentConfig,
152
151
  transaction,
153
152
  type: 'transaction',
154
153
  }),
155
154
  }).toMatchInlineSnapshot(`
156
155
  {
157
- "keyAuthorization": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
158
- "transaction": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
156
+ "keyAuthorization": "0xa83016f0e94c4a6125483ffeba3abb0a8df1bc0f5a503f63639e806b793520bb",
157
+ "transaction": "0x2d7e3c7c38a9acf85f0a9d70a39b0e9e5a05d92c7a73b633a47a45be4a112b3b",
159
158
  }
160
159
  `)
161
160
  })
@@ -171,10 +170,10 @@ describe('selectApprovals', () => {
171
170
  ],
172
171
  threshold: 3,
173
172
  })
174
- const account = MultisigConfig.getAddress(config)
173
+ const account = MultisigConfig.getAddress(config, { factory })
175
174
  const hash = MultisigOperation.getHash({
176
175
  account,
177
- configVersion: 1n,
176
+ config: { ...config, version: 1n },
178
177
  transaction,
179
178
  type: 'transaction',
180
179
  })
@@ -227,178 +226,45 @@ describe('selectApprovals', () => {
227
226
  }
228
227
  `)
229
228
  })
230
-
231
- test('counts a nested owner only after its quorum', async () => {
232
- const childConfig = MultisigConfig.from({
233
- owners: [
234
- { owner: owners[1]!.address, weight: 1 },
235
- { owner: owners[2]!.address, weight: 1 },
236
- ],
237
- threshold: 2,
238
- })
239
- const child = MultisigConfig.getAddress(childConfig)
240
- const config = MultisigConfig.from({
241
- owners: [
242
- { owner: owners[0]!.address, weight: 1 },
243
- { owner: child, weight: 2 },
244
- ],
245
- threshold: 2,
246
- })
247
- const account = MultisigConfig.getAddress(config)
248
- const hash = MultisigOperation.getHash({
249
- account,
250
- configVersion: 1n,
251
- transaction,
252
- type: 'transaction',
253
- })
254
- const childHash = MultisigConfig.getSignPayload({
255
- account: child,
256
- config: { version: 2n },
257
- payload: hash,
258
- })
259
- const childApprovals = [
260
- signApproval(owners[1]!, childHash),
261
- signApproval(owners[2]!, childHash),
262
- ]
263
- const rootApproval = signApproval(owners[0]!, hash)
264
- const resolveConfig: MultisigOperation.selectApprovals.ResolveConfig = ({
265
- account,
266
- }) => {
267
- if (!Address.isEqual(account, child)) throw new Error('unknown account')
268
- return {
269
- config: MultisigConfig.from({ ...childConfig, version: 2n }),
270
- version: 2n,
271
- }
272
- }
273
- const partial = await MultisigOperation.selectApprovals({
274
- account,
275
- approvals: [
276
- rootApproval,
277
- SignatureEnvelope.serialize({
278
- account: child,
279
- config: MultisigConfig.from({ ...childConfig, version: 2n }),
280
- signatures: [SignatureEnvelope.deserialize(childApprovals[0]!)],
281
- type: 'multisig',
282
- }),
283
- ],
284
- config,
285
- hash,
286
- resolveConfig,
287
- })
288
- const complete = await MultisigOperation.selectApprovals({
229
+ test('accepts an explicit account from a chain-configured factory', async () => {
230
+ const selected = await MultisigOperation.selectApprovals({
289
231
  account,
290
- approvals: [
291
- rootApproval,
292
- SignatureEnvelope.serialize({
293
- account: child,
294
- config: MultisigConfig.from({ ...childConfig, version: 2n }),
295
- signatures: childApprovals.map((approval) =>
296
- SignatureEnvelope.deserialize(approval),
297
- ),
298
- type: 'multisig',
299
- }),
300
- ],
232
+ approvals: [],
301
233
  config,
302
- hash,
303
- resolveConfig,
234
+ hash: transactionHash_,
304
235
  })
305
-
306
- expect({
307
- complete: {
308
- ...complete,
309
- approvals: approvalAddresses(complete.approvals, hash),
310
- selectedApprovals: approvalAddresses(complete.selectedApprovals, hash),
311
- },
312
- partial: {
313
- ...partial,
314
- approvals: approvalAddresses(partial.approvals, hash),
315
- selectedApprovals: approvalAddresses(partial.selectedApprovals, hash),
316
- },
317
- }).toMatchInlineSnapshot(`
318
- {
319
- "complete": {
320
- "approvals": [
321
- "0x07e1ed8ea0e9601e5546b0a03aed683df3601407",
322
- "0xe2d2c3c2fc4b17af341cc5c1a459af9606167e8a",
323
- ],
324
- "selectedApprovals": [
325
- "0xe2d2c3c2fc4b17af341cc5c1a459af9606167e8a",
326
- ],
327
- "signatureCount": 1,
328
- "threshold": 2,
329
- "weight": 2,
330
- },
331
- "partial": {
332
- "approvals": [
333
- "0x07e1ed8ea0e9601e5546b0a03aed683df3601407",
334
- "0xe2d2c3c2fc4b17af341cc5c1a459af9606167e8a",
335
- ],
336
- "selectedApprovals": [
337
- "0x07e1ed8ea0e9601e5546b0a03aed683df3601407",
338
- ],
339
- "signatureCount": 1,
340
- "threshold": 2,
341
- "weight": 1,
342
- },
343
- }
344
- `)
236
+ expect(selected.weight).toMatchInlineSnapshot(`0`)
345
237
  })
346
-
347
- test('rejects mismatched nested config versions', async () => {
348
- const childConfig = MultisigConfig.from({
349
- owners: [{ owner: owners[1]!.address, weight: 1 }],
350
- threshold: 1,
351
- })
352
- const child = MultisigConfig.getAddress(childConfig)
353
- const config = MultisigConfig.from({
354
- owners: [{ owner: child, weight: 1 }],
355
- threshold: 1,
356
- })
357
- const account = MultisigConfig.getAddress(config)
358
- const hash = MultisigOperation.getHash({
359
- account,
360
- configVersion: 1n,
361
- transaction,
362
- type: 'transaction',
363
- })
364
- const resolvedConfig = MultisigConfig.from({
365
- ...childConfig,
366
- version: 2n,
367
- })
368
- const childHash = MultisigConfig.getSignPayload({
369
- account: child,
370
- config: resolvedConfig,
371
- payload: hash,
372
- })
373
-
374
- await expect(
375
- MultisigOperation.selectApprovals({
238
+ test('rejects keychain and multisig owner approvals', async () => {
239
+ for (const signature of [
240
+ SignatureEnvelope.from({
241
+ inner: ownerSignature_1,
242
+ type: 'keychain',
243
+ userAddress: account,
244
+ version: 'v2',
245
+ }),
246
+ SignatureEnvelope.from({
376
247
  account,
377
- approvals: [
378
- SignatureEnvelope.serialize({
379
- account: child,
380
- config: resolvedConfig,
381
- signatures: [
382
- SignatureEnvelope.deserialize(
383
- signApproval(owners[1]!, childHash),
384
- ),
385
- ],
386
- type: 'multisig',
387
- }),
388
- ],
389
248
  config,
390
- hash,
391
- resolveConfig: () => ({ config: childConfig, version: 2n }),
249
+ signatures: [ownerSignature_1],
392
250
  }),
393
- ).rejects.toThrowErrorMatchingInlineSnapshot(
394
- `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: resolved config.version must equal version for nested multisig owner 0x7888d60e9cc26c8569d394fce435c248f1e49c3b.]`,
395
- )
251
+ ])
252
+ await expect(
253
+ MultisigOperation.selectApprovals({
254
+ account,
255
+ approvals: [SignatureEnvelope.serialize(signature)],
256
+ config,
257
+ hash: transactionHash_,
258
+ }),
259
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
260
+ `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: only primitive signatures can approve a multisig operation.]`,
261
+ )
396
262
  })
397
263
 
398
264
  test('rejects invalid and non-owner approvals', async () => {
399
265
  const hash = MultisigOperation.getHash({
400
266
  account,
401
- configVersion: 1n,
267
+ config: currentConfig,
402
268
  transaction,
403
269
  type: 'transaction',
404
270
  })
@@ -429,247 +295,109 @@ describe('selectApprovals', () => {
429
295
  `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: signature is from non-owner 0xd3a9f047ad43d7e2e4e7e491f1fe2e657a2651b6.]`,
430
296
  )
431
297
  })
298
+ })
432
299
 
433
- test('requires a resolver for nested owners', async () => {
434
- const childConfig = MultisigConfig.from({
435
- owners: [{ owner: owners[1]!.address, weight: 1 }],
436
- threshold: 1,
437
- })
438
- const child = MultisigConfig.getAddress(childConfig)
439
- const config = MultisigConfig.from({
440
- owners: [{ owner: child, weight: 1 }],
441
- threshold: 1,
442
- })
443
- const account = MultisigConfig.getAddress(config)
444
- const hash = MultisigOperation.getHash({
445
- account,
446
- configVersion: 1n,
447
- transaction,
448
- type: 'transaction',
449
- })
450
- const childHash = MultisigConfig.getSignPayload({
451
- account: child,
452
- config: { version: 1n },
453
- payload: hash,
454
- })
455
-
456
- await expect(
457
- MultisigOperation.selectApprovals({
300
+ describe('serializeKeyAuthorization', () => {
301
+ test('current and initial authorizations', async () => {
302
+ const results = []
303
+ for (const applicableConfig of [currentConfig, config]) {
304
+ const hash = MultisigOperation.getHash({
305
+ account,
306
+ config: applicableConfig,
307
+ keyAuthorization,
308
+ type: 'keyAuthorization',
309
+ })
310
+ const selection = await MultisigOperation.selectApprovals({
458
311
  account,
459
312
  approvals: [
460
- SignatureEnvelope.serialize({
461
- account: child,
462
- config: MultisigConfig.from({ ...childConfig, version: 1n }),
463
- signatures: [
464
- SignatureEnvelope.deserialize(
465
- signApproval(owners[1]!, childHash),
466
- ),
467
- ],
468
- type: 'multisig',
469
- }),
313
+ signApproval(owners[1]!, hash),
314
+ signApproval(owners[0]!, hash),
470
315
  ],
471
- config,
316
+ config: applicableConfig,
472
317
  hash,
473
- }),
474
- ).rejects.toThrowErrorMatchingInlineSnapshot(
475
- `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: nested multisig owner 0x7888d60e9cc26c8569d394fce435c248f1e49c3b requires a config resolver.]`,
476
- )
477
- })
318
+ })
319
+ const serialized = MultisigOperation.serializeKeyAuthorization(
320
+ keyAuthorization,
321
+ {
322
+ account,
323
+ approvals: selection.selectedApprovals,
324
+ config: applicableConfig,
325
+ },
326
+ )
327
+ const value = KeyAuthorization.deserialize(serialized)
328
+ results.push({
329
+ account:
330
+ value.signature?.type === 'multisig'
331
+ ? value.signature.account
332
+ : undefined,
333
+ hash: Hash.keccak256(serialized),
334
+ signatureCount:
335
+ value.signature?.type === 'multisig'
336
+ ? value.signature.signatures.length
337
+ : 0,
338
+ version:
339
+ value.signature?.type === 'multisig'
340
+ ? value.signature.config.version
341
+ : undefined,
342
+ })
343
+ }
478
344
 
479
- test('rejects keychain and accepts initial nested approvals', async () => {
480
- const childConfig = MultisigConfig.from({
481
- owners: [{ owner: owners[1]!.address, weight: 1 }],
482
- threshold: 1,
483
- })
484
- const child = MultisigConfig.getAddress(childConfig)
485
- const config = MultisigConfig.from({
486
- owners: [
487
- { owner: owners[0]!.address, weight: 1 },
488
- { owner: child, weight: 1 },
489
- ],
490
- threshold: 1,
491
- })
492
- const account = MultisigConfig.getAddress(config)
493
- const hash = MultisigOperation.getHash({
494
- account,
495
- configVersion: 1n,
496
- transaction,
497
- type: 'transaction',
498
- })
499
- const childHash = MultisigConfig.getSignPayload({
500
- account: child,
501
- config: childConfig,
502
- payload: hash,
503
- })
345
+ expect(results).toMatchInlineSnapshot(`
346
+ [
347
+ {
348
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
349
+ "hash": "0xcd4283709cc1853dc8ed9cc4dd8c3b6a22e1b01f19ad3f6348f4bebe79590408",
350
+ "signatureCount": 2,
351
+ "version": 1n,
352
+ },
353
+ {
354
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
355
+ "hash": "0x1f66e6adc4ddf8ac9d4575f518be11509ca616ac13d4e0a286b4eef7b96959f2",
356
+ "signatureCount": 2,
357
+ "version": 0n,
358
+ },
359
+ ]
360
+ `)
361
+ })
504
362
 
505
- await expect(
506
- MultisigOperation.selectApprovals({
507
- account,
508
- approvals: [
509
- SignatureEnvelope.serialize({
510
- inner: SignatureEnvelope.deserialize(
511
- signApproval(owners[0]!, hash),
512
- ),
513
- type: 'keychain',
514
- userAddress: owners[0]!.address,
515
- }),
516
- ],
517
- config,
518
- hash,
519
- }),
520
- ).rejects.toThrowErrorMatchingInlineSnapshot(
521
- `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: keychain signatures cannot approve a multisig operation.]`,
522
- )
363
+ test('rejects a signed authorization', async () => {
523
364
  const selection = await MultisigOperation.selectApprovals({
524
365
  account,
525
366
  approvals: [
526
- SignatureEnvelope.serialize({
527
- account: child,
528
- config: childConfig,
529
- signatures: [
530
- SignatureEnvelope.deserialize(signApproval(owners[1]!, childHash)),
531
- ],
532
- type: 'multisig',
533
- }),
367
+ signApproval(owners[0]!, keyAuthorizationHash),
368
+ signApproval(owners[1]!, keyAuthorizationHash),
534
369
  ],
535
- config,
536
- hash,
537
- resolveConfig: () => ({ config: childConfig, version: 0n }),
370
+ config: currentConfig,
371
+ hash: keyAuthorizationHash,
538
372
  })
539
- expect({
540
- signatureCount: selection.signatureCount,
541
- threshold: selection.threshold,
542
- weight: selection.weight,
543
- }).toMatchInlineSnapshot(`
373
+ const signed = MultisigOperation.serializeKeyAuthorization(
374
+ keyAuthorization,
544
375
  {
545
- "signatureCount": 1,
546
- "threshold": 1,
547
- "weight": 1,
548
- }
549
- `)
550
- })
551
-
552
- test('rejects nested account cycles while serializing', () => {
553
- const config = MultisigConfig.from({
554
- owners: [{ owner: account, weight: 1 }],
555
- threshold: 1,
556
- })
557
- const hash = MultisigOperation.getHash({
558
- account,
559
- configVersion: 2n,
560
- transaction,
561
- type: 'transaction',
562
- })
563
- const nestedHash = MultisigConfig.getSignPayload({
564
- account,
565
- config: { version: 2n },
566
- payload: hash,
567
- })
568
-
569
- expect(() =>
570
- SignatureEnvelope.serialize({
571
376
  account,
572
- config: MultisigConfig.from({ ...config, version: 2n }),
573
- signatures: [
574
- SignatureEnvelope.deserialize(signApproval(owners[0]!, nestedHash)),
575
- ],
576
- type: 'multisig',
577
- }),
578
- ).toThrowErrorMatchingInlineSnapshot(
579
- `[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: multisig account cannot be an owner.]`,
377
+ approvals: selection.selectedApprovals,
378
+ config: currentConfig,
379
+ },
580
380
  )
581
- })
582
381
 
583
- test('rejects excess nesting depth', async () => {
584
- const grandchildConfig = MultisigConfig.from({
585
- owners: [{ owner: owners[2]!.address, weight: 1 }],
586
- threshold: 1,
587
- })
588
- const grandchild = MultisigConfig.getAddress(grandchildConfig)
589
- const childConfig = MultisigConfig.from({
590
- owners: [{ owner: grandchild, weight: 1 }],
591
- threshold: 1,
592
- })
593
- const child = MultisigConfig.getAddress(childConfig)
594
- const config = MultisigConfig.from({
595
- owners: [{ owner: child, weight: 1 }],
596
- threshold: 1,
597
- })
598
- const account = MultisigConfig.getAddress(config)
599
- const hash = MultisigOperation.getHash({
600
- account,
601
- configVersion: 1n,
602
- transaction,
603
- type: 'transaction',
604
- })
605
- const childHash = MultisigConfig.getSignPayload({
606
- account: child,
607
- config: { version: 1n },
608
- payload: hash,
609
- })
610
- const grandchildHash = MultisigConfig.getSignPayload({
611
- account: grandchild,
612
- config: { version: 1n },
613
- payload: childHash,
614
- })
615
-
616
- await expect(
617
- MultisigOperation.selectApprovals({
382
+ expect(() =>
383
+ MultisigOperation.serializeKeyAuthorization(signed, {
618
384
  account,
619
- approvals: [
620
- SignatureEnvelope.serialize({
621
- account: child,
622
- config: MultisigConfig.from({ ...childConfig, version: 1n }),
623
- signatures: [
624
- {
625
- account: grandchild,
626
- config: MultisigConfig.from({
627
- ...grandchildConfig,
628
- version: 1n,
629
- }),
630
- signatures: [
631
- SignatureEnvelope.deserialize(
632
- signApproval(owners[2]!, grandchildHash),
633
- ),
634
- ],
635
- type: 'multisig',
636
- },
637
- ],
638
- type: 'multisig',
639
- }),
640
- ],
641
- config,
642
- hash,
643
- resolveConfig: ({ account }) => {
644
- if (Address.isEqual(account, child))
645
- return {
646
- config: MultisigConfig.from({ ...childConfig, version: 1n }),
647
- version: 1n,
648
- }
649
- return {
650
- config: MultisigConfig.from({
651
- ...grandchildConfig,
652
- version: 1n,
653
- }),
654
- version: 1n,
655
- }
656
- },
385
+ approvals: selection.selectedApprovals,
386
+ config: currentConfig,
657
387
  }),
658
- ).rejects.toThrowErrorMatchingInlineSnapshot(
659
- `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: nested multisig owner 0xf529c8f6b2b4c72102af4cfe5eeb55b7d45dede2 is invalid.]`,
388
+ ).toThrowErrorMatchingInlineSnapshot(
389
+ `[MultisigOperation.InvalidOperationError: Invalid multisig operation: keyAuthorization must not contain a signature.]`,
660
390
  )
661
391
  })
662
392
  })
663
393
 
664
394
  describe('serializeTransaction', () => {
665
- test('initialized and bootstrap transactions', async () => {
395
+ test('current and initial transactions', async () => {
666
396
  const results = []
667
- for (const init of [false, true]) {
668
- const configVersion = init ? 0n : 1n
669
- const applicableConfig = init ? config : initializedConfig
397
+ for (const applicableConfig of [currentConfig, config]) {
670
398
  const hash = MultisigOperation.getHash({
671
399
  account,
672
- configVersion,
400
+ config: applicableConfig,
673
401
  transaction,
674
402
  type: 'transaction',
675
403
  })
@@ -686,10 +414,8 @@ describe('serializeTransaction', () => {
686
414
  account,
687
415
  approvals: selection.approvals,
688
416
  config: applicableConfig,
689
- configVersion,
690
417
  createdAt: 1,
691
418
  hash,
692
- init,
693
419
  signatureCount: selection.signatureCount,
694
420
  status: 'pending',
695
421
  threshold: selection.threshold,
@@ -704,7 +430,7 @@ describe('serializeTransaction', () => {
704
430
  const value = TxEnvelopeTempo.deserialize(serialized)
705
431
  results.push({
706
432
  account: value.signature?.account,
707
- configVersion:
433
+ version:
708
434
  value.signature?.type === 'multisig'
709
435
  ? value.signature.config.version
710
436
  : undefined,
@@ -720,18 +446,18 @@ describe('serializeTransaction', () => {
720
446
  expect(results).toMatchInlineSnapshot(`
721
447
  [
722
448
  {
723
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
724
- "configVersion": 1n,
725
- "hash": "0x8309740edaf304284186f7bcfe4527745cd4eb48e7441795ebdd970798091f8f",
449
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
450
+ "hash": "0x6a034f208339f7eaa4a42b3fa03aad5df77ebe83659dac2e4d2b11226d221928",
726
451
  "signatureCount": 2,
727
452
  "type": "0x76",
453
+ "version": 1n,
728
454
  },
729
455
  {
730
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
731
- "configVersion": 0n,
732
- "hash": "0x636af84d8445d87cbcd33039d5a3a2274a5911036b1b7ceb740ac41e2f638611",
456
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
457
+ "hash": "0x04d36e54d7a816b080dfa03370da6fbeb3523ce3eff5211d7f22a3c7e87476ee",
733
458
  "signatureCount": 2,
734
459
  "type": "0x76",
460
+ "version": 0n,
735
461
  },
736
462
  ]
737
463
  `)
@@ -763,7 +489,7 @@ describe('serializeTransaction', () => {
763
489
  for (const transaction of transactions) {
764
490
  const hash = MultisigOperation.getHash({
765
491
  account,
766
- configVersion: 1n,
492
+ config: currentConfig,
767
493
  transaction,
768
494
  type: 'transaction',
769
495
  })
@@ -773,18 +499,16 @@ describe('serializeTransaction', () => {
773
499
  signApproval(owners[0]!, hash),
774
500
  signApproval(owners[1]!, hash),
775
501
  ],
776
- config: initializedConfig,
502
+ config: currentConfig,
777
503
  hash,
778
504
  })
779
505
  const serialized = MultisigOperation.serializeTransaction(
780
506
  MultisigOperation.from({
781
507
  account,
782
508
  approvals: selection.approvals,
783
- config: initializedConfig,
784
- configVersion: 1n,
509
+ config: currentConfig,
785
510
  createdAt: 1,
786
511
  hash,
787
- init: false,
788
512
  signatureCount: selection.signatureCount,
789
513
  status: 'pending',
790
514
  threshold: selection.threshold,
@@ -811,7 +535,7 @@ describe('serializeTransaction', () => {
811
535
  [
812
536
  {
813
537
  "feePayerSignature": null,
814
- "from": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
538
+ "from": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
815
539
  "signatureCount": 2,
816
540
  "type": "0x78",
817
541
  },
@@ -821,7 +545,7 @@ describe('serializeTransaction', () => {
821
545
  "s": "0x0000000000000000000000000000000000000000000000000000000000000006",
822
546
  "yParity": 0,
823
547
  },
824
- "from": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
548
+ "from": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
825
549
  "signatureCount": 2,
826
550
  "type": "0x78",
827
551
  },
@@ -832,7 +556,7 @@ describe('serializeTransaction', () => {
832
556
  test('rejects an approval not retained by the operation', async () => {
833
557
  const hash = MultisigOperation.getHash({
834
558
  account,
835
- configVersion: 1n,
559
+ config: currentConfig,
836
560
  transaction,
837
561
  type: 'transaction',
838
562
  })
@@ -841,17 +565,15 @@ describe('serializeTransaction', () => {
841
565
  const selection = await MultisigOperation.selectApprovals({
842
566
  account,
843
567
  approvals: [approval_1],
844
- config: initializedConfig,
568
+ config: currentConfig,
845
569
  hash,
846
570
  })
847
571
  const operation = MultisigOperation.from({
848
572
  account,
849
573
  approvals: selection.approvals,
850
- config: initializedConfig,
851
- configVersion: 1n,
574
+ config: currentConfig,
852
575
  createdAt: 1,
853
576
  hash,
854
- init: false,
855
577
  signatureCount: selection.signatureCount,
856
578
  status: 'pending',
857
579
  threshold: selection.threshold,
@@ -895,7 +617,7 @@ describe('from', () => {
895
617
  expect({ pending, submitting, success }).toMatchInlineSnapshot(`
896
618
  {
897
619
  "pending": {
898
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
620
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
899
621
  "approvals": [
900
622
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
901
623
  ],
@@ -914,10 +636,8 @@ describe('from', () => {
914
636
  "threshold": 2,
915
637
  "version": 1n,
916
638
  },
917
- "configVersion": 1n,
918
639
  "createdAt": 1,
919
- "hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
920
- "init": false,
640
+ "hash": "0x2d7e3c7c38a9acf85f0a9d70a39b0e9e5a05d92c7a73b633a47a45be4a112b3b",
921
641
  "signatureCount": 1,
922
642
  "status": "pending",
923
643
  "threshold": 2,
@@ -927,7 +647,7 @@ describe('from', () => {
927
647
  "weight": 1,
928
648
  },
929
649
  "submitting": {
930
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
650
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
931
651
  "approvals": [
932
652
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
933
653
  "0x01000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000047cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997807775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d100",
@@ -947,11 +667,9 @@ describe('from', () => {
947
667
  "threshold": 2,
948
668
  "version": 1n,
949
669
  },
950
- "configVersion": 1n,
951
670
  "createdAt": 1,
952
671
  "expiresAt": 10,
953
- "hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
954
- "init": false,
672
+ "hash": "0x2d7e3c7c38a9acf85f0a9d70a39b0e9e5a05d92c7a73b633a47a45be4a112b3b",
955
673
  "signatureCount": 2,
956
674
  "status": "submitting",
957
675
  "submissionId": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
@@ -962,7 +680,7 @@ describe('from', () => {
962
680
  "weight": 2,
963
681
  },
964
682
  "success": {
965
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
683
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
966
684
  "approvals": [
967
685
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
968
686
  "0x01000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000047cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997807775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d100",
@@ -982,10 +700,8 @@ describe('from', () => {
982
700
  "threshold": 2,
983
701
  "version": 1n,
984
702
  },
985
- "configVersion": 1n,
986
703
  "createdAt": 1,
987
- "hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
988
- "init": false,
704
+ "hash": "0x2d7e3c7c38a9acf85f0a9d70a39b0e9e5a05d92c7a73b633a47a45be4a112b3b",
989
705
  "signatureCount": 2,
990
706
  "status": "success",
991
707
  "threshold": 2,
@@ -1011,7 +727,7 @@ describe('from', () => {
1011
727
  ...transactionPending,
1012
728
  hash: MultisigConfig.getSignPayload({
1013
729
  account,
1014
- config: initializedConfig,
730
+ config: currentConfig,
1015
731
  payload: TxEnvelopeTempo.getSignPayload(
1016
732
  TxEnvelopeTempo.deserialize(
1017
733
  Hex.concat(
@@ -1031,7 +747,7 @@ describe('from', () => {
1031
747
  },
1032
748
  `
1033
749
  {
1034
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
750
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
1035
751
  "approvals": [
1036
752
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
1037
753
  ],
@@ -1050,10 +766,8 @@ describe('from', () => {
1050
766
  "threshold": 2,
1051
767
  "version": 1n,
1052
768
  },
1053
- "configVersion": 1n,
1054
769
  "createdAt": 1,
1055
770
  "hash": Any<String>,
1056
- "init": false,
1057
771
  "signatureCount": 1,
1058
772
  "status": "pending",
1059
773
  "threshold": 2,
@@ -1083,7 +797,7 @@ describe('from', () => {
1083
797
  ...transactionPending,
1084
798
  hash: MultisigConfig.getSignPayload({
1085
799
  account,
1086
- config: initializedConfig,
800
+ config: currentConfig,
1087
801
  payload: TxEnvelopeTempo.getSignPayload(
1088
802
  TxEnvelopeTempo.deserialize(
1089
803
  Hex.concat(
@@ -1099,11 +813,10 @@ describe('from', () => {
1099
813
  expect(operation.transaction).toBe(transaction)
1100
814
  })
1101
815
 
1102
- test('bootstrap transaction', () => {
816
+ test('initial transaction', () => {
1103
817
  const operation = MultisigOperation.from({
1104
818
  ...transactionPending,
1105
819
  config,
1106
- configVersion: 0n,
1107
820
  hash: MultisigConfig.getSignPayload({
1108
821
  account,
1109
822
  config,
@@ -1111,7 +824,6 @@ describe('from', () => {
1111
824
  TxEnvelopeTempo.deserialize(transaction),
1112
825
  ),
1113
826
  }),
1114
- init: true,
1115
827
  })
1116
828
 
1117
829
  expect(operation).toMatchInlineSnapshot(
@@ -1121,7 +833,7 @@ describe('from', () => {
1121
833
  },
1122
834
  `
1123
835
  {
1124
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
836
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
1125
837
  "approvals": [
1126
838
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
1127
839
  ],
@@ -1140,10 +852,8 @@ describe('from', () => {
1140
852
  "threshold": 2,
1141
853
  "version": 0n,
1142
854
  },
1143
- "configVersion": 0n,
1144
855
  "createdAt": 1,
1145
856
  "hash": Any<String>,
1146
- "init": true,
1147
857
  "signatureCount": 1,
1148
858
  "status": "pending",
1149
859
  "threshold": 2,
@@ -1156,31 +866,6 @@ describe('from', () => {
1156
866
  )
1157
867
  })
1158
868
 
1159
- test('initialized transaction at config version zero', () => {
1160
- const operation = MultisigOperation.from({
1161
- ...transactionPending,
1162
- config,
1163
- configVersion: 0n,
1164
- hash: MultisigConfig.getSignPayload({
1165
- account,
1166
- config,
1167
- payload: TxEnvelopeTempo.getSignPayload(
1168
- TxEnvelopeTempo.deserialize(transaction),
1169
- ),
1170
- }),
1171
- })
1172
-
1173
- expect({
1174
- configVersion: operation.configVersion,
1175
- init: operation.init,
1176
- }).toMatchInlineSnapshot(`
1177
- {
1178
- "configVersion": 0n,
1179
- "init": false,
1180
- }
1181
- `)
1182
- })
1183
-
1184
869
  test('key authorization states', () => {
1185
870
  const pending = MultisigOperation.from(keyAuthorizationPending)
1186
871
  const authorization = KeyAuthorization.deserialize(keyAuthorization)
@@ -1191,11 +876,8 @@ describe('from', () => {
1191
876
  KeyAuthorization.from(authorization, {
1192
877
  signature: {
1193
878
  account,
1194
- config: initializedConfig,
1195
- signatures: [
1196
- SignatureEnvelope.deserialize(approval_1),
1197
- SignatureEnvelope.deserialize(approval_2),
1198
- ],
879
+ config: currentConfig,
880
+ signatures: [ownerSignature_1, owners[1]!.signature],
1199
881
  type: 'multisig',
1200
882
  },
1201
883
  }),
@@ -1208,7 +890,7 @@ describe('from', () => {
1208
890
  expect({ pending, success }).toMatchInlineSnapshot(`
1209
891
  {
1210
892
  "pending": {
1211
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
893
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
1212
894
  "approvals": [
1213
895
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
1214
896
  ],
@@ -1227,11 +909,9 @@ describe('from', () => {
1227
909
  "threshold": 2,
1228
910
  "version": 1n,
1229
911
  },
1230
- "configVersion": 1n,
1231
912
  "createdAt": 1,
1232
- "hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
1233
- "init": false,
1234
- "keyAuthorization": "0xf838f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36e",
913
+ "hash": "0xa83016f0e94c4a6125483ffeba3abb0a8df1bc0f5a503f63639e806b793520bb",
914
+ "keyAuthorization": "0xf838f782107980943333333333333333333333333333333333333333846b49d2008080808094ef6b17836e1b3647105c3084124485e3e1b0ab7f",
1235
915
  "signatureCount": 1,
1236
916
  "status": "pending",
1237
917
  "threshold": 2,
@@ -1240,7 +920,7 @@ describe('from', () => {
1240
920
  "weight": 1,
1241
921
  },
1242
922
  "success": {
1243
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
923
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
1244
924
  "approvals": [
1245
925
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
1246
926
  "0x01000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000047cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997807775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d100",
@@ -1260,11 +940,9 @@ describe('from', () => {
1260
940
  "threshold": 2,
1261
941
  "version": 1n,
1262
942
  },
1263
- "configVersion": 1n,
1264
943
  "createdAt": 1,
1265
- "hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
1266
- "init": false,
1267
- "keyAuthorization": "0xf901b3f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36eb9017805f9017494f81b7763d3a6876195d780865bd783dbd97dd36ef852a000000000000000000000000000000000000000000000000000000000000000000102eed69407e1ed8ea0e9601e5546b0a03aed683df360140701d694288f0cd85005f34168f731a468aef268c2f9456f01f90108b88201000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200b88201000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000047cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997807775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d100",
944
+ "hash": "0xa83016f0e94c4a6125483ffeba3abb0a8df1bc0f5a503f63639e806b793520bb",
945
+ "keyAuthorization": "0xf901b3f782107980943333333333333333333333333333333333333333846b49d2008080808094ef6b17836e1b3647105c3084124485e3e1b0ab7fb9017805f9017494ef6b17836e1b3647105c3084124485e3e1b0ab7ff852a000000000000000000000000000000000000000000000000000000000000000000102eed69407e1ed8ea0e9601e5546b0a03aed683df360140701d694288f0cd85005f34168f731a468aef268c2f9456f01f90108b88201000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200b88201000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000047cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997807775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d100",
1268
946
  "signatureCount": 2,
1269
947
  "status": "success",
1270
948
  "threshold": 2,
@@ -1276,17 +954,14 @@ describe('from', () => {
1276
954
  `)
1277
955
  })
1278
956
 
1279
- test('bootstrap key authorization', () => {
957
+ test('initial key authorization', () => {
1280
958
  const authorization = KeyAuthorization.deserialize(keyAuthorization)
1281
959
  const keyAuthorization_ = KeyAuthorization.serialize(
1282
960
  KeyAuthorization.from(authorization, {
1283
961
  signature: {
1284
962
  account,
1285
963
  config,
1286
- signatures: [
1287
- SignatureEnvelope.deserialize(approval_1),
1288
- SignatureEnvelope.deserialize(approval_2),
1289
- ],
964
+ signatures: [ownerSignature_1, owners[1]!.signature],
1290
965
  type: 'multisig',
1291
966
  },
1292
967
  }),
@@ -1295,13 +970,11 @@ describe('from', () => {
1295
970
  ...keyAuthorizationPending,
1296
971
  approvals: [approval_1, approval_2],
1297
972
  config,
1298
- configVersion: 0n,
1299
973
  hash: MultisigConfig.getSignPayload({
1300
974
  account,
1301
975
  config,
1302
976
  payload: KeyAuthorization.getSignPayload(authorization),
1303
977
  }),
1304
- init: true,
1305
978
  keyAuthorization: keyAuthorization_,
1306
979
  signatureCount: 2,
1307
980
  status: 'success',
@@ -1315,7 +988,7 @@ describe('from', () => {
1315
988
  },
1316
989
  `
1317
990
  {
1318
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
991
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
1319
992
  "approvals": [
1320
993
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
1321
994
  "0x01000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000047cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997807775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d100",
@@ -1335,10 +1008,8 @@ describe('from', () => {
1335
1008
  "threshold": 2,
1336
1009
  "version": 0n,
1337
1010
  },
1338
- "configVersion": 0n,
1339
1011
  "createdAt": 1,
1340
1012
  "hash": Any<String>,
1341
- "init": true,
1342
1013
  "keyAuthorization": Any<String>,
1343
1014
  "signatureCount": 2,
1344
1015
  "status": "success",
@@ -1363,7 +1034,7 @@ describe('RPC conversion', () => {
1363
1034
  expect({ keyAuthorizationRpc, transactionRpc }).toMatchInlineSnapshot(`
1364
1035
  {
1365
1036
  "keyAuthorizationRpc": {
1366
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
1037
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
1367
1038
  "approvals": [
1368
1039
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
1369
1040
  ],
@@ -1382,11 +1053,9 @@ describe('RPC conversion', () => {
1382
1053
  "threshold": 2,
1383
1054
  "version": "0x1",
1384
1055
  },
1385
- "configVersion": "0x1",
1386
1056
  "createdAt": 1,
1387
- "hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
1388
- "init": false,
1389
- "keyAuthorization": "0xf838f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36e",
1057
+ "hash": "0xa83016f0e94c4a6125483ffeba3abb0a8df1bc0f5a503f63639e806b793520bb",
1058
+ "keyAuthorization": "0xf838f782107980943333333333333333333333333333333333333333846b49d2008080808094ef6b17836e1b3647105c3084124485e3e1b0ab7f",
1390
1059
  "signatureCount": 1,
1391
1060
  "status": "pending",
1392
1061
  "threshold": 2,
@@ -1395,7 +1064,7 @@ describe('RPC conversion', () => {
1395
1064
  "weight": 1,
1396
1065
  },
1397
1066
  "transactionRpc": {
1398
- "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
1067
+ "account": "0xef6b17836e1b3647105c3084124485e3e1b0ab7f",
1399
1068
  "approvals": [
1400
1069
  "0x01000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200",
1401
1070
  ],
@@ -1414,10 +1083,8 @@ describe('RPC conversion', () => {
1414
1083
  "threshold": 2,
1415
1084
  "version": "0x1",
1416
1085
  },
1417
- "configVersion": "0x1",
1418
1086
  "createdAt": 1,
1419
- "hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
1420
- "init": false,
1087
+ "hash": "0x2d7e3c7c38a9acf85f0a9d70a39b0e9e5a05d92c7a73b633a47a45be4a112b3b",
1421
1088
  "signatureCount": 1,
1422
1089
  "status": "pending",
1423
1090
  "threshold": 2,
@@ -1449,7 +1116,7 @@ describe('validation', () => {
1449
1116
  ...transactionPending,
1450
1117
  transaction: TxEnvelopeTempo.serialize(
1451
1118
  TxEnvelopeTempo.deserialize(transaction),
1452
- { signature: SignatureEnvelope.deserialize(approval_1) },
1119
+ { signature: ownerSignature_1 },
1453
1120
  ),
1454
1121
  },
1455
1122
  },
@@ -1550,7 +1217,7 @@ describe('validation', () => {
1550
1217
  account: '0x0000000000000000000000000000000000000000',
1551
1218
  hash: MultisigConfig.getSignPayload({
1552
1219
  account: '0x0000000000000000000000000000000000000000',
1553
- config: initializedConfig,
1220
+ config: currentConfig,
1554
1221
  payload: TxEnvelopeTempo.getSignPayload(
1555
1222
  TxEnvelopeTempo.deserialize(transaction),
1556
1223
  ),
@@ -1617,7 +1284,7 @@ describe('validation', () => {
1617
1284
  },
1618
1285
  },
1619
1286
  {
1620
- name: 'nested bootstrap owner approval',
1287
+ name: 'nested non-owner approval',
1621
1288
  operation: {
1622
1289
  ...transactionPending,
1623
1290
  approvals: [
@@ -1630,35 +1297,35 @@ describe('validation', () => {
1630
1297
  ],
1631
1298
  },
1632
1299
  },
1633
- {
1634
- name: 'bootstrap with initialized version',
1635
- operation: { ...transactionPending, init: true },
1636
- },
1637
1300
  ])('rejects $name', ({ operation }) => {
1638
1301
  expect(() =>
1639
1302
  MultisigOperation.from(operation as MultisigOperation.Operation),
1640
1303
  ).toThrowError(MultisigOperation.InvalidOperationError)
1641
1304
  })
1642
-
1643
- test('rejects mismatched config versions', () => {
1644
- expect(() =>
1645
- MultisigOperation.from({
1646
- ...transactionPending,
1647
- config: { ...initializedConfig, version: 2n },
1305
+ test('accepts initial accounts validated by the chain', () => {
1306
+ const value = MultisigOperation.from({
1307
+ ...transactionPending,
1308
+ config,
1309
+ hash: MultisigOperation.getHash({
1310
+ account,
1311
+ config,
1312
+ transaction,
1313
+ type: 'transaction',
1648
1314
  }),
1649
- ).toThrowErrorMatchingInlineSnapshot(
1650
- `[MultisigOperation.InvalidOperationError: Invalid multisig operation: config.version must equal configVersion.]`,
1651
- )
1315
+ })
1316
+ expect(value.account).toBe(account)
1317
+ expect(value.config).toEqual(config)
1652
1318
  })
1653
1319
 
1654
1320
  test('rejects noncanonical RPC quantities', () => {
1321
+ const operation = MultisigOperation.toRpc(transactionPending)
1655
1322
  expect(() =>
1656
1323
  MultisigOperation.fromRpc({
1657
- ...MultisigOperation.toRpc(transactionPending),
1658
- configVersion: '0x01',
1324
+ ...operation,
1325
+ config: { ...operation.config, version: '0x01' },
1659
1326
  }),
1660
1327
  ).toThrowError(
1661
- 'Invalid multisig operation: configVersion must use canonical quantity encoding.',
1328
+ 'Invalid multisig operation: config.version must use canonical quantity encoding.',
1662
1329
  )
1663
1330
  })
1664
1331
 
@@ -1671,11 +1338,8 @@ describe('validation', () => {
1671
1338
  KeyAuthorization.from(authorization, {
1672
1339
  signature: {
1673
1340
  account,
1674
- config: initializedConfig,
1675
- signatures: [
1676
- SignatureEnvelope.deserialize(approval_1),
1677
- SignatureEnvelope.deserialize(approval_3),
1678
- ],
1341
+ config: currentConfig,
1342
+ signatures: [ownerSignature_1, owners[2]!.signature],
1679
1343
  type: 'multisig',
1680
1344
  },
1681
1345
  }),
@@ -1695,12 +1359,9 @@ describe('validation', () => {
1695
1359
  const signatures = [
1696
1360
  ...SignatureEnvelope.sortMultisigApprovals({
1697
1361
  account,
1698
- config: initializedConfig,
1362
+ config: currentConfig,
1699
1363
  payload: KeyAuthorization.getSignPayload(authorization),
1700
- signatures: [
1701
- SignatureEnvelope.deserialize(approval_1),
1702
- SignatureEnvelope.deserialize(approval_2),
1703
- ],
1364
+ signatures: [ownerSignature_1, owners[1]!.signature],
1704
1365
  }),
1705
1366
  ].reverse()
1706
1367
  const operation = {
@@ -1710,7 +1371,7 @@ describe('validation', () => {
1710
1371
  KeyAuthorization.from(authorization, {
1711
1372
  signature: {
1712
1373
  account,
1713
- config: initializedConfig,
1374
+ config: currentConfig,
1714
1375
  signatures,
1715
1376
  type: 'multisig',
1716
1377
  },
@@ -1735,11 +1396,8 @@ describe('validation', () => {
1735
1396
  KeyAuthorization.from(authorization, {
1736
1397
  signature: {
1737
1398
  account,
1738
- config: initializedConfig,
1739
- signatures: [
1740
- SignatureEnvelope.deserialize(approval_1),
1741
- SignatureEnvelope.deserialize(approval_1),
1742
- ],
1399
+ config: currentConfig,
1400
+ signatures: [ownerSignature_1, ownerSignature_1],
1743
1401
  type: 'multisig',
1744
1402
  },
1745
1403
  }),
@@ -1754,64 +1412,7 @@ describe('validation', () => {
1754
1412
  )
1755
1413
  })
1756
1414
 
1757
- test('rejects reordered nested key authorization approvals', () => {
1758
- const authorization = KeyAuthorization.deserialize(keyAuthorization)
1759
- const nestedConfig = MultisigConfig.from({
1760
- owners: [{ owner: owner_2, weight: 1 }],
1761
- threshold: 1,
1762
- version: 1n,
1763
- })
1764
- const childSignatures = SignatureEnvelope.sortMultisigApprovals({
1765
- account: owner_1,
1766
- config: nestedConfig,
1767
- payload: keyAuthorizationHash,
1768
- signatures: [
1769
- SignatureEnvelope.deserialize(approval_1),
1770
- SignatureEnvelope.deserialize(approval_2),
1771
- ],
1772
- })
1773
- const retainedNested = SignatureEnvelope.from({
1774
- account: owner_1,
1775
- config: nestedConfig,
1776
- signatures: childSignatures,
1777
- type: 'multisig',
1778
- })
1779
- const selectedNested = SignatureEnvelope.from({
1780
- account: owner_1,
1781
- config: nestedConfig,
1782
- signatures: [...childSignatures].reverse(),
1783
- type: 'multisig',
1784
- })
1785
- const selected = SignatureEnvelope.sortMultisigApprovals({
1786
- account,
1787
- config: initializedConfig,
1788
- payload: KeyAuthorization.getSignPayload(authorization),
1789
- signatures: [selectedNested, SignatureEnvelope.deserialize(approval_2)],
1790
- })
1791
- const operation = {
1792
- ...keyAuthorizationPending,
1793
- approvals: [SignatureEnvelope.serialize(retainedNested), approval_2],
1794
- keyAuthorization: KeyAuthorization.serialize(
1795
- KeyAuthorization.from(authorization, {
1796
- signature: {
1797
- account,
1798
- config: initializedConfig,
1799
- signatures: selected,
1800
- type: 'multisig',
1801
- },
1802
- }),
1803
- ),
1804
- signatureCount: 2,
1805
- status: 'success',
1806
- weight: 2,
1807
- } as const
1808
-
1809
- expect(() => MultisigOperation.from(operation)).toThrowError(
1810
- 'Invalid multisig operation: key authorization signature is not a retained approval.',
1811
- )
1812
- })
1813
-
1814
- test('accepts case-insensitive bootstrap configs', () => {
1415
+ test('accepts case-insensitive initial configs', () => {
1815
1416
  const config = MultisigConfig.from({
1816
1417
  owners: [
1817
1418
  {
@@ -1826,7 +1427,7 @@ describe('validation', () => {
1826
1427
  salt: `0x${'AB'.repeat(32)}`,
1827
1428
  threshold: 2,
1828
1429
  })
1829
- const account = MultisigConfig.getAddress(config)
1430
+ const account = MultisigConfig.getAddress(config, { factory })
1830
1431
  const authorization = KeyAuthorization.from({
1831
1432
  account,
1832
1433
  address: '0x3333333333333333333333333333333333333333',
@@ -1839,10 +1440,7 @@ describe('validation', () => {
1839
1440
  account,
1840
1441
  config,
1841
1442
  payload: KeyAuthorization.getSignPayload(authorization),
1842
- signatures: [
1843
- SignatureEnvelope.deserialize(approval_1),
1844
- SignatureEnvelope.deserialize(approval_2),
1845
- ],
1443
+ signatures: [ownerSignature_1, owners[1]!.signature],
1846
1444
  })
1847
1445
  const approvals = signatures.map((signature) =>
1848
1446
  SignatureEnvelope.serialize(signature),
@@ -1852,14 +1450,12 @@ describe('validation', () => {
1852
1450
  account,
1853
1451
  approvals,
1854
1452
  config,
1855
- configVersion: 0n,
1856
1453
  createdAt: 1,
1857
1454
  hash: MultisigConfig.getSignPayload({
1858
1455
  account,
1859
1456
  config,
1860
1457
  payload: KeyAuthorization.getSignPayload(authorization),
1861
1458
  }),
1862
- init: true,
1863
1459
  keyAuthorization: KeyAuthorization.serialize(
1864
1460
  KeyAuthorization.from(authorization, {
1865
1461
  signature: {