@openzeppelin/miden-multisig-client 0.13.3 → 0.14.3

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.
Files changed (145) hide show
  1. package/README.md +10 -13
  2. package/dist/account/builder.d.ts +3 -3
  3. package/dist/account/builder.d.ts.map +1 -1
  4. package/dist/account/builder.js +10 -10
  5. package/dist/account/builder.js.map +1 -1
  6. package/dist/account/builder.test.js +16 -14
  7. package/dist/account/builder.test.js.map +1 -1
  8. package/dist/account/masm/account-components/auth.d.ts +4 -4
  9. package/dist/account/masm/account-components/auth.d.ts.map +1 -1
  10. package/dist/account/masm/account-components/auth.js +8 -12
  11. package/dist/account/masm/account-components/auth.js.map +1 -1
  12. package/dist/account/masm/auth.d.ts +4 -4
  13. package/dist/account/masm/auth.d.ts.map +1 -1
  14. package/dist/account/masm/auth.js +226 -124
  15. package/dist/account/masm/auth.js.map +1 -1
  16. package/dist/account/storage.d.ts.map +1 -1
  17. package/dist/account/storage.js +24 -6
  18. package/dist/account/storage.js.map +1 -1
  19. package/dist/account/storage.test.d.ts +2 -0
  20. package/dist/account/storage.test.d.ts.map +1 -0
  21. package/dist/account/storage.test.js +73 -0
  22. package/dist/account/storage.test.js.map +1 -0
  23. package/dist/client.d.ts +9 -9
  24. package/dist/client.d.ts.map +1 -1
  25. package/dist/client.js +24 -14
  26. package/dist/client.js.map +1 -1
  27. package/dist/client.test.js +45 -8
  28. package/dist/client.test.js.map +1 -1
  29. package/dist/index.d.ts +6 -12
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +6 -12
  32. package/dist/index.js.map +1 -1
  33. package/dist/multisig/proposal/execution.d.ts +3 -2
  34. package/dist/multisig/proposal/execution.d.ts.map +1 -1
  35. package/dist/multisig/proposal/execution.js +8 -12
  36. package/dist/multisig/proposal/execution.js.map +1 -1
  37. package/dist/multisig.d.ts +10 -4
  38. package/dist/multisig.d.ts.map +1 -1
  39. package/dist/multisig.js +97 -71
  40. package/dist/multisig.js.map +1 -1
  41. package/dist/multisig.test.js +481 -29
  42. package/dist/multisig.test.js.map +1 -1
  43. package/dist/procedures.d.ts +8 -8
  44. package/dist/procedures.js +8 -8
  45. package/dist/raw-client.d.ts +13 -0
  46. package/dist/raw-client.d.ts.map +1 -0
  47. package/dist/raw-client.js +42 -0
  48. package/dist/raw-client.js.map +1 -0
  49. package/dist/raw-client.test.d.ts +2 -0
  50. package/dist/raw-client.test.d.ts.map +1 -0
  51. package/dist/raw-client.test.js +89 -0
  52. package/dist/raw-client.test.js.map +1 -0
  53. package/dist/signers/ecdsa.d.ts +3 -1
  54. package/dist/signers/ecdsa.d.ts.map +1 -1
  55. package/dist/signers/ecdsa.js +15 -1
  56. package/dist/signers/ecdsa.js.map +1 -1
  57. package/dist/signers/ecdsa.test.js +27 -4
  58. package/dist/signers/ecdsa.test.js.map +1 -1
  59. package/dist/signers/falcon.d.ts +3 -1
  60. package/dist/signers/falcon.d.ts.map +1 -1
  61. package/dist/signers/falcon.js +15 -1
  62. package/dist/signers/falcon.js.map +1 -1
  63. package/dist/signers/falcon.test.js +39 -3
  64. package/dist/signers/falcon.test.js.map +1 -1
  65. package/dist/transaction/consumeNotes.d.ts +2 -2
  66. package/dist/transaction/consumeNotes.d.ts.map +1 -1
  67. package/dist/transaction/consumeNotes.js +5 -4
  68. package/dist/transaction/consumeNotes.js.map +1 -1
  69. package/dist/transaction/options.d.ts +1 -0
  70. package/dist/transaction/options.d.ts.map +1 -1
  71. package/dist/transaction/p2id.d.ts.map +1 -1
  72. package/dist/transaction/p2id.js +7 -10
  73. package/dist/transaction/p2id.js.map +1 -1
  74. package/dist/transaction/p2id.test.js +19 -9
  75. package/dist/transaction/p2id.test.js.map +1 -1
  76. package/dist/transaction/summary.d.ts +2 -2
  77. package/dist/transaction/summary.d.ts.map +1 -1
  78. package/dist/transaction/summary.js +4 -2
  79. package/dist/transaction/summary.js.map +1 -1
  80. package/dist/transaction/updateGuardian.d.ts +2 -2
  81. package/dist/transaction/updateGuardian.d.ts.map +1 -1
  82. package/dist/transaction/updateGuardian.js +8 -11
  83. package/dist/transaction/updateGuardian.js.map +1 -1
  84. package/dist/transaction/updateProcedureThreshold.d.ts +2 -2
  85. package/dist/transaction/updateProcedureThreshold.d.ts.map +1 -1
  86. package/dist/transaction/updateProcedureThreshold.js +8 -10
  87. package/dist/transaction/updateProcedureThreshold.js.map +1 -1
  88. package/dist/transaction/updateSigners.d.ts +2 -2
  89. package/dist/transaction/updateSigners.d.ts.map +1 -1
  90. package/dist/transaction/updateSigners.js +8 -10
  91. package/dist/transaction/updateSigners.js.map +1 -1
  92. package/dist/transaction.test.js +6 -6
  93. package/dist/transaction.test.js.map +1 -1
  94. package/dist/utils/key.d.ts.map +1 -1
  95. package/dist/utils/key.js +3 -3
  96. package/dist/utils/key.js.map +1 -1
  97. package/dist/utils/key.test.js +4 -2
  98. package/dist/utils/key.test.js.map +1 -1
  99. package/dist/utils/signature.d.ts +2 -0
  100. package/dist/utils/signature.d.ts.map +1 -1
  101. package/dist/utils/signature.js +10 -5
  102. package/dist/utils/signature.js.map +1 -1
  103. package/dist/utils/signature.test.js +9 -9
  104. package/dist/utils/signature.test.js.map +1 -1
  105. package/masm/account_components/auth/multisig.masm +2 -3
  106. package/masm/account_components/auth/multisig_ecdsa.masm +2 -3
  107. package/masm/account_components/auth/multisig_guardian.masm +2 -3
  108. package/masm/account_components/auth/multisig_guardian_ecdsa.masm +2 -3
  109. package/masm/auth/guardian.masm +30 -8
  110. package/masm/auth/guardian_ecdsa.masm +24 -7
  111. package/masm/auth/multisig.masm +86 -55
  112. package/masm/auth/multisig_ecdsa.masm +86 -54
  113. package/package.json +3 -3
  114. package/src/account/builder.test.ts +16 -14
  115. package/src/account/builder.ts +13 -12
  116. package/src/account/masm/account-components/auth.ts +8 -12
  117. package/src/account/masm/auth.ts +226 -124
  118. package/src/account/storage.test.ts +90 -0
  119. package/src/account/storage.ts +27 -6
  120. package/src/client.test.ts +52 -8
  121. package/src/client.ts +39 -16
  122. package/src/index.ts +6 -12
  123. package/src/multisig/proposal/execution.ts +18 -14
  124. package/src/multisig.test.ts +572 -29
  125. package/src/multisig.ts +121 -83
  126. package/src/procedures.ts +8 -8
  127. package/src/raw-client.test.ts +133 -0
  128. package/src/raw-client.ts +75 -0
  129. package/src/signers/ecdsa.test.ts +35 -4
  130. package/src/signers/ecdsa.ts +18 -2
  131. package/src/signers/falcon.test.ts +50 -3
  132. package/src/signers/falcon.ts +18 -2
  133. package/src/transaction/consumeNotes.ts +16 -5
  134. package/src/transaction/options.ts +1 -0
  135. package/src/transaction/p2id.test.ts +19 -9
  136. package/src/transaction/p2id.ts +8 -13
  137. package/src/transaction/summary.ts +11 -4
  138. package/src/transaction/updateGuardian.ts +22 -14
  139. package/src/transaction/updateProcedureThreshold.ts +20 -15
  140. package/src/transaction/updateSigners.ts +22 -14
  141. package/src/transaction.test.ts +6 -6
  142. package/src/utils/key.test.ts +4 -2
  143. package/src/utils/key.ts +7 -3
  144. package/src/utils/signature.test.ts +10 -10
  145. package/src/utils/signature.ts +12 -5
