@openzeppelin/miden-multisig-client 0.13.1 → 0.13.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 (275) hide show
  1. package/README.md +98 -119
  2. package/dist/account/builder.d.ts +18 -0
  3. package/dist/account/builder.d.ts.map +1 -1
  4. package/dist/account/builder.js +59 -29
  5. package/dist/account/builder.js.map +1 -1
  6. package/dist/account/builder.test.js +108 -32
  7. package/dist/account/builder.test.js.map +1 -1
  8. package/dist/account/index.d.ts +1 -1
  9. package/dist/account/index.d.ts.map +1 -1
  10. package/dist/account/index.js +1 -1
  11. package/dist/account/index.js.map +1 -1
  12. package/dist/account/masm/account-components/auth.d.ts +5 -0
  13. package/dist/account/masm/account-components/auth.d.ts.map +1 -0
  14. package/dist/account/masm/account-components/auth.js +67 -0
  15. package/dist/account/masm/account-components/auth.js.map +1 -0
  16. package/dist/account/masm/auth.d.ts +5 -0
  17. package/dist/account/masm/auth.d.ts.map +1 -0
  18. package/dist/account/masm/auth.js +1395 -0
  19. package/dist/account/masm/auth.js.map +1 -0
  20. package/dist/account/masm/index.d.ts +3 -0
  21. package/dist/account/masm/index.d.ts.map +1 -0
  22. package/dist/account/masm/index.js +5 -0
  23. package/dist/account/masm/index.js.map +1 -0
  24. package/dist/account/masm.d.ts +1 -4
  25. package/dist/account/masm.d.ts.map +1 -1
  26. package/dist/account/masm.js +3 -1034
  27. package/dist/account/masm.js.map +1 -1
  28. package/dist/account/storage.d.ts +2 -2
  29. package/dist/account/storage.d.ts.map +1 -1
  30. package/dist/account/storage.js +18 -16
  31. package/dist/account/storage.js.map +1 -1
  32. package/dist/client.d.ts +67 -9
  33. package/dist/client.d.ts.map +1 -1
  34. package/dist/client.js +73 -22
  35. package/dist/client.js.map +1 -1
  36. package/dist/client.test.js +31 -32
  37. package/dist/client.test.js.map +1 -1
  38. package/dist/index.d.ts +54 -12
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +53 -9
  41. package/dist/index.js.map +1 -1
  42. package/dist/inspector.d.ts +32 -6
  43. package/dist/inspector.d.ts.map +1 -1
  44. package/dist/inspector.js +58 -23
  45. package/dist/inspector.js.map +1 -1
  46. package/dist/inspector.test.js +18 -18
  47. package/dist/inspector.test.js.map +1 -1
  48. package/dist/multisig/proposal/execution.d.ts +4 -4
  49. package/dist/multisig/proposal/execution.d.ts.map +1 -1
  50. package/dist/multisig/proposal/execution.js +42 -31
  51. package/dist/multisig/proposal/execution.js.map +1 -1
  52. package/dist/multisig/proposal/parser.d.ts +3 -3
  53. package/dist/multisig/proposal/parser.d.ts.map +1 -1
  54. package/dist/multisig/proposal/parser.js +23 -23
  55. package/dist/multisig/proposal/parser.js.map +1 -1
  56. package/dist/multisig/signing.d.ts +3 -3
  57. package/dist/multisig/signing.d.ts.map +1 -1
  58. package/dist/multisig/signing.js +3 -3
  59. package/dist/multisig/signing.js.map +1 -1
  60. package/dist/multisig.d.ts +188 -48
  61. package/dist/multisig.d.ts.map +1 -1
  62. package/dist/multisig.js +650 -308
  63. package/dist/multisig.js.map +1 -1
  64. package/dist/multisig.test.js +1680 -241
  65. package/dist/multisig.test.js.map +1 -1
  66. package/dist/procedures.d.ts +46 -24
  67. package/dist/procedures.d.ts.map +1 -1
  68. package/dist/procedures.js +46 -21
  69. package/dist/procedures.js.map +1 -1
  70. package/dist/proposal/factory.d.ts +18 -0
  71. package/dist/proposal/factory.d.ts.map +1 -0
  72. package/dist/proposal/factory.js +99 -0
  73. package/dist/proposal/factory.js.map +1 -0
  74. package/dist/proposal/metadata.d.ts +5 -12
  75. package/dist/proposal/metadata.d.ts.map +1 -1
  76. package/dist/proposal/metadata.js +118 -174
  77. package/dist/proposal/metadata.js.map +1 -1
  78. package/dist/proposal/signatures.d.ts +10 -0
  79. package/dist/proposal/signatures.d.ts.map +1 -0
  80. package/dist/proposal/signatures.js +54 -0
  81. package/dist/proposal/signatures.js.map +1 -0
  82. package/dist/signer.d.ts +2 -0
  83. package/dist/signer.d.ts.map +1 -1
  84. package/dist/signer.js +2 -0
  85. package/dist/signer.js.map +1 -1
  86. package/dist/signers/ecdsa.d.ts +3 -0
  87. package/dist/signers/ecdsa.d.ts.map +1 -1
  88. package/dist/signers/ecdsa.js +8 -4
  89. package/dist/signers/ecdsa.js.map +1 -1
  90. package/dist/signers/ecdsa.test.d.ts +2 -0
  91. package/dist/signers/ecdsa.test.d.ts.map +1 -0
  92. package/dist/signers/ecdsa.test.js +65 -0
  93. package/dist/signers/ecdsa.test.js.map +1 -0
  94. package/dist/signers/falcon.d.ts +3 -0
  95. package/dist/signers/falcon.d.ts.map +1 -1
  96. package/dist/signers/falcon.js +8 -4
  97. package/dist/signers/falcon.js.map +1 -1
  98. package/dist/signers/falcon.test.js +12 -0
  99. package/dist/signers/falcon.test.js.map +1 -1
  100. package/dist/signers/miden-wallet.d.ts +3 -1
  101. package/dist/signers/miden-wallet.d.ts.map +1 -1
  102. package/dist/signers/miden-wallet.js +11 -2
  103. package/dist/signers/miden-wallet.js.map +1 -1
  104. package/dist/signers/miden-wallet.test.js +26 -0
  105. package/dist/signers/miden-wallet.test.js.map +1 -1
  106. package/dist/signers/para.d.ts +3 -3
  107. package/dist/signers/para.d.ts.map +1 -1
  108. package/dist/signers/para.js +15 -6
  109. package/dist/signers/para.js.map +1 -1
  110. package/dist/signers/para.test.js +39 -0
  111. package/dist/signers/para.test.js.map +1 -1
  112. package/dist/transaction/consumeNotes.d.ts.map +1 -1
  113. package/dist/transaction/consumeNotes.js +1 -0
  114. package/dist/transaction/consumeNotes.js.map +1 -1
  115. package/dist/transaction/index.d.ts +2 -1
  116. package/dist/transaction/index.d.ts.map +1 -1
  117. package/dist/transaction/index.js +2 -1
  118. package/dist/transaction/index.js.map +1 -1
  119. package/dist/transaction/options.d.ts +1 -1
  120. package/dist/transaction/options.d.ts.map +1 -1
  121. package/dist/transaction/p2id.d.ts +1 -0
  122. package/dist/transaction/p2id.d.ts.map +1 -1
  123. package/dist/transaction/p2id.js +9 -3
  124. package/dist/transaction/p2id.js.map +1 -1
  125. package/dist/transaction/updateGuardian.d.ts +7 -0
  126. package/dist/transaction/updateGuardian.d.ts.map +1 -0
  127. package/dist/transaction/{updatePsm.js → updateGuardian.js} +15 -29
  128. package/dist/transaction/updateGuardian.js.map +1 -0
  129. package/dist/transaction/updateProcedureThreshold.d.ts +9 -0
  130. package/dist/transaction/updateProcedureThreshold.d.ts.map +1 -0
  131. package/dist/transaction/updateProcedureThreshold.js +55 -0
  132. package/dist/transaction/updateProcedureThreshold.js.map +1 -0
  133. package/dist/transaction/updateSigners.d.ts.map +1 -1
  134. package/dist/transaction/updateSigners.js +5 -23
  135. package/dist/transaction/updateSigners.js.map +1 -1
  136. package/dist/transaction.d.ts +2 -1
  137. package/dist/transaction.d.ts.map +1 -1
  138. package/dist/transaction.js +2 -1
  139. package/dist/transaction.js.map +1 -1
  140. package/dist/types/proposal.d.ts +32 -15
  141. package/dist/types/proposal.d.ts.map +1 -1
  142. package/dist/types.d.ts +24 -7
  143. package/dist/types.d.ts.map +1 -1
  144. package/dist/utils/digest.d.ts +5 -0
  145. package/dist/utils/digest.d.ts.map +1 -1
  146. package/dist/utils/digest.js +34 -1
  147. package/dist/utils/digest.js.map +1 -1
  148. package/dist/utils/digest.test.d.ts +2 -0
  149. package/dist/utils/digest.test.d.ts.map +1 -0
  150. package/dist/utils/digest.test.js +48 -0
  151. package/dist/utils/digest.test.js.map +1 -0
  152. package/dist/utils/signature.d.ts +3 -1
  153. package/dist/utils/signature.d.ts.map +1 -1
  154. package/dist/utils/signature.js +31 -6
  155. package/dist/utils/signature.js.map +1 -1
  156. package/dist/utils/word.test.js +1 -52
  157. package/dist/utils/word.test.js.map +1 -1
  158. package/masm/account_components/auth/multisig.masm +13 -0
  159. package/masm/account_components/auth/multisig_ecdsa.masm +13 -0
  160. package/masm/account_components/auth/multisig_guardian.masm +17 -0
  161. package/masm/account_components/auth/multisig_guardian_ecdsa.masm +17 -0
  162. package/masm/auth/guardian.masm +177 -0
  163. package/masm/auth/guardian_ecdsa.masm +178 -0
  164. package/masm/{multisig.masm → auth/multisig.masm} +149 -55
  165. package/masm/{multisig_ecdsa.masm → auth/multisig_ecdsa.masm} +148 -56
  166. package/package.json +11 -9
  167. package/src/account/builder.test.ts +165 -0
  168. package/src/account/builder.ts +71 -34
  169. package/src/account/index.ts +1 -1
  170. package/src/account/masm/account-components/auth.ts +70 -0
  171. package/src/account/masm/auth.ts +1398 -0
  172. package/src/account/masm/index.ts +5 -0
  173. package/src/account/masm.ts +3 -1040
  174. package/src/account/storage.ts +18 -16
  175. package/src/client.test.ts +31 -35
  176. package/src/client.ts +98 -26
  177. package/src/index.ts +84 -22
  178. package/src/inspector.test.ts +17 -17
  179. package/src/inspector.ts +63 -29
  180. package/src/multisig/proposal/execution.ts +66 -49
  181. package/src/multisig/proposal/parser.ts +26 -26
  182. package/src/multisig/signing.ts +4 -4
  183. package/src/multisig.test.ts +2097 -248
  184. package/src/multisig.ts +882 -388
  185. package/src/procedures.ts +50 -26
  186. package/src/proposal/factory.ts +171 -0
  187. package/src/proposal/metadata.ts +165 -0
  188. package/src/proposal/signatures.ts +68 -0
  189. package/src/signer.ts +2 -0
  190. package/src/signers/ecdsa.test.ts +80 -0
  191. package/src/signers/ecdsa.ts +15 -4
  192. package/src/signers/falcon.test.ts +19 -0
  193. package/src/signers/falcon.ts +16 -5
  194. package/src/signers/miden-wallet.test.ts +47 -0
  195. package/src/signers/miden-wallet.ts +18 -1
  196. package/src/signers/para.test.ts +57 -0
  197. package/src/signers/para.ts +26 -7
  198. package/src/transaction/consumeNotes.ts +1 -0
  199. package/src/transaction/index.ts +2 -2
  200. package/src/transaction/options.ts +1 -2
  201. package/src/transaction/p2id.test.ts +190 -0
  202. package/src/transaction/p2id.ts +11 -5
  203. package/src/transaction/rpoRandomCoin.test.ts +64 -0
  204. package/src/transaction/rpoRandomCoin.ts +24 -0
  205. package/src/transaction/{updatePsm.ts → updateGuardian.ts} +19 -32
  206. package/src/transaction/updateProcedureThreshold.ts +97 -0
  207. package/src/transaction/updateSigners.ts +12 -27
  208. package/src/transaction.ts +5 -3
  209. package/src/types/proposal.ts +43 -11
  210. package/src/types.ts +29 -11
  211. package/src/utils/digest.test.ts +55 -0
  212. package/src/utils/digest.ts +51 -1
  213. package/src/utils/signature.ts +47 -9
  214. package/src/utils/word.test.ts +1 -55
  215. package/dist/account.d.ts +0 -104
  216. package/dist/account.d.ts.map +0 -1
  217. package/dist/account.js +0 -136
  218. package/dist/account.js.map +0 -1
  219. package/dist/builder.d.ts +0 -54
  220. package/dist/builder.d.ts.map +0 -1
  221. package/dist/builder.js +0 -78
  222. package/dist/builder.js.map +0 -1
  223. package/dist/http.d.ts +0 -64
  224. package/dist/http.d.ts.map +0 -1
  225. package/dist/http.js +0 -162
  226. package/dist/http.js.map +0 -1
  227. package/dist/keystore.d.ts +0 -65
  228. package/dist/keystore.d.ts.map +0 -1
  229. package/dist/keystore.js +0 -121
  230. package/dist/keystore.js.map +0 -1
  231. package/dist/miden.d.ts +0 -9
  232. package/dist/miden.d.ts.map +0 -1
  233. package/dist/miden.js +0 -26
  234. package/dist/miden.js.map +0 -1
  235. package/dist/multisig/metadata.d.ts +0 -18
  236. package/dist/multisig/metadata.d.ts.map +0 -1
  237. package/dist/multisig/metadata.js +0 -100
  238. package/dist/multisig/metadata.js.map +0 -1
  239. package/dist/multisig/metadata.test.d.ts +0 -2
  240. package/dist/multisig/metadata.test.d.ts.map +0 -1
  241. package/dist/multisig/metadata.test.js +0 -323
  242. package/dist/multisig/metadata.test.js.map +0 -1
  243. package/dist/proposal/exported.d.ts +0 -12
  244. package/dist/proposal/exported.d.ts.map +0 -1
  245. package/dist/proposal/exported.js +0 -88
  246. package/dist/proposal/exported.js.map +0 -1
  247. package/dist/signer.test.d.ts +0 -2
  248. package/dist/signer.test.d.ts.map +0 -1
  249. package/dist/signer.test.js +0 -123
  250. package/dist/signer.test.js.map +0 -1
  251. package/dist/transaction/p2id.interop.test.d.ts +0 -2
  252. package/dist/transaction/p2id.interop.test.d.ts.map +0 -1
  253. package/dist/transaction/p2id.interop.test.js +0 -36
  254. package/dist/transaction/p2id.interop.test.js.map +0 -1
  255. package/dist/transaction/updatePsm.d.ts +0 -7
  256. package/dist/transaction/updatePsm.d.ts.map +0 -1
  257. package/dist/transaction/updatePsm.js.map +0 -1
  258. package/dist/transport/http.d.ts +0 -64
  259. package/dist/transport/http.d.ts.map +0 -1
  260. package/dist/transport/http.js +0 -162
  261. package/dist/transport/http.js.map +0 -1
  262. package/dist/transport/index.d.ts +0 -5
  263. package/dist/transport/index.d.ts.map +0 -1
  264. package/dist/transport/index.js +0 -5
  265. package/dist/transport/index.js.map +0 -1
  266. package/dist/utils/state-validation.d.ts +0 -5
  267. package/dist/utils/state-validation.d.ts.map +0 -1
  268. package/dist/utils/state-validation.js +0 -30
  269. package/dist/utils/state-validation.js.map +0 -1
  270. package/dist/utils/validation.d.ts +0 -6
  271. package/dist/utils/validation.d.ts.map +0 -1
  272. package/dist/utils/validation.js +0 -52
  273. package/dist/utils/validation.js.map +0 -1
  274. package/masm/psm.masm +0 -178
  275. package/masm/psm_ecdsa.masm +0 -179
