@openzeppelin/miden-multisig-client 0.16.1 → 0.17.0-rc.1

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 (207) hide show
  1. package/README.md +192 -11
  2. package/dist/account/builder.d.ts.map +1 -1
  3. package/dist/account/builder.js +32 -25
  4. package/dist/account/builder.js.map +1 -1
  5. package/dist/account/builder.test.js +73 -21
  6. package/dist/account/builder.test.js.map +1 -1
  7. package/dist/account/layout.d.ts +31 -0
  8. package/dist/account/layout.d.ts.map +1 -0
  9. package/dist/account/layout.js +31 -0
  10. package/dist/account/layout.js.map +1 -0
  11. package/dist/account/masm/account-components/auth.d.ts +1 -4
  12. package/dist/account/masm/account-components/auth.d.ts.map +1 -1
  13. package/dist/account/masm/account-components/auth.js +36 -53
  14. package/dist/account/masm/account-components/auth.js.map +1 -1
  15. package/dist/account/masm/index.d.ts +0 -1
  16. package/dist/account/masm/index.d.ts.map +1 -1
  17. package/dist/account/masm/index.js +0 -1
  18. package/dist/account/masm/index.js.map +1 -1
  19. package/dist/account/storage.d.ts +4 -0
  20. package/dist/account/storage.d.ts.map +1 -1
  21. package/dist/account/storage.js +9 -20
  22. package/dist/account/storage.js.map +1 -1
  23. package/dist/client.d.ts +4 -0
  24. package/dist/client.d.ts.map +1 -1
  25. package/dist/client.js +10 -5
  26. package/dist/client.js.map +1 -1
  27. package/dist/client.test.js +74 -16
  28. package/dist/client.test.js.map +1 -1
  29. package/dist/index.d.ts +5 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +3 -3
  32. package/dist/index.js.map +1 -1
  33. package/dist/inspector.d.ts +59 -1
  34. package/dist/inspector.d.ts.map +1 -1
  35. package/dist/inspector.js +157 -29
  36. package/dist/inspector.js.map +1 -1
  37. package/dist/inspector.test.js +246 -37
  38. package/dist/inspector.test.js.map +1 -1
  39. package/dist/multisig.d.ts +109 -33
  40. package/dist/multisig.d.ts.map +1 -1
  41. package/dist/multisig.js +307 -104
  42. package/dist/multisig.js.map +1 -1
  43. package/dist/multisig.test.js +582 -58
  44. package/dist/multisig.test.js.map +1 -1
  45. package/dist/procedures.d.ts +6 -7
  46. package/dist/procedures.d.ts.map +1 -1
  47. package/dist/procedures.js +6 -7
  48. package/dist/procedures.js.map +1 -1
  49. package/dist/proposal/metadata.d.ts.map +1 -1
  50. package/dist/proposal/metadata.js +13 -2
  51. package/dist/proposal/metadata.js.map +1 -1
  52. package/dist/proposal/metadata.test.js +57 -0
  53. package/dist/proposal/metadata.test.js.map +1 -1
  54. package/dist/prover/errors.d.ts +5 -0
  55. package/dist/prover/errors.d.ts.map +1 -1
  56. package/dist/prover/errors.js +7 -155
  57. package/dist/prover/errors.js.map +1 -1
  58. package/dist/prover/errors.test.js +5 -0
  59. package/dist/prover/errors.test.js.map +1 -1
  60. package/dist/prover/retry.d.ts +1 -6
  61. package/dist/prover/retry.d.ts.map +1 -1
  62. package/dist/prover/retry.js +5 -28
  63. package/dist/prover/retry.js.map +1 -1
  64. package/dist/prover/retry.test.js +1 -1
  65. package/dist/prover/retry.test.js.map +1 -1
  66. package/dist/prover/workflow.d.ts +4 -3
  67. package/dist/prover/workflow.d.ts.map +1 -1
  68. package/dist/prover/workflow.js +5 -2
  69. package/dist/prover/workflow.js.map +1 -1
  70. package/dist/prover/workflow.test.js +28 -3
  71. package/dist/prover/workflow.test.js.map +1 -1
  72. package/dist/retry/classify.d.ts +16 -0
  73. package/dist/retry/classify.d.ts.map +1 -0
  74. package/dist/retry/classify.js +187 -0
  75. package/dist/retry/classify.js.map +1 -0
  76. package/dist/retry/runtime.d.ts +13 -0
  77. package/dist/retry/runtime.d.ts.map +1 -0
  78. package/dist/retry/runtime.js +33 -0
  79. package/dist/retry/runtime.js.map +1 -0
  80. package/dist/rpc/config.d.ts +11 -0
  81. package/dist/rpc/config.d.ts.map +1 -0
  82. package/dist/rpc/config.js +17 -0
  83. package/dist/rpc/config.js.map +1 -0
  84. package/dist/rpc/config.test.d.ts +2 -0
  85. package/dist/rpc/config.test.d.ts.map +1 -0
  86. package/dist/rpc/config.test.js +24 -0
  87. package/dist/rpc/config.test.js.map +1 -0
  88. package/dist/rpc/errors.d.ts +2 -0
  89. package/dist/rpc/errors.d.ts.map +1 -0
  90. package/dist/rpc/errors.js +11 -0
  91. package/dist/rpc/errors.js.map +1 -0
  92. package/dist/rpc/errors.test.d.ts +2 -0
  93. package/dist/rpc/errors.test.d.ts.map +1 -0
  94. package/dist/rpc/errors.test.js +34 -0
  95. package/dist/rpc/errors.test.js.map +1 -0
  96. package/dist/rpc/retry.d.ts +4 -0
  97. package/dist/rpc/retry.d.ts.map +1 -0
  98. package/dist/rpc/retry.js +6 -0
  99. package/dist/rpc/retry.js.map +1 -0
  100. package/dist/rpc/retry.test.d.ts +2 -0
  101. package/dist/rpc/retry.test.d.ts.map +1 -0
  102. package/dist/rpc/retry.test.js +98 -0
  103. package/dist/rpc/retry.test.js.map +1 -0
  104. package/dist/transaction/index.d.ts +1 -1
  105. package/dist/transaction/index.d.ts.map +1 -1
  106. package/dist/transaction/index.js +1 -1
  107. package/dist/transaction/index.js.map +1 -1
  108. package/dist/transaction/p2id.d.ts +17 -6
  109. package/dist/transaction/p2id.d.ts.map +1 -1
  110. package/dist/transaction/p2id.js +22 -31
  111. package/dist/transaction/p2id.js.map +1 -1
  112. package/dist/transaction/p2id.test.js +62 -24
  113. package/dist/transaction/p2id.test.js.map +1 -1
  114. package/dist/transaction/summary.d.ts +45 -2
  115. package/dist/transaction/summary.d.ts.map +1 -1
  116. package/dist/transaction/summary.js +42 -2
  117. package/dist/transaction/summary.js.map +1 -1
  118. package/dist/transaction/summary.test.d.ts +2 -0
  119. package/dist/transaction/summary.test.d.ts.map +1 -0
  120. package/dist/transaction/summary.test.js +26 -0
  121. package/dist/transaction/summary.test.js.map +1 -0
  122. package/dist/transaction/updateGuardian.d.ts.map +1 -1
  123. package/dist/transaction/updateGuardian.js +16 -18
  124. package/dist/transaction/updateGuardian.js.map +1 -1
  125. package/dist/transaction/updateProcedureThreshold.d.ts.map +1 -1
  126. package/dist/transaction/updateProcedureThreshold.js +15 -17
  127. package/dist/transaction/updateProcedureThreshold.js.map +1 -1
  128. package/dist/transaction/updateSigners.d.ts +6 -1
  129. package/dist/transaction/updateSigners.d.ts.map +1 -1
  130. package/dist/transaction/updateSigners.js +20 -17
  131. package/dist/transaction/updateSigners.js.map +1 -1
  132. package/dist/transaction.d.ts +2 -2
  133. package/dist/transaction.d.ts.map +1 -1
  134. package/dist/transaction.js +1 -1
  135. package/dist/transaction.js.map +1 -1
  136. package/dist/types/proposal.d.ts +28 -4
  137. package/dist/types/proposal.d.ts.map +1 -1
  138. package/dist/types/proposal.js +18 -0
  139. package/dist/types/proposal.js.map +1 -1
  140. package/dist/types.d.ts +0 -1
  141. package/dist/types.d.ts.map +1 -1
  142. package/dist/utils/signature.d.ts +11 -7
  143. package/dist/utils/signature.d.ts.map +1 -1
  144. package/dist/utils/signature.js +24 -58
  145. package/dist/utils/signature.js.map +1 -1
  146. package/dist/utils/word.d.ts +7 -0
  147. package/dist/utils/word.d.ts.map +1 -1
  148. package/dist/utils/word.js +15 -0
  149. package/dist/utils/word.js.map +1 -1
  150. package/masm/account_components/auth/guarded_multisig.masm +42 -0
  151. package/package.json +7 -4
  152. package/src/account/builder.test.ts +111 -45
  153. package/src/account/builder.ts +45 -33
  154. package/src/account/layout.ts +33 -0
  155. package/src/account/masm/account-components/auth.ts +36 -56
  156. package/src/account/masm/index.ts +0 -1
  157. package/src/account/storage.ts +9 -22
  158. package/src/client.test.ts +87 -16
  159. package/src/client.ts +16 -3
  160. package/src/index.ts +27 -1
  161. package/src/inspector.test.ts +330 -38
  162. package/src/inspector.ts +196 -33
  163. package/src/multisig.test.ts +680 -63
  164. package/src/multisig.ts +400 -115
  165. package/src/procedures.ts +6 -7
  166. package/src/proposal/metadata.test.ts +76 -0
  167. package/src/proposal/metadata.ts +13 -2
  168. package/src/prover/errors.test.ts +8 -0
  169. package/src/prover/errors.ts +7 -175
  170. package/src/prover/retry.test.ts +1 -1
  171. package/src/prover/retry.ts +10 -35
  172. package/src/prover/workflow.test.ts +40 -4
  173. package/src/prover/workflow.ts +16 -4
  174. package/src/retry/classify.ts +220 -0
  175. package/src/retry/runtime.ts +45 -0
  176. package/src/rpc/config.test.ts +45 -0
  177. package/src/rpc/config.ts +30 -0
  178. package/src/rpc/errors.test.ts +69 -0
  179. package/src/rpc/errors.ts +12 -0
  180. package/src/rpc/retry.test.ts +144 -0
  181. package/src/rpc/retry.ts +12 -0
  182. package/src/transaction/index.ts +7 -1
  183. package/src/transaction/p2id.test.ts +112 -31
  184. package/src/transaction/p2id.ts +39 -38
  185. package/src/transaction/summary.test.ts +32 -0
  186. package/src/transaction/summary.ts +83 -4
  187. package/src/transaction/updateGuardian.ts +15 -25
  188. package/src/transaction/updateProcedureThreshold.ts +13 -29
  189. package/src/transaction/updateSigners.ts +38 -30
  190. package/src/transaction.ts +8 -1
  191. package/src/types/proposal.ts +43 -4
  192. package/src/types.ts +0 -1
  193. package/src/utils/signature.ts +32 -65
  194. package/src/utils/word.ts +17 -0
  195. package/dist/account/masm/auth.d.ts +0 -5
  196. package/dist/account/masm/auth.d.ts.map +0 -1
  197. package/dist/account/masm/auth.js +0 -1509
  198. package/dist/account/masm/auth.js.map +0 -1
  199. package/masm/account_components/auth/multisig.masm +0 -12
  200. package/masm/account_components/auth/multisig_ecdsa.masm +0 -12
  201. package/masm/account_components/auth/multisig_guardian.masm +0 -16
  202. package/masm/account_components/auth/multisig_guardian_ecdsa.masm +0 -16
  203. package/masm/auth/guardian.masm +0 -199
  204. package/masm/auth/guardian_ecdsa.masm +0 -195
  205. package/masm/auth/multisig.masm +0 -554
  206. package/masm/auth/multisig_ecdsa.masm +0 -554
  207. package/src/account/masm/auth.ts +0 -1512
