ox 0.14.39 → 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.
- package/CHANGELOG.md +12 -0
- package/_cjs/tempo/MultisigOperation.js +30 -45
- 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 +5 -2
- 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/MultisigOperation.js +31 -48
- 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 +5 -2
- 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/MultisigOperation.d.ts +4 -25
- 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 +3 -3
- 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 +16 -1
- package/tempo/KeyAuthorization.test-d.ts +1 -1
- package/tempo/MultisigOperation.test-d.ts +0 -6
- package/tempo/MultisigOperation.test.ts +196 -145
- package/tempo/MultisigOperation.ts +40 -83
- 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 +4 -4
- package/tempo/SignatureEnvelope.test.ts +2 -2
- package/tempo/SignatureEnvelope.ts +9 -5
- 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/version.ts +1 -1
|
@@ -36,7 +36,7 @@ const config = MultisigConfig.from({
|
|
|
36
36
|
],
|
|
37
37
|
threshold: 2,
|
|
38
38
|
})
|
|
39
|
-
const
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
140
|
+
config: currentConfig,
|
|
143
141
|
keyAuthorization,
|
|
144
142
|
type: 'keyAuthorization',
|
|
145
143
|
}),
|
|
146
144
|
transaction: MultisigOperation.getHash({
|
|
147
145
|
account,
|
|
148
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,12 +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 { config: childConfig, version: 2n }
|
|
266
|
-
}
|
|
267
259
|
const partial = await MultisigOperation.selectApprovals({
|
|
268
260
|
account,
|
|
269
261
|
approvals: [
|
|
@@ -277,7 +269,6 @@ describe('selectApprovals', () => {
|
|
|
277
269
|
],
|
|
278
270
|
config,
|
|
279
271
|
hash,
|
|
280
|
-
resolveConfig,
|
|
281
272
|
})
|
|
282
273
|
const complete = await MultisigOperation.selectApprovals({
|
|
283
274
|
account,
|
|
@@ -294,7 +285,6 @@ describe('selectApprovals', () => {
|
|
|
294
285
|
],
|
|
295
286
|
config,
|
|
296
287
|
hash,
|
|
297
|
-
resolveConfig,
|
|
298
288
|
})
|
|
299
289
|
|
|
300
290
|
expect({
|
|
@@ -338,10 +328,95 @@ describe('selectApprovals', () => {
|
|
|
338
328
|
`)
|
|
339
329
|
})
|
|
340
330
|
|
|
331
|
+
test('rejects conflicting nested config witnesses', async () => {
|
|
332
|
+
const childConfig = MultisigConfig.from({
|
|
333
|
+
owners: [{ owner: owners[1]!.address, weight: 1 }],
|
|
334
|
+
threshold: 1,
|
|
335
|
+
})
|
|
336
|
+
const child = MultisigConfig.getAddress(childConfig)
|
|
337
|
+
const config = MultisigConfig.from({
|
|
338
|
+
owners: [{ owner: child, weight: 1 }],
|
|
339
|
+
threshold: 1,
|
|
340
|
+
})
|
|
341
|
+
const account = MultisigConfig.getAddress(config)
|
|
342
|
+
const hash = MultisigOperation.getHash({
|
|
343
|
+
account,
|
|
344
|
+
config: { ...config, version: 1n },
|
|
345
|
+
transaction,
|
|
346
|
+
type: 'transaction',
|
|
347
|
+
})
|
|
348
|
+
const config_2 = MultisigConfig.from({
|
|
349
|
+
...childConfig,
|
|
350
|
+
version: 2n,
|
|
351
|
+
})
|
|
352
|
+
const config_3 = MultisigConfig.from({
|
|
353
|
+
...childConfig,
|
|
354
|
+
version: 3n,
|
|
355
|
+
})
|
|
356
|
+
const childHash_2 = MultisigConfig.getSignPayload({
|
|
357
|
+
account: child,
|
|
358
|
+
config: config_2,
|
|
359
|
+
payload: hash,
|
|
360
|
+
})
|
|
361
|
+
const childHash_3 = MultisigConfig.getSignPayload({
|
|
362
|
+
account: child,
|
|
363
|
+
config: config_3,
|
|
364
|
+
payload: hash,
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
await expect(
|
|
368
|
+
MultisigOperation.selectApprovals({
|
|
369
|
+
account,
|
|
370
|
+
approvals: [
|
|
371
|
+
SignatureEnvelope.serialize({
|
|
372
|
+
account: child,
|
|
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,
|
|
384
|
+
signatures: [
|
|
385
|
+
SignatureEnvelope.deserialize(
|
|
386
|
+
signApproval(owners[1]!, childHash_3),
|
|
387
|
+
),
|
|
388
|
+
],
|
|
389
|
+
type: 'multisig',
|
|
390
|
+
}),
|
|
391
|
+
],
|
|
392
|
+
config,
|
|
393
|
+
hash,
|
|
394
|
+
}),
|
|
395
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
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.]`,
|
|
413
|
+
)
|
|
414
|
+
})
|
|
415
|
+
|
|
341
416
|
test('rejects invalid and non-owner approvals', async () => {
|
|
342
417
|
const hash = MultisigOperation.getHash({
|
|
343
418
|
account,
|
|
344
|
-
|
|
419
|
+
config: currentConfig,
|
|
345
420
|
transaction,
|
|
346
421
|
type: 'transaction',
|
|
347
422
|
})
|
|
@@ -373,7 +448,7 @@ describe('selectApprovals', () => {
|
|
|
373
448
|
)
|
|
374
449
|
})
|
|
375
450
|
|
|
376
|
-
test('
|
|
451
|
+
test('reads current nested config witnesses from approvals', async () => {
|
|
377
452
|
const childConfig = MultisigConfig.from({
|
|
378
453
|
owners: [{ owner: owners[1]!.address, weight: 1 }],
|
|
379
454
|
threshold: 1,
|
|
@@ -386,36 +461,49 @@ describe('selectApprovals', () => {
|
|
|
386
461
|
const account = MultisigConfig.getAddress(config)
|
|
387
462
|
const hash = MultisigOperation.getHash({
|
|
388
463
|
account,
|
|
389
|
-
|
|
464
|
+
config: { ...config, version: 1n },
|
|
390
465
|
transaction,
|
|
391
466
|
type: 'transaction',
|
|
392
467
|
})
|
|
393
468
|
const childHash = MultisigConfig.getSignPayload({
|
|
394
469
|
account: child,
|
|
395
|
-
config: { version: 1n },
|
|
470
|
+
config: { ...childConfig, version: 1n },
|
|
396
471
|
payload: hash,
|
|
397
472
|
})
|
|
398
473
|
|
|
399
|
-
await
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
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>,
|
|
413
498
|
],
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
499
|
+
"selectedApprovals": [
|
|
500
|
+
Any<String>,
|
|
501
|
+
],
|
|
502
|
+
"signatureCount": 1,
|
|
503
|
+
"threshold": 1,
|
|
504
|
+
"weight": 1,
|
|
505
|
+
}
|
|
506
|
+
`,
|
|
419
507
|
)
|
|
420
508
|
})
|
|
421
509
|
|
|
@@ -435,7 +523,7 @@ describe('selectApprovals', () => {
|
|
|
435
523
|
const account = MultisigConfig.getAddress(config)
|
|
436
524
|
const hash = MultisigOperation.getHash({
|
|
437
525
|
account,
|
|
438
|
-
|
|
526
|
+
config: { ...config, version: 1n },
|
|
439
527
|
transaction,
|
|
440
528
|
type: 'transaction',
|
|
441
529
|
})
|
|
@@ -477,7 +565,6 @@ describe('selectApprovals', () => {
|
|
|
477
565
|
],
|
|
478
566
|
config,
|
|
479
567
|
hash,
|
|
480
|
-
resolveConfig: () => ({ config: childConfig, version: 0n }),
|
|
481
568
|
})
|
|
482
569
|
expect({
|
|
483
570
|
signatureCount: selection.signatureCount,
|
|
@@ -499,7 +586,7 @@ describe('selectApprovals', () => {
|
|
|
499
586
|
})
|
|
500
587
|
const hash = MultisigOperation.getHash({
|
|
501
588
|
account,
|
|
502
|
-
|
|
589
|
+
config: { ...config, version: 2n },
|
|
503
590
|
transaction,
|
|
504
591
|
type: 'transaction',
|
|
505
592
|
})
|
|
@@ -541,18 +628,18 @@ describe('selectApprovals', () => {
|
|
|
541
628
|
const account = MultisigConfig.getAddress(config)
|
|
542
629
|
const hash = MultisigOperation.getHash({
|
|
543
630
|
account,
|
|
544
|
-
|
|
631
|
+
config: { ...config, version: 1n },
|
|
545
632
|
transaction,
|
|
546
633
|
type: 'transaction',
|
|
547
634
|
})
|
|
548
635
|
const childHash = MultisigConfig.getSignPayload({
|
|
549
636
|
account: child,
|
|
550
|
-
config: { version: 1n },
|
|
637
|
+
config: { ...childConfig, version: 1n },
|
|
551
638
|
payload: hash,
|
|
552
639
|
})
|
|
553
640
|
const grandchildHash = MultisigConfig.getSignPayload({
|
|
554
641
|
account: grandchild,
|
|
555
|
-
config: { version: 1n },
|
|
642
|
+
config: { ...grandchildConfig, version: 1n },
|
|
556
643
|
payload: childHash,
|
|
557
644
|
})
|
|
558
645
|
|
|
@@ -583,11 +670,6 @@ describe('selectApprovals', () => {
|
|
|
583
670
|
],
|
|
584
671
|
config,
|
|
585
672
|
hash,
|
|
586
|
-
resolveConfig: ({ account }) => {
|
|
587
|
-
if (Address.isEqual(account, child))
|
|
588
|
-
return { config: childConfig, version: 1n }
|
|
589
|
-
return { config: grandchildConfig, version: 1n }
|
|
590
|
-
},
|
|
591
673
|
}),
|
|
592
674
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
593
675
|
`[MultisigOperation.InvalidApprovalError: Invalid multisig approval: nested multisig owner 0xf529c8f6b2b4c72102af4cfe5eeb55b7d45dede2 is invalid.]`,
|
|
@@ -596,13 +678,12 @@ describe('selectApprovals', () => {
|
|
|
596
678
|
})
|
|
597
679
|
|
|
598
680
|
describe('serializeTransaction', () => {
|
|
599
|
-
test('
|
|
681
|
+
test('current and initial transactions', async () => {
|
|
600
682
|
const results = []
|
|
601
|
-
for (const
|
|
602
|
-
const configVersion = init ? 0n : 1n
|
|
683
|
+
for (const applicableConfig of [currentConfig, config]) {
|
|
603
684
|
const hash = MultisigOperation.getHash({
|
|
604
685
|
account,
|
|
605
|
-
|
|
686
|
+
config: applicableConfig,
|
|
606
687
|
transaction,
|
|
607
688
|
type: 'transaction',
|
|
608
689
|
})
|
|
@@ -612,17 +693,15 @@ describe('serializeTransaction', () => {
|
|
|
612
693
|
signApproval(owners[1]!, hash),
|
|
613
694
|
signApproval(owners[0]!, hash),
|
|
614
695
|
],
|
|
615
|
-
config,
|
|
696
|
+
config: applicableConfig,
|
|
616
697
|
hash,
|
|
617
698
|
})
|
|
618
699
|
const operation = MultisigOperation.from({
|
|
619
700
|
account,
|
|
620
701
|
approvals: selection.approvals,
|
|
621
|
-
config,
|
|
622
|
-
configVersion,
|
|
702
|
+
config: applicableConfig,
|
|
623
703
|
createdAt: 1,
|
|
624
704
|
hash,
|
|
625
|
-
init,
|
|
626
705
|
signatureCount: selection.signatureCount,
|
|
627
706
|
status: 'pending',
|
|
628
707
|
threshold: selection.threshold,
|
|
@@ -637,7 +716,7 @@ describe('serializeTransaction', () => {
|
|
|
637
716
|
const value = TxEnvelopeTempo.deserialize(serialized)
|
|
638
717
|
results.push({
|
|
639
718
|
account: value.signature?.account,
|
|
640
|
-
|
|
719
|
+
version:
|
|
641
720
|
value.signature?.type === 'multisig'
|
|
642
721
|
? value.signature.config.version
|
|
643
722
|
: undefined,
|
|
@@ -654,17 +733,17 @@ describe('serializeTransaction', () => {
|
|
|
654
733
|
[
|
|
655
734
|
{
|
|
656
735
|
"account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
|
|
657
|
-
"configVersion": 1n,
|
|
658
736
|
"hash": "0x8309740edaf304284186f7bcfe4527745cd4eb48e7441795ebdd970798091f8f",
|
|
659
737
|
"signatureCount": 2,
|
|
660
738
|
"type": "0x76",
|
|
739
|
+
"version": 1n,
|
|
661
740
|
},
|
|
662
741
|
{
|
|
663
742
|
"account": "0xf81b7763d3a6876195d780865bd783dbd97dd36e",
|
|
664
|
-
"configVersion": 0n,
|
|
665
743
|
"hash": "0x636af84d8445d87cbcd33039d5a3a2274a5911036b1b7ceb740ac41e2f638611",
|
|
666
744
|
"signatureCount": 2,
|
|
667
745
|
"type": "0x76",
|
|
746
|
+
"version": 0n,
|
|
668
747
|
},
|
|
669
748
|
]
|
|
670
749
|
`)
|
|
@@ -692,7 +771,7 @@ describe('serializeTransaction', () => {
|
|
|
692
771
|
for (const transaction of transactions) {
|
|
693
772
|
const hash = MultisigOperation.getHash({
|
|
694
773
|
account,
|
|
695
|
-
|
|
774
|
+
config: currentConfig,
|
|
696
775
|
transaction,
|
|
697
776
|
type: 'transaction',
|
|
698
777
|
})
|
|
@@ -702,18 +781,16 @@ describe('serializeTransaction', () => {
|
|
|
702
781
|
signApproval(owners[0]!, hash),
|
|
703
782
|
signApproval(owners[1]!, hash),
|
|
704
783
|
],
|
|
705
|
-
config,
|
|
784
|
+
config: currentConfig,
|
|
706
785
|
hash,
|
|
707
786
|
})
|
|
708
787
|
const serialized = MultisigOperation.serializeTransaction(
|
|
709
788
|
MultisigOperation.from({
|
|
710
789
|
account,
|
|
711
790
|
approvals: selection.approvals,
|
|
712
|
-
config,
|
|
713
|
-
configVersion: 1n,
|
|
791
|
+
config: currentConfig,
|
|
714
792
|
createdAt: 1,
|
|
715
793
|
hash,
|
|
716
|
-
init: false,
|
|
717
794
|
signatureCount: selection.signatureCount,
|
|
718
795
|
status: 'pending',
|
|
719
796
|
threshold: selection.threshold,
|
|
@@ -761,7 +838,7 @@ describe('serializeTransaction', () => {
|
|
|
761
838
|
test('rejects an approval not retained by the operation', async () => {
|
|
762
839
|
const hash = MultisigOperation.getHash({
|
|
763
840
|
account,
|
|
764
|
-
|
|
841
|
+
config: currentConfig,
|
|
765
842
|
transaction,
|
|
766
843
|
type: 'transaction',
|
|
767
844
|
})
|
|
@@ -770,17 +847,15 @@ describe('serializeTransaction', () => {
|
|
|
770
847
|
const selection = await MultisigOperation.selectApprovals({
|
|
771
848
|
account,
|
|
772
849
|
approvals: [approval_1],
|
|
773
|
-
config,
|
|
850
|
+
config: currentConfig,
|
|
774
851
|
hash,
|
|
775
852
|
})
|
|
776
853
|
const operation = MultisigOperation.from({
|
|
777
854
|
account,
|
|
778
855
|
approvals: selection.approvals,
|
|
779
|
-
config,
|
|
780
|
-
configVersion: 1n,
|
|
856
|
+
config: currentConfig,
|
|
781
857
|
createdAt: 1,
|
|
782
858
|
hash,
|
|
783
|
-
init: false,
|
|
784
859
|
signatureCount: selection.signatureCount,
|
|
785
860
|
status: 'pending',
|
|
786
861
|
threshold: selection.threshold,
|
|
@@ -843,10 +918,8 @@ describe('from', () => {
|
|
|
843
918
|
"threshold": 2,
|
|
844
919
|
"version": 1n,
|
|
845
920
|
},
|
|
846
|
-
"configVersion": 1n,
|
|
847
921
|
"createdAt": 1,
|
|
848
922
|
"hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
|
|
849
|
-
"init": false,
|
|
850
923
|
"signatureCount": 1,
|
|
851
924
|
"status": "pending",
|
|
852
925
|
"threshold": 2,
|
|
@@ -876,11 +949,9 @@ describe('from', () => {
|
|
|
876
949
|
"threshold": 2,
|
|
877
950
|
"version": 1n,
|
|
878
951
|
},
|
|
879
|
-
"configVersion": 1n,
|
|
880
952
|
"createdAt": 1,
|
|
881
953
|
"expiresAt": 10,
|
|
882
954
|
"hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
|
|
883
|
-
"init": false,
|
|
884
955
|
"signatureCount": 2,
|
|
885
956
|
"status": "submitting",
|
|
886
957
|
"submissionId": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
@@ -911,10 +982,8 @@ describe('from', () => {
|
|
|
911
982
|
"threshold": 2,
|
|
912
983
|
"version": 1n,
|
|
913
984
|
},
|
|
914
|
-
"configVersion": 1n,
|
|
915
985
|
"createdAt": 1,
|
|
916
986
|
"hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
|
|
917
|
-
"init": false,
|
|
918
987
|
"signatureCount": 2,
|
|
919
988
|
"status": "success",
|
|
920
989
|
"threshold": 2,
|
|
@@ -940,7 +1009,7 @@ describe('from', () => {
|
|
|
940
1009
|
...transactionPending,
|
|
941
1010
|
hash: MultisigConfig.getSignPayload({
|
|
942
1011
|
account,
|
|
943
|
-
config:
|
|
1012
|
+
config: currentConfig,
|
|
944
1013
|
payload: TxEnvelopeTempo.getSignPayload(
|
|
945
1014
|
TxEnvelopeTempo.deserialize(transaction),
|
|
946
1015
|
),
|
|
@@ -974,10 +1043,8 @@ describe('from', () => {
|
|
|
974
1043
|
"threshold": 2,
|
|
975
1044
|
"version": 1n,
|
|
976
1045
|
},
|
|
977
|
-
"configVersion": 1n,
|
|
978
1046
|
"createdAt": 1,
|
|
979
1047
|
"hash": Any<String>,
|
|
980
|
-
"init": false,
|
|
981
1048
|
"signatureCount": 1,
|
|
982
1049
|
"status": "pending",
|
|
983
1050
|
"threshold": 2,
|
|
@@ -1003,7 +1070,7 @@ describe('from', () => {
|
|
|
1003
1070
|
...transactionPending,
|
|
1004
1071
|
hash: MultisigConfig.getSignPayload({
|
|
1005
1072
|
account,
|
|
1006
|
-
config:
|
|
1073
|
+
config: currentConfig,
|
|
1007
1074
|
payload: TxEnvelopeTempo.getSignPayload(
|
|
1008
1075
|
TxEnvelopeTempo.deserialize(transaction),
|
|
1009
1076
|
),
|
|
@@ -1014,10 +1081,10 @@ describe('from', () => {
|
|
|
1014
1081
|
expect(operation.transaction).toBe(transaction)
|
|
1015
1082
|
})
|
|
1016
1083
|
|
|
1017
|
-
test('
|
|
1084
|
+
test('initial transaction', () => {
|
|
1018
1085
|
const operation = MultisigOperation.from({
|
|
1019
1086
|
...transactionPending,
|
|
1020
|
-
|
|
1087
|
+
config,
|
|
1021
1088
|
hash: MultisigConfig.getSignPayload({
|
|
1022
1089
|
account,
|
|
1023
1090
|
config,
|
|
@@ -1025,7 +1092,6 @@ describe('from', () => {
|
|
|
1025
1092
|
TxEnvelopeTempo.deserialize(transaction),
|
|
1026
1093
|
),
|
|
1027
1094
|
}),
|
|
1028
|
-
init: true,
|
|
1029
1095
|
})
|
|
1030
1096
|
|
|
1031
1097
|
expect(operation).toMatchInlineSnapshot(
|
|
@@ -1054,10 +1120,8 @@ describe('from', () => {
|
|
|
1054
1120
|
"threshold": 2,
|
|
1055
1121
|
"version": 0n,
|
|
1056
1122
|
},
|
|
1057
|
-
"configVersion": 0n,
|
|
1058
1123
|
"createdAt": 1,
|
|
1059
1124
|
"hash": Any<String>,
|
|
1060
|
-
"init": true,
|
|
1061
1125
|
"signatureCount": 1,
|
|
1062
1126
|
"status": "pending",
|
|
1063
1127
|
"threshold": 2,
|
|
@@ -1070,30 +1134,6 @@ describe('from', () => {
|
|
|
1070
1134
|
)
|
|
1071
1135
|
})
|
|
1072
1136
|
|
|
1073
|
-
test('initialized transaction at config version zero', () => {
|
|
1074
|
-
const operation = MultisigOperation.from({
|
|
1075
|
-
...transactionPending,
|
|
1076
|
-
configVersion: 0n,
|
|
1077
|
-
hash: MultisigConfig.getSignPayload({
|
|
1078
|
-
account,
|
|
1079
|
-
config,
|
|
1080
|
-
payload: TxEnvelopeTempo.getSignPayload(
|
|
1081
|
-
TxEnvelopeTempo.deserialize(transaction),
|
|
1082
|
-
),
|
|
1083
|
-
}),
|
|
1084
|
-
})
|
|
1085
|
-
|
|
1086
|
-
expect({
|
|
1087
|
-
configVersion: operation.configVersion,
|
|
1088
|
-
init: operation.init,
|
|
1089
|
-
}).toMatchInlineSnapshot(`
|
|
1090
|
-
{
|
|
1091
|
-
"configVersion": 0n,
|
|
1092
|
-
"init": false,
|
|
1093
|
-
}
|
|
1094
|
-
`)
|
|
1095
|
-
})
|
|
1096
|
-
|
|
1097
1137
|
test('key authorization states', () => {
|
|
1098
1138
|
const pending = MultisigOperation.from(keyAuthorizationPending)
|
|
1099
1139
|
const authorization = KeyAuthorization.deserialize(keyAuthorization)
|
|
@@ -1104,7 +1144,7 @@ describe('from', () => {
|
|
|
1104
1144
|
KeyAuthorization.from(authorization, {
|
|
1105
1145
|
signature: {
|
|
1106
1146
|
account,
|
|
1107
|
-
config:
|
|
1147
|
+
config: currentConfig,
|
|
1108
1148
|
signatures: [
|
|
1109
1149
|
SignatureEnvelope.deserialize(approval_1),
|
|
1110
1150
|
SignatureEnvelope.deserialize(approval_2),
|
|
@@ -1140,10 +1180,8 @@ describe('from', () => {
|
|
|
1140
1180
|
"threshold": 2,
|
|
1141
1181
|
"version": 1n,
|
|
1142
1182
|
},
|
|
1143
|
-
"configVersion": 1n,
|
|
1144
1183
|
"createdAt": 1,
|
|
1145
1184
|
"hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
|
|
1146
|
-
"init": false,
|
|
1147
1185
|
"keyAuthorization": "0xf838f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36e",
|
|
1148
1186
|
"signatureCount": 1,
|
|
1149
1187
|
"status": "pending",
|
|
@@ -1173,10 +1211,8 @@ describe('from', () => {
|
|
|
1173
1211
|
"threshold": 2,
|
|
1174
1212
|
"version": 1n,
|
|
1175
1213
|
},
|
|
1176
|
-
"configVersion": 1n,
|
|
1177
1214
|
"createdAt": 1,
|
|
1178
1215
|
"hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
|
|
1179
|
-
"init": false,
|
|
1180
1216
|
"keyAuthorization": "0xf901b3f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36eb9017805f9017494f81b7763d3a6876195d780865bd783dbd97dd36ef852a000000000000000000000000000000000000000000000000000000000000000000102eed69407e1ed8ea0e9601e5546b0a03aed683df360140701d694288f0cd85005f34168f731a468aef268c2f9456f01f90108b88201000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000065ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d503200b88201000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000047cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc4766997807775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d100",
|
|
1181
1217
|
"signatureCount": 2,
|
|
1182
1218
|
"status": "success",
|
|
@@ -1189,7 +1225,7 @@ describe('from', () => {
|
|
|
1189
1225
|
`)
|
|
1190
1226
|
})
|
|
1191
1227
|
|
|
1192
|
-
test('
|
|
1228
|
+
test('initial key authorization', () => {
|
|
1193
1229
|
const authorization = KeyAuthorization.deserialize(keyAuthorization)
|
|
1194
1230
|
const keyAuthorization_ = KeyAuthorization.serialize(
|
|
1195
1231
|
KeyAuthorization.from(authorization, {
|
|
@@ -1207,13 +1243,12 @@ describe('from', () => {
|
|
|
1207
1243
|
const operation = MultisigOperation.from({
|
|
1208
1244
|
...keyAuthorizationPending,
|
|
1209
1245
|
approvals: [approval_1, approval_2],
|
|
1210
|
-
|
|
1246
|
+
config,
|
|
1211
1247
|
hash: MultisigConfig.getSignPayload({
|
|
1212
1248
|
account,
|
|
1213
1249
|
config,
|
|
1214
1250
|
payload: KeyAuthorization.getSignPayload(authorization),
|
|
1215
1251
|
}),
|
|
1216
|
-
init: true,
|
|
1217
1252
|
keyAuthorization: keyAuthorization_,
|
|
1218
1253
|
signatureCount: 2,
|
|
1219
1254
|
status: 'success',
|
|
@@ -1247,10 +1282,8 @@ describe('from', () => {
|
|
|
1247
1282
|
"threshold": 2,
|
|
1248
1283
|
"version": 0n,
|
|
1249
1284
|
},
|
|
1250
|
-
"configVersion": 0n,
|
|
1251
1285
|
"createdAt": 1,
|
|
1252
1286
|
"hash": Any<String>,
|
|
1253
|
-
"init": true,
|
|
1254
1287
|
"keyAuthorization": Any<String>,
|
|
1255
1288
|
"signatureCount": 2,
|
|
1256
1289
|
"status": "success",
|
|
@@ -1294,10 +1327,8 @@ describe('RPC conversion', () => {
|
|
|
1294
1327
|
"threshold": 2,
|
|
1295
1328
|
"version": "0x1",
|
|
1296
1329
|
},
|
|
1297
|
-
"configVersion": "0x1",
|
|
1298
1330
|
"createdAt": 1,
|
|
1299
1331
|
"hash": "0xf6995eb69c12c03d3d13b357abf7cac22b4effe52fba8ff02e5aef26161f77a0",
|
|
1300
|
-
"init": false,
|
|
1301
1332
|
"keyAuthorization": "0xf838f782107980943333333333333333333333333333333333333333846b49d2008080808094f81b7763d3a6876195d780865bd783dbd97dd36e",
|
|
1302
1333
|
"signatureCount": 1,
|
|
1303
1334
|
"status": "pending",
|
|
@@ -1326,10 +1357,8 @@ describe('RPC conversion', () => {
|
|
|
1326
1357
|
"threshold": 2,
|
|
1327
1358
|
"version": "0x1",
|
|
1328
1359
|
},
|
|
1329
|
-
"configVersion": "0x1",
|
|
1330
1360
|
"createdAt": 1,
|
|
1331
1361
|
"hash": "0xcdbc24a8fb192f799c5d166b13a99fb29cbb15e71a5e730988d6f8b3c5959d02",
|
|
1332
|
-
"init": false,
|
|
1333
1362
|
"signatureCount": 1,
|
|
1334
1363
|
"status": "pending",
|
|
1335
1364
|
"threshold": 2,
|
|
@@ -1462,7 +1491,7 @@ describe('validation', () => {
|
|
|
1462
1491
|
account: '0x0000000000000000000000000000000000000000',
|
|
1463
1492
|
hash: MultisigConfig.getSignPayload({
|
|
1464
1493
|
account: '0x0000000000000000000000000000000000000000',
|
|
1465
|
-
config:
|
|
1494
|
+
config: currentConfig,
|
|
1466
1495
|
payload: TxEnvelopeTempo.getSignPayload(
|
|
1467
1496
|
TxEnvelopeTempo.deserialize(transaction),
|
|
1468
1497
|
),
|
|
@@ -1529,7 +1558,7 @@ describe('validation', () => {
|
|
|
1529
1558
|
},
|
|
1530
1559
|
},
|
|
1531
1560
|
{
|
|
1532
|
-
name: 'nested
|
|
1561
|
+
name: 'nested non-owner approval',
|
|
1533
1562
|
operation: {
|
|
1534
1563
|
...transactionPending,
|
|
1535
1564
|
approvals: [
|
|
@@ -1542,24 +1571,48 @@ describe('validation', () => {
|
|
|
1542
1571
|
],
|
|
1543
1572
|
},
|
|
1544
1573
|
},
|
|
1545
|
-
{
|
|
1546
|
-
name: 'bootstrap with initialized version',
|
|
1547
|
-
operation: { ...transactionPending, init: true },
|
|
1548
|
-
},
|
|
1549
1574
|
])('rejects $name', ({ operation }) => {
|
|
1550
1575
|
expect(() =>
|
|
1551
1576
|
MultisigOperation.from(operation as MultisigOperation.Operation),
|
|
1552
1577
|
).toThrowError(MultisigOperation.InvalidOperationError)
|
|
1553
1578
|
})
|
|
1554
1579
|
|
|
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
|
+
})
|
|
1586
|
+
expect(() =>
|
|
1587
|
+
MultisigOperation.from({
|
|
1588
|
+
...transactionPending,
|
|
1589
|
+
config,
|
|
1590
|
+
hash: MultisigConfig.getSignPayload({
|
|
1591
|
+
account,
|
|
1592
|
+
config,
|
|
1593
|
+
payload: TxEnvelopeTempo.getSignPayload(
|
|
1594
|
+
TxEnvelopeTempo.deserialize(transaction),
|
|
1595
|
+
),
|
|
1596
|
+
}),
|
|
1597
|
+
}),
|
|
1598
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
1599
|
+
`
|
|
1600
|
+
[MultisigOperation.InvalidOperationError: Invalid multisig operation.
|
|
1601
|
+
|
|
1602
|
+
Details: Invalid native multisig owner approval: initial multisig config does not derive account.]
|
|
1603
|
+
`,
|
|
1604
|
+
)
|
|
1605
|
+
})
|
|
1606
|
+
|
|
1555
1607
|
test('rejects noncanonical RPC quantities', () => {
|
|
1608
|
+
const operation = MultisigOperation.toRpc(transactionPending)
|
|
1556
1609
|
expect(() =>
|
|
1557
1610
|
MultisigOperation.fromRpc({
|
|
1558
|
-
...
|
|
1559
|
-
|
|
1611
|
+
...operation,
|
|
1612
|
+
config: { ...operation.config, version: '0x01' },
|
|
1560
1613
|
}),
|
|
1561
1614
|
).toThrowError(
|
|
1562
|
-
'Invalid multisig operation:
|
|
1615
|
+
'Invalid multisig operation: config.version must use canonical quantity encoding.',
|
|
1563
1616
|
)
|
|
1564
1617
|
})
|
|
1565
1618
|
|
|
@@ -1572,7 +1625,7 @@ describe('validation', () => {
|
|
|
1572
1625
|
KeyAuthorization.from(authorization, {
|
|
1573
1626
|
signature: {
|
|
1574
1627
|
account,
|
|
1575
|
-
config:
|
|
1628
|
+
config: currentConfig,
|
|
1576
1629
|
signatures: [
|
|
1577
1630
|
SignatureEnvelope.deserialize(approval_1),
|
|
1578
1631
|
SignatureEnvelope.deserialize(approval_3),
|
|
@@ -1596,7 +1649,7 @@ describe('validation', () => {
|
|
|
1596
1649
|
const signatures = [
|
|
1597
1650
|
...SignatureEnvelope.sortMultisigApprovals({
|
|
1598
1651
|
account,
|
|
1599
|
-
config:
|
|
1652
|
+
config: currentConfig,
|
|
1600
1653
|
payload: KeyAuthorization.getSignPayload(authorization),
|
|
1601
1654
|
signatures: [
|
|
1602
1655
|
SignatureEnvelope.deserialize(approval_1),
|
|
@@ -1611,7 +1664,7 @@ describe('validation', () => {
|
|
|
1611
1664
|
KeyAuthorization.from(authorization, {
|
|
1612
1665
|
signature: {
|
|
1613
1666
|
account,
|
|
1614
|
-
config:
|
|
1667
|
+
config: currentConfig,
|
|
1615
1668
|
signatures,
|
|
1616
1669
|
type: 'multisig',
|
|
1617
1670
|
},
|
|
@@ -1636,7 +1689,7 @@ describe('validation', () => {
|
|
|
1636
1689
|
KeyAuthorization.from(authorization, {
|
|
1637
1690
|
signature: {
|
|
1638
1691
|
account,
|
|
1639
|
-
config:
|
|
1692
|
+
config: currentConfig,
|
|
1640
1693
|
signatures: [
|
|
1641
1694
|
SignatureEnvelope.deserialize(approval_1),
|
|
1642
1695
|
SignatureEnvelope.deserialize(approval_1),
|
|
@@ -1685,7 +1738,7 @@ describe('validation', () => {
|
|
|
1685
1738
|
})
|
|
1686
1739
|
const selected = SignatureEnvelope.sortMultisigApprovals({
|
|
1687
1740
|
account,
|
|
1688
|
-
config:
|
|
1741
|
+
config: currentConfig,
|
|
1689
1742
|
payload: KeyAuthorization.getSignPayload(authorization),
|
|
1690
1743
|
signatures: [selectedNested, SignatureEnvelope.deserialize(approval_2)],
|
|
1691
1744
|
})
|
|
@@ -1696,7 +1749,7 @@ describe('validation', () => {
|
|
|
1696
1749
|
KeyAuthorization.from(authorization, {
|
|
1697
1750
|
signature: {
|
|
1698
1751
|
account,
|
|
1699
|
-
config:
|
|
1752
|
+
config: currentConfig,
|
|
1700
1753
|
signatures: selected,
|
|
1701
1754
|
type: 'multisig',
|
|
1702
1755
|
},
|
|
@@ -1712,7 +1765,7 @@ describe('validation', () => {
|
|
|
1712
1765
|
)
|
|
1713
1766
|
})
|
|
1714
1767
|
|
|
1715
|
-
test('accepts case-insensitive
|
|
1768
|
+
test('accepts case-insensitive initial configs', () => {
|
|
1716
1769
|
const config = MultisigConfig.from({
|
|
1717
1770
|
owners: [
|
|
1718
1771
|
{
|
|
@@ -1753,14 +1806,12 @@ describe('validation', () => {
|
|
|
1753
1806
|
account,
|
|
1754
1807
|
approvals,
|
|
1755
1808
|
config,
|
|
1756
|
-
configVersion: 0n,
|
|
1757
1809
|
createdAt: 1,
|
|
1758
1810
|
hash: MultisigConfig.getSignPayload({
|
|
1759
1811
|
account,
|
|
1760
1812
|
config,
|
|
1761
1813
|
payload: KeyAuthorization.getSignPayload(authorization),
|
|
1762
1814
|
}),
|
|
1763
|
-
init: true,
|
|
1764
1815
|
keyAuthorization: KeyAuthorization.serialize(
|
|
1765
1816
|
KeyAuthorization.from(authorization, {
|
|
1766
1817
|
signature: {
|