package/README.md CHANGED
@@ -1,82 +1,77 @@
1
1
  # @openzeppelin/miden-multisig-client
2
2
 
3
- TypeScript SDK for private multisignature workflows on Miden. This package wraps the on-chain multisig contracts plus Private State Manager (PSM) coordination so you can:
3
+ TypeScript SDK for private multisignature workflows on Miden. This package wraps the on-chain multisig contracts plus Guardian coordination so you can:
4
4
 
5
- - Create multisig accounts, register them with a PSM, and keep state off-chain
5
+ - Create multisig accounts, register them with a GUARDIAN, and keep state off-chain
6
6
  - Propose, sign, and execute transactions with threshold enforcement
7
7
  - Export/import proposals as files for sharing using side channels
8
- - Integrate external wallets via the external signing API
9
- - Use Falcon or ECDSA signature schemes
10
8
 
11
- ## How Private Multisigs & PSM Work
9
+ ## How Private Multisigs & GUARDIAN Work
12
10
 
13
- Miden multisig accounts store their authentication logic on-chain, but **their state (signers, metadata, proposals)** is kept private. PSM acts as a coordination server:
11
+ Miden multisig accounts store their authentication logic on-chain, but **their state (signers, metadata, proposals)** is kept private. GUARDIAN acts as a coordination server:
14
12
 