package/README.md CHANGED
@@ -17,9 +17,30 @@ Miden multisig accounts store their authentication logic on-chain, but **their s
17
17
  ## Installation
18
18
 
19
19
  ```bash
20
- npm install @openzeppelin/miden-multisig-client @miden-sdk/miden-sdk
20
+ npm install @openzeppelin/miden-multisig-client @miden-sdk/miden-sdk@0.16.0-rc.3
21
21
  ```
22
22
 
23
+ > **Why the peer version is exact**: no stable `0.16.0` is published, so a
24
+ > `0.16.x`/`^0.16.0` range resolves to nothing, and the transaction-summary
25
+ > layout and procedure roots are only byte-compatible within one pre-release
26
+ > pair. Package releases wait for upstream 0.16 to stabilize.
27
+
28
+ ## Miden compatibility
29
+
30
+ This package's version and Miden's are **not** aligned. Pick the release that
31
+ matches your Miden node:
32
+
33
+ | This package | Miden protocol |
34
+ |---|---|
35
+ | 0.17.x | 0.16.x (pre-release) |
36
+ | 0.16.x | 0.15.x |
37
+ | 0.15.x | 0.15.x |
38
+
39
+ Adopting a new Miden line has twice required an irreversible reset of
40
+ Guardian-stored account data, so an upgrade is not a drop-in. Full matrix, the
41
+ breaking changes per line, and what each upgrade does to stored data:
42
+ [MIDEN_COMPATIBILITY.md](https://github.com/OpenZeppelin/guardian/blob/main/docs/MIDEN_COMPATIBILITY.md).
43
+
23
44
  ## Setup
24
45
 
25
46
  ```typescript
@@ -42,6 +63,9 @@ const client = new MultisigClient(midenClient, {
42
63
  url: 'https://prover.example',
43
64
  retry: { maxAttempts: 4 },
44
65
  },
66
+ rpc: {
67
+ retry: { maxAttempts: 3 },
68
+ },
45
69
  });
46
70
  ```
47
71
 
@@ -50,8 +74,49 @@ client's prover is preserved. By default, cloneable remote provers get two total
50
74
  attempts; endpoint-less injected provers, including local and callback provers,
51
75
  run once. A custom URL must be absolute HTTP(S), overrides the injected prover,
52
76
  and never falls back to a default endpoint. Retries apply only to transient
53
- proof failures; transaction execution, submission, local state application,
54
- GUARDIAN calls, and Miden RPC requests are not retried.
77
+ proof failures; transaction execution, submission, local state application, and
78
+ GUARDIAN calls are not retried.
79
+
80
+ An optional `rpc` configuration (`rpc: { retry: { maxAttempts: 3 } }`) tunes
81
+ retries for the idempotent Miden node reads this SDK issues — on-chain
82
+ account lookups, state-commitment verification, and the guardian-switch node
83
+ sync — against transient failures such as rate limiting. The default is two
84
+ total attempts (one retry); an explicit `maxAttempts` of 1 opts out. Syncs
85
+ performed directly on the injected Miden client are owned by the
86
+ application. Transaction submission is never retried under any
87
+ configuration: a submission whose outcome is unknown could execute twice if
88
+ re-sent. There is no timeout setting: the browser WASM RPC client cannot
89
+ cancel an in-flight request, so a JavaScript-side timeout would abandon a
90
+ call whose side effects may still land.
91
+
92
+ ### Note transport endpoint
93
+
94
+ Private notes are relayed through a note transport service that is separate
95
+ from the node RPC. The injected Miden client owns note relay, so the endpoint
96
+ is set when constructing it rather than on `MultisigClientConfig`. The
97
+ `createDevnet` / `createTestnet` helpers wire the matching public transport
98
+ service automatically; a custom node endpoint has no derivable transport
99
+ service, so private-note relay stays disabled until `noteTransportUrl` is set
100
+ explicitly.
101
+
102
+ ```typescript
103
+ const midenClient = await MidenClient.create({
104
+ rpcUrl: 'https://my-node.internal:57291',
105
+ noteTransportUrl: 'https://my-transport.internal',
106
+ });
107
+
108
+ const client = new MultisigClient(midenClient, {
109
+ guardianEndpoint: 'http://localhost:3000',
110
+ midenRpcEndpoint: 'https://my-node.internal:57291',
111
+ });
112
+ ```
113
+
114
+ `noteTransportUrl` also accepts the `'devnet'` and `'testnet'` shorthands, so
115
+ a custom node on a public network can reuse that network's public transport
116
+ service.
117
+
118
+ The full cross-SDK reference, including the Rust equivalents, is
119
+ [`docs/MULTISIG_SDK.md`](https://github.com/OpenZeppelin/guardian/blob/main/docs/MULTISIG_SDK.md).
55
120
 
56
121
  ## Usage
57
122
 
@@ -95,6 +160,47 @@ The configuration is automatically detected from the account's on-chain storage:
95
160
  const multisig = await client.load(accountId, signer);
96
161
  ```
97
162
 
163
+ ### Read Signer Public-Key Commitments
164
+
165
+ Since accounts use the upstream `AuthGuardedMultisig` component, the Miden
166
+ SDK's `Account.getPublicKeyCommitments()` returns the approver commitments
167
+ natively. The `AccountInspector` accessors are the strict, layout-insulated
168
+ alternative (issue #306): they validate the complete set against the
169
+ configured signer count and throw instead of silently omitting unreadable
170
+ entries, and they shield consumers from storage-layout changes across
171
+ contract versions.
172
+
173
+ Holding only a fetched Miden SDK `Account` (e.g. a wallet or dApp):
174
+
175
+ ```typescript
176
+ import { AccountInspector } from '@openzeppelin/miden-multisig-client';
177
+
178
+ const commitments = AccountInspector.getSignerPublicKeyCommitments(account);
179
+ const guardianKey = AccountInspector.getGuardianPublicKeyCommitment(account);
180
+ ```
181
+
182
+ Or from a loaded `Multisig` instance (reads current store-backed state):
183
+
184
+ ```typescript
185
+ const signerKeys = await multisig.getSignerPublicKeyCommitments();
186
+ ```
187
+
188
+ Commitments are ordered by signer index as currently stored; indices re-pack
189
+ when signers are removed, so index 0 is the key listed first at creation (by
190
+ convention the creating client's own key) only until the first membership
191
+ change. Hot/cold roles are a consumer-side convention, not part of on-chain
192
+ state. `getSignerPublicKeyCommitments` throws rather than silently returning
193
+ a truncated list when any signer entry is absent; `getGuardianPublicKeyCommitment`
194
+ throws when the guardian entry is missing (the guarded-multisig always
195
+ includes a guardian). Both are gated on this SDK's pinned contract version
196
+ and reject accounts built from a different miden-standards release.
197
+
198
+ The `Account` passed to `AccountInspector` must come from the same copy of
199
+ `@miden-sdk/miden-sdk` that this package links. An application bundling its
200
+ own SDK copy (common in wallets) will get a descriptive error from the SDK's
201
+ instance checks; construct the account with this package's SDK instance
202
+ instead.
203
+
98
204
  ### Recover An Account By Key
99
205
 
100
206
  When the wallet only holds a signing key from the account's authorization
@@ -135,18 +241,52 @@ console.log('Commitment:', state.commitment);
135
241
  console.log('Created:', state.createdAt);
136
242
  ```
137
243
 
244
+ ### Creating Proposals
245
+
246
+ Every `create*Proposal` method takes its required arguments followed by a
247
+ single optional options object (issue #387) — there are no positional
248
+ optional parameters:
249
+
250
+ ```typescript
251
+ createP2idProposal(recipientId, faucetId, amount, { nonce, noteType, reclaimHeight, timelockHeight }?)
252
+ createConsumeNotesProposal(noteIds, { nonce }?)
253
+ createAddSignerProposal(commitment, { nonce, newThreshold }?)
254
+ createRemoveSignerProposal(commitment, { nonce, newThreshold }?)
255
+ createChangeThresholdProposal(threshold, { nonce }?)
256
+ createUpdateProcedureThresholdProposal(procedure, threshold, { nonce }?)
257
+ createSwitchGuardianProposal(endpoint, pubkey, { nonce }?)
258
+ createCustomProposal(requestBytes, label, { nonce }?)
259
+ ```
260
+
261
+ All methods accept `nonce` (identifies the proposal; defaults to
262
+ `Date.now()`). `newThreshold` defaults to the current threshold on add and to
263
+ the min of the current threshold and the remaining signer count on remove.
264
+ The option shapes are exported as `CreateProposalOptions`,
265
+ `CreateSignerProposalOptions`, and `CreateP2idProposalOptions`.
266
+
267
+ > **Breaking change (issue #387):** these methods previously took `nonce` (and
268
+ > `newThreshold`) as positional parameters. Passing the old positional form
269
+ > now throws at runtime instead of silently applying defaults.
270
+
138
271
  ### Create a Proposal (Add Signer)
139
272
 
140
273
  ```typescript
141
274
  // Create a proposal to add a new signer
142
275
  const proposal = await multisig.createAddSignerProposal(
143
276
  newSignerCommitment, // Commitment of signer to add
144
- undefined,
145
- 3,
277
+ { newThreshold: 3 }, // Options: nonce, newThreshold
146
278
  );
147
279
  console.log('Proposal ID:', proposal.id);
148
280
  ```
149
281
 
282
+ Per-procedure threshold overrides are absolute signature counts and are never
283
+ re-scaled on-chain, so growing the signer set silently lowers every override's
284
+ effective signing ratio (a 2-of-2 override becomes 2-of-n).
285
+ `createAddSignerProposal` logs a `console.warn` per affected override, and
286
+ `multisig.overridesDilutedBySignerGrowth(newNumSigners)` returns them for UIs
287
+ that want to prompt before proposing. Raise the affected overrides via an
288
+ update-procedure-threshold proposal alongside the growth.
289
+
150
290
  ### Sign a Proposal
151
291
 
152
292
  ```typescript
@@ -182,6 +322,26 @@ const status = await multisig.abandonStatus(nonce);
182
322
  // 'waiting' | 'landed' | 'abandoned' | 'unexpected'
183
323
  ```
184
324
 
325
+ ### Delta History
326
+
327
+ Render the account's confirmed history after recovery. One page
328
+ per call, newest-first by nonce, with server-decoded note summaries:
329
+
330
+ ```typescript
331
+ let cursor: string | undefined;
332
+ do {
333
+ const page = await multisig.deltaHistory({ limit: 50, cursor });
334
+ for (const entry of page.entries) {
335
+ console.log(entry.nonce, entry.timestamp, entry.outputNotes);
336
+ }
337
+ cursor = page.nextCursor;
338
+ } while (cursor !== undefined);
339
+ ```
340
+
341
+ Only canonical (confirmed) deltas appear — pending proposals live on
342
+ `syncProposals()` — and only transactions pushed through Guardian are
343
+ visible to it.
344
+
185
345
  ### Check Proposal Status
186
346
 
187
347
  Returns cached proposals without making a network request:
@@ -248,8 +408,11 @@ import { buildP2idTransactionRequest } from '@openzeppelin/miden-multisig-client
248
408
  // The options object accepts `noteType` (`NoteType.Public` (default) or
249
409
  // `NoteType.Private`, from `@miden-sdk/miden-sdk`); a private note publishes
250
410
  // only its hash on chain, so the recipient needs the note shared out-of-band.
251
- // The typed path is `createP2idProposal(recipient, faucet, amount, nonce?,
252
- // { noteType })`, which persists the choice in signed metadata.
411
+ // It also accepts `reclaimHeight`/`timelockHeight` (absolute block heights,
412
+ // issue #366); presence of either builds a P2IDE note instead of plain P2ID.
413
+ // The typed path is `createP2idProposal(recipient, faucet, amount,
414
+ // { nonce, noteType, reclaimHeight, timelockHeight })`, which persists the
415
+ // choices in signed metadata.
253
416
  const { request, salt } = buildP2idTransactionRequest(senderId, recipientId, faucetId, amount);
254
417
  const proposal = await multisig.createCustomProposal(request.serialize(), 'b2agg');
255
418
 
@@ -261,11 +424,13 @@ const proposal = await multisig.createCustomProposal(request.serialize(), 'b2agg
261
424
  const advice = await multisig.prepareCustomExecution(proposal.id, request.serialize());
262
425
 
263
426
  // The browser TransactionRequest is immutable, so rebuild from the same recipe
264
- // (inputs + salt) with the advice, then submit.
427
+ // (inputs + salt) with the advice, then submit. `submitTransaction` takes the
428
+ // proposal id to execute at the proposal's anchored reference block, since the
429
+ // collected signatures only authorize the summary produced there.
265
430
  const { request: finalRequest } = buildP2idTransactionRequest(
266
431
  senderId, recipientId, faucetId, amount, { salt, signatureAdviceMap: advice },
267
432
  );
268
- await multisig.submitTransaction(finalRequest);
433
+ await multisig.submitTransaction(proposal.id, finalRequest);
269
434
  ```
270
435
 
271
436
  The integration keeps only its own recipe (build inputs + salt) so it can
@@ -273,6 +438,22 @@ reproduce the exact transaction at execute time — the SDK does not store the
273
438
  serialized request. The binding check guarantees the rebuilt transaction matches the
274
439
  commitment the cosigners signed.
275
440
 
441
+ If a recipe was not retained, recover the salt from the proposal's transaction
442
+ summary with `summarySalt`:
443
+
444
+ ```typescript
445
+ import { summarySalt } from '@openzeppelin/miden-multisig-client';
446
+ import { TransactionSummary } from '@miden-sdk/miden-sdk';
447
+
448
+ const salt = summarySalt(TransactionSummary.deserialize(bytes));
449
+ ```
450
+
451
+ On the Miden 0.16 pre-release line a summary no longer carries a dedicated salt
452
+ word: it binds seven user-defined elements, and the guarded-multisig auth
453
+ component zeroes the leading three and passes the auth-arg salt as the trailing
454
+ four. `summarySalt` reads that convention, so prefer it over indexing
455
+ `userParams()` by hand.
456
+
276
457
  > **Rust ↔ TS parity:** both SDKs expose the same producer surface —
277
458
  > `createCustomProposal` / `propose_custom_transaction`, `prepareCustomExecution` /
278
459
  > `prepare_custom_execution`, and `submitTransaction` / `submit_transaction`. The
@@ -369,8 +550,8 @@ default to `false`, at which point v1 proposals are refused with
369
550
  `UnsupportedMetadataVersionError(undefined)` on every code path.
370
551
  Deployments should drain or re-propose any v1 `consume_notes`
371
552
  proposals in flight before upgrading past the cut-over client version.
372
- Tracked by spec
373
- [`006-consume-notes-metadata`](../../speckit/features/006-consume-notes-metadata/spec.md).
553
+ Tracked by the `006-consume-notes-metadata` feature spec in the
554
+ repository.
374
555
 
375
556
  ## Testing
376
557
 
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/account/builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAevE;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,cAAc,EACtB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,mBAAmB,CAAC,CAqD9B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CA6CnE"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/account/builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIL,KAAK,WAAW,EAEjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAqBvE;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,cAAc,EACtB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,mBAAmB,CAAC,CAgC9B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAuEnE"}
@@ -6,9 +6,17 @@
6
6
  import { AccountBuilder, AccountComponent, AccountStorageMode, } from '@miden-sdk/miden-sdk';
7
7
  import { getRawMidenClient } from '../raw-client.js';
8
8
  import { buildMultisigStorageSlots, buildGuardianStorageSlots } from './storage.js';
9
- import { MULTISIG_ECDSA_MASM, MULTISIG_MASM, GUARDIAN_ECDSA_MASM, GUARDIAN_MASM, } from './masm/auth.js';
10
- import { MULTISIG_GUARDIAN_ACCOUNT_COMPONENT_MASM, MULTISIG_GUARDIAN_ECDSA_ACCOUNT_COMPONENT_MASM, } from './masm/account-components/auth.js';
9
+ import { GUARDED_MULTISIG_ACCOUNT_COMPONENT_MASM } from './masm/account-components/auth.js';
11
10
  import { normalizeSignerCommitment } from '../utils/signature.js';
11
+ /** Builds the guarded-multisig component without relinking assembler-provided libraries. */
12
+ function buildGuardedMultisigComponent(authBuilder, config) {
13
+ const authSlots = [
14
+ ...buildMultisigStorageSlots(config),
15
+ ...buildGuardianStorageSlots(config),
16
+ ];
17
+ const authComponentCode = authBuilder.compileAccountComponentCode(GUARDED_MULTISIG_ACCOUNT_COMPONENT_MASM);
18
+ return AccountComponent.compile(authComponentCode, authSlots).withSupportsAllTypes();
19
+ }
12
20
  /**
13
21
  * Creates a multisig account with GUARDIAN authentication.
14
22
  *
@@ -19,30 +27,9 @@ import { normalizeSignerCommitment } from '../utils/signature.js';
19
27
  */
20
28
  export async function createMultisigAccount(midenClient, config, midenRpcEndpoint) {
21
29
  validateMultisigConfig(config);
22
- const signatureScheme = config.signatureScheme ?? 'falcon';
23
30
  const rawClient = await getRawMidenClient(midenClient, midenRpcEndpoint);
24
- const authSlots = [
25
- ...buildMultisigStorageSlots(config),
26
- ...buildGuardianStorageSlots(config),
27
- ];
28
- const guardianMasm = signatureScheme === 'ecdsa' ? GUARDIAN_ECDSA_MASM : GUARDIAN_MASM;
29
- const multisigMasm = signatureScheme === 'ecdsa' ? MULTISIG_ECDSA_MASM : MULTISIG_MASM;
30
- const authComponentMasm = signatureScheme === 'ecdsa'
31
- ? MULTISIG_GUARDIAN_ECDSA_ACCOUNT_COMPONENT_MASM
32
- : MULTISIG_GUARDIAN_ACCOUNT_COMPONENT_MASM;
33
- const guardianLibraryPath = signatureScheme === 'ecdsa'
34
- ? 'openzeppelin::auth::guardian_ecdsa'
35
- : 'openzeppelin::auth::guardian';
36
- const multisigLibraryPath = signatureScheme === 'ecdsa'
37
- ? 'openzeppelin::auth::multisig_ecdsa'
38
- : 'openzeppelin::auth::multisig';
39
31
  const authBuilder = await rawClient.createCodeBuilder();
40
- authBuilder.linkModule(guardianLibraryPath, guardianMasm);
41
- authBuilder.linkModule(multisigLibraryPath, multisigMasm);
42
- const authComponentCode = authBuilder.compileAccountComponentCode(authComponentMasm);
43
- const authComponent = AccountComponent
44
- .compile(authComponentCode, authSlots)
45
- .withSupportsAllTypes();
32
+ const authComponent = buildGuardedMultisigComponent(authBuilder, config);
46
33
  let seed = config.seed;
47
34
  // Generate random seed if not provided
48
35
  if (!seed) {
@@ -57,7 +44,7 @@ export async function createMultisigAccount(midenClient, config, midenRpcEndpoin
57
44
  .storageMode(storageMode)
58
45
  .withAuthComponent(authComponent)
59
46
  .withBasicWalletComponent();
60
- const result = accountBuilder.build();
47
+ const result = accountBuilder.buildWithoutSchemaCommitment();
61
48
  await midenClient.accounts.insert({ account: result.account, overwrite: false });
62
49
  return {
63
50
  account: result.account,
@@ -91,6 +78,9 @@ export function validateMultisigConfig(config) {
91
78
  if (!config.guardianCommitment) {
92
79
  throw new Error('GUARDIAN commitment is required');
93
80
  }
81
+ if (signerCommitments.has(normalizeSignerCommitment(config.guardianCommitment))) {
82
+ throw new Error('GUARDIAN commitment must be different from all signer commitments');
83
+ }
94
84
  // Validate procedure thresholds if provided
95
85
  if (config.procedureThresholds) {
96
86
  const seen = new Set();
@@ -106,6 +96,23 @@ export function validateMultisigConfig(config) {
106
96
  }
107
97
  seen.add(pt.procedure);
108
98
  }
99
+ // An override is only enforceable if lowering it costs at least as many
100
+ // signatures as the override itself demands. `update_procedure_threshold`
101
+ // is the procedure that edits overrides, so anything above its own
102
+ // effective threshold can be lowered by a smaller quorum and then used:
103
+ // a 2-of-5 with `send_asset: 4` is a 2-of-5 spend lock, not a 4-of-5 one.
104
+ // Mirrors `AuthMultisig::new` in miden-standards, which rejects the same
105
+ // shape, so Rust cannot build an account TypeScript would otherwise allow.
106
+ const setterOverride = config.procedureThresholds.find((pt) => pt.procedure === 'update_procedure_threshold')?.threshold;
107
+ const setterThreshold = setterOverride ?? config.threshold;
108
+ for (const pt of config.procedureThresholds) {
109
+ if (pt.threshold > setterThreshold) {
110
+ throw new Error(`procedure threshold override for ${pt.procedure} (${pt.threshold}) exceeds the ` +
111
+ `threshold of ${setterThreshold} that guards update_procedure_threshold; such an ` +
112
+ `override can be removed by a smaller quorum. Raise the update_procedure_threshold ` +
113
+ `override to at least ${pt.threshold} to make it enforceable`);
114
+ }
115
+ }
109
116
  }
110
117
  }
111
118
  //# sourceMappingURL=builder.js.map
@@ -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":"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"}
@@ -1,7 +1,6 @@
1
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';
2
+ import { createMultisigAccount, validateMultisigConfig } from './builder.js';
3
+ import { GUARDED_MULTISIG_ACCOUNT_COMPONENT_MASM } from './masm/account-components/auth.js';
5
4
  const { buildMultisigStorageSlots, buildGuardianStorageSlots, withSupportsAllTypes, compileComponent, MockAccountBuilder, } = vi.hoisted(() => {
6
5
  const buildMultisigStorageSlots = vi.fn(() => ['multisig-slots']);
7
6
  const buildGuardianStorageSlots = vi.fn(() => ['guardian-slots']);
@@ -32,6 +31,11 @@ const { buildMultisigStorageSlots, buildGuardianStorageSlots, withSupportsAllTyp
32
31
  account: { id: () => ({ toString: () => '0x' + 'a'.repeat(30) }) },
33
32
  };
34
33
  }
34
+ buildWithoutSchemaCommitment() {
35
+ return {
36
+ account: { id: () => ({ toString: () => '0x' + 'a'.repeat(30) }) },
37
+ };
38
+ }
35
39
  }
36
40
  return {
37
41
  buildMultisigStorageSlots,
@@ -67,7 +71,7 @@ describe('createMultisigAccount', () => {
67
71
  withSupportsAllTypes.mockClear();
68
72
  compileComponent.mockClear();
69
73
  });
70
- it('uses Falcon MASM by default', async () => {
74
+ function makeClient() {
71
75
  const authBuilder = {
72
76
  linkModule: vi.fn(),
73
77
  compileAccountComponentCode: vi.fn((source) => ({ source })),
@@ -78,37 +82,85 @@ describe('createMultisigAccount', () => {
78
82
  insert: vi.fn().mockResolvedValue(undefined),
79
83
  },
80
84
  };
85
+ return { authBuilder, webClient };
86
+ }
87
+ it('compiles the guarded component without re-linking SDK-provided modules (Falcon)', async () => {
88
+ const { authBuilder, webClient } = makeClient();
81
89
  await createMultisigAccount(webClient, {
82
90
  threshold: 1,
83
91
  signerCommitments: ['0x' + '1'.repeat(64)],
84
92
  guardianCommitment: '0x' + '2'.repeat(64),
85
93
  }, 'http://localhost:57291');
86
- expect(authBuilder.linkModule).toHaveBeenNthCalledWith(1, 'openzeppelin::auth::guardian', GUARDIAN_MASM);
87
- expect(authBuilder.linkModule).toHaveBeenNthCalledWith(2, 'openzeppelin::auth::multisig', MULTISIG_MASM);
88
- expect(authBuilder.compileAccountComponentCode).toHaveBeenCalledWith(MULTISIG_GUARDIAN_ACCOUNT_COMPONENT_MASM);
94
+ // The web SDK assembler already provides `miden::standards::auth::*`; re-linking would
95
+ // raise a duplicate-definition error, so the builder must NOT call linkModule.
96
+ expect(authBuilder.linkModule).not.toHaveBeenCalled();
97
+ expect(authBuilder.compileAccountComponentCode).toHaveBeenCalledWith(GUARDED_MULTISIG_ACCOUNT_COMPONENT_MASM);
89
98
  expect(webClient.accounts.insert).toHaveBeenCalledTimes(1);
90
99
  });
91
- it('uses ECDSA MASM when requested', async () => {
92
- const authBuilder = {
93
- linkModule: vi.fn(),
94
- compileAccountComponentCode: vi.fn((source) => ({ source })),
95
- };
96
- const webClient = {
97
- createCodeBuilder: vi.fn().mockReturnValue(authBuilder),
98
- accounts: {
99
- insert: vi.fn().mockResolvedValue(undefined),
100
- },
101
- };
100
+ it('uses the same scheme-agnostic component for ECDSA', async () => {
101
+ const { authBuilder, webClient } = makeClient();
102
102
  await createMultisigAccount(webClient, {
103
103
  threshold: 1,
104
104
  signerCommitments: ['0x' + '1'.repeat(64)],
105
105
  guardianCommitment: '0x' + '2'.repeat(64),
106
106
  signatureScheme: 'ecdsa',
107
107
  }, 'http://localhost:57291');
108
- expect(authBuilder.linkModule).toHaveBeenNthCalledWith(1, 'openzeppelin::auth::guardian_ecdsa', GUARDIAN_ECDSA_MASM);
109
- expect(authBuilder.linkModule).toHaveBeenNthCalledWith(2, 'openzeppelin::auth::multisig_ecdsa', MULTISIG_ECDSA_MASM);
110
- expect(authBuilder.compileAccountComponentCode).toHaveBeenCalledWith(MULTISIG_GUARDIAN_ECDSA_ACCOUNT_COMPONENT_MASM);
108
+ expect(authBuilder.linkModule).not.toHaveBeenCalled();
109
+ expect(authBuilder.compileAccountComponentCode).toHaveBeenCalledWith(GUARDED_MULTISIG_ACCOUNT_COMPONENT_MASM);
111
110
  expect(webClient.accounts.insert).toHaveBeenCalledTimes(1);
112
111
  });
113
112
  });
113
+ describe('validateMultisigConfig', () => {
114
+ const signer = '0x' + '1'.repeat(64);
115
+ it('rejects a guardian commitment equal to a signer (matches upstream Rust invariant)', () => {
116
+ expect(() => validateMultisigConfig({
117
+ threshold: 1,
118
+ signerCommitments: [signer],
119
+ guardianCommitment: signer,
120
+ })).toThrow(/different from all signer commitments/);
121
+ });
122
+ it('accepts a distinct guardian commitment', () => {
123
+ expect(() => validateMultisigConfig({
124
+ threshold: 1,
125
+ signerCommitments: [signer],
126
+ guardianCommitment: '0x' + '2'.repeat(64),
127
+ })).not.toThrow();
128
+ });
129
+ describe('procedure threshold overrides vs update_procedure_threshold', () => {
130
+ const signers = Array.from({ length: 5 }, (_, i) => '0x' + String(i + 1).repeat(64));
131
+ const guardian = '0x' + '9'.repeat(64);
132
+ const config = (threshold, procedureThresholds) => ({
133
+ threshold,
134
+ signerCommitments: signers,
135
+ guardianCommitment: guardian,
136
+ procedureThresholds,
137
+ });
138
+ it('rejects an override above the default threshold that guards the setter', () => {
139
+ expect(() => validateMultisigConfig(config(2, [{ procedure: 'send_asset', threshold: 4 }]))).toThrow(/exceeds the threshold of 2 that guards update_procedure_threshold/);
140
+ });
141
+ it('accepts the same override once the setter is raised to match', () => {
142
+ expect(() => validateMultisigConfig(config(2, [
143
+ { procedure: 'send_asset', threshold: 4 },
144
+ { procedure: 'update_procedure_threshold', threshold: 4 },
145
+ ]))).not.toThrow();
146
+ });
147
+ it('rejects an override above an explicitly raised setter', () => {
148
+ expect(() => validateMultisigConfig(config(2, [
149
+ { procedure: 'send_asset', threshold: 4 },
150
+ { procedure: 'update_procedure_threshold', threshold: 3 },
151
+ ]))).toThrow(/exceeds the threshold of 3 that guards update_procedure_threshold/);
152
+ });
153
+ it('accepts overrides at or below the default threshold', () => {
154
+ expect(() => validateMultisigConfig(config(3, [
155
+ { procedure: 'send_asset', threshold: 3 },
156
+ { procedure: 'receive_asset', threshold: 1 },
157
+ ]))).not.toThrow();
158
+ });
159
+ it('allows the setter override to exceed the default threshold', () => {
160
+ // Raising only the setter is always safe: it makes overrides harder to
161
+ // edit, never easier.
162
+ expect(() => validateMultisigConfig(config(2, [{ procedure: 'update_procedure_threshold', threshold: 5 }]))).not.toThrow();
163
+ });
164
+ });
165
+ });
114
166
  //# sourceMappingURL=builder.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"builder.test.js","sourceRoot":"","sources":["../../src/account/builder.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"builder.test.js","sourceRoot":"","sources":["../../src/account/builder.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `AuthGuardedMultisig` storage slot names (`miden::standards::auth::*`),
3
+ * shared by the writer (`account/storage.ts`) and the readers
4
+ * (`inspector.ts`). Single source of truth so the two cannot drift. These
5
+ * must match the Rust `miden-standards` component exactly: account ID and
6
+ * commitment derive from the storage layout, so any divergence breaks
7
+ * cross-SDK determinism (guarded by the parity test).
8
+ *
9
+ * Deliberately not re-exported from the package index: consumers should use
10
+ * the `AccountInspector` accessors rather than reading storage directly
11
+ * (issue #306).
12
+ */
13
+ export declare const MULTISIG_SLOT_NAMES: {
14
+ readonly THRESHOLD_CONFIG: "miden::standards::auth::multisig::threshold_config";
15
+ readonly SIGNER_PUBLIC_KEYS: "miden::standards::auth::multisig::approver_public_keys";
16
+ readonly SIGNER_SCHEME_IDS: "miden::standards::auth::multisig::approver_schemes";
17
+ readonly EXECUTED_TRANSACTIONS: "miden::standards::auth::multisig::executed_transactions";
18
+ readonly PROCEDURE_THRESHOLDS: "miden::standards::auth::multisig::procedure_thresholds";
19
+ };
20
+ export declare const GUARDIAN_SLOT_NAMES: {
21
+ readonly PUBLIC_KEY: "miden::standards::auth::guardian::pub_key";
22
+ readonly SCHEME_ID: "miden::standards::auth::guardian::scheme";
23
+ };
24
+ /**
25
+ * Sanity ceiling for the signer count read from `threshold_config`. The
26
+ * contract has no on-chain maximum (the felt is only asserted to be a u32),
27
+ * so a corrupt or adversarial account could report an arbitrarily large
28
+ * count; readers bound their loops with this instead of trusting it.
29
+ */
30
+ export declare const MAX_SIGNERS = 1000;
31
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/account/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,mBAAmB;;;;;;CAMtB,CAAC;AAEX,eAAO,MAAM,mBAAmB;;;CAGtB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,WAAW,OAAO,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `AuthGuardedMultisig` storage slot names (`miden::standards::auth::*`),
3
+ * shared by the writer (`account/storage.ts`) and the readers
4
+ * (`inspector.ts`). Single source of truth so the two cannot drift. These
5
+ * must match the Rust `miden-standards` component exactly: account ID and
6
+ * commitment derive from the storage layout, so any divergence breaks
7
+ * cross-SDK determinism (guarded by the parity test).
8
+ *
9
+ * Deliberately not re-exported from the package index: consumers should use
10
+ * the `AccountInspector` accessors rather than reading storage directly
11
+ * (issue #306).
12
+ */
13
+ export const MULTISIG_SLOT_NAMES = {
14
+ THRESHOLD_CONFIG: 'miden::standards::auth::multisig::threshold_config',
15
+ SIGNER_PUBLIC_KEYS: 'miden::standards::auth::multisig::approver_public_keys',
16
+ SIGNER_SCHEME_IDS: 'miden::standards::auth::multisig::approver_schemes',
17
+ EXECUTED_TRANSACTIONS: 'miden::standards::auth::multisig::executed_transactions',
18
+ PROCEDURE_THRESHOLDS: 'miden::standards::auth::multisig::procedure_thresholds',
19
+ };
20
+ export const GUARDIAN_SLOT_NAMES = {
21
+ PUBLIC_KEY: 'miden::standards::auth::guardian::pub_key',
22
+ SCHEME_ID: 'miden::standards::auth::guardian::scheme',
23
+ };
24
+ /**
25
+ * Sanity ceiling for the signer count read from `threshold_config`. The
26
+ * contract has no on-chain maximum (the felt is only asserted to be a u32),
27
+ * so a corrupt or adversarial account could report an arbitrarily large
28
+ * count; readers bound their loops with this instead of trusting it.
29
+ */
30
+ export const MAX_SIGNERS = 1000;
31
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/account/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,gBAAgB,EAAE,oDAAoD;IACtE,kBAAkB,EAAE,wDAAwD;IAC5E,iBAAiB,EAAE,oDAAoD;IACvE,qBAAqB,EAAE,yDAAyD;IAChF,oBAAoB,EAAE,wDAAwD;CACtE,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,UAAU,EAAE,2CAA2C;IACvD,SAAS,EAAE,0CAA0C;CAC7C,CAAC;AAEX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC"}