@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
@@ -3,26 +3,23 @@
3
3
  # This library provides the reusable multisig procedures used by account wrappers.
4
4
 
5
5
  use miden::protocol::active_account
6
+ use miden::protocol::auth::AUTH_UNAUTHORIZED_EVENT
6
7
  use miden::protocol::native_account
7
8
  use miden::standards::auth
8
- type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
9
9
 
10
10
  # CONSTANTS
11
11
  # =================================================================================================
12
12
 
13
13
  # Auth Request Constants
14
14
 
15
- # The event emitted when a signature is not found for a required signer.
16
- const AUTH_UNAUTHORIZED_EVENT=event("miden::auth::unauthorized")
17
-
18
15
  # Storage Layout Constants
19
16
  #
20
- # +-------------------------------+----------+--------------+-------------------+
21
- # | THRESHOLD & APPROVERS CONFIG | PUB KEYS | EXECUTED TXS | PROC THRESHOLDS |
22
- # | (slot) | (map) | (map) | (map) |
23
- # +-------------------------------+----------+--------------+-------------------+
24
- # | 0 | 1 | 2 | 3 |
25
- # +-------------------------------+----------+--------------+-------------------+
17
+ # +-------------------------------+----------+------------+--------------+-------------------+
18
+ # | THRESHOLD & APPROVERS CONFIG | PUB KEYS | SCHEME IDS | EXECUTED TXS | PROC THRESHOLDS |
19
+ # | (slot) | (map) | (map) | (map) | (map) |
20
+ # +-------------------------------+----------+------------+--------------+-------------------+
21
+ # | 0 | 1 | 2 | 3 | 4 |
22
+ # +-------------------------------+----------+------------+--------------+-------------------+
26
23
 
27
24
  # The slot in this component's storage layout where the default signature threshold and
28
25
  # number of approvers are stored as:
@@ -34,6 +31,10 @@ const THRESHOLD_CONFIG_SLOT=word("openzeppelin::multisig::threshold_config")
34
31
  # Map entries: [key_index, 0, 0, 0] => APPROVER_PUBLIC_KEY
35
32
  const PUBLIC_KEYS_MAP_SLOT=word("openzeppelin::multisig::signer_public_keys")
36
33
 
34
+ # The slot in this component's storage layout where signer scheme IDs are stored.
35
+ # Map entries: [key_index, 0, 0, 0] => [scheme_id, 0, 0, 0]
36
+ const APPROVER_SCHEME_ID_SLOT=word("openzeppelin::multisig::signer_scheme_ids")
37
+
37
38
  # The slot in this component's storage layout where executed transactions are stored.
38
39
  # Map entries: transaction_message => [is_executed, 0, 0, 0]
39
40
  const EXECUTED_TXS_SLOT=word("openzeppelin::multisig::executed_transactions")