15
- 1. A proposer pushes a delta (transaction plan) to Private State Manager (PSM). PSM tracks who signed and emits an ack signature once the threshold is met.
16
- 2. Cosigners fetch pending deltas, verify details locally, sign the transaction summary, and push signatures back to PSM.
17
- 3. Once ready, any cosigner builds the final transaction using all cosigner signatures + the PSM ack, executes it on-chain.
13
+ 1. A proposer pushes a delta (transaction plan) to Guardian. GUARDIAN tracks who signed and emits an ack signature once the threshold is met.
14
+ 2. Cosigners fetch pending deltas, verify details locally, sign the transaction summary, and push signatures back to GUARDIAN.
15
+ 3. Once ready, any cosigner builds the final transaction using all cosigner signatures + the GUARDIAN ack, executes it on-chain.
18
16
 
19
17
  ## Installation
20
18
 
21
19
  ```bash
22
- npm install @openzeppelin/miden-multisig-client @miden-sdk/miden-sdk
20
+ npm install @openzeppelin/miden-multisig-client @demox-labs/miden-sdk
23
21
  ```
24
22
 
25
23
  ## Setup
26
24
 
27
25
  ```typescript
28
26
  import { MultisigClient, FalconSigner } from '@openzeppelin/miden-multisig-client';
29
- import { WebClient, AuthSecretKey } from '@miden-sdk/miden-sdk';
27
+ import { WebClient, SecretKey } from '@demox-labs/miden-sdk';
30
28
 
31
29
  // Initialize Miden WebClient
32
30
  const webClient = await WebClient.createClient('https://rpc.testnet.miden.io:443');
33
31
 
34
- // Create a Falcon signer
35
- const secretKey = AuthSecretKey.rpoFalconWithRNG(undefined);
32
+ // Create a signer from your secret key
33
+ const secretKey = SecretKey.rpoFalconWithRNG(seed);
36
34
  const signer = new FalconSigner(secretKey);
37
35
 
38
- // Create MultisigClient and fetch PSM info
36
+ // Create MultisigClient
39
37
  const client = new MultisigClient(webClient, {
40
- psmEndpoint: 'http://localhost:3000',
38
+ guardianEndpoint: 'http://localhost:3000',
39
+ midenRpcEndpoint: 'https://rpc.testnet.miden.io:443',
41
40
  });
42
- const { psmCommitment } = await client.initialize();
43
41
  ```