@@ -2,11 +2,12 @@ import {
2
2
  AdviceMap,
3
3
  Felt,
4
4
  FeltArray,
5
- Rpo256,
5
+ type MidenClient,
6
+ Poseidon2,
6
7
  TransactionRequest,
7
8
  TransactionRequestBuilder,
8
9
  TransactionScript,
9
- WebClient,
10
+ type WasmWebClient,
10
11
  Word,
11
12
  Word as WordType,
12
13
  } from '@miden-sdk/miden-sdk';
@@ -14,6 +15,7 @@ import {
14
15
  MULTISIG_ECDSA_MASM,
15
16
  MULTISIG_MASM,
16
17
  } from '../account/masm/auth.js';
18
+ import { compileTxScript } from '../raw-client.js';
17
19
  import { normalizeHexWord } from '../utils/encoding.js';
18
20
  import { randomWord } from '../utils/random.js';
19
21
  import type { SignatureOptions } from './options.js';
@@ -35,33 +37,35 @@ function buildMultisigConfigAdvice(
35
37
  felts.push(...word.toFelts());
36
38
  }
37
39
  const payload = new FeltArray(felts);
38
- const configHash = Rpo256.hashElements(payload);
40
+ const configHash = Poseidon2.hashElements(payload);
39
41
  return { configHash, payload };