@@ -44,6 +45,7 @@ const PROC_THRESHOLD_ROOTS_SLOT=word("openzeppelin::multisig::procedure_threshol
44
45
 
45
46
  # Executed Transaction Flag Constant
46
47
  const IS_EXECUTED_FLAG=[1, 0, 0, 0]
48
+ const ECDSA_K256_KECCAK_SCHEME_WORD=[1, 0, 0, 0]
47
49
 
48
50
  # ERRORS
49
51
  const ERR_TX_ALREADY_EXECUTED="failed to approve multisig transaction as it was already executed"
@@ -68,7 +70,7 @@ const ERR_PROC_THRESHOLD_EXCEEDS_NUM_APPROVERS="procedure threshold exceeds numb
68
70
  #!
69
71
  #! Panics if:
70
72
  #! - the same transaction has already been executed
71
- pub proc assert_new_tx(msg: BeWord)
73
+ pub proc assert_new_tx(msg: word)
72
74
  push.IS_EXECUTED_FLAG
73
75
  # => [[0, 0, 0, is_executed], MSG]
74
76
 
@@ -112,17 +114,29 @@ proc cleanup_pubkey_mapping(init_num_of_approvers: u32, new_num_of_approvers: u3
112
114
  sub.1
113
115
  # => [i-1, new_num_of_approvers]
114
116
 
115
- dup
116
- # => [i-1, i-1, new_num_of_approvers]
117
-
118
- push.0.0.0
119
- # => [[0, 0, 0, i-1], i-1, new_num_of_approvers]
117
+ dup exec.create_approver_map_key
118
+ # => [APPROVER_MAP_KEY, i-1, new_num_of_approvers]
120
119
 
121
120
  padw swapw
122
- # => [[0, 0, 0, i-1], EMPTY_WORD, i-1, new_num_of_approvers]
121
+ # => [APPROVER_MAP_KEY, EMPTY_WORD, i-1, new_num_of_approvers]
123
122
 
124
123
  push.PUBLIC_KEYS_MAP_SLOT[0..2]
125
- # => [pub_key_slot_prefix, pub_key_slot_suffix, [0, 0, 0, i-1], EMPTY_WORD, i-1, new_num_of_approvers]
124
+ # => [pub_key_slot_prefix, pub_key_slot_suffix, APPROVER_MAP_KEY, EMPTY_WORD, i-1, new_num_of_approvers]
125
+
126
+ exec.native_account::set_map_item
127
+ # => [OLD_MAP_VALUE, i-1, new_num_of_approvers]
128
+
129
+ dropw
130
+ # => [i-1, new_num_of_approvers]
131
+
132
+ dup exec.create_approver_map_key
133
+ # => [APPROVER_MAP_KEY, i-1, new_num_of_approvers]
134
+
135
+ padw swapw
136
+ # => [APPROVER_MAP_KEY, EMPTY_WORD, i-1, new_num_of_approvers]
137
+
138
+ push.APPROVER_SCHEME_ID_SLOT[0..2]
139
+ # => [scheme_slot_prefix, scheme_slot_suffix, APPROVER_MAP_KEY, EMPTY_WORD, i-1, new_num_of_approvers]
126
140
 
127
141
  exec.native_account::set_map_item
128
142
  # => [OLD_MAP_VALUE, i-1, new_num_of_approvers]
@@ -139,15 +153,17 @@ proc cleanup_pubkey_mapping(init_num_of_approvers: u32, new_num_of_approvers: u3
139
153
  # => []
140
154
  end
141
155
 
156
+ proc create_approver_map_key
157
+ push.0.0.0 movup.3
158
+ # => [APPROVER_MAP_KEY]
159
+ end
160
+
142
161
  proc get_threshold_and_num_approvers
143
162
  push.THRESHOLD_CONFIG_SLOT[0..2]
144
163
  exec.active_account::get_initial_item
145
- # => [0, 0, num_approvers, threshold]
146
-
147
- drop drop
148
- # => [num_approvers, threshold]
164
+ # => [threshold, num_approvers]
149
165
 
150
- swap
166
+ movup.2 drop movup.2 drop
151
167
  # => [threshold, num_approvers]
152
168
  end
153
169
 
@@ -167,10 +183,10 @@ proc assert_proc_thresholds_lte_num_approvers(num_approvers: u32)
167
183
  push.PROC_THRESHOLD_ROOTS_SLOT[0..2]
168
184
  # => [proc_roots_slot_prefix, proc_roots_slot_suffix, PROC_ROOT, proc_index, num_approvers]
169
185
 
170
- exec.active_account::get_initial_map_item
171
- # => [[0, 0, 0, proc_threshold], proc_index, num_approvers]
186
+ exec.active_account::get_map_item
187
+ # => [[proc_threshold, 0, 0, 0], proc_index, num_approvers]
172
188
 
173
- drop drop drop
189
+ movdn.3 drop drop drop
174
190
  # => [proc_threshold, proc_index, num_approvers]
175
191
 
176
192
  dup.2
@@ -190,7 +206,7 @@ end
190
206
 
191
207
  # Internal storage helper used by the public `update_procedure_threshold`
192
208
  # entrypoint after it receives direct stack arguments.
193
- proc set_procedure_threshold(proc_threshold: u32, proc_root: BeWord)
209
+ proc set_procedure_threshold(proc_threshold: u32, proc_root: word)
194
210
  exec.get_threshold_and_num_approvers
195
211
  # => [threshold, num_approvers, proc_threshold, PROC_ROOT]
196
212
 
@@ -205,6 +221,7 @@ proc set_procedure_threshold(proc_threshold: u32, proc_root: BeWord)
205
221
  # => [proc_threshold, PROC_ROOT]
206
222
 
207
223
  push.0.0.0
224
+ movup.3
208
225
  swapw
209
226
  # => [PROC_ROOT, PROC_THRESHOLD_WORD]
210
227
 
@@ -237,7 +254,7 @@ end
237
254
  #! 0: new_num_of_approvers
238
255
  #! 1: init_num_of_approvers
239
256
  @locals(2)
240
- pub proc update_signers_and_threshold(multisig_config_hash: BeWord)
257
+ pub proc update_signers_and_threshold(multisig_config_hash: word)
241
258
  adv.push_mapval
242
259
  # => [MULTISIG_CONFIG_HASH, pad(12)]
243
260
 
@@ -245,10 +262,10 @@ pub proc update_signers_and_threshold(multisig_config_hash: BeWord)
245
262
  # => [MULTISIG_CONFIG, pad(12)]
246
263
 
247
264
  # store new_num_of_approvers for later
248
- dup.2 loc_store.0
265
+ dup.1 loc_store.0
249
266
  # => [MULTISIG_CONFIG, pad(12)]
250
267
 
251
- dup.3 dup.3
268
+ dup dup.2
252
269
  # => [num_approvers, threshold, MULTISIG_CONFIG, pad(12)]
253
270
 
254
271
  # make sure that the threshold is smaller than the number of approvers
@@ -256,7 +273,7 @@ pub proc update_signers_and_threshold(multisig_config_hash: BeWord)
256
273
  u32gt assertz.err=ERR_MALFORMED_MULTISIG_CONFIG
257
274
  # => [MULTISIG_CONFIG, pad(12)]
258
275
 
259
- dup.3 dup.3
276
+ dup dup.2
260
277
  # => [num_approvers, threshold, MULTISIG_CONFIG, pad(12)]
261
278
 
262
279
  # make sure that threshold or num_approvers are not zero
@@ -277,7 +294,7 @@ pub proc update_signers_and_threshold(multisig_config_hash: BeWord)
277
294
  # => [OLD_THRESHOLD_CONFIG, pad(12)]
278
295
 
279
296
  # store init_num_of_approvers for later
280
- drop drop loc_store.1 drop
297
+ drop loc_store.1 drop drop
281
298
  # => [pad(12)]
282
299
 
283
300
  loc_load.0
@@ -288,17 +305,35 @@ pub proc update_signers_and_threshold(multisig_config_hash: BeWord)
288
305
  sub.1
289
306
  # => [i-1, pad(12)]
290
307
 
291
- dup push.0.0.0
292
- # => [[0, 0, 0, i-1], i-1, pad(12)]
308
+ dup exec.create_approver_map_key
309
+ # => [APPROVER_MAP_KEY, i-1, pad(12)]
293
310
 
294
311
  padw adv_loadw
295
- # => [PUB_KEY, [0, 0, 0, i-1], i-1, pad(12)]
312
+ # => [PUB_KEY, APPROVER_MAP_KEY, i-1, pad(12)]
296
313
 
297
314
  swapw
298
- # => [[0, 0, 0, i-1], PUB_KEY, i-1, pad(12)]
315
+ # => [APPROVER_MAP_KEY, PUB_KEY, i-1, pad(12)]
299
316
 
300
317
  push.PUBLIC_KEYS_MAP_SLOT[0..2]
301
- # => [pub_key_slot_prefix, pub_key_slot_suffix, [0, 0, 0, i-1], PUB_KEY, i-1, pad(12)]
318
+ # => [pub_key_slot_prefix, pub_key_slot_suffix, APPROVER_MAP_KEY, PUB_KEY, i-1, pad(12)]
319
+
320
+ exec.native_account::set_map_item
321
+ # => [OLD_VALUE, i-1, pad(12)]
322
+
323
+ dropw
324
+ # => [i-1, pad(12)]
325
+
326
+ dup exec.create_approver_map_key
327
+ # => [APPROVER_MAP_KEY, i-1, pad(12)]
328
+
329
+ push.ECDSA_K256_KECCAK_SCHEME_WORD
330
+ # => [SCHEME_ID_WORD, APPROVER_MAP_KEY, i-1, pad(12)]
331
+
332
+ swapw
333
+ # => [APPROVER_MAP_KEY, [1, 0, 0, 0], i-1, pad(12)]
334
+
335
+ push.APPROVER_SCHEME_ID_SLOT[0..2]
336
+ # => [scheme_slot_prefix, scheme_slot_suffix, APPROVER_MAP_KEY, [1, 0, 0, 0], i-1, pad(12)]
302
337
 
303
338
  exec.native_account::set_map_item
304
339
  # => [OLD_VALUE, i-1, pad(12)]
@@ -331,7 +366,7 @@ end
331
366
  #! Outputs:
332
367
  #! Operand stack: []
333
368
  #! Invocation: call
334
- pub proc update_procedure_threshold(proc_threshold: u32, proc_root: BeWord)
369
+ pub proc update_procedure_threshold(proc_threshold: u32, proc_root: word)
335
370
  exec.set_procedure_threshold
336
371
  end
337
372
 
@@ -387,9 +422,9 @@ proc compute_transaction_threshold(default_threshold: u32) -> u32
387
422
  # 2b. get the override proc_threshold of that procedure
388
423
  # if the procedure has no override threshold, the returned map item will be [0, 0, 0, 0]
389
424
  exec.active_account::get_initial_map_item
390
- # => [[0, 0, 0, proc_threshold], num_procedures-1, transaction_threshold]
425
+ # => [[proc_threshold, 0, 0, 0], num_procedures-1, transaction_threshold]
391
426
 
392
- drop drop drop dup dup.3
427
+ movdn.3 drop drop drop dup dup.3
393
428
  # => [transaction_threshold, proc_threshold, proc_threshold, num_procedures-1, transaction_threshold]
394
429
 
395
430
  u32assert2.err="transaction threshold or procedure threshold are not u32"
@@ -458,18 +493,18 @@ end
458
493
  #!
459
494
  #! Invocation: exec
460
495
  @locals(1)
461
- pub proc auth_tx(salt: BeWord) -> BeWord
496
+ pub proc auth_tx(salt: word)
462
497
  exec.native_account::incr_nonce drop
463
498
  # => [SALT]
464
499
 
465
500
  # ------ Computing transaction summary ------
466
501
 
467
502
  exec.auth::create_tx_summary
468
- # => [SALT, OUTPUT_NOTES_COMMITMENT, INPUT_NOTES_COMMITMENT, ACCOUNT_DELTA_COMMITMENT]
503
+ # => [ACCOUNT_DELTA_COMMITMENT, INPUT_NOTES_COMMITMENT, OUTPUT_NOTES_COMMITMENT, SALT]
469
504
 
470
505
  # to build a tx_summary in the host, we need these four words in the advice provider
471
- exec.auth::adv_insert_hqword
472
- # => [SALT, OUTPUT_NOTES_COMMITMENT, INPUT_NOTES_COMMITMENT, ACCOUNT_DELTA_COMMITMENT]
506
+ adv.insert_hqword
507
+ # => [ACCOUNT_DELTA_COMMITMENT, INPUT_NOTES_COMMITMENT, OUTPUT_NOTES_COMMITMENT, SALT]
473
508
 
474
509
  # the commitment to the tx summary is the message that is signed
475
510
  exec.auth::hash_tx_summary
@@ -477,22 +512,19 @@ pub proc auth_tx(salt: BeWord) -> BeWord
477
512
 
478
513
  # ------ Verifying approver signatures ------
479
514
 
480
- push.THRESHOLD_CONFIG_SLOT[0..2]
481
- # => [config_slot_prefix, config_slot_suffix, TX_SUMMARY_COMMITMENT]
482
-
483
- exec.active_account::get_initial_item
484
- # => [0, 0, num_of_approvers, default_threshold, TX_SUMMARY_COMMITMENT]
485
-
486
- drop drop
487
- # => [num_of_approvers, default_threshold, TX_SUMMARY_COMMITMENT]
515
+ exec.get_threshold_and_num_approvers
516
+ # => [default_threshold, num_of_approvers, TX_SUMMARY_COMMITMENT]
488
517
 
489
- swap movdn.5
518
+ movdn.5
490
519
  # => [num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
491
520
 
492
521
  push.PUBLIC_KEYS_MAP_SLOT[0..2]
493
522
  # => [pub_key_slot_prefix, pub_key_slot_suffix, num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
494
523
 
495
- exec.::miden::standards::auth::ecdsa_k256_keccak::verify_signatures
524
+ push.APPROVER_SCHEME_ID_SLOT[0..2]
525
+ # => [scheme_id_slot_prefix, scheme_id_slot_suffix, pub_key_slot_prefix, pub_key_slot_suffix, num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
526
+
527
+ exec.::miden::standards::auth::signature::verify_signatures
496
528
  # => [num_verified_signatures, TX_SUMMARY_COMMITMENT, default_threshold]
497
529
 
498
530
  # ------ Checking threshold is >= num_verified_signatures ------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openzeppelin/miden-multisig-client",
3
- "version": "0.13.3",
3
+ "version": "0.14.3",
4
4
  "description": "TypeScript SDK for Miden multisig accounts with GUARDIAN integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,9 +28,9 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@noble/curves": "^1.9.7",
31
- "@miden-sdk/miden-sdk": "0.13.0",
31
+ "@miden-sdk/miden-sdk": "0.14.3",
32
32
  "@noble/hashes": "^2.0.1",
33
- "@openzeppelin/guardian-client": "^0.13.3"
33
+ "@openzeppelin/guardian-client": "^0.14.3"
34
34
  },
35
35
  "devDependencies": {
36
36
  "typescript": "^5.7.2",
@@ -98,13 +98,14 @@ describe('createMultisigAccount', () => {
98
98
 
99
99
  it('uses Falcon MASM by default', async () => {
100
100
  const authBuilder = {
101
- buildLibrary: vi.fn((libraryPath, source) => ({ libraryPath, source })),
102
- linkStaticLibrary: vi.fn(),
103
- compileAccountComponentCode: vi.fn((source) => `auth:${source.slice(0, 16)}`),
101
+ linkModule: vi.fn(),
102
+ compileAccountComponentCode: vi.fn((source) => ({ source })),
104
103
  };
105
104
  const webClient = {
106
105
  createCodeBuilder: vi.fn().mockReturnValue(authBuilder),
107
- newAccount: vi.fn(),
106
+ accounts: {
107
+ insert: vi.fn().mockResolvedValue(undefined),
108
+ },
108
109
  };
109
110
 
110
111
  await createMultisigAccount(webClient as never, {
@@ -113,12 +114,12 @@ describe('createMultisigAccount', () => {
113
114
  guardianCommitment: '0x' + '2'.repeat(64),
114
115
  });
115
116
 
116
- expect(authBuilder.buildLibrary).toHaveBeenNthCalledWith(
117
+ expect(authBuilder.linkModule).toHaveBeenNthCalledWith(
117
118
  1,
118
119
  'openzeppelin::auth::guardian',
119
120
  GUARDIAN_MASM,
120
121
  );
121
- expect(authBuilder.buildLibrary).toHaveBeenNthCalledWith(
122
+ expect(authBuilder.linkModule).toHaveBeenNthCalledWith(
122
123
  2,
123
124
  'openzeppelin::auth::multisig',
124
125
  MULTISIG_MASM,
@@ -126,18 +127,19 @@ describe('createMultisigAccount', () => {
126
127
  expect(authBuilder.compileAccountComponentCode).toHaveBeenCalledWith(
127
128
  MULTISIG_GUARDIAN_ACCOUNT_COMPONENT_MASM,
128
129
  );
129
- expect(webClient.newAccount).toHaveBeenCalledTimes(1);
130
+ expect(webClient.accounts.insert).toHaveBeenCalledTimes(1);
130
131
  });
131
132
 
132
133
  it('uses ECDSA MASM when requested', async () => {
133
134
  const authBuilder = {
134
- buildLibrary: vi.fn((libraryPath, source) => ({ libraryPath, source })),
135
- linkStaticLibrary: vi.fn(),
136
- compileAccountComponentCode: vi.fn((source) => `auth:${source.slice(0, 16)}`),
135
+ linkModule: vi.fn(),
136
+ compileAccountComponentCode: vi.fn((source) => ({ source })),
137
137
  };
138
138
  const webClient = {
139
139
  createCodeBuilder: vi.fn().mockReturnValue(authBuilder),
140
- newAccount: vi.fn(),
140
+ accounts: {
141
+ insert: vi.fn().mockResolvedValue(undefined),
142
+ },
141
143
  };
142
144
 
143
145
  await createMultisigAccount(webClient as never, {
@@ -147,12 +149,12 @@ describe('createMultisigAccount', () => {
147
149
  signatureScheme: 'ecdsa',
148
150
  });
149
151
 
150
- expect(authBuilder.buildLibrary).toHaveBeenNthCalledWith(
152
+ expect(authBuilder.linkModule).toHaveBeenNthCalledWith(
151
153
  1,
152
154
  'openzeppelin::auth::guardian_ecdsa',
153
155
  GUARDIAN_ECDSA_MASM,
154
156
  );
155
- expect(authBuilder.buildLibrary).toHaveBeenNthCalledWith(
157
+ expect(authBuilder.linkModule).toHaveBeenNthCalledWith(
156
158
  2,
157
159
  'openzeppelin::auth::multisig_ecdsa',
158
160
  MULTISIG_ECDSA_MASM,
@@ -160,6 +162,6 @@ describe('createMultisigAccount', () => {
160
162
  expect(authBuilder.compileAccountComponentCode).toHaveBeenCalledWith(
161
163
  MULTISIG_GUARDIAN_ECDSA_ACCOUNT_COMPONENT_MASM,
162
164
  );
163
- expect(webClient.newAccount).toHaveBeenCalledTimes(1);
165
+ expect(webClient.accounts.insert).toHaveBeenCalledTimes(1);
164
166
  });
165
167
  });
@@ -9,9 +9,10 @@ import {
9
9
  AccountComponent,
10
10
  AccountType,
11
11
  AccountStorageMode,
12
- type WebClient,
12
+ type MidenClient,
13
13
  } from '@miden-sdk/miden-sdk';
14
14
  import type { MultisigConfig, CreateAccountResult } from '../types.js';
15
+ import { getRawMidenClient } from '../raw-client.js';
15
16
  import { buildMultisigStorageSlots, buildGuardianStorageSlots } from './storage.js';
16
17
  import {
17
18
  MULTISIG_ECDSA_MASM,
@@ -28,16 +29,18 @@ import { normalizeSignerCommitment } from '../utils/signature.js';
28
29
  /**
29
30
  * Creates a multisig account with GUARDIAN authentication.
30
31
  *
31
- * @param webClient - Initialized Miden WebClient
32
+ * @param midenClient - Initialized MidenClient
32
33
  * @param config - Multisig configuration
33
34
  * @returns The created account and seed
34
35
  */
35
36
  export async function createMultisigAccount(
36
- webClient: WebClient,
37
- config: MultisigConfig
37
+ midenClient: MidenClient,
38
+ config: MultisigConfig,
39
+ midenRpcEndpoint?: string,
38
40
  ): Promise<CreateAccountResult> {
39
41
  validateMultisigConfig(config);
40
42
  const signatureScheme = config.signatureScheme ?? 'falcon';
43
+ const rawClient = await getRawMidenClient(midenClient, midenRpcEndpoint);
41
44
  const authSlots = [
42
45
  ...buildMultisigStorageSlots(config),
43
46
  ...buildGuardianStorageSlots(config),
@@ -54,14 +57,12 @@ export async function createMultisigAccount(
54
57
  ? 'openzeppelin::auth::multisig_ecdsa'
55
58
  : 'openzeppelin::auth::multisig';
56
59
 
57
- const authBuilder = webClient.createCodeBuilder();
58
- const guardianLib = authBuilder.buildLibrary(guardianLibraryPath, guardianMasm);
59
- authBuilder.linkStaticLibrary(guardianLib);
60
- const multisigLib = authBuilder.buildLibrary(multisigLibraryPath, multisigMasm);
61
- authBuilder.linkStaticLibrary(multisigLib);
62
- const authCode = authBuilder.compileAccountComponentCode(authComponentMasm);
60
+ const authBuilder = rawClient.createCodeBuilder();
61
+ authBuilder.linkModule(guardianLibraryPath, guardianMasm);
62
+ authBuilder.linkModule(multisigLibraryPath, multisigMasm);
63
+ const authComponentCode = authBuilder.compileAccountComponentCode(authComponentMasm);
63
64
  const authComponent = AccountComponent
64
- .compile(authCode, authSlots)
65
+ .compile(authComponentCode, authSlots)
65
66
  .withSupportsAllTypes();
66
67
 
67
68
  let seed = config.seed;
@@ -82,7 +83,7 @@ export async function createMultisigAccount(
82
83
 
83
84
  const result = accountBuilder.build();
84
85
 
85
- await webClient.newAccount(result.account, false);
86
+ await midenClient.accounts.insert({ account: result.account, overwrite: false });
86
87
 
87
88
  return {
88
89
  account: result.account,
@@ -5,12 +5,11 @@ export const MULTISIG_ACCOUNT_COMPONENT_MASM = `# Multi-Signature RPO Falcon 512
5
5
 
6
6
  use openzeppelin::auth::multisig
7
7
 
8
- type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
9
-
10
8
  pub use multisig::update_signers_and_threshold
11
9
  pub use multisig::update_procedure_threshold
12
10
 
13
- pub proc auth_tx_multisig(salt: BeWord)
11
+ @auth_script
12
+ pub proc auth_tx_multisig(salt: word)
14
13
  exec.multisig::auth_tx
15
14
  exec.multisig::assert_new_tx
16
15
  end
@@ -21,14 +20,13 @@ export const MULTISIG_GUARDIAN_ACCOUNT_COMPONENT_MASM = `# Multi-Signature RPO F
21
20
  use openzeppelin::auth::multisig
22
21
  use openzeppelin::auth::guardian
23
22
 
24
- type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
25
-
26
23
  pub use multisig::update_signers_and_threshold
27
24
  pub use multisig::update_procedure_threshold
28
25
  pub use guardian::update_guardian_public_key
29
26
  pub use guardian::verify_guardian_signature
30
27
 
31
- pub proc auth_tx_multisig_guardian(salt: BeWord)
28
+ @auth_script
29
+ pub proc auth_tx_multisig_guardian(salt: word)
32
30
  exec.multisig::auth_tx
33
31
  exec.guardian::verify_guardian_signature
34
32
  exec.multisig::assert_new_tx
@@ -39,12 +37,11 @@ export const MULTISIG_ECDSA_ACCOUNT_COMPONENT_MASM = `# Multi-Signature ECDSA se
39
37
 
40
38
  use openzeppelin::auth::multisig_ecdsa
41
39
 
42
- type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
43
-
44
40
  pub use multisig_ecdsa::update_signers_and_threshold
45
41
  pub use multisig_ecdsa::update_procedure_threshold
46
42
 
47
- pub proc auth_tx_multisig_ecdsa(salt: BeWord)
43
+ @auth_script
44
+ pub proc auth_tx_multisig_ecdsa(salt: word)
48
45
  exec.multisig_ecdsa::auth_tx
49
46
  exec.multisig_ecdsa::assert_new_tx
50
47
  end
@@ -55,14 +52,13 @@ export const MULTISIG_GUARDIAN_ECDSA_ACCOUNT_COMPONENT_MASM = `# Multi-Signature
55
52
  use openzeppelin::auth::multisig_ecdsa
56
53
  use openzeppelin::auth::guardian_ecdsa
57
54
 
58
- type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
59
-
60
55
  pub use multisig_ecdsa::update_signers_and_threshold
61
56
  pub use multisig_ecdsa::update_procedure_threshold
62
57
  pub use guardian_ecdsa::update_guardian_public_key
63
58
  pub use guardian_ecdsa::verify_guardian_signature
64
59
 
65
- pub proc auth_tx_multisig_guardian_ecdsa(salt: BeWord)
60
+ @auth_script
61
+ pub proc auth_tx_multisig_guardian_ecdsa(salt: word)
66
62
  exec.multisig_ecdsa::auth_tx
67
63
  exec.guardian_ecdsa::verify_guardian_signature
68
64
  exec.multisig_ecdsa::assert_new_tx