44
42
 
45
- ### ECDSA Signer
43
+ ## Usage
46
44
 
47
- ```typescript
48
- import { MultisigClient, EcdsaSigner } from '@openzeppelin/miden-multisig-client';
49
- import { AuthSecretKey } from '@miden-sdk/miden-sdk';
45
+ ### Get GUARDIAN Public Key
50
46
 
51
- const secretKey = AuthSecretKey.ecdsaWithRNG(undefined);
52
- const signer = new EcdsaSigner(secretKey);
47
+ Before creating a multisig, get the GUARDIAN server's public key commitment:
53
48
 
54
- const client = new MultisigClient(webClient, { psmEndpoint: 'http://localhost:3000' });
55
- const { psmCommitment } = await client.initialize('ecdsa');
49
+ ```typescript
50
+ const guardianCommitment = await client.guardianClient.getPubkey();
56
51
  ```
57
52
 
58
- ## Usage
59
-
60
53
  ### Create a Multisig Account
61
54
 
62
55
  ```typescript
63
56
  const config = {
64
- threshold: 2,
65
- signerCommitments: [signer.commitment, otherSignerCommitment],
66
- psmCommitment,
67
- signatureScheme: 'falcon', // or 'ecdsa'
57
+ threshold: 2, // Require 2 signatures
58
+ signerCommitments: [
59
+ signer.commitment, // Your commitment
60
+ otherSigner.commitment, // Cosigner's commitment
61
+ ],
62
+ guardianCommitment,
68
63
  };
69
64
 
70
65
  const multisig = await client.create(config, signer);
71
66
  console.log('Account ID:', multisig.accountId);
72
67
  ```
73
68
 
74
- ### Register on PSM
69
+ ### Register on GUARDIAN
75
70
 
76
- After creating the account, register it on the PSM server:
71
+ After creating the account, register it on the GUARDIAN server:
77
72
 
78
73
  ```typescript
79
- await multisig.registerOnPsm();
74
+ await multisig.registerOnGuardian();
80
75
  ```
81
76
 
82
77
  ### Load an Existing Multisig
@@ -87,63 +82,59 @@ The configuration is automatically detected from the account's on-chain storage:
87
82
  const multisig = await client.load(accountId, signer);
88
83
  ```
89
84
 
90
- ### Sync Everything
91
-
92
- Fetch proposals, state, consumable notes, and config in one call:
85
+ ### Fetch Account State
93
86
 
94
87
  ```typescript
95
- const { proposals, state, notes, config } = await multisig.syncAll();
96
- for (const p of proposals) {
97
- console.log(`${p.id}: ${p.status.type}`);
98
- }
88
+ const state = await multisig.fetchState();
89
+ console.log('Commitment:', state.commitment);
90
+ console.log('Created:', state.createdAt);
99
91
  ```
100
92
 
101
- ### List Cached Proposals
102
-
103
- Returns cached proposals without making a network request:
93
+ ### Create a Proposal (Add Signer)
104
94
 
105
95
  ```typescript
106
- const proposals = multisig.listTransactionProposals();
107
- for (const p of proposals) {
108
- if (p.status.type === 'pending') {
109
- console.log(`Pending: ${p.status.signaturesCollected}/${p.status.signaturesRequired}`);
110
- } else if (p.status.type === 'ready') {
111
- console.log('Ready to execute!');
112
- }
113
- }
96
+ // Create a proposal to add a new signer
97
+ const nonce = Math.floor(Math.random() * 1_000_000_000);
98
+ const proposal = await multisig.createAddSignerProposal(
99
+ webClient,
100
+ newSignerCommitment, // Commitment of signer to add
101
+ nonce, // Optional nonce (random value)
102
+ 3, // Optional new threshold
103
+ );
104
+ console.log('Proposal ID:', proposal.id);
114
105
  ```
115
106
 
116
- ### Create Proposals
117
-
118
- All create methods return `{ proposal, proposals }` — the new proposal plus an auto-synced full list:
107
+ ### Sign a Proposal
119
108
 
120
109
  ```typescript
121
- // Add a signer
122
- const { proposal, proposals } = await multisig.createAddSignerProposal(
123
- newSignerCommitment,
124
- { newThreshold: 3 },
125
- );
126
-
127
- // Remove a signer
128
- await multisig.createRemoveSignerProposal(signerToRemove);
129
-
130
- // Change threshold
131
- await multisig.createChangeThresholdProposal(3);
110
+ const signedProposal = await multisig.signProposal(proposal.id);
111
+ console.log('Signatures:', signedProposal.signatures.length);
112
+ ```
132
113
 
133
- // Consume notes
134
- await multisig.createConsumeNotesProposal(noteIds);
114
+ ### Sync Proposals
135
115
 
