@openzeppelin/miden-multisig-client 0.14.6 → 0.14.9-rc.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 +114 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/multisig/config.d.ts +8 -0
- package/dist/multisig/config.d.ts.map +1 -0
- package/dist/multisig/config.js +8 -0
- package/dist/multisig/config.js.map +1 -0
- package/dist/multisig/consumeNotesErrors.d.ts +48 -0
- package/dist/multisig/consumeNotesErrors.d.ts.map +1 -0
- package/dist/multisig/consumeNotesErrors.js +58 -0
- package/dist/multisig/consumeNotesErrors.js.map +1 -0
- package/dist/multisig/consumeNotesErrors.test.d.ts +2 -0
- package/dist/multisig/consumeNotesErrors.test.d.ts.map +1 -0
- package/dist/multisig/consumeNotesErrors.test.js +28 -0
- package/dist/multisig/consumeNotesErrors.test.js.map +1 -0
- package/dist/multisig/proposal/execution.js +3 -2
- package/dist/multisig/proposal/execution.js.map +1 -1
- package/dist/multisig.d.ts +28 -5
- package/dist/multisig.d.ts.map +1 -1
- package/dist/multisig.js +235 -8
- package/dist/multisig.js.map +1 -1
- package/dist/proposal/metadata.d.ts.map +1 -1
- package/dist/proposal/metadata.js +18 -5
- package/dist/proposal/metadata.js.map +1 -1
- package/dist/proposal/metadata.test.d.ts +2 -0
- package/dist/proposal/metadata.test.d.ts.map +1 -0
- package/dist/proposal/metadata.test.js +87 -0
- package/dist/proposal/metadata.test.js.map +1 -0
- package/dist/transaction/consumeNotes.d.ts +13 -1
- package/dist/transaction/consumeNotes.d.ts.map +1 -1
- package/dist/transaction/consumeNotes.js +30 -13
- package/dist/transaction/consumeNotes.js.map +1 -1
- package/dist/types/proposal.d.ts +26 -5
- package/dist/types/proposal.d.ts.map +1 -1
- package/dist/types/proposal.js +10 -1
- package/dist/types/proposal.js.map +1 -1
- package/dist/types/proposal.test.d.ts +2 -0
- package/dist/types/proposal.test.d.ts.map +1 -0
- package/dist/types/proposal.test.js +56 -0
- package/dist/types/proposal.test.js.map +1 -0
- package/dist/utils/encoding.d.ts +8 -0
- package/dist/utils/encoding.d.ts.map +1 -1
- package/dist/utils/encoding.js +8 -0
- package/dist/utils/encoding.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +24 -0
- package/src/multisig/config.ts +7 -0
- package/src/multisig/consumeNotesErrors.test.ts +43 -0
- package/src/multisig/consumeNotesErrors.ts +74 -0
- package/src/multisig.ts +341 -12
- package/src/proposal/metadata.test.ts +99 -0
- package/src/proposal/metadata.ts +19 -6
- package/src/transaction/consumeNotes.ts +40 -17
- package/src/types/proposal.test.ts +68 -0
- package/src/types/proposal.ts +42 -9
- package/src/utils/encoding.ts +13 -0
- package/src/multisig/proposal/execution.ts +0 -385
- package/src/multisig/proposal/parser.ts +0 -191
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { ProposalMetadataCodec } from './metadata.js';
|
|
3
|
+
describe('ProposalMetadataCodec consume_notes v2 round-trip (issue #229)', () => {
|
|
4
|
+
it('toGuardian threads metadataVersion and notes to the wire', () => {
|
|
5
|
+
const md = {
|
|
6
|
+
proposalType: 'consume_notes',
|
|
7
|
+
description: 'consume one note',
|
|
8
|
+
noteIds: ['0xabc'],
|
|
9
|
+
metadataVersion: 2,
|
|
10
|
+
notes: ['YmFzZTY0Tm90ZQ=='],
|
|
11
|
+
};
|
|
12
|
+
const wire = ProposalMetadataCodec.toGuardian(md);
|
|
13
|
+
expect(wire.noteIds).toEqual(['0xabc']);
|
|
14
|
+
expect(wire.consumeNotesMetadataVersion).toBe(2);
|
|
15
|
+
expect(wire.consumeNotesNotes).toEqual(['YmFzZTY0Tm90ZQ==']);
|
|
16
|
+
});
|
|
17
|
+
it('fromGuardian reconstructs the v2 fields', () => {
|
|
18
|
+
const wire = {
|
|
19
|
+
proposalType: 'consume_notes',
|
|
20
|
+
noteIds: ['0xabc'],
|
|
21
|
+
consumeNotesMetadataVersion: 2,
|
|
22
|
+
consumeNotesNotes: ['YmFzZTY0Tm90ZQ=='],
|
|
23
|
+
};
|
|
24
|
+
const md = ProposalMetadataCodec.fromGuardian(wire);
|
|
25
|
+
expect(md.proposalType).toBe('consume_notes');
|
|
26
|
+
expect(md.metadataVersion).toBe(2);
|
|
27
|
+
expect(md.notes).toEqual(['YmFzZTY0Tm90ZQ==']);
|
|
28
|
+
});
|
|
29
|
+
it('round-trips a v1 (legacy) proposal without spurious v2 fields', () => {
|
|
30
|
+
const md = {
|
|
31
|
+
proposalType: 'consume_notes',
|
|
32
|
+
description: 'legacy',
|
|
33
|
+
noteIds: ['0xabc'],
|
|
34
|
+
};
|
|
35
|
+
const wire = ProposalMetadataCodec.toGuardian(md);
|
|
36
|
+
expect(wire.consumeNotesMetadataVersion).toBeUndefined();
|
|
37
|
+
expect(wire.consumeNotesNotes).toBeUndefined();
|
|
38
|
+
const back = ProposalMetadataCodec.fromGuardian(wire);
|
|
39
|
+
expect(back.metadataVersion).toBeUndefined();
|
|
40
|
+
expect(back.notes).toBeUndefined();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('ProposalMetadataCodec custom proposal types (issue #266)', () => {
|
|
44
|
+
it('fromGuardian collapses an unmodeled type to the custom bucket, keeping the raw label', () => {
|
|
45
|
+
const wire = {
|
|
46
|
+
proposalType: 'b2agg',
|
|
47
|
+
description: 'agglayer bridge note',
|
|
48
|
+
};
|
|
49
|
+
const md = ProposalMetadataCodec.fromGuardian(wire);
|
|
50
|
+
expect(md.proposalType).toBe('custom');
|
|
51
|
+
expect(md.rawProposalType).toBe('b2agg');
|
|
52
|
+
});
|
|
53
|
+
it('toGuardian round-trips the raw label, not the custom bucket', () => {
|
|
54
|
+
const md = {
|
|
55
|
+
proposalType: 'custom',
|
|
56
|
+
description: 'agglayer bridge note',
|
|
57
|
+
rawProposalType: 'b2agg',
|
|
58
|
+
};
|
|
59
|
+
const wire = ProposalMetadataCodec.toGuardian(md);
|
|
60
|
+
expect(wire.proposalType).toBe('b2agg');
|
|
61
|
+
const back = ProposalMetadataCodec.fromGuardian(wire);
|
|
62
|
+
expect(back.proposalType).toBe('custom');
|
|
63
|
+
expect(back.rawProposalType).toBe('b2agg');
|
|
64
|
+
});
|
|
65
|
+
it('validate accepts a custom proposal', () => {
|
|
66
|
+
const md = {
|
|
67
|
+
proposalType: 'custom',
|
|
68
|
+
description: 'opaque',
|
|
69
|
+
rawProposalType: 'b2agg',
|
|
70
|
+
};
|
|
71
|
+
expect(ProposalMetadataCodec.validate(md)).toBe(md);
|
|
72
|
+
});
|
|
73
|
+
it('round-trips update_procedure_threshold through the codec', () => {
|
|
74
|
+
const wire = {
|
|
75
|
+
proposalType: 'update_procedure_threshold',
|
|
76
|
+
targetProcedure: 'send_asset',
|
|
77
|
+
targetThreshold: 2,
|
|
78
|
+
};
|
|
79
|
+
const md = ProposalMetadataCodec.fromGuardian(wire);
|
|
80
|
+
expect(md.proposalType).toBe('update_procedure_threshold');
|
|
81
|
+
const back = ProposalMetadataCodec.toGuardian(md);
|
|
82
|
+
expect(back.proposalType).toBe('update_procedure_threshold');
|
|
83
|
+
expect(back.targetProcedure).toBe('send_asset');
|
|
84
|
+
expect(back.targetThreshold).toBe(2);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=metadata.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.test.js","sourceRoot":"","sources":["../../src/proposal/metadata.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
import type { MidenClient, TransactionRequest, WasmWebClient, Word } from '@miden-sdk/miden-sdk';
|
|
1
|
+
import type { MidenClient, Note, TransactionRequest, WasmWebClient, Word } from '@miden-sdk/miden-sdk';
|
|
2
2
|
import type { SignatureOptions } from './options.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build a consume-notes request from loaded `Note` objects (no local-store
|
|
5
|
+
* read). v2 verification path for issue #229.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildConsumeNotesTransactionRequestFromNotes(notes: Note[], options?: SignatureOptions): {
|
|
8
|
+
request: TransactionRequest;
|
|
9
|
+
salt: Word;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Legacy/creation adapter: fetches notes from the local store and delegates
|
|
13
|
+
* to the from-notes variant. v2 verification MUST NOT call this.
|
|
14
|
+
*/
|
|
3
15
|
export declare function buildConsumeNotesTransactionRequest(client: MidenClient | WasmWebClient, noteIds: string[], options?: SignatureOptions): Promise<{
|
|
4
16
|
request: TransactionRequest;
|
|
5
17
|
salt: Word;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consumeNotes.d.ts","sourceRoot":"","sources":["../../src/transaction/consumeNotes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,IAAI,EACL,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"consumeNotes.d.ts","sourceRoot":"","sources":["../../src/transaction/consumeNotes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,IAAI,EACJ,kBAAkB,EAClB,aAAa,EACb,IAAI,EACL,MAAM,sBAAsB,CAAC;AAW9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;GAGG;AACH,wBAAgB,4CAA4C,CAC1D,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,GAAE,gBAAqB,GAC7B;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CA2B7C;AAED;;;GAGG;AACH,wBAAsB,mCAAmC,CACvD,MAAM,EAAE,WAAW,GAAG,aAAa,EACnC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC,CAgBtD"}
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import { NoteAndArgs, NoteAndArgsArray, TransactionRequestBuilder, Word as WordType, } from '@miden-sdk/miden-sdk';
|
|
2
|
+
import { LegacyConsumeNotesNoteMissingError } from '../multisig/consumeNotesErrors.js';
|
|
2
3
|
import { getRawMidenClient } from '../raw-client.js';
|
|
3
|
-
import { randomWord } from '../utils/random.js';
|
|
4
4
|
import { normalizeHexWord } from '../utils/encoding.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { randomWord } from '../utils/random.js';
|
|
6
|
+
/**
|
|
7
|
+
* Build a consume-notes request from loaded `Note` objects (no local-store
|
|
8
|
+
* read). v2 verification path for issue #229.
|
|
9
|
+
*/
|
|
10
|
+
export function buildConsumeNotesTransactionRequestFromNotes(notes, options = {}) {
|
|
11
|
+
if (notes.length === 0) {
|
|
12
|
+
throw new Error('At least one note is required');
|
|
8
13
|
}
|
|
9
|
-
const rawClient = await getRawMidenClient(client, options.midenRpcEndpoint);
|
|
10
14
|
const noteAndArgsArray = new NoteAndArgsArray();
|
|
11
|
-
for (const
|
|
12
|
-
|
|
13
|
-
if (!inputNoteRecord) {
|
|
14
|
-
throw new Error(`Note not found in local store: ${noteIdHex}`);
|
|
15
|
-
}
|
|
16
|
-
const note = inputNoteRecord.toNote();
|
|
17
|
-
const noteAndArgs = new NoteAndArgs(note, null);
|
|
18
|
-
noteAndArgsArray.push(noteAndArgs);
|
|
15
|
+
for (const note of notes) {
|
|
16
|
+
noteAndArgsArray.push(new NoteAndArgs(note, null));
|
|
19
17
|
}
|
|
20
18
|
const authSaltHex = options.salt ? options.salt.toHex() : randomWord().toHex();
|
|
21
19
|
const authSaltForBuilder = WordType.fromHex(normalizeHexWord(authSaltHex));
|
|
@@ -31,4 +29,23 @@ export async function buildConsumeNotesTransactionRequest(client, noteIds, optio
|
|
|
31
29
|
salt: authSaltForReturn,
|
|
32
30
|
};
|
|
33
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Legacy/creation adapter: fetches notes from the local store and delegates
|
|
34
|
+
* to the from-notes variant. v2 verification MUST NOT call this.
|
|
35
|
+
*/
|
|
36
|
+
export async function buildConsumeNotesTransactionRequest(client, noteIds, options = {}) {
|
|
37
|
+
if (noteIds.length === 0) {
|
|
38
|
+
throw new Error('At least one note ID is required');
|
|
39
|
+
}
|
|
40
|
+
const rawClient = await getRawMidenClient(client, options.midenRpcEndpoint);
|
|
41
|
+
const notes = [];
|
|
42
|
+
for (const noteIdHex of noteIds) {
|
|
43
|
+
const inputNoteRecord = await rawClient.getInputNote(noteIdHex);
|
|
44
|
+
if (!inputNoteRecord) {
|
|
45
|
+
throw new LegacyConsumeNotesNoteMissingError(noteIdHex);
|
|
46
|
+
}
|
|
47
|
+
notes.push(inputNoteRecord.toNote());
|
|
48
|
+
}
|
|
49
|
+
return buildConsumeNotesTransactionRequestFromNotes(notes, options);
|
|
50
|
+
}
|
|
34
51
|
//# sourceMappingURL=consumeNotes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consumeNotes.js","sourceRoot":"","sources":["../../src/transaction/consumeNotes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"consumeNotes.js","sourceRoot":"","sources":["../../src/transaction/consumeNotes.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,yBAAyB,EACzB,IAAI,IAAI,QAAQ,GACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kCAAkC,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD;;;GAGG;AACH,MAAM,UAAU,4CAA4C,CAC1D,KAAa,EACb,UAA4B,EAAE;IAE9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,gBAAgB,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,CAAC;IAC/E,MAAM,kBAAkB,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC;IAE3E,IAAI,SAAS,GAAG,IAAI,yBAAyB,EAAE,CAAC;IAChD,SAAS,GAAG,SAAS,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;IACvD,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAEtD,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAC/B,SAAS,GAAG,SAAS,CAAC,eAAe,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC;IAE1E,OAAO;QACL,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE;QAC1B,IAAI,EAAE,iBAAiB;KACxB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mCAAmC,CACvD,MAAmC,EACnC,OAAiB,EACjB,UAA4B,EAAE;IAE9B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;QAChC,MAAM,eAAe,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAChE,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,MAAM,IAAI,kCAAkC,CAAC,SAAS,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,4CAA4C,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC"}
|
package/dist/types/proposal.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import type { ProposalSignature,
|
|
1
|
+
import type { ProposalSignature, SignatureScheme } from '@openzeppelin/guardian-client';
|
|
2
2
|
import type { ProcedureName } from '../procedures.js';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Closed set of proposal types the multisig SDK models behaviorally, plus the
|
|
5
|
+
* `'custom'` bucket for any server-defined type the SDK does not model (issue
|
|
6
|
+
* #266). Defined explicitly (not derived from the now-arbitrary guardian-client
|
|
7
|
+
* wire union) so the exhaustive switches in the metadata codec stay sound.
|
|
8
|
+
*/
|
|
9
|
+
export type ProposalType = 'add_signer' | 'remove_signer' | 'change_threshold' | 'update_procedure_threshold' | 'switch_guardian' | 'consume_notes' | 'p2id' | 'custom';
|
|
4
10
|
export type ProposalStatus = 'pending' | 'ready' | 'finalized';
|
|
5
11
|
export type TransactionProposalStatus = {
|
|
6
12
|
type: 'pending';
|
|
@@ -41,20 +47,35 @@ export interface UpdateProcedureThresholdProposalMetadata extends BaseProposalMe
|
|
|
41
47
|
targetProcedure: ProcedureName;
|
|
42
48
|
targetThreshold: number;
|
|
43
49
|
}
|
|
50
|
+
/** `consume_notes` metadata version. Absence on the wire => v1 (issue #229). */
|
|
51
|
+
export declare const CONSUME_NOTES_METADATA_VERSION_V2: 2;
|
|
52
|
+
/** Max serialized v2 metadata, enforced at creation (FR-011). */
|
|
53
|
+
export declare const MAX_CONSUME_NOTES_METADATA_BYTES: number;
|
|
44
54
|
export interface ConsumeNotesProposalMetadata extends BaseProposalMetadata {
|
|
45
55
|
proposalType: 'consume_notes';
|
|
46
56
|
noteIds: string[];
|
|
57
|
+
/** Absent or `1` => v1 (legacy), `2` => v2 (issue #229). */
|
|
58
|
+
metadataVersion?: 1 | 2;
|
|
59
|
+
/** v2: base64-encoded `note.serialize()` output, index-aligned with `noteIds`. */
|
|
60
|
+
notes?: string[];
|
|
47
61
|
}
|
|
62
|
+
export declare function isConsumeNotesV2(md: ConsumeNotesProposalMetadata): boolean;
|
|
63
|
+
export declare function isConsumeNotesV1(md: ConsumeNotesProposalMetadata): boolean;
|
|
48
64
|
export interface P2IdProposalMetadata extends BaseProposalMetadata {
|
|
49
65
|
proposalType: 'p2id';
|
|
50
66
|
recipientId: string;
|
|
51
67
|
faucetId: string;
|
|
52
68
|
amount: string;
|
|
53
69
|
}
|
|
54
|
-
export interface
|
|
55
|
-
proposalType: '
|
|
70
|
+
export interface CustomProposalMetadata extends BaseProposalMetadata {
|
|
71
|
+
proposalType: 'custom';
|
|
72
|
+
/** Original server-defined proposal label, e.g. "b2agg" (issue #266). Mirrors
|
|
73
|
+
* Rust `ProposalMetadata.proposal_type`; it is what lets a custom proposal
|
|
74
|
+
* round-trip back to GUARDIAN/export, so it is required in the domain model.
|
|
75
|
+
* Any wire-level optionality is resolved in the parser/codec boundary. */
|
|
76
|
+
rawProposalType: string;
|
|
56
77
|
}
|
|
57
|
-
export type ProposalMetadata = UpdateSignersProposalMetadata | SwitchGuardianProposalMetadata | UpdateProcedureThresholdProposalMetadata | ConsumeNotesProposalMetadata | P2IdProposalMetadata |
|
|
78
|
+
export type ProposalMetadata = UpdateSignersProposalMetadata | SwitchGuardianProposalMetadata | UpdateProcedureThresholdProposalMetadata | ConsumeNotesProposalMetadata | P2IdProposalMetadata | CustomProposalMetadata;
|
|
58
79
|
export interface Proposal {
|
|
59
80
|
id: string;
|
|
60
81
|
accountId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proposal.d.ts","sourceRoot":"","sources":["../../src/types/proposal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"proposal.d.ts","sourceRoot":"","sources":["../../src/types/proposal.ts"],"names":[],"mappings":"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"}
|
package/dist/types/proposal.js
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/** `consume_notes` metadata version. Absence on the wire => v1 (issue #229). */
|
|
2
|
+
export const CONSUME_NOTES_METADATA_VERSION_V2 = 2;
|
|
3
|
+
/** Max serialized v2 metadata, enforced at creation (FR-011). */
|
|
4
|
+
export const MAX_CONSUME_NOTES_METADATA_BYTES = 256 * 1024;
|
|
5
|
+
export function isConsumeNotesV2(md) {
|
|
6
|
+
return md.metadataVersion === CONSUME_NOTES_METADATA_VERSION_V2;
|
|
7
|
+
}
|
|
8
|
+
export function isConsumeNotesV1(md) {
|
|
9
|
+
return md.metadataVersion === undefined || md.metadataVersion === 1;
|
|
10
|
+
}
|
|
2
11
|
//# sourceMappingURL=proposal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proposal.js","sourceRoot":"","sources":["../../src/types/proposal.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"proposal.js","sourceRoot":"","sources":["../../src/types/proposal.ts"],"names":[],"mappings":"AA6DA,gFAAgF;AAChF,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAU,CAAC;AAE5D,iEAAiE;AACjE,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAG,GAAG,IAAI,CAAC;AAW3D,MAAM,UAAU,gBAAgB,CAAC,EAAgC;IAC/D,OAAO,EAAE,CAAC,eAAe,KAAK,iCAAiC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAgC;IAC/D,OAAO,EAAE,CAAC,eAAe,KAAK,SAAS,IAAI,EAAE,CAAC,eAAe,KAAK,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposal.test.d.ts","sourceRoot":"","sources":["../../src/types/proposal.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { CONSUME_NOTES_METADATA_VERSION_V2, MAX_CONSUME_NOTES_METADATA_BYTES, isConsumeNotesV1, isConsumeNotesV2, } from './proposal.js';
|
|
3
|
+
describe('consume_notes metadata v1/v2 discriminator (issue #229)', () => {
|
|
4
|
+
it('v1 metadata omits metadataVersion and notes on the wire', () => {
|
|
5
|
+
const md = {
|
|
6
|
+
proposalType: 'consume_notes',
|
|
7
|
+
description: '',
|
|
8
|
+
noteIds: ['0xabc', '0xdef'],
|
|
9
|
+
};
|
|
10
|
+
const json = JSON.parse(JSON.stringify(md));
|
|
11
|
+
expect(json.metadataVersion).toBeUndefined();
|
|
12
|
+
expect(json.notes).toBeUndefined();
|
|
13
|
+
expect(isConsumeNotesV1(md)).toBe(true);
|
|
14
|
+
expect(isConsumeNotesV2(md)).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
it('v2 metadata round-trips with discriminator and embedded notes', () => {
|
|
17
|
+
const md = {
|
|
18
|
+
proposalType: 'consume_notes',
|
|
19
|
+
description: '',
|
|
20
|
+
noteIds: ['0xabc'],
|
|
21
|
+
metadataVersion: CONSUME_NOTES_METADATA_VERSION_V2,
|
|
22
|
+
notes: ['YmFzZTY0Tm90ZQ=='],
|
|
23
|
+
};
|
|
24
|
+
const json = JSON.stringify(md);
|
|
25
|
+
const parsed = JSON.parse(json);
|
|
26
|
+
expect(parsed.metadataVersion).toBe(2);
|
|
27
|
+
expect(parsed.notes).toEqual(['YmFzZTY0Tm90ZQ==']);
|
|
28
|
+
expect(isConsumeNotesV2(parsed)).toBe(true);
|
|
29
|
+
expect(isConsumeNotesV1(parsed)).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
it('explicit metadataVersion === 1 is treated as v1', () => {
|
|
32
|
+
const md = {
|
|
33
|
+
proposalType: 'consume_notes',
|
|
34
|
+
description: '',
|
|
35
|
+
noteIds: ['0xabc'],
|
|
36
|
+
metadataVersion: 1, // legacy explicit-v1 case
|
|
37
|
+
};
|
|
38
|
+
expect(isConsumeNotesV1(md)).toBe(true);
|
|
39
|
+
expect(isConsumeNotesV2(md)).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
it('unknown future version is neither v1 nor v2; dispatch handles rejection', () => {
|
|
42
|
+
const md = {
|
|
43
|
+
proposalType: 'consume_notes',
|
|
44
|
+
description: '',
|
|
45
|
+
noteIds: ['0xabc'],
|
|
46
|
+
metadataVersion: 99,
|
|
47
|
+
};
|
|
48
|
+
expect(isConsumeNotesV1(md)).toBe(false);
|
|
49
|
+
expect(isConsumeNotesV2(md)).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
it('pins MAX_CONSUME_NOTES_METADATA_BYTES at 256 KiB', () => {
|
|
52
|
+
expect(MAX_CONSUME_NOTES_METADATA_BYTES).toBe(256 * 1024);
|
|
53
|
+
expect(MAX_CONSUME_NOTES_METADATA_BYTES).toBe(262_144);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=proposal.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposal.test.js","sourceRoot":"","sources":["../../src/types/proposal.test.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/encoding.d.ts
CHANGED
|
@@ -3,5 +3,13 @@ export declare function normalizeHexWord(hex: string): string;
|
|
|
3
3
|
export declare function bytesToHex(bytes: Uint8Array): string;
|
|
4
4
|
export declare function hexToBytes(hex: string): Uint8Array;
|
|
5
5
|
export declare function uint8ArrayToBase64(bytes: Uint8Array): string;
|
|
6
|
+
/** Serialize a Miden `Note` to base64 (v2 `consume_notes` metadata, issue #229). */
|
|
7
|
+
export declare function noteToBase64(note: {
|
|
8
|
+
serialize(): Uint8Array;
|
|
9
|
+
}): string;
|
|
10
|
+
/** Decode a base64 note. `noteCtor` is `Note` from `@miden-sdk/miden-sdk`. */
|
|
11
|
+
export declare function noteFromBase64<TNote>(base64: string, noteCtor: {
|
|
12
|
+
deserialize(bytes: Uint8Array): TNote;
|
|
13
|
+
}): TNote;
|
|
6
14
|
export declare function base64ToUint8Array(base64: string): Uint8Array;
|
|
7
15
|
//# sourceMappingURL=encoding.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMpD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAOlD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAa5D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAgB7D"}
|
|
1
|
+
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMpD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAOlD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAa5D;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,SAAS,IAAI,UAAU,CAAA;CAAE,GAAG,MAAM,CAEtE;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,KAAK,EAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE;IAAE,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,KAAK,CAAA;CAAE,GAClD,KAAK,CAEP;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAgB7D"}
|
package/dist/utils/encoding.js
CHANGED
|
@@ -35,6 +35,14 @@ export function uint8ArrayToBase64(bytes) {
|
|
|
35
35
|
}
|
|
36
36
|
throw new Error('No base64 encoder available in this environment');
|
|
37
37
|
}
|
|
38
|
+
/** Serialize a Miden `Note` to base64 (v2 `consume_notes` metadata, issue #229). */
|
|
39
|
+
export function noteToBase64(note) {
|
|
40
|
+
return uint8ArrayToBase64(note.serialize());
|
|
41
|
+
}
|
|
42
|
+
/** Decode a base64 note. `noteCtor` is `Note` from `@miden-sdk/miden-sdk`. */
|
|
43
|
+
export function noteFromBase64(base64, noteCtor) {
|
|
44
|
+
return noteCtor.deserialize(base64ToUint8Array(base64));
|
|
45
|
+
}
|
|
38
46
|
export function base64ToUint8Array(base64) {
|
|
39
47
|
const binary = typeof atob === 'function'
|
|
40
48
|
? atob(base64)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openzeppelin/miden-multisig-client",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.9-rc.0",
|
|
4
4
|
"description": "TypeScript SDK for Miden multisig accounts with GUARDIAN integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@noble/curves": "^1.9.7",
|
|
31
31
|
"@miden-sdk/miden-sdk": "0.14.5",
|
|
32
32
|
"@noble/hashes": "^2.0.1",
|
|
33
|
-
"@openzeppelin/guardian-client": "^0.14.
|
|
33
|
+
"@openzeppelin/guardian-client": "^0.14.9-rc.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"typescript": "^5.7.2",
|
package/src/index.ts
CHANGED
|
@@ -79,6 +79,30 @@ export {
|
|
|
79
79
|
StorageLayoutBuilder,
|
|
80
80
|
} from './account/index.js';
|
|
81
81
|
|
|
82
|
+
export {
|
|
83
|
+
CONSUME_NOTES_METADATA_VERSION_V2,
|
|
84
|
+
MAX_CONSUME_NOTES_METADATA_BYTES,
|
|
85
|
+
isConsumeNotesV1,
|
|
86
|
+
isConsumeNotesV2,
|
|
87
|
+
} from './types/proposal.js';
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
LEGACY_CONSUME_NOTES_ENABLED,
|
|
91
|
+
} from './multisig/config.js';
|
|
92
|
+
|
|
93
|
+
export {
|
|
94
|
+
type ConsumeNotesErrorCode,
|
|
95
|
+
NoteBindingMismatchError,
|
|
96
|
+
UnsupportedMetadataVersionError,
|
|
97
|
+
ConsumeNotesMetadataOversizeError,
|
|
98
|
+
LegacyConsumeNotesNoteMissingError,
|
|
99
|
+
} from './multisig/consumeNotesErrors.js';
|
|
100
|
+
|
|
101
|
+
export {
|
|
102
|
+
noteToBase64,
|
|
103
|
+
noteFromBase64,
|
|
104
|
+
} from './utils/encoding.js';
|
|
105
|
+
|
|
82
106
|
export {
|
|
83
107
|
PROCEDURE_ROOTS,
|
|
84
108
|
getProcedureRoot,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether this build accepts v1 `consume_notes` metadata (issue #229).
|
|
3
|
+
* Mirrors the Rust `legacy-consume-notes` Cargo feature. Flip to `false`
|
|
4
|
+
* in the cut-over release; v1 proposals will then be refused with
|
|
5
|
+
* `UnsupportedMetadataVersionError`.
|
|
6
|
+
*/
|
|
7
|
+
export const LEGACY_CONSUME_NOTES_ENABLED = true;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
ConsumeNotesMetadataOversizeError,
|
|
4
|
+
LegacyConsumeNotesNoteMissingError,
|
|
5
|
+
NoteBindingMismatchError,
|
|
6
|
+
UnsupportedMetadataVersionError,
|
|
7
|
+
} from './consumeNotesErrors.js';
|
|
8
|
+
|
|
9
|
+
describe('consume_notes error taxonomy (issue #229)', () => {
|
|
10
|
+
it('pins stable codes identical to the Rust SDK', () => {
|
|
11
|
+
expect(new NoteBindingMismatchError('x').code).toBe('consume_notes_note_binding_mismatch');
|
|
12
|
+
expect(new UnsupportedMetadataVersionError(99).code).toBe(
|
|
13
|
+
'consume_notes_unsupported_metadata_version',
|
|
14
|
+
);
|
|
15
|
+
expect(new ConsumeNotesMetadataOversizeError(1, 2).code).toBe(
|
|
16
|
+
'consume_notes_metadata_oversize',
|
|
17
|
+
);
|
|
18
|
+
expect(new LegacyConsumeNotesNoteMissingError('0xabc').code).toBe(
|
|
19
|
+
'consume_notes_legacy_note_missing',
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('preserves structured error fields for programmatic branching', () => {
|
|
24
|
+
const oversize = new ConsumeNotesMetadataOversizeError(262_144, 300_000);
|
|
25
|
+
expect(oversize.limit).toBe(262_144);
|
|
26
|
+
expect(oversize.actual).toBe(300_000);
|
|
27
|
+
|
|
28
|
+
const missing = new LegacyConsumeNotesNoteMissingError('0xnoteid');
|
|
29
|
+
expect(missing.noteId).toBe('0xnoteid');
|
|
30
|
+
|
|
31
|
+
const unsupported = new UnsupportedMetadataVersionError(99);
|
|
32
|
+
expect(unsupported.found).toBe(99);
|
|
33
|
+
const absent = new UnsupportedMetadataVersionError(undefined);
|
|
34
|
+
expect(absent.found).toBeUndefined();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('extends Error so instanceof Error and instanceof <subclass> both work', () => {
|
|
38
|
+
const err = new NoteBindingMismatchError('boom');
|
|
39
|
+
expect(err).toBeInstanceOf(Error);
|
|
40
|
+
expect(err).toBeInstanceOf(NoteBindingMismatchError);
|
|
41
|
+
expect(err.name).toBe('NoteBindingMismatchError');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable error identifiers for the `consume_notes` v2 metadata flow
|
|
3
|
+
* (issue #229). These string codes are pinned identical to the Rust
|
|
4
|
+
* SDK's `MultisigError::code()` values per spec FR-021 / FR-022, so
|
|
5
|
+
* cross-SDK tests and operator diagnostics share one taxonomy.
|
|
6
|
+
*/
|
|
7
|
+
export type ConsumeNotesErrorCode =
|
|
8
|
+
| 'consume_notes_note_binding_mismatch'
|
|
9
|
+
| 'consume_notes_unsupported_metadata_version'
|
|
10
|
+
| 'consume_notes_metadata_oversize'
|
|
11
|
+
| 'consume_notes_legacy_note_missing';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* v2 metadata's embedded `notes` array did not match its declared
|
|
15
|
+
* `noteIds` — either a length mismatch, or an embedded note whose
|
|
16
|
+
* `note.id()` did not match the corresponding `noteIds[i]`. Spec FR-007.
|
|
17
|
+
*/
|
|
18
|
+
export class NoteBindingMismatchError extends Error {
|
|
19
|
+
readonly code: ConsumeNotesErrorCode = 'consume_notes_note_binding_mismatch';
|
|
20
|
+
constructor(message: string) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = 'NoteBindingMismatchError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* `metadataVersion` is a value the client does not support — either a
|
|
28
|
+
* legacy (v1) proposal on a cut-over client, or an unrecognized future
|
|
29
|
+
* version. Spec FR-009 / FR-019.
|
|
30
|
+
*/
|
|
31
|
+
export class UnsupportedMetadataVersionError extends Error {
|
|
32
|
+
readonly code: ConsumeNotesErrorCode = 'consume_notes_unsupported_metadata_version';
|
|
33
|
+
readonly found: number | undefined;
|
|
34
|
+
constructor(found: number | undefined, message?: string) {
|
|
35
|
+
super(
|
|
36
|
+
message ??
|
|
37
|
+
`unsupported consume_notes metadata version: ${found === undefined ? 'absent' : String(found)}`,
|
|
38
|
+
);
|
|
39
|
+
this.name = 'UnsupportedMetadataVersionError';
|
|
40
|
+
this.found = found;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Serialized v2 metadata exceeded the per-proposal cap
|
|
46
|
+
* (`MAX_CONSUME_NOTES_METADATA_BYTES`, 256 KiB). Raised at proposal-
|
|
47
|
+
* creation time before any signature collection begins. Spec FR-011.
|
|
48
|
+
*/
|
|
49
|
+
export class ConsumeNotesMetadataOversizeError extends Error {
|
|
50
|
+
readonly code: ConsumeNotesErrorCode = 'consume_notes_metadata_oversize';
|
|
51
|
+
readonly limit: number;
|
|
52
|
+
readonly actual: number;
|
|
53
|
+
constructor(limit: number, actual: number) {
|
|
54
|
+
super(`consume_notes metadata exceeds size limit: limit=${limit} bytes, actual=${actual} bytes`);
|
|
55
|
+
this.name = 'ConsumeNotesMetadataOversizeError';
|
|
56
|
+
this.limit = limit;
|
|
57
|
+
this.actual = actual;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* v1 (legacy) verification path: the cosigner's local Miden store did
|
|
63
|
+
* not contain the referenced note. This is the exact failure issue #229
|
|
64
|
+
* exists to eliminate; on v2 proposals it is not reachable.
|
|
65
|
+
*/
|
|
66
|
+
export class LegacyConsumeNotesNoteMissingError extends Error {
|
|
67
|
+
readonly code: ConsumeNotesErrorCode = 'consume_notes_legacy_note_missing';
|
|
68
|
+
readonly noteId: string;
|
|
69
|
+
constructor(noteId: string) {
|
|
70
|
+
super(`consume_notes legacy verification: note not found in local store: ${noteId}`);
|
|
71
|
+
this.name = 'LegacyConsumeNotesNoteMissingError';
|
|
72
|
+
this.noteId = noteId;
|
|
73
|
+
}
|
|
74
|
+
}
|