@openzeppelin/miden-multisig-client 0.13.4 → 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.
- package/README.md +10 -13
- package/dist/account/builder.d.ts +3 -3
- package/dist/account/builder.d.ts.map +1 -1
- package/dist/account/builder.js +10 -10
- package/dist/account/builder.js.map +1 -1
- package/dist/account/builder.test.js +16 -14
- package/dist/account/builder.test.js.map +1 -1
- package/dist/account/masm/account-components/auth.d.ts +4 -4
- package/dist/account/masm/account-components/auth.d.ts.map +1 -1
- package/dist/account/masm/account-components/auth.js +8 -12
- package/dist/account/masm/account-components/auth.js.map +1 -1
- package/dist/account/masm/auth.d.ts +4 -4
- package/dist/account/masm/auth.d.ts.map +1 -1
- package/dist/account/masm/auth.js +226 -124
- package/dist/account/masm/auth.js.map +1 -1
- package/dist/account/storage.d.ts.map +1 -1
- package/dist/account/storage.js +24 -6
- package/dist/account/storage.js.map +1 -1
- package/dist/account/storage.test.d.ts +2 -0
- package/dist/account/storage.test.d.ts.map +1 -0
- package/dist/account/storage.test.js +73 -0
- package/dist/account/storage.test.js.map +1 -0
- package/dist/client.d.ts +9 -9
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +24 -14
- package/dist/client.js.map +1 -1
- package/dist/client.test.js +45 -8
- package/dist/client.test.js.map +1 -1
- package/dist/index.d.ts +6 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -12
- package/dist/index.js.map +1 -1
- package/dist/multisig/proposal/execution.d.ts +3 -2
- package/dist/multisig/proposal/execution.d.ts.map +1 -1
- package/dist/multisig/proposal/execution.js +8 -12
- package/dist/multisig/proposal/execution.js.map +1 -1
- package/dist/multisig.d.ts +7 -4
- package/dist/multisig.d.ts.map +1 -1
- package/dist/multisig.js +53 -35
- package/dist/multisig.js.map +1 -1
- package/dist/multisig.test.js +17 -29
- package/dist/multisig.test.js.map +1 -1
- package/dist/procedures.d.ts +8 -8
- package/dist/procedures.js +8 -8
- package/dist/raw-client.d.ts +13 -0
- package/dist/raw-client.d.ts.map +1 -0
- package/dist/raw-client.js +42 -0
- package/dist/raw-client.js.map +1 -0
- package/dist/raw-client.test.d.ts +2 -0
- package/dist/raw-client.test.d.ts.map +1 -0
- package/dist/raw-client.test.js +89 -0
- package/dist/raw-client.test.js.map +1 -0
- package/dist/signers/ecdsa.d.ts +3 -1
- package/dist/signers/ecdsa.d.ts.map +1 -1
- package/dist/signers/ecdsa.js +15 -1
- package/dist/signers/ecdsa.js.map +1 -1
- package/dist/signers/ecdsa.test.js +27 -4
- package/dist/signers/ecdsa.test.js.map +1 -1
- package/dist/signers/falcon.d.ts +3 -1
- package/dist/signers/falcon.d.ts.map +1 -1
- package/dist/signers/falcon.js +15 -1
- package/dist/signers/falcon.js.map +1 -1
- package/dist/signers/falcon.test.js +39 -3
- package/dist/signers/falcon.test.js.map +1 -1
- package/dist/transaction/consumeNotes.d.ts +2 -2
- package/dist/transaction/consumeNotes.d.ts.map +1 -1
- package/dist/transaction/consumeNotes.js +5 -4
- package/dist/transaction/consumeNotes.js.map +1 -1
- package/dist/transaction/options.d.ts +1 -0
- package/dist/transaction/options.d.ts.map +1 -1
- package/dist/transaction/p2id.d.ts.map +1 -1
- package/dist/transaction/p2id.js +7 -10
- package/dist/transaction/p2id.js.map +1 -1
- package/dist/transaction/p2id.test.js +19 -9
- package/dist/transaction/p2id.test.js.map +1 -1
- package/dist/transaction/summary.d.ts +2 -2
- package/dist/transaction/summary.d.ts.map +1 -1
- package/dist/transaction/summary.js +4 -2
- package/dist/transaction/summary.js.map +1 -1
- package/dist/transaction/updateGuardian.d.ts +2 -2
- package/dist/transaction/updateGuardian.d.ts.map +1 -1
- package/dist/transaction/updateGuardian.js +8 -11
- package/dist/transaction/updateGuardian.js.map +1 -1
- package/dist/transaction/updateProcedureThreshold.d.ts +2 -2
- package/dist/transaction/updateProcedureThreshold.d.ts.map +1 -1
- package/dist/transaction/updateProcedureThreshold.js +8 -10
- package/dist/transaction/updateProcedureThreshold.js.map +1 -1
- package/dist/transaction/updateSigners.d.ts +2 -2
- package/dist/transaction/updateSigners.d.ts.map +1 -1
- package/dist/transaction/updateSigners.js +8 -10
- package/dist/transaction/updateSigners.js.map +1 -1
- package/dist/transaction.test.js +6 -6
- package/dist/transaction.test.js.map +1 -1
- package/dist/utils/key.d.ts.map +1 -1
- package/dist/utils/key.js +3 -3
- package/dist/utils/key.js.map +1 -1
- package/dist/utils/key.test.js +4 -2
- package/dist/utils/key.test.js.map +1 -1
- package/dist/utils/signature.d.ts +2 -0
- package/dist/utils/signature.d.ts.map +1 -1
- package/dist/utils/signature.js +10 -5
- package/dist/utils/signature.js.map +1 -1
- package/dist/utils/signature.test.js +9 -9
- package/dist/utils/signature.test.js.map +1 -1
- package/masm/account_components/auth/multisig.masm +2 -3
- package/masm/account_components/auth/multisig_ecdsa.masm +2 -3
- package/masm/account_components/auth/multisig_guardian.masm +2 -3
- package/masm/account_components/auth/multisig_guardian_ecdsa.masm +2 -3
- package/masm/auth/guardian.masm +30 -8
- package/masm/auth/guardian_ecdsa.masm +24 -7
- package/masm/auth/multisig.masm +86 -55
- package/masm/auth/multisig_ecdsa.masm +86 -54
- package/package.json +3 -3
- package/src/account/builder.test.ts +16 -14
- package/src/account/builder.ts +13 -12
- package/src/account/masm/account-components/auth.ts +8 -12
- package/src/account/masm/auth.ts +226 -124
- package/src/account/storage.test.ts +90 -0
- package/src/account/storage.ts +27 -6
- package/src/client.test.ts +52 -8
- package/src/client.ts +39 -16
- package/src/index.ts +6 -12
- package/src/multisig/proposal/execution.ts +18 -14
- package/src/multisig.test.ts +17 -29
- package/src/multisig.ts +61 -36
- package/src/procedures.ts +8 -8
- package/src/raw-client.test.ts +133 -0
- package/src/raw-client.ts +75 -0
- package/src/signers/ecdsa.test.ts +35 -4
- package/src/signers/ecdsa.ts +18 -2
- package/src/signers/falcon.test.ts +50 -3
- package/src/signers/falcon.ts +18 -2
- package/src/transaction/consumeNotes.ts +16 -5
- package/src/transaction/options.ts +1 -0
- package/src/transaction/p2id.test.ts +19 -9
- package/src/transaction/p2id.ts +8 -13
- package/src/transaction/summary.ts +11 -4
- package/src/transaction/updateGuardian.ts +22 -14
- package/src/transaction/updateProcedureThreshold.ts +20 -15
- package/src/transaction/updateSigners.ts +22 -14
- package/src/transaction.test.ts +6 -6
- package/src/utils/key.test.ts +4 -2
- package/src/utils/key.ts +7 -3
- package/src/utils/signature.test.ts +10 -10
- 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 |
|
|
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:
|
|
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
|
-
# => [
|
|
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
|
-
# => [
|
|
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,
|
|
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
|
-
# => [
|
|
146
|
-
|
|
147
|
-
drop drop
|
|
148
|
-
# => [num_approvers, threshold]
|
|
164
|
+
# => [threshold, num_approvers]
|
|
149
165
|
|
|
150
|
-
|
|
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::
|
|
171
|
-
# => [[
|
|
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:
|
|
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:
|
|
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.
|
|
265
|
+
dup.1 loc_store.0
|
|
249
266
|
# => [MULTISIG_CONFIG, pad(12)]
|
|
250
267
|
|
|
251
|
-
dup
|
|
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
|
|
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
|
|
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
|
|
292
|
-
# => [
|
|
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,
|
|
312
|
+
# => [PUB_KEY, APPROVER_MAP_KEY, i-1, pad(12)]
|
|
296
313
|
|
|
297
314
|
swapw
|
|
298
|
-
# => [
|
|
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,
|
|
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:
|
|
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
|
-
# => [[
|
|
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:
|
|
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
|
-
# => [
|
|
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
|
-
|
|
472
|
-
# => [
|
|
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
|
-
|
|
481
|
-
# => [
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
31
|
+
"@miden-sdk/miden-sdk": "0.14.3",
|
|
32
32
|
"@noble/hashes": "^2.0.1",
|
|
33
|
-
"@openzeppelin/guardian-client": "^0.
|
|
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
|
-
|
|
102
|
-
|
|
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
|
-
|
|
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.
|
|
117
|
+
expect(authBuilder.linkModule).toHaveBeenNthCalledWith(
|
|
117
118
|
1,
|
|
118
119
|
'openzeppelin::auth::guardian',
|
|
119
120
|
GUARDIAN_MASM,
|
|
120
121
|
);
|
|
121
|
-
expect(authBuilder.
|
|
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.
|
|
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
|
-
|
|
135
|
-
|
|
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
|
-
|
|
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.
|
|
152
|
+
expect(authBuilder.linkModule).toHaveBeenNthCalledWith(
|
|
151
153
|
1,
|
|
152
154
|
'openzeppelin::auth::guardian_ecdsa',
|
|
153
155
|
GUARDIAN_ECDSA_MASM,
|
|
154
156
|
);
|
|
155
|
-
expect(authBuilder.
|
|
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.
|
|
165
|
+
expect(webClient.accounts.insert).toHaveBeenCalledTimes(1);
|
|
164
166
|
});
|
|
165
167
|
});
|
package/src/account/builder.ts
CHANGED
|
@@ -9,9 +9,10 @@ import {
|
|
|
9
9
|
AccountComponent,
|
|
10
10
|
AccountType,
|
|
11
11
|
AccountStorageMode,
|
|
12
|
-
type
|
|
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
|
|
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
|
-
|
|
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 =
|
|
58
|
-
|
|
59
|
-
authBuilder.
|
|
60
|
-
const
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|