136
- // Send payment (P2ID)
137
- await multisig.createSendProposal(recipientId, faucetId, amount);
116
+ Fetches proposals from the GUARDIAN server and updates local state:
138
117
 
139
- // Switch PSM provider
140
- await multisig.createSwitchPsmProposal(newEndpoint, newPubkey);
118
+ ```typescript
119
+ const proposals = await multisig.syncProposals();
120
+ for (const p of proposals) {
121
+ console.log(`${p.id}: ${p.status}`);
122
+ }
141
123
  ```
142
124
 
143
- ### Sign a Proposal
125
+ ### Check Proposal Status
126
+
127
+ Returns cached proposals without making a network request:
144
128
 
145
129
  ```typescript
146
- const proposals = await multisig.signTransactionProposal(proposal.commitment);
130
+ const proposals = multisig.listProposals();
131
+ for (const p of proposals) {
132
+ if (p.status === 'pending') {
133
+ console.log(`Pending signatures: ${p.signatures.length}`);
134
+ } else if (p.status === 'ready') {
135
+ console.log('Ready to execute!');
136
+ }
137
+ }
147
138
  ```
148
139
 
149
140
  ### Execute a Proposal
@@ -151,69 +142,57 @@ const proposals = await multisig.signTransactionProposal(proposal.commitment);
151
142
  When a proposal has enough signatures:
152
143
 
153
144
  ```typescript
154
- if (proposal.status.type === 'ready') {
155
- await multisig.executeTransactionProposal(proposal.commitment);
145
+ if (proposal.status === 'ready') {
146
+ await multisig.executeProposal(proposal.id, webClient);
147
+ console.log('Transaction executed on-chain!');
156
148
  }
157
149
  ```
158
150
 
159
- ### External Signing
160
-
161
- For wallet integrations where the signing key is external (e.g., a browser wallet):
151
+ ### Export Proposal for Offline Signing
162
152
 
163
153
  ```typescript
164
- // Fetch proposals
165
- const proposals = multisig.listTransactionProposals();
166
-
167
- // Sign the commitment externally
168
- const signature = await wallet.sign(proposals[0].commitment);
169
-
170
- // Submit the external signature
171
- await multisig.signTransactionProposalExternal({
172
- commitment: proposals[0].commitment,
173
- signature,
174
- publicKey: wallet.publicKey,
175
- scheme: 'ecdsa',
176
- });
154
+ const exported = await multisig.exportProposal(proposal.id);
155
+ // Send `exported` to offline signer
156
+ console.log('TX Summary:', exported.txSummaryBase64);
157
+ console.log('Commitment to sign:', exported.commitment);
177
158
  ```
178
159
 
179
- ### Wallet Signers
160
+ ### Import and Sign a Proposal Offline
180
161
 
181
- For integrating with external wallets, use `ParaSigner` or `MidenWalletSigner`:
162
+ Imported proposals are now validated against their transaction summary before they are cached or
163
+ signed:
182
164
 
183
165
  ```typescript
184
- import { ParaSigner, MidenWalletSigner } from '@openzeppelin/miden-multisig-client';
185
-
186
- // Para wallet integration
187
- const signer = new ParaSigner(paraContext, walletId, commitment, publicKey);
188
-
189
- // Miden wallet integration
190
- const signer = new MidenWalletSigner(walletContext, commitment, 'ecdsa');
166
+ const imported = await multisig.importProposal(jsonFromCosigner);
167
+ const signedJson = await multisig.signProposalOffline(imported.id);
168
+ console.log(signedJson);
191
169
  ```
192
170
 
193
- ### Export/Import Proposals
171
+ ## Transaction Utilities
194
172
 
195
- Share proposals via side channels for offline signing:
173
+ The package also exports utility functions for building transactions:
196
174
 
197
175
  ```typescript
198
- // Export
199
- const json = multisig.exportTransactionProposalToJson(proposal.commitment);
200
-
201
- // Sign offline and get updated JSON
202
- const signedJson = multisig.signTransactionProposalOffline(proposal.commitment);
203
-
204
- // Import
205
- const { proposal, proposals } = multisig.importTransactionProposal(json);
176
+ import {
177
+ normalizeHexWord,
178
+ hexToUint8Array,
179
+ signatureHexToBytes,
180
+ buildSignatureAdviceEntry,
181
+ } from '@openzeppelin/miden-multisig-client';
182
+
183
+ // Normalize hex for Word.fromHex (pads to 64 chars)
184
+ const normalized = normalizeHexWord('abc123');
185
+ // => '0x0000...abc123'
186
+
187
+ // Convert hex to bytes
188
+ const bytes = hexToUint8Array('deadbeef');
189
+ // => Uint8Array([0xde, 0xad, 0xbe, 0xef])
190
+
191
+ // Add auth scheme prefix to signature
192
+ const sigBytes = signatureHexToBytes(signatureHex);
193
+ // => Uint8Array with 0x00 prefix (RpoFalcon512)
206
194
  ```
207
195
 
208
- ## Signers
209
-
210
- | Signer | Scheme | Use case |
211
- |--------|--------|----------|
212
- | `FalconSigner` | `falcon` | Local Falcon key (default) |
213
- | `EcdsaSigner` | `ecdsa` | Local ECDSA key |
214
- | `ParaSigner` | `ecdsa` | External wallet via Para protocol |
215
- | `MidenWalletSigner` | any | Miden wallet browser extension |
216
-
217
196
  ## Testing
218
197
 
