ox 0.14.40 → 0.14.41

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.
@@ -36,7 +36,7 @@ const config = MultisigConfig.from({
36
36
  ],
37
37
  threshold: 2,
38
38
  })
39
- const initializedConfig = MultisigConfig.from({ ...config, version: 1n })
39
+ const currentConfig = MultisigConfig.from({ ...config, version: 1n })
40
40
  const account = MultisigConfig.getAddress(config)
41
41
  const ownerSignature_1 = owners[0]!.signature
42
42
  const approval_1 = SignatureEnvelope.serialize(ownerSignature_1)
@@ -63,14 +63,14 @@ const keyAuthorization = KeyAuthorization.serialize(
63
63
 
64
64
  const transactionHash_ = MultisigConfig.getSignPayload({
65
65
  account,
66
- config: initializedConfig,
66
+ config: currentConfig,
67
67
  payload: TxEnvelopeTempo.getSignPayload(
68
68
  TxEnvelopeTempo.deserialize(transaction),
69
69
  ),
70
70
  })
71
71
  const keyAuthorizationHash = MultisigConfig.getSignPayload({
72
72
  account,
73
- config: initializedConfig,
73
+ config: currentConfig,
74
74
  payload: KeyAuthorization.getSignPayload(
75
75
  KeyAuthorization.deserialize(keyAuthorization),
76
76
  ),
@@ -79,10 +79,8 @@ const keyAuthorizationHash = MultisigConfig.getSignPayload({
79
79
  const base = {
80
80
  account,
81
81
  approvals: [approval_1],
82
- config: initializedConfig,
83
- configVersion: 1n,
82
+ config: currentConfig,
84
83
  createdAt: 1,
85
- init: false,
86
84
  signatureCount: 1,
87
85
  threshold: 2,
88
86
  updatedAt: 2,
@@ -139,13 +137,13 @@ describe('getHash', () => {
139
137
  expect({
140
138
  keyAuthorization: MultisigOperation.getHash({
141
139
  account,
142
- configVersion: 1n,
140
+ config: currentConfig,
143
141
  keyAuthorization,
144
142
  type: 'keyAuthorization',
145
143
  }),
146
144
  transaction: MultisigOperation.getHash({
147
145
  account,
148
- configVersion: 1n,
146
+ config: currentConfig,
149
147
  transaction,
150
148
  type: 'transaction',
151
149
  }),
@@ -171,7 +169,7 @@ describe('selectApprovals', () => {
171
169
  const account = MultisigConfig.getAddress(config)
172
170
  const hash = MultisigOperation.getHash({
173
171
  account,
174
- configVersion: 1n,
172
+ config: { ...config, version: 1n },
175
173
  transaction,
176
174
  type: 'transaction',
177
175
  })
@@ -244,13 +242,13 @@ describe('selectApprovals', () => {
244
242
  const account = MultisigConfig.getAddress(config)
245
243
  const hash = MultisigOperation.getHash({
246
244
  account,
247
- configVersion: 1n,
245
+ config: { ...config, version: 1n },
248
246
  transaction,
249
247
  type: 'transaction',
250
248
  })
251
249
  const childHash = MultisigConfig.getSignPayload({
252
250
  account: child,
253
- config: { version: 2n },
251
+ config: { ...childConfig, version: 2n },
254
252
  payload: hash,
255
253
  })
256
254
  const childApprovals = [
@@ -258,15 +256,6 @@ describe('selectApprovals', () => {
258
256
  signApproval(owners[2]!, childHash),
259
257
  ]
260
258
  const rootApproval = signApproval(owners[0]!, hash)
261
- const resolveConfig: MultisigOperation.selectApprovals.ResolveConfig = ({
262
- account,
263
- }) => {
264
- if (!Address.isEqual(account, child)) throw new Error('unknown account')
265
- return {
266
- config: MultisigConfig.from({ ...childConfig, version: 2n }),
267
- version: 2n,
268
- }
269
- }
270
259
  const partial = await MultisigOperation.selectApprovals({
271
260
  account,
272
261
  approvals: [
@@ -280,7 +269,6 @@ describe('selectApprovals', () => {
280
269
  ],
281
270
  config,
282
271
  hash,
283
- resolveConfig,
284
272
  })
285
273
  const complete = await MultisigOperation.selectApprovals({
286
274
  account,
@@ -297,7 +285,6 @@ describe('selectApprovals', () => {
297
285
  ],
298
286
  config,
299
287
  hash,
300
- resolveConfig,
301
288
  })
302
289
 
303
290
  expect({
@@ -341,7 +328,7 @@ describe('selectApprovals', () => {
341
328
  `)
342
329
  })
343
330
 
344
- test('rejects mismatched nested config versions', async () => {
331
+ test('rejects conflicting nested config witnesses', async () => {
345
332
  const childConfig = MultisigConfig.from({
346
333
  owners: [{ owner: owners[1]!.address, weight: 1 }],
347
334
  threshold: 1,
@@ -354,17 +341,26 @@ describe('selectApprovals', () => {
354
341
  const account = MultisigConfig.getAddress(config)
355
342
  const hash = MultisigOperation.getHash({
356
343
  account,
357
- configVersion: 1n,
344
+ config: { ...config, version: 1n },
358
345
  transaction,
359
346
  type: 'transaction',
360
347
  })
361
- const resolvedConfig = MultisigConfig.from({
348
+ const config_2 = MultisigConfig.from({
362
349
  ...childConfig,
363
350
  version: 2n,
364
351
  })
365
- const childHash = MultisigConfig.getSignPayload({
352
+ const config_3 = MultisigConfig.from({
353
+ ...childConfig,
354
+ version: 3n,
355
+ })
356
+ const childHash_2 = MultisigConfig.getSignPayload({
366
357
  account: child,
367
- config: resolvedConfig,
358
+ config: config_2,
359
+ payload: hash,
360
+ })
361
+ const childHash_3 = MultisigConfig.getSignPayload({
362
+ account: child,
363
+ config: config_3,
368
364
  payload: hash,
369
365
  })
370
366
 
@@ -374,10 +370,20 @@ describe('selectApprovals', () => {
374
370
  approvals: [
375
371
  SignatureEnvelope.serialize({
376
372
  account: child,
377
- config: resolvedConfig,
373
+ config: config_2,
374
+ signatures: [
375
+ SignatureEnvelope.deserialize(
376
+ signApproval(owners[1]!, childHash_2),
377
+ ),
378
+ ],
379
+ type: 'multisig',
380
+ }),
381
+ SignatureEnvelope.serialize({
382
+ account: child,
383
+ config: config_3,
378
384
  signatures: [
379
385
  SignatureEnvelope.deserialize(
380
- signApproval(owners[1]!, childHash),
386
+ signApproval(owners[1]!, childHash_3),
381
387
  ),
382
388
  ],
383
389
  type: 'multisig',
@@ -385,17 +391,32 @@ describe('selectApprovals', () => {
385
391
  ],
386
392
  config,
387
393
  hash,
388
- resolveConfig: () => ({ config: childConfig, version: 2n }),
389
394
  }),
390
395
  ).rejects.toThrowErrorMatchingInlineSnapshot(
391
- `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: resolved config.version must equal version for nested multisig owner 0x7888d60e9cc26c8569d394fce435c248f1e49c3b.]`,
396
+ `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: nested multisig owner 0x7888d60e9cc26c8569d394fce435c248f1e49c3b has conflicting config witnesses.]`,
397
+ )
398
+ })
399
+
400
+ test('rejects an initial root config for another account', async () => {
401
+ await expect(
402
+ MultisigOperation.selectApprovals({
403
+ account,
404
+ approvals: [],
405
+ config: MultisigConfig.from({
406
+ ...config,
407
+ salt: `0x${'ff'.repeat(32)}`,
408
+ }),
409
+ hash: transactionHash_,
410
+ }),
411
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
412
+ `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: initial config does not derive the root multisig account.]`,
392
413
  )
393
414
  })
394
415
 
395
416
  test('rejects invalid and non-owner approvals', async () => {
396
417
  const hash = MultisigOperation.getHash({
397
418
  account,
398
- configVersion: 1n,
419
+ config: currentConfig,
399
420
  transaction,
400
421
  type: 'transaction',
401
422
  })
@@ -427,7 +448,7 @@ describe('selectApprovals', () => {
427
448
  )
428
449
  })
429
450
 
430
- test('requires a resolver for nested owners', async () => {
451
+ test('reads current nested config witnesses from approvals', async () => {
431
452
  const childConfig = MultisigConfig.from({
432
453
  owners: [{ owner: owners[1]!.address, weight: 1 }],
433
454
  threshold: 1,
@@ -440,36 +461,49 @@ describe('selectApprovals', () => {
440
461
  const account = MultisigConfig.getAddress(config)
441
462
  const hash = MultisigOperation.getHash({
442
463
  account,
443
- configVersion: 1n,
464
+ config: { ...config, version: 1n },
444
465
  transaction,
445
466
  type: 'transaction',
446
467
  })
447
468
  const childHash = MultisigConfig.getSignPayload({
448
469
  account: child,
449
- config: { version: 1n },
470
+ config: { ...childConfig, version: 1n },
450
471
  payload: hash,
451
472
  })
452
473
 
453
- await expect(
454
- MultisigOperation.selectApprovals({
455
- account,
456
- approvals: [
457
- SignatureEnvelope.serialize({
458
- account: child,
459
- config: MultisigConfig.from({ ...childConfig, version: 1n }),
460
- signatures: [
461
- SignatureEnvelope.deserialize(
462
- signApproval(owners[1]!, childHash),
463
- ),
464
- ],
465
- type: 'multisig',
466
- }),
474
+ const selection = await MultisigOperation.selectApprovals({
475
+ account,
476
+ approvals: [
477
+ SignatureEnvelope.serialize({
478
+ account: child,
479
+ config: MultisigConfig.from({ ...childConfig, version: 1n }),
480
+ signatures: [
481
+ SignatureEnvelope.deserialize(signApproval(owners[1]!, childHash)),
482
+ ],
483
+ type: 'multisig',
484
+ }),
485
+ ],
486
+ config,
487
+ hash,
488
+ })
489
+ expect(selection).toMatchInlineSnapshot(
490
+ {
491
+ approvals: [expect.any(String)],
492
+ selectedApprovals: [expect.any(String)],
493
+ },
494
+ `
495
+ {
496
+ "approvals": [
497
+ Any<String>,
467
498
  ],
468
- config,
469
- hash,
470
- }),
471
- ).rejects.toThrowErrorMatchingInlineSnapshot(
472
- `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: nested multisig owner 0x7888d60e9cc26c8569d394fce435c248f1e49c3b requires a config resolver.]`,
499
+ "selectedApprovals": [
500
+ Any<String>,
501
+ ],
502
+ "signatureCount": 1,
503
+ "threshold": 1,
504
+ "weight": 1,
505
+ }
506
+ `,
473
507
  )
474
508
  })
475
509
 
@@ -489,7 +523,7 @@ describe('selectApprovals', () => {
489
523
  const account = MultisigConfig.getAddress(config)
490
524
  const hash = MultisigOperation.getHash({
491
525
  account,
492
- configVersion: 1n,
526
+ config: { ...config, version: 1n },
493
527
  transaction,
494
528
  type: 'transaction',
495
529
  })
@@ -531,7 +565,6 @@ describe('selectApprovals', () => {
531
565
  ],
532
566
  config,
533
567
  hash,
534
- resolveConfig: () => ({ config: childConfig, version: 0n }),
535
568
  })
536
569
  expect({
537
570
  signatureCount: selection.signatureCount,
@@ -553,7 +586,7 @@ describe('selectApprovals', () => {
553
586
  })
554
587
  const hash = MultisigOperation.getHash({
555
588
  account,
556
- configVersion: 2n,
589
+ config: { ...config, version: 2n },
557
590
  transaction,
558
591
  type: 'transaction',
559
592
  })
@@ -595,18 +628,18 @@ describe('selectApprovals', () => {
595
628
  const account = MultisigConfig.getAddress(config)
596
629
  const hash = MultisigOperation.getHash({
597
630
  account,
598
- configVersion: 1n,
631
+ config: { ...config, version: 1n },
599
632
  transaction,
600
633
  type: 'transaction',
601
634
  })
602
635
  const childHash = MultisigConfig.getSignPayload({
603
636
  account: child,
604
- config: { version: 1n },
637
+ config: { ...childConfig, version: 1n },
605
638
  payload: hash,
606
639
  })
607
640
  const grandchildHash = MultisigConfig.getSignPayload({
608
641
  account: grandchild,
609
- config: { version: 1n },
642
+ config: { ...grandchildConfig, version: 1n },
610
643
  payload: childHash,
611
644
  })
612
645
 
@@ -637,20 +670,6 @@ describe('selectApprovals', () => {
637
670
  ],
638
671
  config,
639
672
  hash,
640
- resolveConfig: ({ account }) => {
641
- if (Address.isEqual(account, child))
642
- return {
643
- config: MultisigConfig.from({ ...childConfig, version: 1n }),
644
- version: 1n,
645
- }
646
- return {
647
- config: MultisigConfig.from({
648
- ...grandchildConfig,
649
- version: 1n,
650
- }),
651
- version: 1n,
652
- }
653
- },
654
673
  }),
655
674
  ).rejects.toThrowErrorMatchingInlineSnapshot(
656
675
  `[MultisigOperation.InvalidApprovalError: Invalid multisig approval: nested multisig owner 0xf529c8f6b2b4c72102af4cfe5eeb55b7d45dede2 is invalid.]`,
@@ -659,14 +678,12 @@ describe('selectApprovals', () => {
659
678
  })
660
679
 
661
680
  describe('serializeTransaction', () => {
662
- test('initialized and bootstrap transactions', async () => {
681
+ test('current and initial transactions', async () => {
663
682
  const results = []
664
- for (const init of [false, true]) {
665
- const configVersion = init ? 0n : 1n
666
- const applicableConfig = init ? config : initializedConfig
683
+ for (const applicableConfig of [currentConfig, config]) {
667
684
  const hash = MultisigOperation.getHash({
668
685
  account,
669
- configVersion,
686
+ config: applicableConfig,
670
687
  transaction,
671
688
  type: 'transaction',
672
689
  })
@@ -683,10 +700,8 @@ describe('serializeTransaction', () => {
683
700
  account,
684
701
  approvals: selection.approvals,
685
702
  config: applicableConfig,
686
- configVersion,
687
703
  createdAt: 1,
688
704
  hash,
689
- init,
690
705
  signatureCount: selection.signatureCount,
691
706
  status: 'pending',
692
707
  threshold: selection.threshold,
@@ -701,7 +716,7 @@ describe('serializeTransaction', () => {
701
716
  const value = TxEnvelopeTempo.deserialize(serialized)
702
717
  results.push({
703
718
  account: value.signature?.account,
704
- configVersion:
719
+ version:
705
720
  value.signature?.type === 'multisig'
706
721
  ? value.signature.config.version
707
722
  : undefined,
@@ -718,17 +733,17 @@ describe('serializeTransaction', () => {
718
733
  [
719
734
  {
720
735
  "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
721
- "configVersion": 1n,
722
736
  "hash": "0x8309740edaf304284186f7bcfe4527745cd4eb48e7441795ebdd970798091f8f",
723
737
  "signatureCount": 2,
724
738
  "type": "0x76",
739
+ "version": 1n,
725
740
  },
726
741
  {
727
742
  "account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
728
- "configVersion": 0n,
729
743
  "hash": "0x636af84d8445d87cbcd33039d5a3a2274a5911036b1b7ceb740ac41e2f638611",
730
744
  "signatureCount": 2,
731
745
  "type": "0x76",
746
+ "version": 0n,
732
747
  },
733
748
  ]
734
749
  `)
@@ -756,7 +771,7 @@ describe('serializeTransaction', () => {
756
771
  for (const transaction of transactions) {
757
772
  const hash = MultisigOperation.getHash({
758
773
  account,
759
- configVersion: 1n,
774
+ config: currentConfig,
760
775
  transaction,
761
776
  type: 'transaction',
762
777
  })
@@ -766,18 +781,16 @@ describe('serializeTransaction', () => {
766
781
  signApproval(owners[0]!, hash),
767
782
  signApproval(owners[1]!, hash),
768
783
  ],
769
- config: initializedConfig,
784
+ config: currentConfig,
770
785
  hash,
771
786
  })
772
787
  const serialized = MultisigOperation.serializeTransaction(
773
788
  MultisigOperation.from({
774
789
  account,
775
790
  approvals: selection.approvals,
776
- config: initializedConfig,
777
- configVersion: 1n,
791
+ config: currentConfig,
778
792
  createdAt: 1,
779
793
  hash,
780
- init: false,
781
794
  signatureCount: selection.signatureCount,
782
795
  status: 'pending',
783
796
  threshold: selection.threshold,
@@ -825,7 +838,7 @@ describe('serializeTransaction', () => {
825
838
  test('rejects an approval not retained by the operation', async () => {
826
839
  const hash = MultisigOperation.getHash({
827
840
  account,
828
- configVersion: 1n,
841
+ config: currentConfig,
829
842
  transaction,
830
843
  type: 'transaction',
831
844
  })
@@ -834,17 +847,15 @@ describe('serializeTransaction', () => {
834
847
  const selection = await MultisigOperation.selectApprovals({
835
848
  account,
836
849
  approvals: [approval_1],
837
- config: initializedConfig,
850
+ config: currentConfig,
838
851
  hash,
839
852
  })
840
853
  const operation = MultisigOperation.from({
841
854
  account,
842
855
  approvals: selection.approvals,
843
- config: initializedConfig,
844
- configVersion: 1n,
856
+ config: currentConfig,
845
857
  createdAt: 1,
846
858
  hash,
847
- init: false,
848
859
  signatureCount: selection.signatureCount,
849
860
  status: 'pending',
850
861
  threshold: selection.threshold,
@@ -907,10 +918,8 @@ describe('from', () => {
907
918
  "threshold": 2,
908
919
  "version": 1n,
909
920
  },
910
- "configVersion": 1n,
911
921
  "createdAt": 1,
912
922
  "hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
913
- "init": false,
914
923
  "signatureCount": 1,
915
924
  "status": "pending",
916
925
  "threshold": 2,
@@ -940,11 +949,9 @@ describe('from', () => {
940
949
  "threshold": 2,
941
950
  "version": 1n,
942
951
  },
943
- "configVersion": 1n,
944
952
  "createdAt": 1,
945
953
  "expiresAt": 10,
946
954
  "hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
947
- "init": false,
948
955
  "signatureCount": 2,
949
956
  "status": "submitting",
950
957
  "submissionId": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
@@ -975,10 +982,8 @@ describe('from', () => {
975
982
  "threshold": 2,
976
983
  "version": 1n,
977
984
  },
978
- "configVersion": 1n,
979
985
  "createdAt": 1,
980
986
  "hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
981
- "init": false,
982
987
  "signatureCount": 2,
983
988
  "status": "success",
984
989
  "threshold": 2,
@@ -1004,7 +1009,7 @@ describe('from', () => {
1004
1009
  ...transactionPending,
1005
1010
  hash: MultisigConfig.getSignPayload({
1006
1011
  account,
1007
- config: initializedConfig,
1012
+ config: currentConfig,
1008
1013
  payload: TxEnvelopeTempo.getSignPayload(
1009
1014
  TxEnvelopeTempo.deserialize(transaction),
1010
1015
  ),
@@ -1038,10 +1043,8 @@ describe('from', () => {
1038
1043
  "threshold": 2,
1039
1044
  "version": 1n,
1040
1045
  },
1041
- "configVersion": 1n,
1042
1046
  "createdAt": 1,
1043
1047
  "hash": Any<String>,
1044
- "init": false,
1045
1048
  "signatureCount": 1,
1046
1049
  "status": "pending",
1047
1050
  "threshold": 2,
@@ -1067,7 +1070,7 @@ describe('from', () => {
1067
1070
  ...transactionPending,
1068
1071
  hash: MultisigConfig.getSignPayload({
1069
1072
  account,
1070
- config: initializedConfig,
1073
+ config: currentConfig,
1071
1074
  payload: TxEnvelopeTempo.getSignPayload(
1072
1075
  TxEnvelopeTempo.deserialize(transaction),
1073
1076
  ),
@@ -1078,11 +1081,10 @@ describe('from', () => {
1078
1081
  expect(operation.transaction).toBe(transaction)
1079
1082
  })
1080
1083
 
1081
- test('bootstrap transaction', () => {
1084
+ test('initial transaction', () => {
1082
1085
  const operation = MultisigOperation.from({
1083
1086
  ...transactionPending,
1084
1087
  config,
1085
- configVersion: 0n,
1086
1088
  hash: MultisigConfig.getSignPayload({
1087
1089
  account,
1088
1090
  config,
@@ -1090,7 +1092,6 @@ describe('from', () => {
1090
1092
  TxEnvelopeTempo.deserialize(transaction),
1091
1093
  ),
1092
1094
  }),
1093
- init: true,
1094
1095
  })
1095
1096
 
1096
1097
  expect(operation).toMatchInlineSnapshot(
@@ -1119,10 +1120,8 @@ describe('from', () => {
1119
1120
  "threshold": 2,
1120
1121
  "version": 0n,
1121
1122
  },
1122
- "configVersion": 0n,
1123
1123
  "createdAt": 1,
1124
1124
  "hash": Any<String>,
1125
- "init": true,
1126
1125
  "signatureCount": 1,
1127
1126
  "status": "pending",
1128
1127
  "threshold": 2,
@@ -1135,31 +1134,6 @@ describe('from', () => {
1135
1134
  )
1136
1135
  })
1137
1136
 
1138
- test('initialized transaction at config version zero', () => {
1139
- const operation = MultisigOperation.from({
1140
- ...transactionPending,
1141
- config,
1142
- configVersion: 0n,
1143
- hash: MultisigConfig.getSignPayload({
1144
- account,
1145
- config,
1146
- payload: TxEnvelopeTempo.getSignPayload(
1147
- TxEnvelopeTempo.deserialize(transaction),
1148
- ),
1149
- }),
1150
- })
1151
-
1152
- expect({
1153
- configVersion: operation.configVersion,
1154
- init: operation.init,
1155
- }).toMatchInlineSnapshot(`
1156
- {
1157
- "configVersion": 0n,
1158
- "init": false,
1159
- }
1160
- `)
1161
- })
1162
-
1163
1137
  test('key authorization states', () => {
1164
1138
  const pending = MultisigOperation.from(keyAuthorizationPending)
1165
1139
  const authorization = KeyAuthorization.deserialize(keyAuthorization)
@@ -1170,7 +1144,7 @@ describe('from', () => {
1170
1144
  KeyAuthorization.from(authorization, {
1171
1145
  signature: {
1172
1146
  account,
1173
- config: initializedConfig,
1147
+ config: currentConfig,
1174
1148
  signatures: [
1175
1149
  SignatureEnvelope.deserialize(approval_1),
1176
1150
  SignatureEnvelope.deserialize(approval_2),
@@ -1206,10 +1180,8 @@ describe('from', () => {
1206
1180
  "threshold": 2,
1207
1181
  "version": 1n,
1208
1182
  },
1209
- "configVersion": 1n,
1210
1183
  "createdAt": 1,
1211
1184
  "hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
1212
- "init": false,
1213
1185
  "keyAuthorization": "0xf838f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36e",
1214
1186
  "signatureCount": 1,
1215
1187
  "status": "pending",
@@ -1239,10 +1211,8 @@ describe('from', () => {
1239
1211
  "threshold": 2,
1240
1212
  "version": 1n,
1241
1213
  },
1242
- "configVersion": 1n,
1243
1214
  "createdAt": 1,
1244
1215
  "hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
1245
- "init": false,
1246
1216
  "keyAuthorization": "0xf901b3f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36eb9017805f9017494f81b7763d3a6876195d780865bd783dbd97dd36ef852a000000000000000000000000000000000000000000000000000000000000000000102eed69407e1ed8ea0e9601e5546b0a03aed683df360140701d694288f0cd85005f34168f731a468aef268c2f9456f01f90108b88201000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200b88201000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000047cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997807775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d100",
1247
1217
  "signatureCount": 2,
1248
1218
  "status": "success",
@@ -1255,7 +1225,7 @@ describe('from', () => {
1255
1225
  `)
1256
1226
  })
1257
1227
 
1258
- test('bootstrap key authorization', () => {
1228
+ test('initial key authorization', () => {
1259
1229
  const authorization = KeyAuthorization.deserialize(keyAuthorization)
1260
1230
  const keyAuthorization_ = KeyAuthorization.serialize(
1261
1231
  KeyAuthorization.from(authorization, {
@@ -1274,13 +1244,11 @@ describe('from', () => {
1274
1244
  ...keyAuthorizationPending,
1275
1245
  approvals: [approval_1, approval_2],
1276
1246
  config,
1277
- configVersion: 0n,
1278
1247
  hash: MultisigConfig.getSignPayload({
1279
1248
  account,
1280
1249
  config,
1281
1250
  payload: KeyAuthorization.getSignPayload(authorization),
1282
1251
  }),
1283
- init: true,
1284
1252
  keyAuthorization: keyAuthorization_,
1285
1253
  signatureCount: 2,
1286
1254
  status: 'success',
@@ -1314,10 +1282,8 @@ describe('from', () => {
1314
1282
  "threshold": 2,
1315
1283
  "version": 0n,
1316
1284
  },
1317
- "configVersion": 0n,
1318
1285
  "createdAt": 1,
1319
1286
  "hash": Any<String>,
1320
- "init": true,
1321
1287
  "keyAuthorization": Any<String>,
1322
1288
  "signatureCount": 2,
1323
1289
  "status": "success",
@@ -1361,10 +1327,8 @@ describe('RPC conversion', () => {
1361
1327
  "threshold": 2,
1362
1328
  "version": "0x1",
1363
1329
  },
1364
- "configVersion": "0x1",
1365
1330
  "createdAt": 1,
1366
1331
  "hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
1367
- "init": false,
1368
1332
  "keyAuthorization": "0xf838f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36e",
1369
1333
  "signatureCount": 1,
1370
1334
  "status": "pending",
@@ -1393,10 +1357,8 @@ describe('RPC conversion', () => {
1393
1357
  "threshold": 2,
1394
1358
  "version": "0x1",
1395
1359
  },
1396
- "configVersion": "0x1",
1397
1360
  "createdAt": 1,
1398
1361
  "hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
1399
- "init": false,
1400
1362
  "signatureCount": 1,
1401
1363
  "status": "pending",
1402
1364
  "threshold": 2,
@@ -1529,7 +1491,7 @@ describe('validation', () => {
1529
1491
  account: '0x0000000000000000000000000000000000000000',
1530
1492
  hash: MultisigConfig.getSignPayload({
1531
1493
  account: '0x0000000000000000000000000000000000000000',
1532
- config: initializedConfig,
1494
+ config: currentConfig,
1533
1495
  payload: TxEnvelopeTempo.getSignPayload(
1534
1496
  TxEnvelopeTempo.deserialize(transaction),
1535
1497
  ),
@@ -1596,7 +1558,7 @@ describe('validation', () => {
1596
1558
  },
1597
1559
  },
1598
1560
  {
1599
- name: 'nested bootstrap owner approval',
1561
+ name: 'nested non-owner approval',
1600
1562
  operation: {
1601
1563
  ...transactionPending,
1602
1564
  approvals: [
@@ -1609,35 +1571,48 @@ describe('validation', () => {
1609
1571
  ],
1610
1572
  },
1611
1573
  },
1612
- {
1613
- name: 'bootstrap with initialized version',
1614
- operation: { ...transactionPending, init: true },
1615
- },
1616
1574
  ])('rejects $name', ({ operation }) => {
1617
1575
  expect(() =>
1618
1576
  MultisigOperation.from(operation as MultisigOperation.Operation),
1619
1577
  ).toThrowError(MultisigOperation.InvalidOperationError)
1620
1578
  })
1621
1579
 
1622
- test('rejects mismatched config versions', () => {
1580
+ test('rejects an initial config for another account', () => {
1581
+ const config = MultisigConfig.from({
1582
+ ...transactionPending.config,
1583
+ salt: `0x${'ff'.repeat(32)}`,
1584
+ version: 0n,
1585
+ })
1623
1586
  expect(() =>
1624
1587
  MultisigOperation.from({
1625
1588
  ...transactionPending,
1626
- config: { ...initializedConfig, version: 2n },
1589
+ config,
1590
+ hash: MultisigConfig.getSignPayload({
1591
+ account,
1592
+ config,
1593
+ payload: TxEnvelopeTempo.getSignPayload(
1594
+ TxEnvelopeTempo.deserialize(transaction),
1595
+ ),
1596
+ }),
1627
1597
  }),
1628
1598
  ).toThrowErrorMatchingInlineSnapshot(
1629
- `[MultisigOperation.InvalidOperationError: Invalid multisig operation: config.version must equal configVersion.]`,
1599
+ `
1600
+ [MultisigOperation.InvalidOperationError: Invalid multisig operation.
1601
+
1602
+ Details: Invalid native multisig owner approval: initial multisig config does not derive account.]
1603
+ `,
1630
1604
  )
1631
1605
  })
1632
1606
 
1633
1607
  test('rejects noncanonical RPC quantities', () => {
1608
+ const operation = MultisigOperation.toRpc(transactionPending)
1634
1609
  expect(() =>
1635
1610
  MultisigOperation.fromRpc({
1636
- ...MultisigOperation.toRpc(transactionPending),
1637
- configVersion: '0x01',
1611
+ ...operation,
1612
+ config: { ...operation.config, version: '0x01' },
1638
1613
  }),
1639
1614
  ).toThrowError(
1640
- 'Invalid multisig operation: configVersion must use canonical quantity encoding.',
1615
+ 'Invalid multisig operation: config.version must use canonical quantity encoding.',
1641
1616
  )
1642
1617
  })
1643
1618
 
@@ -1650,7 +1625,7 @@ describe('validation', () => {
1650
1625
  KeyAuthorization.from(authorization, {
1651
1626
  signature: {
1652
1627
  account,
1653
- config: initializedConfig,
1628
+ config: currentConfig,
1654
1629
  signatures: [
1655
1630
  SignatureEnvelope.deserialize(approval_1),
1656
1631
  SignatureEnvelope.deserialize(approval_3),
@@ -1674,7 +1649,7 @@ describe('validation', () => {
1674
1649
  const signatures = [
1675
1650
  ...SignatureEnvelope.sortMultisigApprovals({
1676
1651
  account,
1677
- config: initializedConfig,
1652
+ config: currentConfig,
1678
1653
  payload: KeyAuthorization.getSignPayload(authorization),
1679
1654
  signatures: [
1680
1655
  SignatureEnvelope.deserialize(approval_1),
@@ -1689,7 +1664,7 @@ describe('validation', () => {
1689
1664
  KeyAuthorization.from(authorization, {
1690
1665
  signature: {
1691
1666
  account,
1692
- config: initializedConfig,
1667
+ config: currentConfig,
1693
1668
  signatures,
1694
1669
  type: 'multisig',
1695
1670
  },
@@ -1714,7 +1689,7 @@ describe('validation', () => {
1714
1689
  KeyAuthorization.from(authorization, {
1715
1690
  signature: {
1716
1691
  account,
1717
- config: initializedConfig,
1692
+ config: currentConfig,
1718
1693
  signatures: [
1719
1694
  SignatureEnvelope.deserialize(approval_1),
1720
1695
  SignatureEnvelope.deserialize(approval_1),
@@ -1763,7 +1738,7 @@ describe('validation', () => {
1763
1738
  })
1764
1739
  const selected = SignatureEnvelope.sortMultisigApprovals({
1765
1740
  account,
1766
- config: initializedConfig,
1741
+ config: currentConfig,
1767
1742
  payload: KeyAuthorization.getSignPayload(authorization),
1768
1743
  signatures: [selectedNested, SignatureEnvelope.deserialize(approval_2)],
1769
1744
  })
@@ -1774,7 +1749,7 @@ describe('validation', () => {
1774
1749
  KeyAuthorization.from(authorization, {
1775
1750
  signature: {
1776
1751
  account,
1777
- config: initializedConfig,
1752
+ config: currentConfig,
1778
1753
  signatures: selected,
1779
1754
  type: 'multisig',
1780
1755
  },
@@ -1790,7 +1765,7 @@ describe('validation', () => {
1790
1765
  )
1791
1766
  })
1792
1767
 
1793
- test('accepts case-insensitive bootstrap configs', () => {
1768
+ test('accepts case-insensitive initial configs', () => {
1794
1769
  const config = MultisigConfig.from({
1795
1770
  owners: [
1796
1771
  {
@@ -1831,14 +1806,12 @@ describe('validation', () => {
1831
1806
  account,
1832
1807
  approvals,
1833
1808
  config,
1834
- configVersion: 0n,
1835
1809
  createdAt: 1,
1836
1810
  hash: MultisigConfig.getSignPayload({
1837
1811
  account,
1838
1812
  config,
1839
1813
  payload: KeyAuthorization.getSignPayload(authorization),
1840
1814
  }),
1841
- init: true,
1842
1815
  keyAuthorization: KeyAuthorization.serialize(
1843
1816
  KeyAuthorization.from(authorization, {
1844
1817
  signature: {