ox 0.14.38 → 0.14.40
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.
- package/CHANGELOG.md +20 -0
- package/_cjs/tempo/MultisigConfig.js +71 -15
- package/_cjs/tempo/MultisigConfig.js.map +1 -1
- package/_cjs/tempo/MultisigOperation.js +43 -35
- package/_cjs/tempo/MultisigOperation.js.map +1 -1
- package/_cjs/tempo/MultisigWitness.js +92 -0
- package/_cjs/tempo/MultisigWitness.js.map +1 -0
- package/_cjs/tempo/SignatureEnvelope.js +71 -108
- package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
- package/_cjs/tempo/TransactionRequest.js +7 -1
- package/_cjs/tempo/TransactionRequest.js.map +1 -1
- package/_cjs/tempo/index.js +2 -1
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/tempo/MultisigConfig.js +140 -71
- package/_esm/tempo/MultisigConfig.js.map +1 -1
- package/_esm/tempo/MultisigOperation.js +43 -36
- package/_esm/tempo/MultisigOperation.js.map +1 -1
- package/_esm/tempo/MultisigWitness.js +123 -0
- package/_esm/tempo/MultisigWitness.js.map +1 -0
- package/_esm/tempo/SignatureEnvelope.js +84 -143
- package/_esm/tempo/SignatureEnvelope.js.map +1 -1
- package/_esm/tempo/TransactionRequest.js +7 -1
- package/_esm/tempo/TransactionRequest.js.map +1 -1
- package/_esm/tempo/index.js +9 -0
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_types/tempo/KeyAuthorization.d.ts +1 -1
- package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
- package/_types/tempo/MultisigConfig.d.ts +137 -73
- package/_types/tempo/MultisigConfig.d.ts.map +1 -1
- package/_types/tempo/MultisigOperation.d.ts +1 -1
- package/_types/tempo/MultisigOperation.d.ts.map +1 -1
- package/_types/tempo/MultisigWitness.d.ts +106 -0
- package/_types/tempo/MultisigWitness.d.ts.map +1 -0
- package/_types/tempo/SignatureEnvelope.d.ts +81 -75
- package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/_types/tempo/TransactionRequest.d.ts +6 -3
- package/_types/tempo/TransactionRequest.d.ts.map +1 -1
- package/_types/tempo/index.d.ts +9 -0
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/package.json +21 -1
- package/tempo/KeyAuthorization.test-d.ts +12 -0
- package/tempo/KeyAuthorization.test.ts +54 -0
- package/tempo/KeyAuthorization.ts +1 -1
- package/tempo/MultisigConfig.test-d/package.json +6 -0
- package/tempo/MultisigConfig.test-d.ts +52 -0
- package/tempo/MultisigConfig.test.ts +291 -263
- package/tempo/MultisigConfig.ts +250 -95
- package/tempo/MultisigOperation.test-d.ts +6 -0
- package/tempo/MultisigOperation.test.ts +200 -81
- package/tempo/MultisigOperation.ts +42 -34
- package/tempo/MultisigWitness/package.json +6 -0
- package/tempo/MultisigWitness.test-d/package.json +6 -0
- package/tempo/MultisigWitness.test-d.ts +42 -0
- package/tempo/MultisigWitness.test.ts +289 -0
- package/tempo/MultisigWitness.ts +210 -0
- package/tempo/RpcSchemaTempo.test-d.ts +25 -0
- package/tempo/SignatureEnvelope.test-d.ts +57 -40
- package/tempo/SignatureEnvelope.test.ts +523 -480
- package/tempo/SignatureEnvelope.ts +250 -257
- package/tempo/TransactionRequest.test-d/package.json +6 -0
- package/tempo/TransactionRequest.test-d.ts +24 -0
- package/tempo/TransactionRequest.test.ts +102 -1
- package/tempo/TransactionRequest.ts +12 -2
- package/tempo/index.ts +9 -0
- package/tempo/multisig.e2e.test.ts +113 -86
- package/version.ts +1 -1
|
@@ -36,6 +36,7 @@ const config = MultisigConfig.from({
|
|
|
36
36
|
],
|
|
37
37
|
threshold: 2,
|
|
38
38
|
})
|
|
39
|
+
const initializedConfig = MultisigConfig.from({ ...config, version: 1n })
|
|
39
40
|
const account = MultisigConfig.getAddress(config)
|
|
40
41
|
const ownerSignature_1 = owners[0]!.signature
|
|
41
42
|
const approval_1 = SignatureEnvelope.serialize(ownerSignature_1)
|
|
@@ -62,23 +63,23 @@ const keyAuthorization = KeyAuthorization.serialize(
|
|
|
62
63
|
|
|
63
64
|
const transactionHash_ = MultisigConfig.getSignPayload({
|
|
64
65
|
account,
|
|
66
|
+
config: initializedConfig,
|
|
65
67
|
payload: TxEnvelopeTempo.getSignPayload(
|
|
66
68
|
TxEnvelopeTempo.deserialize(transaction),
|
|
67
69
|
),
|
|
68
|
-
version: 1n,
|
|
69
70
|
})
|
|
70
71
|
const keyAuthorizationHash = MultisigConfig.getSignPayload({
|
|
71
72
|
account,
|
|
73
|
+
config: initializedConfig,
|
|
72
74
|
payload: KeyAuthorization.getSignPayload(
|
|
73
75
|
KeyAuthorization.deserialize(keyAuthorization),
|
|
74
76
|
),
|
|
75
|
-
version: 1n,
|
|
76
77
|
})
|
|
77
78
|
|
|
78
79
|
const base = {
|
|
79
80
|
account,
|
|
80
81
|
approvals: [approval_1],
|
|
81
|
-
config,
|
|
82
|
+
config: initializedConfig,
|
|
82
83
|
configVersion: 1n,
|
|
83
84
|
createdAt: 1,
|
|
84
85
|
init: false,
|
|
@@ -249,8 +250,8 @@ describe('selectApprovals', () => {
|
|
|
249
250
|
})
|
|
250
251
|
const childHash = MultisigConfig.getSignPayload({
|
|
251
252
|
account: child,
|
|
253
|
+
config: { version: 2n },
|
|
252
254
|
payload: hash,
|
|
253
|
-
version: 2n,
|
|
254
255
|
})
|
|
255
256
|
const childApprovals = [
|
|
256
257
|
signApproval(owners[1]!, childHash),
|
|
@@ -261,7 +262,10 @@ describe('selectApprovals', () => {
|
|
|
261
262
|
account,
|
|
262
263
|
}) => {
|
|
263
264
|
if (!Address.isEqual(account, child)) throw new Error('unknown account')
|
|
264
|
-
return {
|
|
265
|
+
return {
|
|
266
|
+
config: MultisigConfig.from({ ...childConfig, version: 2n }),
|
|
267
|
+
version: 2n,
|
|
268
|
+
}
|
|
265
269
|
}
|
|
266
270
|
const partial = await MultisigOperation.selectApprovals({
|
|
267
271
|
account,
|
|
@@ -269,6 +273,7 @@ describe('selectApprovals', () => {
|
|
|
269
273
|
rootApproval,
|
|
270
274
|
SignatureEnvelope.serialize({
|
|
271
275
|
account: child,
|
|
276
|
+
config: MultisigConfig.from({ ...childConfig, version: 2n }),
|
|
272
277
|
signatures: [SignatureEnvelope.deserialize(childApprovals[0]!)],
|
|
273
278
|
type: 'multisig',
|
|
274
279
|
}),
|
|
@@ -283,6 +288,7 @@ describe('selectApprovals', () => {
|
|
|
283
288
|
rootApproval,
|
|
284
289
|
SignatureEnvelope.serialize({
|
|
285
290
|
account: child,
|
|
291
|
+
config: MultisigConfig.from({ ...childConfig, version: 2n }),
|
|
286
292
|
signatures: childApprovals.map((approval) =>
|
|
287
293
|
SignatureEnvelope.deserialize(approval),
|
|
288
294
|
),
|
|
@@ -335,6 +341,57 @@ describe('selectApprovals', () => {
|
|
|
335
341
|
`)
|
|
336
342
|
})
|
|
337
343
|
|
|
344
|
+
test('rejects mismatched nested config versions', async () => {
|
|
345
|
+
const childConfig = MultisigConfig.from({
|
|
346
|
+
owners: [{ owner: owners[1]!.address, weight: 1 }],
|
|
347
|
+
threshold: 1,
|
|
348
|
+
})
|
|
349
|
+
const child = MultisigConfig.getAddress(childConfig)
|
|
350
|
+
const config = MultisigConfig.from({
|
|
351
|
+
owners: [{ owner: child, weight: 1 }],
|
|
352
|
+
threshold: 1,
|
|
353
|
+
})
|
|
354
|
+
const account = MultisigConfig.getAddress(config)
|
|
355
|
+
const hash = MultisigOperation.getHash({
|
|
356
|
+
account,
|
|
357
|
+
configVersion: 1n,
|
|
358
|
+
transaction,
|
|
359
|
+
type: 'transaction',
|
|
360
|
+
})
|
|
361
|
+
const resolvedConfig = MultisigConfig.from({
|
|
362
|
+
...childConfig,
|
|
363
|
+
version: 2n,
|
|
364
|
+
})
|
|
365
|
+
const childHash = MultisigConfig.getSignPayload({
|
|
366
|
+
account: child,
|
|
367
|
+
config: resolvedConfig,
|
|
368
|
+
payload: hash,
|
|
369
|
+
})
|
|
370
|
+
|
|
371
|
+
await expect(
|
|
372
|
+
MultisigOperation.selectApprovals({
|
|
373
|
+
account,
|
|
374
|
+
approvals: [
|
|
375
|
+
SignatureEnvelope.serialize({
|
|
376
|
+
account: child,
|
|
377
|
+
config: resolvedConfig,
|
|
378
|
+
signatures: [
|
|
379
|
+
SignatureEnvelope.deserialize(
|
|
380
|
+
signApproval(owners[1]!, childHash),
|
|
381
|
+
),
|
|
382
|
+
],
|
|
383
|
+
type: 'multisig',
|
|
384
|
+
}),
|
|
385
|
+
],
|
|
386
|
+
config,
|
|
387
|
+
hash,
|
|
388
|
+
resolveConfig: () => ({ config: childConfig, version: 2n }),
|
|
389
|
+
}),
|
|
390
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
391
|
+
`[MultisigOperation.InvalidApprovalError: Invalid multisig approval: resolved config.version must equal version for nested multisig owner 0x7888d60e9cc26c8569d394fce435c248f1e49c3b.]`,
|
|
392
|
+
)
|
|
393
|
+
})
|
|
394
|
+
|
|
338
395
|
test('rejects invalid and non-owner approvals', async () => {
|
|
339
396
|
const hash = MultisigOperation.getHash({
|
|
340
397
|
account,
|
|
@@ -389,8 +446,8 @@ describe('selectApprovals', () => {
|
|
|
389
446
|
})
|
|
390
447
|
const childHash = MultisigConfig.getSignPayload({
|
|
391
448
|
account: child,
|
|
449
|
+
config: { version: 1n },
|
|
392
450
|
payload: hash,
|
|
393
|
-
version: 1n,
|
|
394
451
|
})
|
|
395
452
|
|
|
396
453
|
await expect(
|
|
@@ -399,6 +456,7 @@ describe('selectApprovals', () => {
|
|
|
399
456
|
approvals: [
|
|
400
457
|
SignatureEnvelope.serialize({
|
|
401
458
|
account: child,
|
|
459
|
+
config: MultisigConfig.from({ ...childConfig, version: 1n }),
|
|
402
460
|
signatures: [
|
|
403
461
|
SignatureEnvelope.deserialize(
|
|
404
462
|
signApproval(owners[1]!, childHash),
|
|
@@ -415,7 +473,7 @@ describe('selectApprovals', () => {
|
|
|
415
473
|
)
|
|
416
474
|
})
|
|
417
475
|
|
|
418
|
-
test('rejects keychain and
|
|
476
|
+
test('rejects keychain and accepts initial nested approvals', async () => {
|
|
419
477
|
const childConfig = MultisigConfig.from({
|
|
420
478
|
owners: [{ owner: owners[1]!.address, weight: 1 }],
|
|
421
479
|
threshold: 1,
|
|
@@ -437,8 +495,8 @@ describe('selectApprovals', () => {
|
|
|
437
495
|
})
|
|
438
496
|
const childHash = MultisigConfig.getSignPayload({
|
|
439
497
|
account: child,
|
|
498
|
+
config: childConfig,
|
|
440
499
|
payload: hash,
|
|
441
|
-
version: 0n,
|
|
442
500
|
})
|
|
443
501
|
|
|
444
502
|
await expect(
|
|
@@ -459,31 +517,36 @@ describe('selectApprovals', () => {
|
|
|
459
517
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
460
518
|
`[MultisigOperation.InvalidApprovalError: Invalid multisig approval: keychain signatures cannot approve a multisig operation.]`,
|
|
461
519
|
)
|
|
462
|
-
await
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
520
|
+
const selection = await MultisigOperation.selectApprovals({
|
|
521
|
+
account,
|
|
522
|
+
approvals: [
|
|
523
|
+
SignatureEnvelope.serialize({
|
|
524
|
+
account: child,
|
|
525
|
+
config: childConfig,
|
|
526
|
+
signatures: [
|
|
527
|
+
SignatureEnvelope.deserialize(signApproval(owners[1]!, childHash)),
|
|
528
|
+
],
|
|
529
|
+
type: 'multisig',
|
|
530
|
+
}),
|
|
531
|
+
],
|
|
532
|
+
config,
|
|
533
|
+
hash,
|
|
534
|
+
resolveConfig: () => ({ config: childConfig, version: 0n }),
|
|
535
|
+
})
|
|
536
|
+
expect({
|
|
537
|
+
signatureCount: selection.signatureCount,
|
|
538
|
+
threshold: selection.threshold,
|
|
539
|
+
weight: selection.weight,
|
|
540
|
+
}).toMatchInlineSnapshot(`
|
|
541
|
+
{
|
|
542
|
+
"signatureCount": 1,
|
|
543
|
+
"threshold": 1,
|
|
544
|
+
"weight": 1,
|
|
545
|
+
}
|
|
546
|
+
`)
|
|
484
547
|
})
|
|
485
548
|
|
|
486
|
-
test('rejects nested account cycles',
|
|
549
|
+
test('rejects nested account cycles while serializing', () => {
|
|
487
550
|
const config = MultisigConfig.from({
|
|
488
551
|
owners: [{ owner: account, weight: 1 }],
|
|
489
552
|
threshold: 1,
|
|
@@ -496,30 +559,21 @@ describe('selectApprovals', () => {
|
|
|
496
559
|
})
|
|
497
560
|
const nestedHash = MultisigConfig.getSignPayload({
|
|
498
561
|
account,
|
|
562
|
+
config: { version: 2n },
|
|
499
563
|
payload: hash,
|
|
500
|
-
version: 2n,
|
|
501
564
|
})
|
|
502
565
|
|
|
503
|
-
|
|
504
|
-
|
|
566
|
+
expect(() =>
|
|
567
|
+
SignatureEnvelope.serialize({
|
|
505
568
|
account,
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
signatures: [
|
|
510
|
-
SignatureEnvelope.deserialize(
|
|
511
|
-
signApproval(owners[0]!, nestedHash),
|
|
512
|
-
),
|
|
513
|
-
],
|
|
514
|
-
type: 'multisig',
|
|
515
|
-
}),
|
|
569
|
+
config: MultisigConfig.from({ ...config, version: 2n }),
|
|
570
|
+
signatures: [
|
|
571
|
+
SignatureEnvelope.deserialize(signApproval(owners[0]!, nestedHash)),
|
|
516
572
|
],
|
|
517
|
-
|
|
518
|
-
hash,
|
|
519
|
-
resolveConfig: () => ({ config, version: 2n }),
|
|
573
|
+
type: 'multisig',
|
|
520
574
|
}),
|
|
521
|
-
).
|
|
522
|
-
`[
|
|
575
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
576
|
+
`[SignatureEnvelope.InvalidMultisigApprovalError: Invalid native multisig owner approval: multisig account cannot be an owner.]`,
|
|
523
577
|
)
|
|
524
578
|
})
|
|
525
579
|
|
|
@@ -547,13 +601,13 @@ describe('selectApprovals', () => {
|
|
|
547
601
|
})
|
|
548
602
|
const childHash = MultisigConfig.getSignPayload({
|
|
549
603
|
account: child,
|
|
604
|
+
config: { version: 1n },
|
|
550
605
|
payload: hash,
|
|
551
|
-
version: 1n,
|
|
552
606
|
})
|
|
553
607
|
const grandchildHash = MultisigConfig.getSignPayload({
|
|
554
608
|
account: grandchild,
|
|
609
|
+
config: { version: 1n },
|
|
555
610
|
payload: childHash,
|
|
556
|
-
version: 1n,
|
|
557
611
|
})
|
|
558
612
|
|
|
559
613
|
await expect(
|
|
@@ -562,9 +616,14 @@ describe('selectApprovals', () => {
|
|
|
562
616
|
approvals: [
|
|
563
617
|
SignatureEnvelope.serialize({
|
|
564
618
|
account: child,
|
|
619
|
+
config: MultisigConfig.from({ ...childConfig, version: 1n }),
|
|
565
620
|
signatures: [
|
|
566
621
|
{
|
|
567
622
|
account: grandchild,
|
|
623
|
+
config: MultisigConfig.from({
|
|
624
|
+
...grandchildConfig,
|
|
625
|
+
version: 1n,
|
|
626
|
+
}),
|
|
568
627
|
signatures: [
|
|
569
628
|
SignatureEnvelope.deserialize(
|
|
570
629
|
signApproval(owners[2]!, grandchildHash),
|
|
@@ -580,8 +639,17 @@ describe('selectApprovals', () => {
|
|
|
580
639
|
hash,
|
|
581
640
|
resolveConfig: ({ account }) => {
|
|
582
641
|
if (Address.isEqual(account, child))
|
|
583
|
-
return {
|
|
584
|
-
|
|
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
|
+
}
|
|
585
653
|
},
|
|
586
654
|
}),
|
|
587
655
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
@@ -595,6 +663,7 @@ describe('serializeTransaction', () => {
|
|
|
595
663
|
const results = []
|
|
596
664
|
for (const init of [false, true]) {
|
|
597
665
|
const configVersion = init ? 0n : 1n
|
|
666
|
+
const applicableConfig = init ? config : initializedConfig
|
|
598
667
|
const hash = MultisigOperation.getHash({
|
|
599
668
|
account,
|
|
600
669
|
configVersion,
|
|
@@ -607,13 +676,13 @@ describe('serializeTransaction', () => {
|
|
|
607
676
|
signApproval(owners[1]!, hash),
|
|
608
677
|
signApproval(owners[0]!, hash),
|
|
609
678
|
],
|
|
610
|
-
config,
|
|
679
|
+
config: applicableConfig,
|
|
611
680
|
hash,
|
|
612
681
|
})
|
|
613
682
|
const operation = MultisigOperation.from({
|
|
614
683
|
account,
|
|
615
684
|
approvals: selection.approvals,
|
|
616
|
-
config,
|
|
685
|
+
config: applicableConfig,
|
|
617
686
|
configVersion,
|
|
618
687
|
createdAt: 1,
|
|
619
688
|
hash,
|
|
@@ -632,8 +701,11 @@ describe('serializeTransaction', () => {
|
|
|
632
701
|
const value = TxEnvelopeTempo.deserialize(serialized)
|
|
633
702
|
results.push({
|
|
634
703
|
account: value.signature?.account,
|
|
704
|
+
configVersion:
|
|
705
|
+
value.signature?.type === 'multisig'
|
|
706
|
+
? value.signature.config.version
|
|
707
|
+
: undefined,
|
|
635
708
|
hash: Hash.keccak256(serialized),
|
|
636
|
-
init: value.signature?.type === 'multisig' && !!value.signature.init,
|
|
637
709
|
signatureCount:
|
|
638
710
|
value.signature?.type === 'multisig'
|
|
639
711
|
? value.signature.signatures.length
|
|
@@ -646,15 +718,15 @@ describe('serializeTransaction', () => {
|
|
|
646
718
|
[
|
|
647
719
|
{
|
|
648
720
|
"account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
|
|
649
|
-
"
|
|
650
|
-
"
|
|
721
|
+
"configVersion": 1n,
|
|
722
|
+
"hash": "0x8309740edaf304284186f7bcfe4527745cd4eb48e7441795ebdd970798091f8f",
|
|
651
723
|
"signatureCount": 2,
|
|
652
724
|
"type": "0x76",
|
|
653
725
|
},
|
|
654
726
|
{
|
|
655
727
|
"account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
|
|
656
|
-
"
|
|
657
|
-
"
|
|
728
|
+
"configVersion": 0n,
|
|
729
|
+
"hash": "0x636af84d8445d87cbcd33039d5a3a2274a5911036b1b7ceb740ac41e2f638611",
|
|
658
730
|
"signatureCount": 2,
|
|
659
731
|
"type": "0x76",
|
|
660
732
|
},
|
|
@@ -694,14 +766,14 @@ describe('serializeTransaction', () => {
|
|
|
694
766
|
signApproval(owners[0]!, hash),
|
|
695
767
|
signApproval(owners[1]!, hash),
|
|
696
768
|
],
|
|
697
|
-
config,
|
|
769
|
+
config: initializedConfig,
|
|
698
770
|
hash,
|
|
699
771
|
})
|
|
700
772
|
const serialized = MultisigOperation.serializeTransaction(
|
|
701
773
|
MultisigOperation.from({
|
|
702
774
|
account,
|
|
703
775
|
approvals: selection.approvals,
|
|
704
|
-
config,
|
|
776
|
+
config: initializedConfig,
|
|
705
777
|
configVersion: 1n,
|
|
706
778
|
createdAt: 1,
|
|
707
779
|
hash,
|
|
@@ -762,13 +834,13 @@ describe('serializeTransaction', () => {
|
|
|
762
834
|
const selection = await MultisigOperation.selectApprovals({
|
|
763
835
|
account,
|
|
764
836
|
approvals: [approval_1],
|
|
765
|
-
config,
|
|
837
|
+
config: initializedConfig,
|
|
766
838
|
hash,
|
|
767
839
|
})
|
|
768
840
|
const operation = MultisigOperation.from({
|
|
769
841
|
account,
|
|
770
842
|
approvals: selection.approvals,
|
|
771
|
-
config,
|
|
843
|
+
config: initializedConfig,
|
|
772
844
|
configVersion: 1n,
|
|
773
845
|
createdAt: 1,
|
|
774
846
|
hash,
|
|
@@ -833,6 +905,7 @@ describe('from', () => {
|
|
|
833
905
|
],
|
|
834
906
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
835
907
|
"threshold": 2,
|
|
908
|
+
"version": 1n,
|
|
836
909
|
},
|
|
837
910
|
"configVersion": 1n,
|
|
838
911
|
"createdAt": 1,
|
|
@@ -865,6 +938,7 @@ describe('from', () => {
|
|
|
865
938
|
],
|
|
866
939
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
867
940
|
"threshold": 2,
|
|
941
|
+
"version": 1n,
|
|
868
942
|
},
|
|
869
943
|
"configVersion": 1n,
|
|
870
944
|
"createdAt": 1,
|
|
@@ -899,6 +973,7 @@ describe('from', () => {
|
|
|
899
973
|
],
|
|
900
974
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
901
975
|
"threshold": 2,
|
|
976
|
+
"version": 1n,
|
|
902
977
|
},
|
|
903
978
|
"configVersion": 1n,
|
|
904
979
|
"createdAt": 1,
|
|
@@ -929,10 +1004,10 @@ describe('from', () => {
|
|
|
929
1004
|
...transactionPending,
|
|
930
1005
|
hash: MultisigConfig.getSignPayload({
|
|
931
1006
|
account,
|
|
1007
|
+
config: initializedConfig,
|
|
932
1008
|
payload: TxEnvelopeTempo.getSignPayload(
|
|
933
1009
|
TxEnvelopeTempo.deserialize(transaction),
|
|
934
1010
|
),
|
|
935
|
-
version: 1n,
|
|
936
1011
|
}),
|
|
937
1012
|
transaction,
|
|
938
1013
|
})
|
|
@@ -961,6 +1036,7 @@ describe('from', () => {
|
|
|
961
1036
|
],
|
|
962
1037
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
963
1038
|
"threshold": 2,
|
|
1039
|
+
"version": 1n,
|
|
964
1040
|
},
|
|
965
1041
|
"configVersion": 1n,
|
|
966
1042
|
"createdAt": 1,
|
|
@@ -991,10 +1067,10 @@ describe('from', () => {
|
|
|
991
1067
|
...transactionPending,
|
|
992
1068
|
hash: MultisigConfig.getSignPayload({
|
|
993
1069
|
account,
|
|
1070
|
+
config: initializedConfig,
|
|
994
1071
|
payload: TxEnvelopeTempo.getSignPayload(
|
|
995
1072
|
TxEnvelopeTempo.deserialize(transaction),
|
|
996
1073
|
),
|
|
997
|
-
version: 1n,
|
|
998
1074
|
}),
|
|
999
1075
|
transaction,
|
|
1000
1076
|
})
|
|
@@ -1005,13 +1081,14 @@ describe('from', () => {
|
|
|
1005
1081
|
test('bootstrap transaction', () => {
|
|
1006
1082
|
const operation = MultisigOperation.from({
|
|
1007
1083
|
...transactionPending,
|
|
1084
|
+
config,
|
|
1008
1085
|
configVersion: 0n,
|
|
1009
1086
|
hash: MultisigConfig.getSignPayload({
|
|
1010
1087
|
account,
|
|
1088
|
+
config,
|
|
1011
1089
|
payload: TxEnvelopeTempo.getSignPayload(
|
|
1012
1090
|
TxEnvelopeTempo.deserialize(transaction),
|
|
1013
1091
|
),
|
|
1014
|
-
version: 0n,
|
|
1015
1092
|
}),
|
|
1016
1093
|
init: true,
|
|
1017
1094
|
})
|
|
@@ -1040,6 +1117,7 @@ describe('from', () => {
|
|
|
1040
1117
|
],
|
|
1041
1118
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
1042
1119
|
"threshold": 2,
|
|
1120
|
+
"version": 0n,
|
|
1043
1121
|
},
|
|
1044
1122
|
"configVersion": 0n,
|
|
1045
1123
|
"createdAt": 1,
|
|
@@ -1060,13 +1138,14 @@ describe('from', () => {
|
|
|
1060
1138
|
test('initialized transaction at config version zero', () => {
|
|
1061
1139
|
const operation = MultisigOperation.from({
|
|
1062
1140
|
...transactionPending,
|
|
1141
|
+
config,
|
|
1063
1142
|
configVersion: 0n,
|
|
1064
1143
|
hash: MultisigConfig.getSignPayload({
|
|
1065
1144
|
account,
|
|
1145
|
+
config,
|
|
1066
1146
|
payload: TxEnvelopeTempo.getSignPayload(
|
|
1067
1147
|
TxEnvelopeTempo.deserialize(transaction),
|
|
1068
1148
|
),
|
|
1069
|
-
version: 0n,
|
|
1070
1149
|
}),
|
|
1071
1150
|
})
|
|
1072
1151
|
|
|
@@ -1091,6 +1170,7 @@ describe('from', () => {
|
|
|
1091
1170
|
KeyAuthorization.from(authorization, {
|
|
1092
1171
|
signature: {
|
|
1093
1172
|
account,
|
|
1173
|
+
config: initializedConfig,
|
|
1094
1174
|
signatures: [
|
|
1095
1175
|
SignatureEnvelope.deserialize(approval_1),
|
|
1096
1176
|
SignatureEnvelope.deserialize(approval_2),
|
|
@@ -1124,6 +1204,7 @@ describe('from', () => {
|
|
|
1124
1204
|
],
|
|
1125
1205
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
1126
1206
|
"threshold": 2,
|
|
1207
|
+
"version": 1n,
|
|
1127
1208
|
},
|
|
1128
1209
|
"configVersion": 1n,
|
|
1129
1210
|
"createdAt": 1,
|
|
@@ -1156,12 +1237,13 @@ describe('from', () => {
|
|
|
1156
1237
|
],
|
|
1157
1238
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
1158
1239
|
"threshold": 2,
|
|
1240
|
+
"version": 1n,
|
|
1159
1241
|
},
|
|
1160
1242
|
"configVersion": 1n,
|
|
1161
1243
|
"createdAt": 1,
|
|
1162
1244
|
"hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
|
|
1163
1245
|
"init": false,
|
|
1164
|
-
"keyAuthorization": "
|
|
1246
|
+
"keyAuthorization": "0xf901b3f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36eb9017805f9017494f81b7763d3a6876195d780865bd783dbd97dd36ef852a000000000000000000000000000000000000000000000000000000000000000000102eed69407e1ed8ea0e9601e5546b0a03aed683df360140701d694288f0cd85005f34168f731a468aef268c2f9456f01f90108b88201000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200b88201000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000047cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997807775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d100",
|
|
1165
1247
|
"signatureCount": 2,
|
|
1166
1248
|
"status": "success",
|
|
1167
1249
|
"threshold": 2,
|
|
@@ -1179,7 +1261,7 @@ describe('from', () => {
|
|
|
1179
1261
|
KeyAuthorization.from(authorization, {
|
|
1180
1262
|
signature: {
|
|
1181
1263
|
account,
|
|
1182
|
-
|
|
1264
|
+
config,
|
|
1183
1265
|
signatures: [
|
|
1184
1266
|
SignatureEnvelope.deserialize(approval_1),
|
|
1185
1267
|
SignatureEnvelope.deserialize(approval_2),
|
|
@@ -1191,11 +1273,12 @@ describe('from', () => {
|
|
|
1191
1273
|
const operation = MultisigOperation.from({
|
|
1192
1274
|
...keyAuthorizationPending,
|
|
1193
1275
|
approvals: [approval_1, approval_2],
|
|
1276
|
+
config,
|
|
1194
1277
|
configVersion: 0n,
|
|
1195
1278
|
hash: MultisigConfig.getSignPayload({
|
|
1196
1279
|
account,
|
|
1280
|
+
config,
|
|
1197
1281
|
payload: KeyAuthorization.getSignPayload(authorization),
|
|
1198
|
-
version: 0n,
|
|
1199
1282
|
}),
|
|
1200
1283
|
init: true,
|
|
1201
1284
|
keyAuthorization: keyAuthorization_,
|
|
@@ -1229,6 +1312,7 @@ describe('from', () => {
|
|
|
1229
1312
|
],
|
|
1230
1313
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
1231
1314
|
"threshold": 2,
|
|
1315
|
+
"version": 0n,
|
|
1232
1316
|
},
|
|
1233
1317
|
"configVersion": 0n,
|
|
1234
1318
|
"createdAt": 1,
|
|
@@ -1252,6 +1336,9 @@ describe('RPC conversion', () => {
|
|
|
1252
1336
|
const transactionRpc = MultisigOperation.toRpc(transactionPending)
|
|
1253
1337
|
const keyAuthorizationRpc = MultisigOperation.toRpc(keyAuthorizationPending)
|
|
1254
1338
|
|
|
1339
|
+
expect(() =>
|
|
1340
|
+
JSON.stringify({ keyAuthorizationRpc, transactionRpc }),
|
|
1341
|
+
).not.toThrow()
|
|
1255
1342
|
expect({ keyAuthorizationRpc, transactionRpc }).toMatchInlineSnapshot(`
|
|
1256
1343
|
{
|
|
1257
1344
|
"keyAuthorizationRpc": {
|
|
@@ -1272,6 +1359,7 @@ describe('RPC conversion', () => {
|
|
|
1272
1359
|
],
|
|
1273
1360
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
1274
1361
|
"threshold": 2,
|
|
1362
|
+
"version": "0x1",
|
|
1275
1363
|
},
|
|
1276
1364
|
"configVersion": "0x1",
|
|
1277
1365
|
"createdAt": 1,
|
|
@@ -1303,6 +1391,7 @@ describe('RPC conversion', () => {
|
|
|
1303
1391
|
],
|
|
1304
1392
|
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
1305
1393
|
"threshold": 2,
|
|
1394
|
+
"version": "0x1",
|
|
1306
1395
|
},
|
|
1307
1396
|
"configVersion": "0x1",
|
|
1308
1397
|
"createdAt": 1,
|
|
@@ -1440,10 +1529,10 @@ describe('validation', () => {
|
|
|
1440
1529
|
account: '0x0000000000000000000000000000000000000000',
|
|
1441
1530
|
hash: MultisigConfig.getSignPayload({
|
|
1442
1531
|
account: '0x0000000000000000000000000000000000000000',
|
|
1532
|
+
config: initializedConfig,
|
|
1443
1533
|
payload: TxEnvelopeTempo.getSignPayload(
|
|
1444
1534
|
TxEnvelopeTempo.deserialize(transaction),
|
|
1445
1535
|
),
|
|
1446
|
-
version: 1n,
|
|
1447
1536
|
}),
|
|
1448
1537
|
},
|
|
1449
1538
|
},
|
|
@@ -1513,7 +1602,7 @@ describe('validation', () => {
|
|
|
1513
1602
|
approvals: [
|
|
1514
1603
|
SignatureEnvelope.serialize({
|
|
1515
1604
|
account,
|
|
1516
|
-
|
|
1605
|
+
config,
|
|
1517
1606
|
signatures: [ownerSignature_1],
|
|
1518
1607
|
type: 'multisig',
|
|
1519
1608
|
}),
|
|
@@ -1530,6 +1619,17 @@ describe('validation', () => {
|
|
|
1530
1619
|
).toThrowError(MultisigOperation.InvalidOperationError)
|
|
1531
1620
|
})
|
|
1532
1621
|
|
|
1622
|
+
test('rejects mismatched config versions', () => {
|
|
1623
|
+
expect(() =>
|
|
1624
|
+
MultisigOperation.from({
|
|
1625
|
+
...transactionPending,
|
|
1626
|
+
config: { ...initializedConfig, version: 2n },
|
|
1627
|
+
}),
|
|
1628
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
1629
|
+
`[MultisigOperation.InvalidOperationError: Invalid multisig operation: config.version must equal configVersion.]`,
|
|
1630
|
+
)
|
|
1631
|
+
})
|
|
1632
|
+
|
|
1533
1633
|
test('rejects noncanonical RPC quantities', () => {
|
|
1534
1634
|
expect(() =>
|
|
1535
1635
|
MultisigOperation.fromRpc({
|
|
@@ -1550,6 +1650,7 @@ describe('validation', () => {
|
|
|
1550
1650
|
KeyAuthorization.from(authorization, {
|
|
1551
1651
|
signature: {
|
|
1552
1652
|
account,
|
|
1653
|
+
config: initializedConfig,
|
|
1553
1654
|
signatures: [
|
|
1554
1655
|
SignatureEnvelope.deserialize(approval_1),
|
|
1555
1656
|
SignatureEnvelope.deserialize(approval_3),
|
|
@@ -1573,12 +1674,12 @@ describe('validation', () => {
|
|
|
1573
1674
|
const signatures = [
|
|
1574
1675
|
...SignatureEnvelope.sortMultisigApprovals({
|
|
1575
1676
|
account,
|
|
1677
|
+
config: initializedConfig,
|
|
1576
1678
|
payload: KeyAuthorization.getSignPayload(authorization),
|
|
1577
1679
|
signatures: [
|
|
1578
1680
|
SignatureEnvelope.deserialize(approval_1),
|
|
1579
1681
|
SignatureEnvelope.deserialize(approval_2),
|
|
1580
1682
|
],
|
|
1581
|
-
version: 1n,
|
|
1582
1683
|
}),
|
|
1583
1684
|
].reverse()
|
|
1584
1685
|
const operation = {
|
|
@@ -1586,7 +1687,12 @@ describe('validation', () => {
|
|
|
1586
1687
|
approvals: [approval_1, approval_2],
|
|
1587
1688
|
keyAuthorization: KeyAuthorization.serialize(
|
|
1588
1689
|
KeyAuthorization.from(authorization, {
|
|
1589
|
-
signature: {
|
|
1690
|
+
signature: {
|
|
1691
|
+
account,
|
|
1692
|
+
config: initializedConfig,
|
|
1693
|
+
signatures,
|
|
1694
|
+
type: 'multisig',
|
|
1695
|
+
},
|
|
1590
1696
|
}),
|
|
1591
1697
|
),
|
|
1592
1698
|
signatureCount: 2,
|
|
@@ -1608,6 +1714,7 @@ describe('validation', () => {
|
|
|
1608
1714
|
KeyAuthorization.from(authorization, {
|
|
1609
1715
|
signature: {
|
|
1610
1716
|
account,
|
|
1717
|
+
config: initializedConfig,
|
|
1611
1718
|
signatures: [
|
|
1612
1719
|
SignatureEnvelope.deserialize(approval_1),
|
|
1613
1720
|
SignatureEnvelope.deserialize(approval_1),
|
|
@@ -1628,37 +1735,49 @@ describe('validation', () => {
|
|
|
1628
1735
|
|
|
1629
1736
|
test('rejects reordered nested key authorization approvals', () => {
|
|
1630
1737
|
const authorization = KeyAuthorization.deserialize(keyAuthorization)
|
|
1738
|
+
const nestedConfig = MultisigConfig.from({
|
|
1739
|
+
owners: [{ owner: owner_2, weight: 1 }],
|
|
1740
|
+
threshold: 1,
|
|
1741
|
+
version: 1n,
|
|
1742
|
+
})
|
|
1631
1743
|
const childSignatures = SignatureEnvelope.sortMultisigApprovals({
|
|
1632
1744
|
account: owner_1,
|
|
1745
|
+
config: nestedConfig,
|
|
1633
1746
|
payload: keyAuthorizationHash,
|
|
1634
1747
|
signatures: [
|
|
1635
1748
|
SignatureEnvelope.deserialize(approval_1),
|
|
1636
1749
|
SignatureEnvelope.deserialize(approval_2),
|
|
1637
1750
|
],
|
|
1638
|
-
version: 1n,
|
|
1639
1751
|
})
|
|
1640
1752
|
const retainedNested = SignatureEnvelope.from({
|
|
1641
1753
|
account: owner_1,
|
|
1754
|
+
config: nestedConfig,
|
|
1642
1755
|
signatures: childSignatures,
|
|
1643
1756
|
type: 'multisig',
|
|
1644
1757
|
})
|
|
1645
1758
|
const selectedNested = SignatureEnvelope.from({
|
|
1646
1759
|
account: owner_1,
|
|
1760
|
+
config: nestedConfig,
|
|
1647
1761
|
signatures: [...childSignatures].reverse(),
|
|
1648
1762
|
type: 'multisig',
|
|
1649
1763
|
})
|
|
1650
1764
|
const selected = SignatureEnvelope.sortMultisigApprovals({
|
|
1651
1765
|
account,
|
|
1766
|
+
config: initializedConfig,
|
|
1652
1767
|
payload: KeyAuthorization.getSignPayload(authorization),
|
|
1653
1768
|
signatures: [selectedNested, SignatureEnvelope.deserialize(approval_2)],
|
|
1654
|
-
version: 1n,
|
|
1655
1769
|
})
|
|
1656
1770
|
const operation = {
|
|
1657
1771
|
...keyAuthorizationPending,
|
|
1658
1772
|
approvals: [SignatureEnvelope.serialize(retainedNested), approval_2],
|
|
1659
1773
|
keyAuthorization: KeyAuthorization.serialize(
|
|
1660
1774
|
KeyAuthorization.from(authorization, {
|
|
1661
|
-
signature: {
|
|
1775
|
+
signature: {
|
|
1776
|
+
account,
|
|
1777
|
+
config: initializedConfig,
|
|
1778
|
+
signatures: selected,
|
|
1779
|
+
type: 'multisig',
|
|
1780
|
+
},
|
|
1662
1781
|
}),
|
|
1663
1782
|
),
|
|
1664
1783
|
signatureCount: 2,
|
|
@@ -1697,12 +1816,12 @@ describe('validation', () => {
|
|
|
1697
1816
|
})
|
|
1698
1817
|
const signatures = SignatureEnvelope.sortMultisigApprovals({
|
|
1699
1818
|
account,
|
|
1819
|
+
config,
|
|
1700
1820
|
payload: KeyAuthorization.getSignPayload(authorization),
|
|
1701
1821
|
signatures: [
|
|
1702
1822
|
SignatureEnvelope.deserialize(approval_1),
|
|
1703
1823
|
SignatureEnvelope.deserialize(approval_2),
|
|
1704
1824
|
],
|
|
1705
|
-
version: 0n,
|
|
1706
1825
|
})
|
|
1707
1826
|
const approvals = signatures.map((signature) =>
|
|
1708
1827
|
SignatureEnvelope.serialize(signature),
|
|
@@ -1716,15 +1835,15 @@ describe('validation', () => {
|
|
|
1716
1835
|
createdAt: 1,
|
|
1717
1836
|
hash: MultisigConfig.getSignPayload({
|
|
1718
1837
|
account,
|
|
1838
|
+
config,
|
|
1719
1839
|
payload: KeyAuthorization.getSignPayload(authorization),
|
|
1720
|
-
version: 0n,
|
|
1721
1840
|
}),
|
|
1722
1841
|
init: true,
|
|
1723
1842
|
keyAuthorization: KeyAuthorization.serialize(
|
|
1724
1843
|
KeyAuthorization.from(authorization, {
|
|
1725
1844
|
signature: {
|
|
1726
1845
|
account,
|
|
1727
|
-
|
|
1846
|
+
config,
|
|
1728
1847
|
signatures,
|
|
1729
1848
|
type: 'multisig',
|
|
1730
1849
|
},
|