219
198
  ```bash
@@ -1,5 +1,23 @@
1
+ /**
2
+ * Account builder for creating multisig accounts with GUARDIAN authentication.
3
+ *
4
+ * This module provides functionality to create multisig accounts.
5
+ */
1
6
  import { type WebClient } from '@miden-sdk/miden-sdk';
2
7
  import type { MultisigConfig, CreateAccountResult } from '../types.js';
8
+ /**
9
+ * Creates a multisig account with GUARDIAN authentication.
10
+ *
11
+ * @param webClient - Initialized Miden WebClient
12
+ * @param config - Multisig configuration
13
+ * @returns The created account and seed
14
+ */
3
15
  export declare function createMultisigAccount(webClient: WebClient, config: MultisigConfig): Promise<CreateAccountResult>;
16
+ /**
17
+ * Validates a multisig configuration.
18
+ *
19
+ * @param config - The configuration to validate
20
+ * @throws Error if configuration is invalid
21
+ */
4
22
  export declare function validateMultisigConfig(config: MultisigConfig): void;
5
23
  //# sourceMappingURL=builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/account/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIvE,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,mBAAmB,CAAC,CA8C9B;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CA4CnE"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/account/builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAcvE;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,mBAAmB,CAAC,CAqD9B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CA6CnE"}
@@ -1,36 +1,59 @@
1
+ /**
2
+ * Account builder for creating multisig accounts with GUARDIAN authentication.
3
+ *
4
+ * This module provides functionality to create multisig accounts.
5
+ */
1
6
  import { AccountBuilder, AccountComponent, AccountType, AccountStorageMode, } from '@miden-sdk/miden-sdk';
2
- import { buildMultisigStorageSlots, buildPsmStorageSlots } from './storage.js';
3
- import { MULTISIG_MASM, MULTISIG_ECDSA_MASM, PSM_MASM, PSM_ECDSA_MASM } from './masm.js';
7
+ import { buildMultisigStorageSlots, buildGuardianStorageSlots } from './storage.js';
8
+ import { MULTISIG_ECDSA_MASM, MULTISIG_MASM, GUARDIAN_ECDSA_MASM, GUARDIAN_MASM, } from './masm/auth.js';
9
+ import { MULTISIG_GUARDIAN_ACCOUNT_COMPONENT_MASM, MULTISIG_GUARDIAN_ECDSA_ACCOUNT_COMPONENT_MASM, } from './masm/account-components/auth.js';
10
+ import { normalizeSignerCommitment } from '../utils/signature.js';
11
+ /**
12
+ * Creates a multisig account with GUARDIAN authentication.
13
+ *
14
+ * @param webClient - Initialized Miden WebClient
15
+ * @param config - Multisig configuration
16
+ * @returns The created account and seed
17
+ */
4
18
  export async function createMultisigAccount(webClient, config) {
5
19
  validateMultisigConfig(config);
6
20
  const signatureScheme = config.signatureScheme ?? 'falcon';
7
- const multisigSlots = buildMultisigStorageSlots(config);
8
- const psmSlots = buildPsmStorageSlots(config);
9
- const psmBuilder = webClient.createCodeBuilder();
10
- const psmMasm = signatureScheme === 'ecdsa' ? PSM_ECDSA_MASM : PSM_MASM;
11
- const psmCode = psmBuilder.compileAccountComponentCode(psmMasm);
12
- const psmComponent = AccountComponent
13
- .compile(psmCode, psmSlots)
14
- .withSupportsAllTypes();
21
+ const authSlots = [
22
+ ...buildMultisigStorageSlots(config),
23
+ ...buildGuardianStorageSlots(config),
24
+ ];
25
+ const guardianMasm = signatureScheme === 'ecdsa' ? GUARDIAN_ECDSA_MASM : GUARDIAN_MASM;
15
26
  const multisigMasm = signatureScheme === 'ecdsa' ? MULTISIG_ECDSA_MASM : MULTISIG_MASM;
16
- const psmLibraryPath = signatureScheme === 'ecdsa' ? 'openzeppelin::psm_ecdsa' : 'openzeppelin::psm';
17
- const multisigBuilder = webClient.createCodeBuilder();
18
- const psmLib = multisigBuilder.buildLibrary(psmLibraryPath, psmMasm);
19
- multisigBuilder.linkStaticLibrary(psmLib);
20
- const multisigCode = multisigBuilder.compileAccountComponentCode(multisigMasm);
21
- const multisigComponent = AccountComponent
22
- .compile(multisigCode, multisigSlots)
27
+ const authComponentMasm = signatureScheme === 'ecdsa'
28
+ ? MULTISIG_GUARDIAN_ECDSA_ACCOUNT_COMPONENT_MASM
29
+ : MULTISIG_GUARDIAN_ACCOUNT_COMPONENT_MASM;
30
+ const guardianLibraryPath = signatureScheme === 'ecdsa'
31
+ ? 'openzeppelin::auth::guardian_ecdsa'
32
+ : 'openzeppelin::auth::guardian';
33
+ const multisigLibraryPath = signatureScheme === 'ecdsa'
34
+ ? 'openzeppelin::auth::multisig_ecdsa'
35
+ : 'openzeppelin::auth::multisig';
36
+ const authBuilder = webClient.createCodeBuilder();
37
+ const guardianLib = authBuilder.buildLibrary(guardianLibraryPath, guardianMasm);
38
+ authBuilder.linkStaticLibrary(guardianLib);
39
+ const multisigLib = authBuilder.buildLibrary(multisigLibraryPath, multisigMasm);
40
+ authBuilder.linkStaticLibrary(multisigLib);
41
+ const authCode = authBuilder.compileAccountComponentCode(authComponentMasm);
42
+ const authComponent = AccountComponent
43
+ .compile(authCode, authSlots)
23
44
  .withSupportsAllTypes();
24
- const seed = new Uint8Array(32);
25
- crypto.getRandomValues(seed);
45
+ let seed = config.seed;
46
+ // Generate random seed if not provided
47
+ if (!seed) {
48
+ seed = crypto.getRandomValues(new Uint8Array(32));
49
+ }
26
50
  const storageMode = config.storageMode === 'public'
27
51
  ? AccountStorageMode.public()
28
52
  : AccountStorageMode.private();
29
53
  const accountBuilder = new AccountBuilder(seed)
30
54
  .accountType(AccountType.RegularAccountUpdatableCode)
31
55
  .storageMode(storageMode)
32
- .withAuthComponent(multisigComponent)
33
- .withComponent(psmComponent)
56
+ .withAuthComponent(authComponent)
34
57
  .withBasicWalletComponent();
35
58
  const result = accountBuilder.build();
36
59
  await webClient.newAccount(result.account, false);
@@ -39,6 +62,12 @@ export async function createMultisigAccount(webClient, config) {
39
62
  seed,
40
63
  };
41
64
  }
65
+ /**
66
+ * Validates a multisig configuration.
67
+ *
68
+ * @param config - The configuration to validate
69
+ * @throws Error if configuration is invalid
70
+ */
42
71
  export function validateMultisigConfig(config) {
43
72
  if (config.threshold === 0) {
44
73
  throw new Error('threshold must be greater than 0');
@@ -46,20 +75,21 @@ export function validateMultisigConfig(config) {
46
75
  if (config.signerCommitments.length === 0) {
47
76
  throw new Error('at least one signer commitment is required');
48
77
  }
49
- for (const commitment of config.signerCommitments) {
50
- const stripped = commitment.startsWith('0x') || commitment.startsWith('0X')
51
- ? commitment.slice(2)
52
- : commitment;
53
- if (stripped.length > 64) {
54
- throw new Error(`signerCommitments must be 32-byte commitment hex (64 chars), got ${stripped.length} chars`);
78
+ const signerCommitments = new Set();
79
+ for (const signerCommitment of config.signerCommitments) {
80
+ const normalizedCommitment = normalizeSignerCommitment(signerCommitment);
81
+ if (signerCommitments.has(normalizedCommitment)) {
82
+ throw new Error(`duplicate signer commitment: ${normalizedCommitment}`);
55
83
  }
84
+ signerCommitments.add(normalizedCommitment);
56
85
  }
57
86
  if (config.threshold > config.signerCommitments.length) {
58
87
  throw new Error(`threshold (${config.threshold}) cannot exceed number of signers (${config.signerCommitments.length})`);
59
88
  }
60
- if (!config.psmCommitment) {
61
- throw new Error('PSM commitment is required');
89
+ if (!config.guardianCommitment) {
90
+ throw new Error('GUARDIAN commitment is required');
62
91
  }
92
+ // Validate procedure thresholds if provided
63
93
  if (config.procedureThresholds) {
64
94
  const seen = new Set();
65
95
  for (const pt of config.procedureThresholds) {
@@ -1 +1 @@
1
- {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/account/builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/account/builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,mBAAmB,EACnB,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,wCAAwC,EACxC,8CAA8C,GAC/C,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,SAAoB,EACpB,MAAsB;IAEtB,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,QAAQ,CAAC;IAC3D,MAAM,SAAS,GAAG;QAChB,GAAG,yBAAyB,CAAC,MAAM,CAAC;QACpC,GAAG,yBAAyB,CAAC,MAAM,CAAC;KACrC,CAAC;IACF,MAAM,YAAY,GAAG,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,aAAa,CAAC;IACvF,MAAM,YAAY,GAAG,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,aAAa,CAAC;IACvF,MAAM,iBAAiB,GAAG,eAAe,KAAK,OAAO;QACnD,CAAC,CAAC,8CAA8C;QAChD,CAAC,CAAC,wCAAwC,CAAC;IAC7C,MAAM,mBAAmB,GAAG,eAAe,KAAK,OAAO;QACrD,CAAC,CAAC,oCAAoC;QACtC,CAAC,CAAC,8BAA8B,CAAC;IACnC,MAAM,mBAAmB,GAAG,eAAe,KAAK,OAAO;QACrD,CAAC,CAAC,oCAAoC;QACtC,CAAC,CAAC,8BAA8B,CAAC;IAEnC,MAAM,WAAW,GAAG,SAAS,CAAC,iBAAiB,EAAE,CAAC;IAClD,MAAM,WAAW,GAAG,WAAW,CAAC,YAAY,CAAC,mBAAmB,EAAE,YAAY,CAAC,CAAC;IAChF,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,WAAW,CAAC,YAAY,CAAC,mBAAmB,EAAE,YAAY,CAAC,CAAC;IAChF,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,WAAW,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,CAAC;IAC5E,MAAM,aAAa,GAAG,gBAAgB;SACnC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC;SAC5B,oBAAoB,EAAE,CAAC;IAE1B,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACvB,uCAAuC;IACvC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,KAAK,QAAQ;QACjD,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;QAC7B,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC;IAEjC,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC;SAC5C,WAAW,CAAC,WAAW,CAAC,2BAA2B,CAAC;SACpD,WAAW,CAAC,WAAW,CAAC;SACxB,iBAAiB,CAAC,aAAa,CAAC;SAChC,wBAAwB,EAAE,CAAC;IAE9B,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;IAEtC,MAAM,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAElD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,IAAI;KACL,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAsB;IAC3D,IAAI,MAAM,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,MAAM,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,KAAK,MAAM,gBAAgB,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACxD,MAAM,oBAAoB,GAAG,yBAAyB,CAAC,gBAAgB,CAAC,CAAC;QACzE,IAAI,iBAAiB,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,gCAAgC,oBAAoB,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,iBAAiB,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CACb,cAAc,MAAM,CAAC,SAAS,sCAAsC,MAAM,CAAC,iBAAiB,CAAC,MAAM,GAAG,CACvG,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,4CAA4C;IAC5C,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC5C,IAAI,EAAE,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,EAAE,CAAC,SAAS,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC;gBACnD,MAAM,IAAI,KAAK,CACb,wBAAwB,EAAE,CAAC,SAAS,sCAAsC,MAAM,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAC7G,CAAC;YACJ,CAAC;YAED,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,sCAAsC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;YACxE,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,39 +1,115 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- vi.mock('@miden-sdk/miden-sdk', () => ({
3
- AccountBuilder: vi.fn(),
4
- AccountComponent: { compile: vi.fn() },
5
- AccountStorageMode: { public: vi.fn(), private: vi.fn() },
6
- AccountType: { RegularAccountUpdatableCode: 'regular' },
7
- }));
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { createMultisigAccount } from './builder.js';
3
+ import { MULTISIG_ECDSA_MASM, MULTISIG_MASM, GUARDIAN_ECDSA_MASM, GUARDIAN_MASM, } from './masm/auth.js';
4
+ import { MULTISIG_GUARDIAN_ACCOUNT_COMPONENT_MASM, MULTISIG_GUARDIAN_ECDSA_ACCOUNT_COMPONENT_MASM, } from './masm/account-components/auth.js';
5
+ const { buildMultisigStorageSlots, buildGuardianStorageSlots, withSupportsAllTypes, compileComponent, MockAccountBuilder, } = vi.hoisted(() => {
6
+ const buildMultisigStorageSlots = vi.fn(() => ['multisig-slots']);
7
+ const buildGuardianStorageSlots = vi.fn(() => ['guardian-slots']);
8
+ const withSupportsAllTypes = vi.fn((component) => component);
9
+ const compileComponent = vi.fn((code, slots) => ({
10
+ code,
11
+ slots,
12
+ withSupportsAllTypes: () => withSupportsAllTypes({ code, slots }),
13
+ }));
14
+ class MockAccountBuilder {
15
+ accountType() {
16
+ return this;
17
+ }
18
+ storageMode() {
19
+ return this;
20
+ }
21
+ withAuthComponent() {
22
+ return this;
23
+ }
24
+ withComponent() {
25
+ return this;
26
+ }
27
+ withBasicWalletComponent() {
28
+ return this;
29
+ }
30
+ build() {
31
+ return {
32
+ account: { id: () => ({ toString: () => '0x' + 'a'.repeat(30) }) },
33
+ };
34
+ }
35
+ }
36
+ return {
37
+ buildMultisigStorageSlots,
38
+ buildGuardianStorageSlots,
39
+ withSupportsAllTypes,
40
+ compileComponent,
41
+ MockAccountBuilder,
42
+ };
43
+ });
8
44
  vi.mock('./storage.js', () => ({
9
- buildMultisigStorageSlots: vi.fn(),
10
- buildPsmStorageSlots: vi.fn(),
45
+ buildMultisigStorageSlots,
46
+ buildGuardianStorageSlots,
11
47
  }));
12
- vi.mock('./masm.js', () => ({
13
- MULTISIG_MASM: '',
14
- PSM_MASM: '',
48
+ vi.mock('@miden-sdk/miden-sdk', () => ({
49
+ AccountBuilder: MockAccountBuilder,
50
+ AccountComponent: {
51
+ compile: compileComponent,
52
+ },
53
+ AccountType: {
54
+ RegularAccountUpdatableCode: 'regular',
55
+ },
56
+ AccountStorageMode: {
57
+ public: () => 'public',
58
+ private: () => 'private',
59
+ },
15
60
  }));
16
- import { validateMultisigConfig } from './builder.js';
17
- describe('validateMultisigConfig', () => {
18
- it('rejects duplicate signer commitments after normalization', () => {
19
- expect(() => validateMultisigConfig({
20
- threshold: 2,
21
- signerCommitments: [
22
- '0x' + 'a'.repeat(64),
23
- '0x' + 'A'.repeat(64),
24
- ],
25
- psmCommitment: '0x' + 'c'.repeat(64),
26
- })).toThrow('duplicate signer commitment');
61
+ describe('createMultisigAccount', () => {
62
+ beforeEach(() => {
63
+ vi.stubGlobal('crypto', {
64
+ getRandomValues(buffer) {
65
+ return buffer;
66
+ },
67
+ });
68
+ buildMultisigStorageSlots.mockClear();
69
+ buildGuardianStorageSlots.mockClear();
70
+ withSupportsAllTypes.mockClear();
71
+ compileComponent.mockClear();
72
+ });
73
+ it('uses Falcon MASM by default', async () => {
74
+ const authBuilder = {
75
+ buildLibrary: vi.fn((libraryPath, source) => ({ libraryPath, source })),
76
+ linkStaticLibrary: vi.fn(),
77
+ compileAccountComponentCode: vi.fn((source) => `auth:${source.slice(0, 16)}`),
78
+ };
79
+ const webClient = {
80
+ createCodeBuilder: vi.fn().mockReturnValue(authBuilder),
81
+ newAccount: vi.fn(),
82
+ };
83
+ await createMultisigAccount(webClient, {
84
+ threshold: 1,
85
+ signerCommitments: ['0x' + '1'.repeat(64)],
86
+ guardianCommitment: '0x' + '2'.repeat(64),
87
+ });
88
+ expect(authBuilder.buildLibrary).toHaveBeenNthCalledWith(1, 'openzeppelin::auth::guardian', GUARDIAN_MASM);
89
+ expect(authBuilder.buildLibrary).toHaveBeenNthCalledWith(2, 'openzeppelin::auth::multisig', MULTISIG_MASM);
90
+ expect(authBuilder.compileAccountComponentCode).toHaveBeenCalledWith(MULTISIG_GUARDIAN_ACCOUNT_COMPONENT_MASM);
91
+ expect(webClient.newAccount).toHaveBeenCalledTimes(1);
27
92
  });
28
- it('accepts unique signer commitments', () => {
29
- expect(() => validateMultisigConfig({
30
- threshold: 2,
31
- signerCommitments: [
32
- '0x' + 'a'.repeat(64),
33
- '0x' + 'b'.repeat(64),
34
- ],
35
- psmCommitment: '0x' + 'c'.repeat(64),
36
- })).not.toThrow();
93
+ it('uses ECDSA MASM when requested', async () => {
94
+ const authBuilder = {
95
+ buildLibrary: vi.fn((libraryPath, source) => ({ libraryPath, source })),
96
+ linkStaticLibrary: vi.fn(),
97
+ compileAccountComponentCode: vi.fn((source) => `auth:${source.slice(0, 16)}`),
98
+ };
99
+ const webClient = {
100
+ createCodeBuilder: vi.fn().mockReturnValue(authBuilder),
101
+ newAccount: vi.fn(),
102
+ };
103
+ await createMultisigAccount(webClient, {
104
+ threshold: 1,
105
+ signerCommitments: ['0x' + '1'.repeat(64)],
106
+ guardianCommitment: '0x' + '2'.repeat(64),
107
+ signatureScheme: 'ecdsa',
108
+ });
109
+ expect(authBuilder.buildLibrary).toHaveBeenNthCalledWith(1, 'openzeppelin::auth::guardian_ecdsa', GUARDIAN_ECDSA_MASM);
110
+ expect(authBuilder.buildLibrary).toHaveBeenNthCalledWith(2, 'openzeppelin::auth::multisig_ecdsa', MULTISIG_ECDSA_MASM);
111
+ expect(authBuilder.compileAccountComponentCode).toHaveBeenCalledWith(MULTISIG_GUARDIAN_ECDSA_ACCOUNT_COMPONENT_MASM);
112
+ expect(webClient.newAccount).toHaveBeenCalledTimes(1);
37
113
  });
38
114
  });
39
115
  //# sourceMappingURL=builder.test.js.map