40
42
  }
41
43
 
42
- function buildUpdateSignersScript(
43
- webClient: WebClient,
44
+ async function buildUpdateSignersScript(
45
+ client: MidenClient | WasmWebClient,
44
46
  signatureScheme: SignatureScheme,
45
- ): TransactionScript {
46
- const libBuilder = webClient.createCodeBuilder();
47
+ midenRpcEndpoint?: string,
48
+ ): Promise<TransactionScript> {
47
49
  const multisigMasm = signatureScheme === 'ecdsa' ? MULTISIG_ECDSA_MASM : MULTISIG_MASM;
48
50
 
49
- const multisigLib = libBuilder.buildLibrary('auth::multisig', multisigMasm);
50
- libBuilder.linkDynamicLibrary(multisigLib);
51
-
52
51
  const scriptSource = `
53
- use auth::multisig
52
+ use oz_multisig::multisig
54
53
 
55
54
  begin
56
55
  call.multisig::update_signers_and_threshold
57
56
  end
58
57
  `;
59
58
 
60
- return libBuilder.compileTxScript(scriptSource);
59
+ return compileTxScript(
60
+ client,
61
+ scriptSource,
62
+ [{ namespace: 'oz_multisig::multisig', code: multisigMasm }],
63
+ midenRpcEndpoint,
64
+ );
61
65
  }
62
66
 
63
67
  export async function buildUpdateSignersTransactionRequest(
64
- webClient: WebClient,
68
+ client: MidenClient | WasmWebClient,
65
69
  threshold: number,
66
70
  signerCommitments: string[],
67
71
  options: SignatureOptions = {},
@@ -76,7 +80,11 @@ export async function buildUpdateSignersTransactionRequest(
76
80
  const advice = new AdviceMap();
77
81
  advice.insert(configHashForAdvice, payload);
78
82
 
79
- const script = buildUpdateSignersScript(webClient, signatureScheme);
83
+ const script = await buildUpdateSignersScript(
84
+ client,
85
+ signatureScheme,
86
+ options.midenRpcEndpoint,
87
+ );
80
88
 
81
89
  const authSaltHex = options.salt ? options.salt.toHex() : randomWord().toHex();
82
90
 
@@ -6,7 +6,7 @@ vi.mock('@miden-sdk/miden-sdk', () => ({
6
6
  AdviceMap: vi.fn(),
7
7
  Felt: vi.fn().mockImplementation((v) => ({ value: v })),
8
8
  FeltArray: vi.fn().mockImplementation((arr) => arr),
9
- Rpo256: { hashElements: vi.fn() },
9
+ Poseidon2: { hashElements: vi.fn() },
10
10
  Signature: { deserialize: vi.fn() },
11
11
  TransactionRequestBuilder: vi.fn().mockImplementation(() => ({
12
12
  withCustomScript: vi.fn().mockReturnThis(),
@@ -110,21 +110,21 @@ describe('transaction utilities', () => {
110
110
  });
111
111
 
112
112
  describe('signatureHexToBytes', () => {
113
- it('should prepend auth scheme byte (0 = RpoFalcon512)', () => {
113
+ it('should prepend auth scheme byte (2 = Falcon Poseidon2)', () => {
114
114
  const result = signatureHexToBytes('deadbeef');
115
- expect(result[0]).toBe(0); // RpoFalcon512 scheme byte
115
+ expect(result[0]).toBe(2);
116
116
  expect(result.slice(1)).toEqual(new Uint8Array([0xde, 0xad, 0xbe, 0xef]));
117
117
  });
118
118
 
119
119
  it('should prepend auth scheme byte (1 = ECDSA)', () => {
120
120
  const result = signatureHexToBytes('deadbeef', 'ecdsa');
121
- expect(result[0]).toBe(1); // ECDSA scheme byte
121
+ expect(result[0]).toBe(1);
122
122
  expect(result.slice(1)).toEqual(new Uint8Array([0xde, 0xad, 0xbe, 0xef]));
123
123
  });
124
124
 
125
125
  it('should handle 0x prefix', () => {
126
126
  const result = signatureHexToBytes('0xaabbccdd');
127
- expect(result[0]).toBe(0);
127
+ expect(result[0]).toBe(2);
128
128
  expect(result.slice(1)).toEqual(new Uint8Array([0xaa, 0xbb, 0xcc, 0xdd]));
129
129
  });
130
130
 
@@ -136,7 +136,7 @@ describe('transaction utilities', () => {
136
136
 
137
137
  it('should handle empty signature', () => {
138
138
  const result = signatureHexToBytes('');
139
- expect(result).toEqual(new Uint8Array([0])); // Just the prefix
139
+ expect(result).toEqual(new Uint8Array([2]));
140
140
  });
141
141
  });
142
142
  });
@@ -18,6 +18,8 @@ vi.mock('@miden-sdk/miden-sdk', () => ({
18
18
  }));
19
19
 
20
20
  vi.mock('./signature.js', () => ({
21
+ ECDSA_AUTH_SCHEME_ID: 1,
22
+ FALCON_AUTH_SCHEME_ID: 2,
21
23
  tryComputeCommitmentHex: vi.fn((_hex: string, _scheme: string) => '0x' + 'cc'.repeat(32)),
22
24
  }));
23
25
 
@@ -32,9 +34,9 @@ describe('PublicKeyFormat', () => {
32
34
  expect(result.publicKeyHex).toMatch(/^0x[a-f0-9]{64}$/);
33
35
  });
34
36
 
35
- it('should detect 0x00-prefixed key as falcon', () => {
37
+ it('should detect 0x02-prefixed key as falcon', () => {
36
38
  const bytes = new Uint8Array(200);
37
- bytes[0] = 0x00;
39
+ bytes[0] = 0x02;
38
40
  bytes[1] = 0xab;
39
41
  const result = PublicKeyFormat.parse(bytes);
40
42
  expect(result.scheme).toBe('falcon');
package/src/utils/key.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  import { Word } from '@miden-sdk/miden-sdk';
2
2
  import type { SignatureScheme } from '../types.js';
3
3
  import { bytesToHex } from './encoding.js';
4
- import { tryComputeCommitmentHex } from './signature.js';
4
+ import {
5
+ ECDSA_AUTH_SCHEME_ID,
6
+ FALCON_AUTH_SCHEME_ID,
7
+ tryComputeCommitmentHex,
8
+ } from './signature.js';
5
9
 
6
10
  export class PublicKeyFormat {
7
11
  static parse(publicKey: Uint8Array): {
@@ -16,12 +20,12 @@ export class PublicKeyFormat {
16
20
 
17
21
  const firstByte = publicKey[0];
18
22
 
19
- if (firstByte === 0x00 && publicKey.length > 100) {
23
+ if (firstByte === FALCON_AUTH_SCHEME_ID && publicKey.length > 100) {
20
24
  const hex = bytesToHex(publicKey.slice(1));
21
25
  return { scheme: 'falcon', publicKeyHex: hex, commitment: tryComputeCommitmentHex(hex, 'falcon') };
22
26
  }
23
27
 
24
- if (firstByte === 0x01 && publicKey.length === 34) {
28
+ if (firstByte === ECDSA_AUTH_SCHEME_ID && publicKey.length === 34) {
25
29
  const hex = bytesToHex(publicKey.slice(1));
26
30
  return { scheme: 'ecdsa', publicKeyHex: hex, commitment: tryComputeCommitmentHex(hex, 'ecdsa') };
27
31
  }
@@ -14,7 +14,7 @@ vi.mock('@miden-sdk/miden-sdk', () => ({
14
14
  })),
15
15
  Felt: vi.fn().mockImplementation((v: bigint) => ({ value: v })),
16
16
  FeltArray: vi.fn().mockImplementation((arr: any[]) => arr),
17
- Rpo256: {
17
+ Poseidon2: {
18
18
  hashElements: vi.fn().mockReturnValue({
19
19
  toHex: () => '0x' + 'h'.repeat(64),
20
20
  }),
@@ -48,15 +48,15 @@ describe('signature utilities', () => {
48
48
  });
49
49
 
50
50
  describe('signatureHexToBytes', () => {
51
- it('prepends auth scheme byte (0 = RpoFalcon512)', () => {
51
+ it('prepends auth scheme byte (2 = Falcon Poseidon2)', () => {
52
52
  const result = signatureHexToBytes('deadbeef');
53
- expect(result[0]).toBe(0); // RpoFalcon512 scheme byte
53
+ expect(result[0]).toBe(2);
54
54
  });
55
55
 
56
56
  it('prepends auth scheme byte (1 = ECDSA)', () => {
57
57
  const result = signatureHexToBytes('deadbeef', 'ecdsa');
58
- expect(result[0]).toBe(1); // ECDSA scheme byte
59
- });
58
+ expect(result[0]).toBe(1);
59
+ });
60
60
 
61
61
  it('converts hex to bytes after prefix', () => {
62
62
  const result = signatureHexToBytes('deadbeef');
@@ -65,7 +65,7 @@ describe('signature utilities', () => {
65
65
 
66
66
  it('handles 0x prefix', () => {
67
67
  const result = signatureHexToBytes('0xaabbccdd');
68
- expect(result[0]).toBe(0);
68
+ expect(result[0]).toBe(2);
69
69
  expect(result.slice(1)).toEqual(new Uint8Array([0xaa, 0xbb, 0xcc, 0xdd]));
70
70
  });
71
71
 
@@ -77,12 +77,12 @@ describe('signature utilities', () => {
77
77
 
78
78
  it('handles empty signature', () => {
79
79
  const result = signatureHexToBytes('');
80
- expect(result).toEqual(new Uint8Array([0])); // Just the prefix
80
+ expect(result).toEqual(new Uint8Array([2]));
81
81
  });
82
82
 
83
83
  it('handles empty with 0x prefix', () => {
84
84
  const result = signatureHexToBytes('0x');
85
- expect(result).toEqual(new Uint8Array([0]));
85
+ expect(result).toEqual(new Uint8Array([2]));
86
86
  });
87
87
  });
88
88
 
@@ -100,14 +100,14 @@ describe('signature utilities', () => {
100
100
  });
101
101
 
102
102
  it('hashes pubkey commitment and message to produce key', async () => {
103
- const { Word, Signature, Rpo256 } = await import('@miden-sdk/miden-sdk');
103
+ const { Word, Signature, Poseidon2 } = await import('@miden-sdk/miden-sdk');
104
104
  const pubkeyCommitment = Word.fromHex('0x' + 'a'.repeat(64));
105
105
  const message = Word.fromHex('0x' + 'b'.repeat(64));
106
106
  const signature = Signature.deserialize(new Uint8Array([0, 1, 2, 3]));
107
107
 
108
108
  buildSignatureAdviceEntry(pubkeyCommitment, message, signature);
109
109
 
110
- expect(Rpo256.hashElements).toHaveBeenCalled();
110
+ expect(Poseidon2.hashElements).toHaveBeenCalled();
111
111
  });
112
112
 
113
113
  it('uses toPreparedSignature to get values', async () => {
@@ -1,15 +1,22 @@
1
- import { AdviceMap, Felt, FeltArray, Rpo256, Signature, Word } from '@miden-sdk/miden-sdk';
1
+ import { AdviceMap, Felt, FeltArray, Poseidon2, Signature, Word } from '@miden-sdk/miden-sdk';
2
2
  import * as midenSdk from '@miden-sdk/miden-sdk';
3
3
  import { hexToBytes, normalizeHexWord } from './encoding.js';
4
4
  import type { ProposalSignatureEntry, SignatureScheme } from '../types.js';
5
5
 
6
+ export const ECDSA_AUTH_SCHEME_ID = 1;
7
+ export const FALCON_AUTH_SCHEME_ID = 2;
8
+
9
+ function authSchemeId(scheme: SignatureScheme): number {
10
+ return scheme === 'ecdsa' ? ECDSA_AUTH_SCHEME_ID : FALCON_AUTH_SCHEME_ID;
11
+ }
12
+
6
13
  export function signatureHexToBytes(
7
14
  hex: string,
8
15
  scheme: SignatureScheme = 'falcon',
9
16
  ): Uint8Array {
10
17
  const sigBytes = hexToBytes(hex);
11
18
  const withPrefix = new Uint8Array(sigBytes.length + 1);
12
- withPrefix[0] = scheme === 'ecdsa' ? 1 : 0;
19
+ withPrefix[0] = authSchemeId(scheme);
13
20
  withPrefix.set(sigBytes, 1);
14
21
  return withPrefix;
15
22
  }
@@ -45,7 +52,7 @@ export function buildSignatureAdviceEntry(
45
52
  ...pubkeyCommitment.toFelts(),
46
53
  ...message.toFelts(),
47
54
  ]);
48
- const key = Rpo256.hashElements(elements);
55
+ const key = Poseidon2.hashElements(elements);
49
56
 
50
57
  let values: Felt[];
51
58
  if (ecdsaPubkeyHex && ecdsaSigHex) {
@@ -69,7 +76,7 @@ export function tryComputeCommitmentHex(
69
76
  ): string | null {
70
77
  const bytes = hexToBytes(pubkeyHex);
71
78
  const withPrefix = new Uint8Array(bytes.length + 1);
72
- withPrefix[0] = scheme === 'ecdsa' ? 1 : 0;
79
+ withPrefix[0] = authSchemeId(scheme);
73
80
  withPrefix.set(bytes, 1);
74
81
 
75
82
  try {
@@ -98,7 +105,7 @@ export function verifyEcdsaCommitment(
98
105
 
99
106
  const packedFelts = bytesToPackedU32Felts(bytes);
100
107
  const feltArray = new FeltArray(packedFelts);
101
- const computed = Rpo256.hashElements(feltArray);
108
+ const computed = Poseidon2.hashElements(feltArray);
102
109
  const computedHex = normalizeHexWord(computed.toHex());
103
110
  const expectedNorm = normalizeHexWord(expectedCommitmentHex);
104
111
  return {