@openzeppelin/miden-multisig-client 0.15.2 → 0.16.0
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/README.md +25 -1
- package/dist/account/builder.d.ts +2 -1
- package/dist/account/builder.d.ts.map +1 -1
- package/dist/account/builder.js +1 -0
- package/dist/account/builder.js.map +1 -1
- package/dist/account/builder.test.js +2 -2
- package/dist/account/builder.test.js.map +1 -1
- package/dist/client.d.ts +9 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +5 -5
- package/dist/client.js.map +1 -1
- package/dist/client.test.js +46 -15
- package/dist/client.test.js.map +1 -1
- package/dist/connectivity.d.ts +38 -0
- package/dist/connectivity.d.ts.map +1 -0
- package/dist/connectivity.js +97 -0
- package/dist/connectivity.js.map +1 -0
- package/dist/connectivity.test.d.ts +2 -0
- package/dist/connectivity.test.d.ts.map +1 -0
- package/dist/connectivity.test.js +61 -0
- package/dist/connectivity.test.js.map +1 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/multisig.d.ts +68 -7
- package/dist/multisig.d.ts.map +1 -1
- package/dist/multisig.js +90 -18
- package/dist/multisig.js.map +1 -1
- package/dist/multisig.test.js +214 -79
- package/dist/multisig.test.js.map +1 -1
- package/dist/proposal/metadata.d.ts.map +1 -1
- package/dist/proposal/metadata.js +12 -0
- package/dist/proposal/metadata.js.map +1 -1
- package/dist/proposal/metadata.test.js +49 -0
- package/dist/proposal/metadata.test.js.map +1 -1
- package/dist/raw-client.d.ts +2 -2
- package/dist/raw-client.d.ts.map +1 -1
- package/dist/raw-client.js +14 -4
- package/dist/raw-client.js.map +1 -1
- package/dist/raw-client.test.js +25 -3
- package/dist/raw-client.test.js.map +1 -1
- package/dist/transaction/consumeNotes.d.ts +6 -2
- package/dist/transaction/consumeNotes.d.ts.map +1 -1
- package/dist/transaction/consumeNotes.js +0 -4
- package/dist/transaction/consumeNotes.js.map +1 -1
- package/dist/transaction/options.d.ts +3 -0
- package/dist/transaction/options.d.ts.map +1 -1
- package/dist/transaction/p2id.d.ts +20 -2
- package/dist/transaction/p2id.d.ts.map +1 -1
- package/dist/transaction/p2id.js +46 -3
- package/dist/transaction/p2id.js.map +1 -1
- package/dist/transaction/p2id.test.js +66 -6
- package/dist/transaction/p2id.test.js.map +1 -1
- package/dist/transaction/summary.d.ts +2 -1
- package/dist/transaction/summary.d.ts.map +1 -1
- package/dist/transaction/summary.js.map +1 -1
- package/dist/transaction/updateGuardian.d.ts +6 -2
- package/dist/transaction/updateGuardian.d.ts.map +1 -1
- package/dist/transaction/updateGuardian.js.map +1 -1
- package/dist/transaction/updateProcedureThreshold.d.ts +7 -2
- package/dist/transaction/updateProcedureThreshold.d.ts.map +1 -1
- package/dist/transaction/updateProcedureThreshold.js.map +1 -1
- package/dist/transaction/updateSigners.d.ts +7 -2
- package/dist/transaction/updateSigners.d.ts.map +1 -1
- package/dist/transaction/updateSigners.js.map +1 -1
- package/dist/transaction.d.ts +1 -1
- package/dist/transaction.d.ts.map +1 -1
- package/dist/transaction.js +1 -1
- package/dist/transaction.js.map +1 -1
- package/dist/types/proposal.d.ts +5 -0
- package/dist/types/proposal.d.ts.map +1 -1
- package/dist/types/proposal.js +3 -0
- package/dist/types/proposal.js.map +1 -1
- package/package.json +3 -3
- package/src/account/builder.test.ts +19 -11
- package/src/account/builder.ts +2 -1
- package/src/client.test.ts +67 -15
- package/src/client.ts +18 -10
- package/src/connectivity.test.ts +67 -0
- package/src/connectivity.ts +111 -0
- package/src/index.ts +20 -1
- package/src/multisig.test.ts +267 -80
- package/src/multisig.ts +109 -20
- package/src/proposal/metadata.test.ts +60 -0
- package/src/proposal/metadata.ts +14 -0
- package/src/raw-client.test.ts +41 -3
- package/src/raw-client.ts +15 -5
- package/src/transaction/consumeNotes.ts +11 -1
- package/src/transaction/options.ts +4 -0
- package/src/transaction/p2id.test.ts +98 -8
- package/src/transaction/p2id.ts +64 -4
- package/src/transaction/summary.ts +12 -0
- package/src/transaction/updateGuardian.ts +11 -1
- package/src/transaction/updateProcedureThreshold.ts +13 -1
- package/src/transaction/updateSigners.ts +13 -1
- package/src/transaction.ts +3 -0
- package/src/types/proposal.ts +9 -0
package/dist/multisig.test.js
CHANGED
|
@@ -15,6 +15,10 @@ vi.mock('@miden-sdk/miden-sdk', () => ({
|
|
|
15
15
|
AccountId: {
|
|
16
16
|
fromHex: vi.fn((hex) => ({ toString: () => hex })),
|
|
17
17
|
},
|
|
18
|
+
NoteType: {
|
|
19
|
+
Private: 0,
|
|
20
|
+
Public: 1,
|
|
21
|
+
},
|
|
18
22
|
TransactionSummary: {
|
|
19
23
|
deserialize: vi.fn().mockReturnValue({
|
|
20
24
|
toCommitment: () => ({
|
|
@@ -79,6 +83,16 @@ vi.mock('./transaction.js', () => ({
|
|
|
79
83
|
request: {},
|
|
80
84
|
salt: { toHex: () => '0x' + 'd'.repeat(64) },
|
|
81
85
|
}),
|
|
86
|
+
// Mirrors the real implementations against the mocked NoteType values
|
|
87
|
+
// (Private = 0, Public = 1).
|
|
88
|
+
parseP2idNoteType: vi.fn((value) => {
|
|
89
|
+
if (value === undefined || value === 'public')
|
|
90
|
+
return 1;
|
|
91
|
+
if (value === 'private')
|
|
92
|
+
return 0;
|
|
93
|
+
throw new Error(`unsupported metadata.noteType '${value}': expected 'public' or 'private'`);
|
|
94
|
+
}),
|
|
95
|
+
p2idNoteTypeToMetadata: vi.fn((noteType) => (noteType === 0 ? 'private' : undefined)),
|
|
82
96
|
}));
|
|
83
97
|
vi.mock('./utils/signature.js', async () => {
|
|
84
98
|
const actual = await vi.importActual('./utils/signature.js');
|
|
@@ -106,6 +120,7 @@ vi.mock('./inspector.js', () => ({
|
|
|
106
120
|
// Mock fetch for GUARDIAN client
|
|
107
121
|
const mockFetch = vi.fn();
|
|
108
122
|
vi.stubGlobal('fetch', mockFetch);
|
|
123
|
+
const MIDEN_RPC_ENDPOINT = 'https://rpc.devnet.miden.io';
|
|
109
124
|
function mockedAccount(commitmentHex, nonce = 0) {
|
|
110
125
|
return {
|
|
111
126
|
commitment: () => ({
|
|
@@ -124,6 +139,9 @@ describe('Multisig', () => {
|
|
|
124
139
|
let mockSigner;
|
|
125
140
|
let mockAccount;
|
|
126
141
|
let mockWebClient;
|
|
142
|
+
function createTestMultisig(config, signer = mockSigner, accountId) {
|
|
143
|
+
return new Multisig(mockAccount, config, guardian, signer, mockWebClient, accountId, MIDEN_RPC_ENDPOINT);
|
|
144
|
+
}
|
|
127
145
|
beforeEach(() => {
|
|
128
146
|
mockFetch.mockReset();
|
|
129
147
|
vi.mocked(executeForSummary).mockResolvedValue({
|
|
@@ -191,7 +209,7 @@ describe('Multisig', () => {
|
|
|
191
209
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
192
210
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
193
211
|
};
|
|
194
|
-
const multisig =
|
|
212
|
+
const multisig = createTestMultisig(config);
|
|
195
213
|
expect(multisig.threshold).toBe(2);
|
|
196
214
|
expect(multisig.signerCommitments).toEqual(config.signerCommitments);
|
|
197
215
|
expect(multisig.guardianCommitment).toBe(config.guardianCommitment);
|
|
@@ -204,10 +222,18 @@ describe('Multisig', () => {
|
|
|
204
222
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
205
223
|
};
|
|
206
224
|
const accountId = '0x' + 'd'.repeat(30);
|
|
207
|
-
const multisig =
|
|
225
|
+
const multisig = createTestMultisig(config, mockSigner, accountId);
|
|
208
226
|
expect(multisig.account).toBe(mockAccount);
|
|
209
227
|
expect(multisig.accountId).toBe(accountId);
|
|
210
228
|
});
|
|
229
|
+
it('should reject a missing Miden RPC endpoint immediately', () => {
|
|
230
|
+
const config = {
|
|
231
|
+
threshold: 2,
|
|
232
|
+
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
233
|
+
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
234
|
+
};
|
|
235
|
+
expect(() => new Multisig(mockAccount, config, guardian, mockSigner, mockWebClient, undefined, undefined)).toThrow('missing required configuration: midenRpcEndpoint');
|
|
236
|
+
});
|
|
211
237
|
});
|
|
212
238
|
describe('accountId', () => {
|
|
213
239
|
it('should return account ID from account', () => {
|
|
@@ -216,7 +242,7 @@ describe('Multisig', () => {
|
|
|
216
242
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
217
243
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
218
244
|
};
|
|
219
|
-
const multisig =
|
|
245
|
+
const multisig = createTestMultisig(config);
|
|
220
246
|
expect(multisig.accountId).toBe('0x' + 'a'.repeat(30));
|
|
221
247
|
});
|
|
222
248
|
it('should return provided account ID when constructor override is set', () => {
|
|
@@ -226,7 +252,7 @@ describe('Multisig', () => {
|
|
|
226
252
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
227
253
|
};
|
|
228
254
|
const accountId = '0x' + 'e'.repeat(30);
|
|
229
|
-
const multisig =
|
|
255
|
+
const multisig = createTestMultisig(config, mockSigner, accountId);
|
|
230
256
|
expect(multisig.accountId).toBe(accountId);
|
|
231
257
|
});
|
|
232
258
|
});
|
|
@@ -237,7 +263,7 @@ describe('Multisig', () => {
|
|
|
237
263
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
238
264
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
239
265
|
};
|
|
240
|
-
const multisig =
|
|
266
|
+
const multisig = createTestMultisig(config);
|
|
241
267
|
expect(multisig.signerCommitment).toBe(mockSigner.commitment);
|
|
242
268
|
});
|
|
243
269
|
});
|
|
@@ -248,7 +274,7 @@ describe('Multisig', () => {
|
|
|
248
274
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
249
275
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
250
276
|
};
|
|
251
|
-
const multisig =
|
|
277
|
+
const multisig = createTestMultisig(config);
|
|
252
278
|
mockFetch.mockResolvedValueOnce({
|
|
253
279
|
ok: true,
|
|
254
280
|
json: async () => ({
|
|
@@ -399,14 +425,15 @@ describe('Multisig', () => {
|
|
|
399
425
|
await expect(multisig.syncState()).rejects.toThrow('Refusing to overwrite local state');
|
|
400
426
|
expect(mockWebClient.newAccount).not.toHaveBeenCalled();
|
|
401
427
|
});
|
|
402
|
-
it('
|
|
428
|
+
it('keeps local state and refreshes config from it when GUARDIAN nonce is behind local', async () => {
|
|
403
429
|
const config = {
|
|
404
430
|
threshold: 1,
|
|
405
431
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
406
432
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
407
433
|
};
|
|
408
434
|
const multisig = new Multisig(mockAccount, config, guardian, mockSigner, mockWebClient, undefined, 'https://rpc.devnet.miden.io');
|
|
409
|
-
|
|
435
|
+
const localAccount = mockedAccount('0x' + 'a'.repeat(64), 3);
|
|
436
|
+
mockWebClient.getAccount.mockResolvedValueOnce(localAccount);
|
|
410
437
|
mockAccountDeserialize.mockReturnValueOnce(mockedAccount('0x' + 'b'.repeat(64), 2));
|
|
411
438
|
mockFetch.mockResolvedValueOnce({
|
|
412
439
|
ok: true,
|
|
@@ -418,8 +445,23 @@ describe('Multisig', () => {
|
|
|
418
445
|
updated_at: '2024-01-02T00:00:00Z',
|
|
419
446
|
}),
|
|
420
447
|
});
|
|
421
|
-
|
|
448
|
+
mockDetectConfig.mockReturnValueOnce({
|
|
449
|
+
threshold: 2,
|
|
450
|
+
numSigners: 2,
|
|
451
|
+
signerCommitments: ['0x' + '1'.repeat(64), '0x' + '2'.repeat(64)],
|
|
452
|
+
guardianEnabled: true,
|
|
453
|
+
guardianCommitment: '0x' + 'd'.repeat(64),
|
|
454
|
+
vaultBalances: [],
|
|
455
|
+
procedureThresholds: new Map(),
|
|
456
|
+
});
|
|
457
|
+
// GUARDIAN behind local (nonce 2 < 3): no throw, local kept, no overwrite,
|
|
458
|
+
// and the decision needs no on-chain round-trip.
|
|
459
|
+
await expect(multisig.syncState()).resolves.toBeDefined();
|
|
422
460
|
expect(mockWebClient.newAccount).not.toHaveBeenCalled();
|
|
461
|
+
expect(mockRpcGetAccountDetails).not.toHaveBeenCalled();
|
|
462
|
+
// Config refreshed from the authoritative local account (UI unfreezes).
|
|
463
|
+
expect(multisig.account).toBe(localAccount);
|
|
464
|
+
expect(multisig.threshold).toBe(2);
|
|
423
465
|
});
|
|
424
466
|
it('should throw when incoming state nonce equals local nonce but commitment differs', async () => {
|
|
425
467
|
const config = {
|
|
@@ -440,9 +482,36 @@ describe('Multisig', () => {
|
|
|
440
482
|
updated_at: '2024-01-02T00:00:00Z',
|
|
441
483
|
}),
|
|
442
484
|
});
|
|
443
|
-
await expect(multisig.syncState()).rejects.toThrow('incoming nonce 2
|
|
485
|
+
await expect(multisig.syncState()).rejects.toThrow('incoming nonce 2 equals local nonce 2 but commitments differ');
|
|
444
486
|
expect(mockWebClient.newAccount).not.toHaveBeenCalled();
|
|
445
487
|
});
|
|
488
|
+
it('unfreezes Multisig.account after execute when GUARDIAN still lags by one nonce (regression, #343)', async () => {
|
|
489
|
+
const config = {
|
|
490
|
+
threshold: 1,
|
|
491
|
+
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
492
|
+
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
493
|
+
};
|
|
494
|
+
const multisig = new Multisig(mockAccount, config, guardian, mockSigner, mockWebClient, undefined, 'https://rpc.devnet.miden.io');
|
|
495
|
+
// Post-execute: local advanced to nonce 1, GUARDIAN still reports nonce 0
|
|
496
|
+
// (candidate not canonicalized yet). Before the fix this threw and left
|
|
497
|
+
// Multisig.account frozen at the pre-execute snapshot.
|
|
498
|
+
const localAccount = mockedAccount('0x' + 'a'.repeat(64), 1);
|
|
499
|
+
mockWebClient.getAccount.mockResolvedValueOnce(localAccount);
|
|
500
|
+
mockAccountDeserialize.mockReturnValueOnce(mockedAccount('0x' + 'b'.repeat(64), 0));
|
|
501
|
+
mockFetch.mockResolvedValueOnce({
|
|
502
|
+
ok: true,
|
|
503
|
+
json: async () => ({
|
|
504
|
+
account_id: multisig.accountId,
|
|
505
|
+
commitment: '0x' + 'b'.repeat(64),
|
|
506
|
+
state_json: { data: 'AQID' },
|
|
507
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
508
|
+
updated_at: '2024-01-02T00:00:00Z',
|
|
509
|
+
}),
|
|
510
|
+
});
|
|
511
|
+
await expect(multisig.syncState()).resolves.toBeDefined();
|
|
512
|
+
expect(mockWebClient.newAccount).not.toHaveBeenCalled();
|
|
513
|
+
expect(multisig.account).toBe(localAccount);
|
|
514
|
+
});
|
|
446
515
|
});
|
|
447
516
|
describe('verifyStateCommitment', () => {
|
|
448
517
|
it('should pass when local and on-chain commitments match', async () => {
|
|
@@ -490,7 +559,7 @@ describe('Multisig', () => {
|
|
|
490
559
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
491
560
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
492
561
|
};
|
|
493
|
-
const multisig =
|
|
562
|
+
const multisig = createTestMultisig(config);
|
|
494
563
|
mockFetch.mockResolvedValueOnce({
|
|
495
564
|
ok: true,
|
|
496
565
|
json: async () => ({
|
|
@@ -513,7 +582,7 @@ describe('Multisig', () => {
|
|
|
513
582
|
scheme: 'ecdsa',
|
|
514
583
|
};
|
|
515
584
|
guardian.setSigner(ecdsaSigner);
|
|
516
|
-
const multisig =
|
|
585
|
+
const multisig = createTestMultisig(config, ecdsaSigner);
|
|
517
586
|
mockFetch.mockResolvedValueOnce({
|
|
518
587
|
ok: true,
|
|
519
588
|
json: async () => ({
|
|
@@ -537,7 +606,7 @@ describe('Multisig', () => {
|
|
|
537
606
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
538
607
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
539
608
|
};
|
|
540
|
-
const multisig = new Multisig(mockAccount, config, guardian, mockSigner, mockWebClient, '0x' + 'e'.repeat(30));
|
|
609
|
+
const multisig = new Multisig(mockAccount, config, guardian, mockSigner, mockWebClient, '0x' + 'e'.repeat(30), MIDEN_RPC_ENDPOINT);
|
|
541
610
|
mockFetch.mockResolvedValueOnce({
|
|
542
611
|
ok: true,
|
|
543
612
|
json: async () => ({
|
|
@@ -553,7 +622,7 @@ describe('Multisig', () => {
|
|
|
553
622
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
554
623
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
555
624
|
};
|
|
556
|
-
const multisig =
|
|
625
|
+
const multisig = createTestMultisig(config);
|
|
557
626
|
mockFetch.mockResolvedValueOnce({
|
|
558
627
|
ok: true,
|
|
559
628
|
json: async () => ({
|
|
@@ -571,7 +640,7 @@ describe('Multisig', () => {
|
|
|
571
640
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
572
641
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
573
642
|
};
|
|
574
|
-
const multisig =
|
|
643
|
+
const multisig = createTestMultisig(config);
|
|
575
644
|
const mockProposals = [
|
|
576
645
|
{
|
|
577
646
|
account_id: '0x' + 'a'.repeat(30),
|
|
@@ -616,7 +685,7 @@ describe('Multisig', () => {
|
|
|
616
685
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
617
686
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
618
687
|
};
|
|
619
|
-
const multisig =
|
|
688
|
+
const multisig = createTestMultisig(config);
|
|
620
689
|
const mockProposals = [
|
|
621
690
|
{
|
|
622
691
|
account_id: '0x' + 'a'.repeat(30),
|
|
@@ -659,7 +728,7 @@ describe('Multisig', () => {
|
|
|
659
728
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
660
729
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
661
730
|
};
|
|
662
|
-
const multisig =
|
|
731
|
+
const multisig = createTestMultisig(config);
|
|
663
732
|
mockFetch.mockResolvedValueOnce({
|
|
664
733
|
ok: true,
|
|
665
734
|
json: async () => ({
|
|
@@ -701,7 +770,7 @@ describe('Multisig', () => {
|
|
|
701
770
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
702
771
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
703
772
|
};
|
|
704
|
-
const multisig =
|
|
773
|
+
const multisig = createTestMultisig(config);
|
|
705
774
|
const mockProposals = [
|
|
706
775
|
{
|
|
707
776
|
account_id: '0x' + 'a'.repeat(30),
|
|
@@ -743,7 +812,7 @@ describe('Multisig', () => {
|
|
|
743
812
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
744
813
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
745
814
|
};
|
|
746
|
-
const multisig =
|
|
815
|
+
const multisig = createTestMultisig(config);
|
|
747
816
|
const mockProposals = [
|
|
748
817
|
{
|
|
749
818
|
account_id: '0x' + 'a'.repeat(30),
|
|
@@ -792,7 +861,7 @@ describe('Multisig', () => {
|
|
|
792
861
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
793
862
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
794
863
|
};
|
|
795
|
-
const multisig =
|
|
864
|
+
const multisig = createTestMultisig(config);
|
|
796
865
|
expect(multisig.listProposals()).toEqual([]);
|
|
797
866
|
});
|
|
798
867
|
});
|
|
@@ -803,7 +872,7 @@ describe('Multisig', () => {
|
|
|
803
872
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
804
873
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
805
874
|
};
|
|
806
|
-
const multisig =
|
|
875
|
+
const multisig = createTestMultisig(config);
|
|
807
876
|
const mockDelta = {
|
|
808
877
|
account_id: '0x' + 'a'.repeat(30),
|
|
809
878
|
nonce: 1,
|
|
@@ -841,7 +910,7 @@ describe('Multisig', () => {
|
|
|
841
910
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
842
911
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
843
912
|
};
|
|
844
|
-
const multisig =
|
|
913
|
+
const multisig = createTestMultisig(config);
|
|
845
914
|
const mockDelta = {
|
|
846
915
|
account_id: '0x' + 'a'.repeat(30),
|
|
847
916
|
nonce: 1,
|
|
@@ -877,7 +946,7 @@ describe('Multisig', () => {
|
|
|
877
946
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
878
947
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
879
948
|
};
|
|
880
|
-
const multisig =
|
|
949
|
+
const multisig = createTestMultisig(config);
|
|
881
950
|
const mockDelta = {
|
|
882
951
|
account_id: '0x' + 'a'.repeat(30),
|
|
883
952
|
nonce: 1,
|
|
@@ -927,7 +996,7 @@ describe('Multisig', () => {
|
|
|
927
996
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
928
997
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
929
998
|
};
|
|
930
|
-
const multisig =
|
|
999
|
+
const multisig = createTestMultisig(config);
|
|
931
1000
|
const mockDelta = {
|
|
932
1001
|
account_id: '0x' + 'a'.repeat(30),
|
|
933
1002
|
nonce: 1,
|
|
@@ -960,6 +1029,66 @@ describe('Multisig', () => {
|
|
|
960
1029
|
const proposal = await multisig.createP2idProposal('0xrecipient', '0xfaucet', 100n, 1);
|
|
961
1030
|
expect(proposal.metadata.description).toBe('Send 100 of asset 0xfaucet... to 0xrecipien...');
|
|
962
1031
|
});
|
|
1032
|
+
it('threads a private noteType into the request and wire metadata (issue #322)', async () => {
|
|
1033
|
+
const { executeForSummary, buildP2idTransactionRequest } = await import('./transaction.js');
|
|
1034
|
+
const { NoteType } = await import('@miden-sdk/miden-sdk');
|
|
1035
|
+
vi.mocked(executeForSummary).mockResolvedValue({
|
|
1036
|
+
toCommitment: () => ({
|
|
1037
|
+
toHex: () => '0x' + 'c'.repeat(64),
|
|
1038
|
+
}),
|
|
1039
|
+
serialize: () => new Uint8Array([1, 2, 3]),
|
|
1040
|
+
});
|
|
1041
|
+
const config = {
|
|
1042
|
+
threshold: 1,
|
|
1043
|
+
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1044
|
+
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1045
|
+
};
|
|
1046
|
+
const multisig = createTestMultisig(config);
|
|
1047
|
+
const mockDelta = {
|
|
1048
|
+
account_id: '0x' + 'a'.repeat(30),
|
|
1049
|
+
nonce: 1,
|
|
1050
|
+
prev_commitment: '0x' + 'b'.repeat(64),
|
|
1051
|
+
delta_payload: {
|
|
1052
|
+
tx_summary: { data: 'AQID' },
|
|
1053
|
+
signatures: [],
|
|
1054
|
+
metadata: {
|
|
1055
|
+
proposal_type: 'p2id',
|
|
1056
|
+
recipient_id: '0xrecipient',
|
|
1057
|
+
faucet_id: '0xfaucet',
|
|
1058
|
+
amount: '100',
|
|
1059
|
+
note_type: 'private',
|
|
1060
|
+
description: '',
|
|
1061
|
+
},
|
|
1062
|
+
},
|
|
1063
|
+
status: {
|
|
1064
|
+
status: 'pending',
|
|
1065
|
+
timestamp: '2024-01-01T00:00:00Z',
|
|
1066
|
+
proposer_id: '0x' + 'c'.repeat(64),
|
|
1067
|
+
cosigner_sigs: [],
|
|
1068
|
+
},
|
|
1069
|
+
};
|
|
1070
|
+
mockFetch.mockResolvedValueOnce({
|
|
1071
|
+
ok: true,
|
|
1072
|
+
json: async () => ({
|
|
1073
|
+
delta: mockDelta,
|
|
1074
|
+
commitment: '0x' + 'c'.repeat(64),
|
|
1075
|
+
}),
|
|
1076
|
+
});
|
|
1077
|
+
const proposal = await multisig.createP2idProposal('0xrecipient', '0xfaucet', 100n, 1, {
|
|
1078
|
+
noteType: NoteType.Private,
|
|
1079
|
+
});
|
|
1080
|
+
// Propose path builds the private note...
|
|
1081
|
+
expect(vi.mocked(buildP2idTransactionRequest)).toHaveBeenCalledWith(expect.any(String), '0xrecipient', '0xfaucet', 100n, expect.anything(), { noteType: NoteType.Private });
|
|
1082
|
+
// ...and the rebuild-from-metadata path parses note_type back to Private.
|
|
1083
|
+
const lastCall = vi.mocked(buildP2idTransactionRequest).mock.calls.at(-1);
|
|
1084
|
+
expect(lastCall[5]).toMatchObject({ noteType: NoteType.Private });
|
|
1085
|
+
// The pushed wire metadata carries note_type so cosigners rebuild the
|
|
1086
|
+
// same private note at verification/execution.
|
|
1087
|
+
const pushBody = JSON.parse(mockFetch.mock.calls.at(-1)[1].body);
|
|
1088
|
+
expect(pushBody.delta_payload.metadata.note_type).toBe('private');
|
|
1089
|
+
expect(proposal.metadata.proposalType).toBe('p2id');
|
|
1090
|
+
expect(proposal.metadata.noteType).toBe('private');
|
|
1091
|
+
});
|
|
963
1092
|
});
|
|
964
1093
|
describe('createChangeThresholdProposal', () => {
|
|
965
1094
|
it('passes the signer scheme to update-signers requests', async () => {
|
|
@@ -1007,7 +1136,7 @@ describe('Multisig', () => {
|
|
|
1007
1136
|
commitment: '0x' + 'c'.repeat(64),
|
|
1008
1137
|
}),
|
|
1009
1138
|
});
|
|
1010
|
-
const multisig =
|
|
1139
|
+
const multisig = createTestMultisig(config, ecdsaSigner);
|
|
1011
1140
|
await multisig.createChangeThresholdProposal(2, 1);
|
|
1012
1141
|
expect(buildUpdateSignersTransactionRequest).toHaveBeenCalledWith(mockWebClient, 2, config.signerCommitments, { signatureScheme: 'ecdsa' });
|
|
1013
1142
|
});
|
|
@@ -1022,7 +1151,7 @@ describe('Multisig', () => {
|
|
|
1022
1151
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1023
1152
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1024
1153
|
};
|
|
1025
|
-
const multisig =
|
|
1154
|
+
const multisig = createTestMultisig(config);
|
|
1026
1155
|
const newGuardianPubkey = '0x' + '1'.repeat(64);
|
|
1027
1156
|
mockFetch.mockResolvedValueOnce({
|
|
1028
1157
|
ok: true,
|
|
@@ -1062,7 +1191,7 @@ describe('Multisig', () => {
|
|
|
1062
1191
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1063
1192
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1064
1193
|
};
|
|
1065
|
-
const multisig =
|
|
1194
|
+
const multisig = createTestMultisig(config);
|
|
1066
1195
|
mockFetch.mockResolvedValueOnce({
|
|
1067
1196
|
ok: true,
|
|
1068
1197
|
json: async () => ({ commitment: '0x' + '2'.repeat(64) }),
|
|
@@ -1084,7 +1213,7 @@ describe('Multisig', () => {
|
|
|
1084
1213
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1085
1214
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1086
1215
|
};
|
|
1087
|
-
const multisig =
|
|
1216
|
+
const multisig = createTestMultisig(config, ecdsaSigner);
|
|
1088
1217
|
const newGuardianCommitment = '0x' + '1'.repeat(64);
|
|
1089
1218
|
mockFetch.mockResolvedValueOnce({
|
|
1090
1219
|
ok: true,
|
|
@@ -1126,7 +1255,7 @@ describe('Multisig', () => {
|
|
|
1126
1255
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
1127
1256
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1128
1257
|
};
|
|
1129
|
-
const multisig =
|
|
1258
|
+
const multisig = createTestMultisig(config);
|
|
1130
1259
|
const mockDelta = {
|
|
1131
1260
|
account_id: '0x' + 'a'.repeat(30),
|
|
1132
1261
|
nonce: 1,
|
|
@@ -1181,7 +1310,7 @@ describe('Multisig', () => {
|
|
|
1181
1310
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
1182
1311
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1183
1312
|
};
|
|
1184
|
-
const multisig =
|
|
1313
|
+
const multisig = createTestMultisig(config, ecdsaSigner);
|
|
1185
1314
|
const mockDelta = {
|
|
1186
1315
|
account_id: '0x' + 'a'.repeat(30),
|
|
1187
1316
|
nonce: 1,
|
|
@@ -1221,7 +1350,7 @@ describe('Multisig', () => {
|
|
|
1221
1350
|
signerCommitments: [mockSigner.commitment],
|
|
1222
1351
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1223
1352
|
};
|
|
1224
|
-
const multisig =
|
|
1353
|
+
const multisig = createTestMultisig(config);
|
|
1225
1354
|
// First create a proposal
|
|
1226
1355
|
const mockDelta = {
|
|
1227
1356
|
account_id: '0x' + 'a'.repeat(30),
|
|
@@ -1290,7 +1419,7 @@ describe('Multisig', () => {
|
|
|
1290
1419
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1291
1420
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1292
1421
|
};
|
|
1293
|
-
const multisig =
|
|
1422
|
+
const multisig = createTestMultisig(config);
|
|
1294
1423
|
const mockDelta = {
|
|
1295
1424
|
account_id: '0x' + 'a'.repeat(30),
|
|
1296
1425
|
nonce: 1,
|
|
@@ -1332,7 +1461,7 @@ describe('Multisig', () => {
|
|
|
1332
1461
|
signerCommitments: [mockSigner.commitment],
|
|
1333
1462
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1334
1463
|
};
|
|
1335
|
-
const multisig =
|
|
1464
|
+
const multisig = createTestMultisig(config);
|
|
1336
1465
|
const proposalId = '0x' + 'd'.repeat(64);
|
|
1337
1466
|
mockFetch.mockResolvedValueOnce({
|
|
1338
1467
|
ok: true,
|
|
@@ -1373,7 +1502,7 @@ describe('Multisig', () => {
|
|
|
1373
1502
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1374
1503
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1375
1504
|
};
|
|
1376
|
-
const multisig =
|
|
1505
|
+
const multisig = createTestMultisig(config);
|
|
1377
1506
|
vi.mocked(executeForSummary).mockResolvedValueOnce({
|
|
1378
1507
|
toCommitment: () => ({
|
|
1379
1508
|
toHex: () => '0x' + 'f'.repeat(64),
|
|
@@ -1401,7 +1530,7 @@ describe('Multisig', () => {
|
|
|
1401
1530
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1402
1531
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1403
1532
|
};
|
|
1404
|
-
const multisig =
|
|
1533
|
+
const multisig = createTestMultisig(config);
|
|
1405
1534
|
vi.mocked(executeForSummary).mockResolvedValueOnce({
|
|
1406
1535
|
toCommitment: () => ({
|
|
1407
1536
|
toHex: () => '0x' + 'c'.repeat(64),
|
|
@@ -1441,7 +1570,7 @@ describe('Multisig', () => {
|
|
|
1441
1570
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
1442
1571
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1443
1572
|
};
|
|
1444
|
-
const multisig =
|
|
1573
|
+
const multisig = createTestMultisig(config);
|
|
1445
1574
|
const mockProposals = [
|
|
1446
1575
|
{
|
|
1447
1576
|
account_id: '0x' + 'a'.repeat(30),
|
|
@@ -1488,7 +1617,7 @@ describe('Multisig', () => {
|
|
|
1488
1617
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
1489
1618
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1490
1619
|
};
|
|
1491
|
-
const multisig =
|
|
1620
|
+
const multisig = createTestMultisig(config);
|
|
1492
1621
|
const publicKey = '0x' + 'd'.repeat(66);
|
|
1493
1622
|
mockFetch.mockResolvedValueOnce({
|
|
1494
1623
|
ok: true,
|
|
@@ -1541,12 +1670,18 @@ describe('Multisig', () => {
|
|
|
1541
1670
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1542
1671
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1543
1672
|
};
|
|
1544
|
-
const multisig =
|
|
1673
|
+
const multisig = createTestMultisig(config);
|
|
1545
1674
|
mockFetch.mockResolvedValueOnce({
|
|
1546
1675
|
ok: false,
|
|
1547
1676
|
status: 404,
|
|
1548
1677
|
statusText: 'Not Found',
|
|
1549
|
-
|
|
1678
|
+
// Feature 009: only a conforming { code, message, meta } envelope is
|
|
1679
|
+
// folded into the error message; raw text bodies are dropped.
|
|
1680
|
+
text: async () => JSON.stringify({
|
|
1681
|
+
code: 'GUARDIAN_PROPOSAL_NOT_FOUND',
|
|
1682
|
+
message: 'Proposal not found',
|
|
1683
|
+
meta: { retryable: false },
|
|
1684
|
+
}),
|
|
1550
1685
|
});
|
|
1551
1686
|
await expect(multisig.exportProposal('0x' + 'nonexistent'.repeat(5))).rejects.toThrow('Proposal not found');
|
|
1552
1687
|
});
|
|
@@ -1558,7 +1693,7 @@ describe('Multisig', () => {
|
|
|
1558
1693
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1559
1694
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1560
1695
|
};
|
|
1561
|
-
const multisig =
|
|
1696
|
+
const multisig = createTestMultisig(config);
|
|
1562
1697
|
const exported = {
|
|
1563
1698
|
accountId: multisig.accountId,
|
|
1564
1699
|
nonce: 1,
|
|
@@ -1585,7 +1720,7 @@ describe('Multisig', () => {
|
|
|
1585
1720
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1586
1721
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1587
1722
|
};
|
|
1588
|
-
const multisig =
|
|
1723
|
+
const multisig = createTestMultisig(config);
|
|
1589
1724
|
const publicKey = '0x' + 'd'.repeat(66);
|
|
1590
1725
|
const proposal = await multisig.importProposal(JSON.stringify({
|
|
1591
1726
|
accountId: multisig.accountId,
|
|
@@ -1626,7 +1761,7 @@ describe('Multisig', () => {
|
|
|
1626
1761
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1627
1762
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1628
1763
|
};
|
|
1629
|
-
const multisig =
|
|
1764
|
+
const multisig = createTestMultisig(config);
|
|
1630
1765
|
await expect(multisig.importProposal(JSON.stringify({
|
|
1631
1766
|
accountId: multisig.accountId,
|
|
1632
1767
|
nonce: 1,
|
|
@@ -1653,7 +1788,7 @@ describe('Multisig', () => {
|
|
|
1653
1788
|
signerCommitments: ['0x' + 'a'.repeat(64), mockSigner.commitment],
|
|
1654
1789
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1655
1790
|
};
|
|
1656
|
-
const multisig =
|
|
1791
|
+
const multisig = createTestMultisig(config);
|
|
1657
1792
|
const exported = {
|
|
1658
1793
|
accountId: multisig.accountId,
|
|
1659
1794
|
nonce: 1,
|
|
@@ -1689,7 +1824,7 @@ describe('Multisig', () => {
|
|
|
1689
1824
|
scheme: 'ecdsa',
|
|
1690
1825
|
publicKey: '0x' + '2'.repeat(66),
|
|
1691
1826
|
};
|
|
1692
|
-
const multisig =
|
|
1827
|
+
const multisig = createTestMultisig(config, ecdsaSigner);
|
|
1693
1828
|
const cachedProposalId = '0x' + 'c'.repeat(64);
|
|
1694
1829
|
const requestedProposalId = '0x' + 'C'.repeat(64);
|
|
1695
1830
|
const cosignerPubkey = '0x' + '3'.repeat(66);
|
|
@@ -1781,7 +1916,7 @@ describe('Multisig', () => {
|
|
|
1781
1916
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1782
1917
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1783
1918
|
};
|
|
1784
|
-
const multisig =
|
|
1919
|
+
const multisig = createTestMultisig(config);
|
|
1785
1920
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
1786
1921
|
const newGuardianPubkey = '0x' + '1'.repeat(64);
|
|
1787
1922
|
const finalRequest = { kind: 'final-switch-guardian-request' };
|
|
@@ -1829,7 +1964,7 @@ describe('Multisig', () => {
|
|
|
1829
1964
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1830
1965
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1831
1966
|
};
|
|
1832
|
-
const multisig =
|
|
1967
|
+
const multisig = createTestMultisig(config);
|
|
1833
1968
|
await expect(multisig.createTransactionProposalRequest('0x' + 'nonexistent'.repeat(5))).rejects.toThrow('Proposal not found');
|
|
1834
1969
|
});
|
|
1835
1970
|
it('should throw if proposal is still pending', async () => {
|
|
@@ -1838,7 +1973,7 @@ describe('Multisig', () => {
|
|
|
1838
1973
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
1839
1974
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1840
1975
|
};
|
|
1841
|
-
const multisig =
|
|
1976
|
+
const multisig = createTestMultisig(config);
|
|
1842
1977
|
const mockProposals = [
|
|
1843
1978
|
{
|
|
1844
1979
|
account_id: '0x' + 'a'.repeat(30),
|
|
@@ -1881,7 +2016,7 @@ describe('Multisig', () => {
|
|
|
1881
2016
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1882
2017
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1883
2018
|
};
|
|
1884
|
-
const multisig =
|
|
2019
|
+
const multisig = createTestMultisig(config);
|
|
1885
2020
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
1886
2021
|
vi.mocked(executeForSummary).mockResolvedValueOnce({
|
|
1887
2022
|
toCommitment: () => ({
|
|
@@ -1917,7 +2052,7 @@ describe('Multisig', () => {
|
|
|
1917
2052
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
1918
2053
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1919
2054
|
};
|
|
1920
|
-
const multisig =
|
|
2055
|
+
const multisig = createTestMultisig(config);
|
|
1921
2056
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
1922
2057
|
multisig.proposals.set(proposalId, {
|
|
1923
2058
|
id: proposalId,
|
|
@@ -1952,7 +2087,7 @@ describe('Multisig', () => {
|
|
|
1952
2087
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
1953
2088
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
1954
2089
|
};
|
|
1955
|
-
const multisig =
|
|
2090
|
+
const multisig = createTestMultisig(config);
|
|
1956
2091
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
1957
2092
|
multisig.proposals.set(proposalId, {
|
|
1958
2093
|
id: proposalId,
|
|
@@ -2012,7 +2147,7 @@ describe('Multisig', () => {
|
|
|
2012
2147
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2013
2148
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2014
2149
|
};
|
|
2015
|
-
const multisig =
|
|
2150
|
+
const multisig = createTestMultisig(config);
|
|
2016
2151
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
2017
2152
|
const finalRequest = { kind: 'fresh-message-word-request' };
|
|
2018
2153
|
vi.mocked(buildUpdateSignersTransactionRequest)
|
|
@@ -2105,7 +2240,7 @@ describe('Multisig', () => {
|
|
|
2105
2240
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
2106
2241
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2107
2242
|
};
|
|
2108
|
-
const multisig =
|
|
2243
|
+
const multisig = createTestMultisig(config);
|
|
2109
2244
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
2110
2245
|
multisig.proposals.set(proposalId, {
|
|
2111
2246
|
id: proposalId,
|
|
@@ -2142,7 +2277,7 @@ describe('Multisig', () => {
|
|
|
2142
2277
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2143
2278
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2144
2279
|
};
|
|
2145
|
-
const multisig =
|
|
2280
|
+
const multisig = createTestMultisig(config);
|
|
2146
2281
|
await expect(multisig.executeProposal('0x' + 'nonexistent'.repeat(5))).rejects.toThrow('Proposal not found');
|
|
2147
2282
|
});
|
|
2148
2283
|
it('should throw if proposal is still pending', async () => {
|
|
@@ -2151,7 +2286,7 @@ describe('Multisig', () => {
|
|
|
2151
2286
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
2152
2287
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2153
2288
|
};
|
|
2154
|
-
const multisig =
|
|
2289
|
+
const multisig = createTestMultisig(config);
|
|
2155
2290
|
// Sync with pending proposal (only 1 signature)
|
|
2156
2291
|
const mockProposals = [
|
|
2157
2292
|
{
|
|
@@ -2196,7 +2331,7 @@ describe('Multisig', () => {
|
|
|
2196
2331
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2197
2332
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2198
2333
|
};
|
|
2199
|
-
const multisig =
|
|
2334
|
+
const multisig = createTestMultisig(config);
|
|
2200
2335
|
const readyDelta = {
|
|
2201
2336
|
account_id: '0x' + 'a'.repeat(30),
|
|
2202
2337
|
nonce: 1,
|
|
@@ -2258,7 +2393,7 @@ describe('Multisig', () => {
|
|
|
2258
2393
|
scheme: 'ecdsa',
|
|
2259
2394
|
publicKey: '0x' + '2'.repeat(66),
|
|
2260
2395
|
};
|
|
2261
|
-
const multisig =
|
|
2396
|
+
const multisig = createTestMultisig(config, ecdsaSigner);
|
|
2262
2397
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
2263
2398
|
const cosignerPubkey = '0x' + '3'.repeat(66);
|
|
2264
2399
|
const ackPubkey = '0x' + '4'.repeat(66);
|
|
@@ -2344,7 +2479,7 @@ describe('Multisig', () => {
|
|
|
2344
2479
|
scheme: 'ecdsa',
|
|
2345
2480
|
publicKey: '0x' + '2'.repeat(66),
|
|
2346
2481
|
};
|
|
2347
|
-
const multisig =
|
|
2482
|
+
const multisig = createTestMultisig(config, ecdsaSigner);
|
|
2348
2483
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
2349
2484
|
const cosignerPubkey = '0x' + '3'.repeat(66);
|
|
2350
2485
|
const ackPubkey = '0x' + '4'.repeat(66);
|
|
@@ -2417,7 +2552,7 @@ describe('Multisig', () => {
|
|
|
2417
2552
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2418
2553
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2419
2554
|
};
|
|
2420
|
-
const multisig =
|
|
2555
|
+
const multisig = createTestMultisig(config);
|
|
2421
2556
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
2422
2557
|
const newGuardianPubkey = '0x' + '1'.repeat(64);
|
|
2423
2558
|
multisig.proposals.set(proposalId, {
|
|
@@ -2495,7 +2630,7 @@ describe('Multisig', () => {
|
|
|
2495
2630
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2496
2631
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2497
2632
|
};
|
|
2498
|
-
const multisig =
|
|
2633
|
+
const multisig = createTestMultisig(config);
|
|
2499
2634
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
2500
2635
|
const newGuardianPubkey = '0x' + '1'.repeat(64);
|
|
2501
2636
|
multisig.proposals.set(proposalId, {
|
|
@@ -2541,7 +2676,7 @@ describe('Multisig', () => {
|
|
|
2541
2676
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2542
2677
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2543
2678
|
};
|
|
2544
|
-
const multisig =
|
|
2679
|
+
const multisig = createTestMultisig(config);
|
|
2545
2680
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
2546
2681
|
multisig.proposals.set(proposalId, {
|
|
2547
2682
|
id: proposalId,
|
|
@@ -2576,7 +2711,7 @@ describe('Multisig', () => {
|
|
|
2576
2711
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
2577
2712
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2578
2713
|
};
|
|
2579
|
-
const multisig =
|
|
2714
|
+
const multisig = createTestMultisig(config);
|
|
2580
2715
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
2581
2716
|
multisig.proposals.set(proposalId, {
|
|
2582
2717
|
id: proposalId,
|
|
@@ -2621,7 +2756,7 @@ describe('Multisig', () => {
|
|
|
2621
2756
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
2622
2757
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2623
2758
|
};
|
|
2624
|
-
const multisig =
|
|
2759
|
+
const multisig = createTestMultisig(config);
|
|
2625
2760
|
const proposalId = '0x' + 'c'.repeat(64);
|
|
2626
2761
|
multisig.proposals.set(proposalId, {
|
|
2627
2762
|
id: proposalId,
|
|
@@ -2687,7 +2822,7 @@ describe('Multisig', () => {
|
|
|
2687
2822
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2688
2823
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2689
2824
|
};
|
|
2690
|
-
const multisig =
|
|
2825
|
+
const multisig = createTestMultisig(config);
|
|
2691
2826
|
const builtinDelta = {
|
|
2692
2827
|
...customDelta('change_threshold', [falconSig('0x' + 'a'.repeat(64))]),
|
|
2693
2828
|
};
|
|
@@ -2709,7 +2844,7 @@ describe('Multisig', () => {
|
|
|
2709
2844
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
2710
2845
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2711
2846
|
};
|
|
2712
|
-
const multisig =
|
|
2847
|
+
const multisig = createTestMultisig(config);
|
|
2713
2848
|
mockFetch.mockResolvedValueOnce({
|
|
2714
2849
|
ok: true,
|
|
2715
2850
|
json: async () => customDelta('b2agg', [falconSig('0x' + 'a'.repeat(64))]),
|
|
@@ -2722,7 +2857,7 @@ describe('Multisig', () => {
|
|
|
2722
2857
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2723
2858
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2724
2859
|
};
|
|
2725
|
-
const multisig =
|
|
2860
|
+
const multisig = createTestMultisig(config);
|
|
2726
2861
|
// Signed commitment comes from TransactionSummary.deserialize -> 'c' * 64.
|
|
2727
2862
|
// Make the binding request derive a different commitment so the check fails.
|
|
2728
2863
|
vi.mocked(executeForSummary).mockResolvedValueOnce({
|
|
@@ -2743,7 +2878,7 @@ describe('Multisig', () => {
|
|
|
2743
2878
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2744
2879
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2745
2880
|
};
|
|
2746
|
-
const multisig =
|
|
2881
|
+
const multisig = createTestMultisig(config);
|
|
2747
2882
|
const ready = customDelta('b2agg', [falconSig('0x' + 'a'.repeat(64))]);
|
|
2748
2883
|
// getDeltaProposal
|
|
2749
2884
|
mockFetch.mockResolvedValueOnce({
|
|
@@ -2765,7 +2900,7 @@ describe('Multisig', () => {
|
|
|
2765
2900
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2766
2901
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2767
2902
|
};
|
|
2768
|
-
const multisig =
|
|
2903
|
+
const multisig = createTestMultisig(config);
|
|
2769
2904
|
// Create a proposal with metadata
|
|
2770
2905
|
const mockDelta = {
|
|
2771
2906
|
account_id: '0x' + 'a'.repeat(30),
|
|
@@ -2818,7 +2953,7 @@ describe('Multisig', () => {
|
|
|
2818
2953
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
2819
2954
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2820
2955
|
};
|
|
2821
|
-
const multisig =
|
|
2956
|
+
const multisig = createTestMultisig(config);
|
|
2822
2957
|
// Sync proposals - no local proposals exist
|
|
2823
2958
|
const mockProposals = [
|
|
2824
2959
|
{
|
|
@@ -2859,7 +2994,7 @@ describe('Multisig', () => {
|
|
|
2859
2994
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2860
2995
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2861
2996
|
};
|
|
2862
|
-
const multisig =
|
|
2997
|
+
const multisig = createTestMultisig(config);
|
|
2863
2998
|
const mockDelta = {
|
|
2864
2999
|
account_id: '0x' + 'a'.repeat(30),
|
|
2865
3000
|
nonce: 1,
|
|
@@ -2901,7 +3036,7 @@ describe('Multisig', () => {
|
|
|
2901
3036
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2902
3037
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2903
3038
|
};
|
|
2904
|
-
const multisig =
|
|
3039
|
+
const multisig = createTestMultisig(config);
|
|
2905
3040
|
const mockDelta = {
|
|
2906
3041
|
account_id: '0x' + 'a'.repeat(30),
|
|
2907
3042
|
nonce: 1,
|
|
@@ -2945,7 +3080,7 @@ describe('Multisig', () => {
|
|
|
2945
3080
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
2946
3081
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2947
3082
|
};
|
|
2948
|
-
const multisig =
|
|
3083
|
+
const multisig = createTestMultisig(config);
|
|
2949
3084
|
const mockDelta = {
|
|
2950
3085
|
account_id: '0x' + 'a'.repeat(30),
|
|
2951
3086
|
nonce: 1,
|
|
@@ -2990,7 +3125,7 @@ describe('Multisig', () => {
|
|
|
2990
3125
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
2991
3126
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
2992
3127
|
};
|
|
2993
|
-
const multisig =
|
|
3128
|
+
const multisig = createTestMultisig(config);
|
|
2994
3129
|
// First sync with 1 signature (pending)
|
|
2995
3130
|
const mockProposalsPending = [
|
|
2996
3131
|
{
|
|
@@ -3074,7 +3209,7 @@ describe('Multisig', () => {
|
|
|
3074
3209
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64), '0x' + 'c'.repeat(64)],
|
|
3075
3210
|
guardianCommitment: '0x' + 'd'.repeat(64),
|
|
3076
3211
|
};
|
|
3077
|
-
const multisig =
|
|
3212
|
+
const multisig = createTestMultisig(config);
|
|
3078
3213
|
expect(multisig.threshold).toBe(3);
|
|
3079
3214
|
});
|
|
3080
3215
|
it('should expose signerCommitments', () => {
|
|
@@ -3084,7 +3219,7 @@ describe('Multisig', () => {
|
|
|
3084
3219
|
signerCommitments,
|
|
3085
3220
|
guardianCommitment: '0x' + 'd'.repeat(64),
|
|
3086
3221
|
};
|
|
3087
|
-
const multisig =
|
|
3222
|
+
const multisig = createTestMultisig(config);
|
|
3088
3223
|
expect(multisig.signerCommitments).toEqual(signerCommitments);
|
|
3089
3224
|
});
|
|
3090
3225
|
it('should expose guardianCommitment', () => {
|
|
@@ -3094,7 +3229,7 @@ describe('Multisig', () => {
|
|
|
3094
3229
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
3095
3230
|
guardianCommitment,
|
|
3096
3231
|
};
|
|
3097
|
-
const multisig =
|
|
3232
|
+
const multisig = createTestMultisig(config);
|
|
3098
3233
|
expect(multisig.guardianCommitment).toBe(guardianCommitment);
|
|
3099
3234
|
});
|
|
3100
3235
|
it('should expose account when provided', () => {
|
|
@@ -3103,7 +3238,7 @@ describe('Multisig', () => {
|
|
|
3103
3238
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
3104
3239
|
guardianCommitment: '0x' + 'd'.repeat(64),
|
|
3105
3240
|
};
|
|
3106
|
-
const multisig =
|
|
3241
|
+
const multisig = createTestMultisig(config);
|
|
3107
3242
|
expect(multisig.account).toBe(mockAccount);
|
|
3108
3243
|
});
|
|
3109
3244
|
});
|
|
@@ -3114,7 +3249,7 @@ describe('Multisig', () => {
|
|
|
3114
3249
|
signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
|
|
3115
3250
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
3116
3251
|
};
|
|
3117
|
-
const multisig =
|
|
3252
|
+
const multisig = createTestMultisig(config);
|
|
3118
3253
|
// Simulates a GUARDIAN response with canonical snake_case metadata
|
|
3119
3254
|
const rustProposals = [
|
|
3120
3255
|
{
|
|
@@ -3158,7 +3293,7 @@ describe('Multisig', () => {
|
|
|
3158
3293
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
3159
3294
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
3160
3295
|
};
|
|
3161
|
-
const multisig =
|
|
3296
|
+
const multisig = createTestMultisig(config);
|
|
3162
3297
|
// P2ID proposal with canonical snake_case fields
|
|
3163
3298
|
const p2idProposals = [
|
|
3164
3299
|
{
|
|
@@ -3209,7 +3344,7 @@ describe('Multisig', () => {
|
|
|
3209
3344
|
signerCommitments: ['0x' + 'a'.repeat(64)],
|
|
3210
3345
|
guardianCommitment: '0x' + 'c'.repeat(64),
|
|
3211
3346
|
};
|
|
3212
|
-
const multisig =
|
|
3347
|
+
const multisig = createTestMultisig(config);
|
|
3213
3348
|
const switchGuardianProposals = [
|
|
3214
3349
|
{
|
|
3215
3350
|
account_id: '0x' + 'a'.repeat(30),
|