@openzeppelin/miden-multisig-client 0.12.8 → 0.13.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.
- package/README.md +42 -4
- package/dist/account/builder.d.ts +1 -1
- package/dist/account/builder.d.ts.map +1 -1
- package/dist/account/builder.js +7 -5
- package/dist/account/builder.js.map +1 -1
- package/dist/account/builder.test.d.ts +2 -0
- package/dist/account/builder.test.d.ts.map +1 -0
- package/dist/account/builder.test.js +39 -0
- package/dist/account/builder.test.js.map +1 -0
- package/dist/account/masm.d.ts +3 -3
- package/dist/account/masm.d.ts.map +1 -1
- package/dist/account/masm.js +101 -98
- package/dist/account/masm.js.map +1 -1
- package/dist/account/storage.d.ts +1 -1
- package/dist/account/storage.d.ts.map +1 -1
- package/dist/account/storage.js +17 -7
- package/dist/account/storage.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -2
- package/dist/client.js.map +1 -1
- package/dist/client.test.js +4 -4
- package/dist/client.test.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/inspector.d.ts +1 -1
- package/dist/inspector.d.ts.map +1 -1
- package/dist/inspector.js +16 -10
- package/dist/inspector.js.map +1 -1
- package/dist/inspector.test.js +33 -22
- package/dist/inspector.test.js.map +1 -1
- package/dist/multisig/helpers.d.ts +1 -1
- package/dist/multisig/helpers.d.ts.map +1 -1
- package/dist/multisig/helpers.js +1 -1
- package/dist/multisig/helpers.js.map +1 -1
- package/dist/multisig/helpers.test.js +2 -2
- package/dist/multisig/helpers.test.js.map +1 -1
- package/dist/multisig/proposal/execution.d.ts +19 -0
- package/dist/multisig/proposal/execution.d.ts.map +1 -0
- package/dist/multisig/proposal/execution.js +158 -0
- package/dist/multisig/proposal/execution.js.map +1 -0
- package/dist/multisig/proposal/parser.d.ts +17 -0
- package/dist/multisig/proposal/parser.d.ts.map +1 -0
- package/dist/multisig/proposal/parser.js +147 -0
- package/dist/multisig/proposal/parser.js.map +1 -0
- package/dist/multisig/signing.d.ts +5 -0
- package/dist/multisig/signing.d.ts.map +1 -0
- package/dist/multisig/signing.js +14 -0
- package/dist/multisig/signing.js.map +1 -0
- package/dist/multisig.d.ts +10 -13
- package/dist/multisig.d.ts.map +1 -1
- package/dist/multisig.js +128 -337
- package/dist/multisig.js.map +1 -1
- package/dist/multisig.test.js +8 -4
- package/dist/multisig.test.js.map +1 -1
- package/dist/proposal/exported.d.ts +12 -0
- package/dist/proposal/exported.d.ts.map +1 -0
- package/dist/proposal/exported.js +88 -0
- package/dist/proposal/exported.js.map +1 -0
- package/dist/proposal/metadata.d.ts +15 -0
- package/dist/proposal/metadata.d.ts.map +1 -0
- package/dist/proposal/metadata.js +212 -0
- package/dist/proposal/metadata.js.map +1 -0
- package/dist/signer.d.ts +2 -20
- package/dist/signer.d.ts.map +1 -1
- package/dist/signer.js +2 -82
- package/dist/signer.js.map +1 -1
- package/dist/signer.test.js +22 -16
- package/dist/signer.test.js.map +1 -1
- package/dist/signers/ecdsa.d.ts +12 -0
- package/dist/signers/ecdsa.d.ts.map +1 -0
- package/dist/signers/ecdsa.js +30 -0
- package/dist/signers/ecdsa.js.map +1 -0
- package/dist/signers/falcon.d.ts +12 -0
- package/dist/signers/falcon.d.ts.map +1 -0
- package/dist/signers/falcon.js +31 -0
- package/dist/signers/falcon.js.map +1 -0
- package/dist/signers/falcon.test.d.ts +2 -0
- package/dist/signers/falcon.test.d.ts.map +1 -0
- package/dist/signers/falcon.test.js +113 -0
- package/dist/signers/falcon.test.js.map +1 -0
- package/dist/signers/index.d.ts +5 -0
- package/dist/signers/index.d.ts.map +1 -0
- package/dist/signers/index.js +5 -0
- package/dist/signers/index.js.map +1 -0
- package/dist/signers/miden-wallet.d.ts +16 -0
- package/dist/signers/miden-wallet.d.ts.map +1 -0
- package/dist/signers/miden-wallet.js +35 -0
- package/dist/signers/miden-wallet.js.map +1 -0
- package/dist/signers/miden-wallet.test.d.ts +2 -0
- package/dist/signers/miden-wallet.test.d.ts.map +1 -0
- package/dist/signers/miden-wallet.test.js +107 -0
- package/dist/signers/miden-wallet.test.js.map +1 -0
- package/dist/signers/para.d.ts +21 -0
- package/dist/signers/para.d.ts.map +1 -0
- package/dist/signers/para.js +43 -0
- package/dist/signers/para.js.map +1 -0
- package/dist/signers/para.test.d.ts +2 -0
- package/dist/signers/para.test.d.ts.map +1 -0
- package/dist/signers/para.test.js +88 -0
- package/dist/signers/para.test.js.map +1 -0
- package/dist/transaction/consumeNotes.d.ts +3 -3
- package/dist/transaction/consumeNotes.d.ts.map +1 -1
- package/dist/transaction/consumeNotes.js +11 -7
- package/dist/transaction/consumeNotes.js.map +1 -1
- package/dist/transaction/options.d.ts +2 -2
- package/dist/transaction/options.d.ts.map +1 -1
- package/dist/transaction/p2id.d.ts +1 -1
- package/dist/transaction/p2id.d.ts.map +1 -1
- package/dist/transaction/p2id.interop.test.d.ts +2 -0
- package/dist/transaction/p2id.interop.test.d.ts.map +1 -0
- package/dist/transaction/p2id.interop.test.js +36 -0
- package/dist/transaction/p2id.interop.test.js.map +1 -0
- package/dist/transaction/p2id.js +5 -5
- package/dist/transaction/p2id.js.map +1 -1
- package/dist/transaction/p2id.test.d.ts +2 -0
- package/dist/transaction/p2id.test.d.ts.map +1 -0
- package/dist/transaction/p2id.test.js +138 -0
- package/dist/transaction/p2id.test.js.map +1 -0
- package/dist/transaction/rpoRandomCoin.d.ts +7 -0
- package/dist/transaction/rpoRandomCoin.d.ts.map +1 -0
- package/dist/transaction/rpoRandomCoin.js +17 -0
- package/dist/transaction/rpoRandomCoin.js.map +1 -0
- package/dist/transaction/rpoRandomCoin.test.d.ts +2 -0
- package/dist/transaction/rpoRandomCoin.test.d.ts.map +1 -0
- package/dist/transaction/rpoRandomCoin.test.js +52 -0
- package/dist/transaction/rpoRandomCoin.test.js.map +1 -0
- package/dist/transaction/summary.d.ts +1 -1
- package/dist/transaction/summary.d.ts.map +1 -1
- package/dist/transaction/summary.js +1 -1
- package/dist/transaction/summary.js.map +1 -1
- package/dist/transaction/updatePsm.d.ts +1 -1
- package/dist/transaction/updatePsm.d.ts.map +1 -1
- package/dist/transaction/updatePsm.js +5 -5
- package/dist/transaction/updatePsm.js.map +1 -1
- package/dist/transaction/updateSigners.d.ts +1 -1
- package/dist/transaction/updateSigners.d.ts.map +1 -1
- package/dist/transaction/updateSigners.js +5 -5
- package/dist/transaction/updateSigners.js.map +1 -1
- package/dist/transaction.test.js +1 -1
- package/dist/transaction.test.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/digest.d.ts +6 -0
- package/dist/utils/digest.d.ts.map +1 -0
- package/dist/utils/digest.js +22 -0
- package/dist/utils/digest.js.map +1 -0
- package/dist/utils/ecdsa.d.ts +8 -0
- package/dist/utils/ecdsa.d.ts.map +1 -0
- package/dist/utils/ecdsa.js +60 -0
- package/dist/utils/ecdsa.js.map +1 -0
- package/dist/utils/ecdsa.test.d.ts +2 -0
- package/dist/utils/ecdsa.test.d.ts.map +1 -0
- package/dist/utils/ecdsa.test.js +85 -0
- package/dist/utils/ecdsa.test.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/key.d.ts +10 -0
- package/dist/utils/key.d.ts.map +1 -0
- package/dist/utils/key.js +38 -0
- package/dist/utils/key.js.map +1 -0
- package/dist/utils/key.test.d.ts +2 -0
- package/dist/utils/key.test.d.ts.map +1 -0
- package/dist/utils/key.test.js +80 -0
- package/dist/utils/key.test.js.map +1 -0
- package/dist/utils/random.d.ts +1 -1
- package/dist/utils/random.d.ts.map +1 -1
- package/dist/utils/random.js +1 -1
- package/dist/utils/random.js.map +1 -1
- package/dist/utils/signature.d.ts +2 -1
- package/dist/utils/signature.d.ts.map +1 -1
- package/dist/utils/signature.js +6 -3
- package/dist/utils/signature.js.map +1 -1
- package/dist/utils/signature.test.js +11 -11
- package/dist/utils/signature.test.js.map +1 -1
- package/dist/utils/state-validation.d.ts +5 -0
- package/dist/utils/state-validation.d.ts.map +1 -0
- package/dist/utils/state-validation.js +30 -0
- package/dist/utils/state-validation.js.map +1 -0
- package/dist/utils/validation.d.ts +6 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +52 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/word.d.ts +6 -1
- package/dist/utils/word.d.ts.map +1 -1
- package/dist/utils/word.js +11 -0
- package/dist/utils/word.js.map +1 -1
- package/dist/utils/word.test.js +54 -3
- package/dist/utils/word.test.js.map +1 -1
- package/package.json +4 -5
- package/src/account/builder.ts +7 -5
- package/src/account/masm.ts +103 -99
- package/src/account/storage.ts +19 -7
- package/src/client.test.ts +4 -4
- package/src/client.ts +3 -3
- package/src/index.ts +8 -1
- package/src/inspector.test.ts +38 -25
- package/src/inspector.ts +18 -10
- package/src/multisig/helpers.test.ts +2 -2
- package/src/multisig/helpers.ts +2 -1
- package/src/multisig/proposal/execution.ts +364 -0
- package/src/multisig/proposal/parser.ts +191 -0
- package/src/multisig/signing.ts +24 -0
- package/src/multisig.test.ts +8 -4
- package/src/multisig.ts +176 -434
- package/src/signer.ts +2 -95
- package/src/signers/ecdsa.ts +35 -0
- package/src/{signer.test.ts → signers/falcon.test.ts} +29 -33
- package/src/signers/falcon.ts +36 -0
- package/src/signers/index.ts +4 -0
- package/src/signers/miden-wallet.test.ts +119 -0
- package/src/signers/miden-wallet.ts +49 -0
- package/src/signers/para.test.ts +103 -0
- package/src/signers/para.ts +60 -0
- package/src/transaction/consumeNotes.ts +14 -10
- package/src/transaction/options.ts +2 -2
- package/src/transaction/p2id.ts +3 -8
- package/src/transaction/summary.ts +2 -2
- package/src/transaction/updatePsm.ts +5 -6
- package/src/transaction/updateSigners.ts +5 -6
- package/src/transaction.test.ts +1 -1
- package/src/types.ts +1 -1
- package/src/utils/digest.ts +25 -0
- package/src/utils/ecdsa.test.ts +104 -0
- package/src/utils/ecdsa.ts +77 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/key.test.ts +89 -0
- package/src/utils/key.ts +49 -0
- package/src/utils/random.ts +1 -1
- package/src/utils/signature.test.ts +11 -11
- package/src/utils/signature.ts +10 -3
- package/src/utils/word.test.ts +57 -3
- package/src/utils/word.ts +13 -1
package/dist/account/masm.js
CHANGED
|
@@ -3,12 +3,11 @@ export const MULTISIG_MASM = `# Multi-Signature RPO Falcon 512 Authentication Co
|
|
|
3
3
|
# This component provides multi-signature authentication for accounts.
|
|
4
4
|
# It integrates with the PSM component for optional PSM signature verification.
|
|
5
5
|
|
|
6
|
-
use miden::active_account
|
|
7
|
-
use miden::native_account
|
|
8
|
-
use miden::auth
|
|
6
|
+
use miden::protocol::active_account
|
|
7
|
+
use miden::protocol::native_account
|
|
8
|
+
use miden::standards::auth
|
|
9
9
|
use openzeppelin::psm
|
|
10
10
|
|
|
11
|
-
# Type definitions for v0.12 syntax
|
|
12
11
|
type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
|
|
13
12
|
|
|
14
13
|
# CONSTANTS
|
|
@@ -17,7 +16,7 @@ type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
|
|
|
17
16
|
# Auth Request Constants
|
|
18
17
|
|
|
19
18
|
# The event emitted when a signature is not found for a required signer.
|
|
20
|
-
const AUTH_UNAUTHORIZED_EVENT
|
|
19
|
+
const AUTH_UNAUTHORIZED_EVENT=event("miden::auth::unauthorized")
|
|
21
20
|
|
|
22
21
|
# Storage Layout Constants
|
|
23
22
|
#
|
|
@@ -32,29 +31,29 @@ const AUTH_UNAUTHORIZED_EVENT = event("miden::auth::unauthorized")
|
|
|
32
31
|
# number of approvers are stored as:
|
|
33
32
|
# [default_threshold, num_approvers, 0, 0].
|
|
34
33
|
# The threshold is guaranteed to be less than or equal to num_approvers.
|
|
35
|
-
const THRESHOLD_CONFIG_SLOT
|
|
34
|
+
const THRESHOLD_CONFIG_SLOT=word("openzeppelin::multisig::threshold_config")
|
|
36
35
|
|
|
37
36
|
# The slot in this component's storage layout where the public keys map is stored.
|
|
38
37
|
# Map entries: [key_index, 0, 0, 0] => APPROVER_PUBLIC_KEY
|
|
39
|
-
const PUBLIC_KEYS_MAP_SLOT
|
|
38
|
+
const PUBLIC_KEYS_MAP_SLOT=word("openzeppelin::multisig::signer_public_keys")
|
|
40
39
|
|
|
41
40
|
# The slot in this component's storage layout where executed transactions are stored.
|
|
42
41
|
# Map entries: transaction_message => [is_executed, 0, 0, 0]
|
|
43
|
-
const EXECUTED_TXS_SLOT
|
|
42
|
+
const EXECUTED_TXS_SLOT=word("openzeppelin::multisig::executed_transactions")
|
|
44
43
|
|
|
45
44
|
# The slot in this component's storage layout where procedure thresholds are stored.
|
|
46
45
|
# Map entries: PROC_ROOT => [proc_threshold, 0, 0, 0]
|
|
47
|
-
const PROC_THRESHOLD_ROOTS_SLOT
|
|
46
|
+
const PROC_THRESHOLD_ROOTS_SLOT=word("openzeppelin::multisig::procedure_thresholds")
|
|
48
47
|
|
|
49
48
|
# Executed Transaction Flag Constant
|
|
50
|
-
const IS_EXECUTED_FLAG
|
|
49
|
+
const IS_EXECUTED_FLAG=[1, 0, 0, 0]
|
|
51
50
|
|
|
52
51
|
# ERRORS
|
|
53
|
-
const ERR_TX_ALREADY_EXECUTED
|
|
52
|
+
const ERR_TX_ALREADY_EXECUTED="failed to approve multisig transaction as it was already executed"
|
|
54
53
|
|
|
55
|
-
const ERR_MALFORMED_MULTISIG_CONFIG
|
|
54
|
+
const ERR_MALFORMED_MULTISIG_CONFIG="number of approvers must be equal to or greater than threshold"
|
|
56
55
|
|
|
57
|
-
const ERR_ZERO_IN_MULTISIG_CONFIG
|
|
56
|
+
const ERR_ZERO_IN_MULTISIG_CONFIG="number of approvers or threshold must not be zero"
|
|
58
57
|
|
|
59
58
|
# MULTISIG PROCEDURES
|
|
60
59
|
# =================================================================================================
|
|
@@ -73,14 +72,14 @@ proc assert_new_tx(msg: BeWord)
|
|
|
73
72
|
swapw
|
|
74
73
|
# => [MSG, IS_EXECUTED_FLAG]
|
|
75
74
|
|
|
76
|
-
push.EXECUTED_TXS_SLOT
|
|
77
|
-
# => [
|
|
75
|
+
push.EXECUTED_TXS_SLOT[0..2]
|
|
76
|
+
# => [txs_slot_prefix, txs_slot_suffix, MSG, IS_EXECUTED_FLAG]
|
|
78
77
|
|
|
79
78
|
# Set the key value pair in the map to mark transaction as executed
|
|
80
79
|
exec.native_account::set_map_item
|
|
81
|
-
# => [
|
|
80
|
+
# => [[0, 0, 0, is_executed]]
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
drop drop drop
|
|
84
83
|
# => [is_executed]
|
|
85
84
|
|
|
86
85
|
assertz.err=ERR_TX_ALREADY_EXECUTED
|
|
@@ -119,13 +118,13 @@ proc cleanup_pubkey_mapping(init_num_of_approvers: u32, new_num_of_approvers: u3
|
|
|
119
118
|
padw swapw
|
|
120
119
|
# => [[0, 0, 0, i-1], EMPTY_WORD, i-1, new_num_of_approvers]
|
|
121
120
|
|
|
122
|
-
push.PUBLIC_KEYS_MAP_SLOT
|
|
123
|
-
# => [
|
|
121
|
+
push.PUBLIC_KEYS_MAP_SLOT[0..2]
|
|
122
|
+
# => [pub_key_slot_prefix, pub_key_slot_suffix, [0, 0, 0, i-1], EMPTY_WORD, i-1, new_num_of_approvers]
|
|
124
123
|
|
|
125
124
|
exec.native_account::set_map_item
|
|
126
|
-
# => [
|
|
125
|
+
# => [OLD_MAP_VALUE, i-1, new_num_of_approvers]
|
|
127
126
|
|
|
128
|
-
dropw
|
|
127
|
+
dropw
|
|
129
128
|
# => [i-1, new_num_of_approvers]
|
|
130
129
|
|
|
131
130
|
dup.1 dup.1
|
|
@@ -155,7 +154,8 @@ end
|
|
|
155
154
|
#! Locals:
|
|
156
155
|
#! 0: new_num_of_approvers
|
|
157
156
|
#! 1: init_num_of_approvers
|
|
158
|
-
|
|
157
|
+
@locals(2)
|
|
158
|
+
pub proc update_signers_and_threshold(multisig_config_hash: BeWord)
|
|
159
159
|
adv.push_mapval
|
|
160
160
|
# => [MULTISIG_CONFIG_HASH, pad(12)]
|
|
161
161
|
|
|
@@ -182,8 +182,8 @@ pub proc update_signers_and_threshold.2(multisig_config_hash: BeWord)
|
|
|
182
182
|
eq.0 assertz.err=ERR_ZERO_IN_MULTISIG_CONFIG
|
|
183
183
|
# => [MULTISIG_CONFIG, pad(12)]
|
|
184
184
|
|
|
185
|
-
push.THRESHOLD_CONFIG_SLOT
|
|
186
|
-
# => [
|
|
185
|
+
push.THRESHOLD_CONFIG_SLOT[0..2]
|
|
186
|
+
# => [config_slot_prefix, config_slot_suffix, MULTISIG_CONFIG, pad(12)]
|
|
187
187
|
|
|
188
188
|
exec.native_account::set_item
|
|
189
189
|
# => [OLD_THRESHOLD_CONFIG, pad(12)]
|
|
@@ -209,13 +209,13 @@ pub proc update_signers_and_threshold.2(multisig_config_hash: BeWord)
|
|
|
209
209
|
swapw
|
|
210
210
|
# => [[0, 0, 0, i-1], PUB_KEY, i-1, pad(12)]
|
|
211
211
|
|
|
212
|
-
push.PUBLIC_KEYS_MAP_SLOT
|
|
213
|
-
# => [
|
|
212
|
+
push.PUBLIC_KEYS_MAP_SLOT[0..2]
|
|
213
|
+
# => [pub_key_slot_prefix, pub_key_slot_suffix, [0, 0, 0, i-1], PUB_KEY, i-1, pad(12)]
|
|
214
214
|
|
|
215
215
|
exec.native_account::set_map_item
|
|
216
|
-
# => [
|
|
216
|
+
# => [OLD_VALUE, i-1, pad(12)]
|
|
217
217
|
|
|
218
|
-
dropw
|
|
218
|
+
dropw
|
|
219
219
|
# => [i-1, pad(12)]
|
|
220
220
|
|
|
221
221
|
dup neq.0
|
|
@@ -242,7 +242,8 @@ end
|
|
|
242
242
|
#
|
|
243
243
|
#! Inputs: [default_threshold]
|
|
244
244
|
#! Outputs: [transaction_threshold]
|
|
245
|
-
|
|
245
|
+
@locals(1)
|
|
246
|
+
proc compute_transaction_threshold(default_threshold: u32) -> u32
|
|
246
247
|
# 1. initialize transaction_threshold = 0
|
|
247
248
|
# 2. iterate through all account procedures
|
|
248
249
|
# a. check if the procedure was called during the transaction
|
|
@@ -281,8 +282,8 @@ proc compute_transaction_threshold.1(default_threshold: u32) -> u32
|
|
|
281
282
|
if.true
|
|
282
283
|
# => [PROC_ROOT, num_procedures-1, transaction_threshold]
|
|
283
284
|
|
|
284
|
-
push.PROC_THRESHOLD_ROOTS_SLOT
|
|
285
|
-
# => [
|
|
285
|
+
push.PROC_THRESHOLD_ROOTS_SLOT[0..2]
|
|
286
|
+
# => [PROC_THRESHOLD_ROOTS_SLOT_prefix, PROC_THRESHOLD_ROOTS_SLOT_suffix, PROC_ROOT, num_procedures-1, transaction_threshold]
|
|
286
287
|
|
|
287
288
|
# 2b. get the override proc_threshold of that procedure
|
|
288
289
|
# if the procedure has no override threshold, the returned map item will be [0, 0, 0, 0]
|
|
@@ -359,7 +360,8 @@ end
|
|
|
359
360
|
#! - PSM signature verification fails (if PSM is enabled).
|
|
360
361
|
#!
|
|
361
362
|
#! Invocation: call
|
|
362
|
-
|
|
363
|
+
@locals(1)
|
|
364
|
+
pub proc auth_tx_rpo_falcon512_multisig(salt: BeWord)
|
|
363
365
|
exec.native_account::incr_nonce drop
|
|
364
366
|
# => [SALT]
|
|
365
367
|
|
|
@@ -378,8 +380,8 @@ pub proc auth_tx_rpo_falcon512_multisig.1(salt: BeWord)
|
|
|
378
380
|
|
|
379
381
|
# ------ Verifying approver signatures ------
|
|
380
382
|
|
|
381
|
-
push.THRESHOLD_CONFIG_SLOT
|
|
382
|
-
# => [
|
|
383
|
+
push.THRESHOLD_CONFIG_SLOT[0..2]
|
|
384
|
+
# => [config_slot_prefix, config_slot_suffix, TX_SUMMARY_COMMITMENT]
|
|
383
385
|
|
|
384
386
|
exec.active_account::get_initial_item
|
|
385
387
|
# => [0, 0, num_of_approvers, default_threshold, TX_SUMMARY_COMMITMENT]
|
|
@@ -390,10 +392,10 @@ pub proc auth_tx_rpo_falcon512_multisig.1(salt: BeWord)
|
|
|
390
392
|
swap movdn.5
|
|
391
393
|
# => [num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
|
|
392
394
|
|
|
393
|
-
push.PUBLIC_KEYS_MAP_SLOT
|
|
394
|
-
# => [
|
|
395
|
+
push.PUBLIC_KEYS_MAP_SLOT[0..2]
|
|
396
|
+
# => [pub_key_slot_prefix, pub_key_slot_suffix, num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
|
|
395
397
|
|
|
396
|
-
exec.::miden::auth::
|
|
398
|
+
exec.::miden::standards::auth::falcon512_rpo::verify_signatures
|
|
397
399
|
# => [num_verified_signatures, TX_SUMMARY_COMMITMENT, default_threshold]
|
|
398
400
|
|
|
399
401
|
# ------ Checking threshold is >= num_verified_signatures ------
|
|
@@ -428,12 +430,11 @@ export const MULTISIG_ECDSA_MASM = `# Multi-Signature ECDSA secp256k1 Authentica
|
|
|
428
430
|
# ECDSA secp256k1 (k256/keccak) signatures instead of RPO Falcon 512.
|
|
429
431
|
# It integrates with the PSM component for optional PSM signature verification.
|
|
430
432
|
|
|
431
|
-
use miden::active_account
|
|
432
|
-
use miden::native_account
|
|
433
|
-
use miden::auth
|
|
433
|
+
use miden::protocol::active_account
|
|
434
|
+
use miden::protocol::native_account
|
|
435
|
+
use miden::standards::auth
|
|
434
436
|
use openzeppelin::psm_ecdsa
|
|
435
437
|
|
|
436
|
-
# Type definitions for v0.12 syntax
|
|
437
438
|
type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
|
|
438
439
|
|
|
439
440
|
# CONSTANTS
|
|
@@ -442,7 +443,7 @@ type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
|
|
|
442
443
|
# Auth Request Constants
|
|
443
444
|
|
|
444
445
|
# The event emitted when a signature is not found for a required signer.
|
|
445
|
-
const AUTH_UNAUTHORIZED_EVENT
|
|
446
|
+
const AUTH_UNAUTHORIZED_EVENT=event("miden::auth::unauthorized")
|
|
446
447
|
|
|
447
448
|
# Storage Layout Constants
|
|
448
449
|
#
|
|
@@ -457,29 +458,29 @@ const AUTH_UNAUTHORIZED_EVENT = event("miden::auth::unauthorized")
|
|
|
457
458
|
# number of approvers are stored as:
|
|
458
459
|
# [default_threshold, num_approvers, 0, 0].
|
|
459
460
|
# The threshold is guaranteed to be less than or equal to num_approvers.
|
|
460
|
-
const THRESHOLD_CONFIG_SLOT
|
|
461
|
+
const THRESHOLD_CONFIG_SLOT=word("openzeppelin::multisig::threshold_config")
|
|
461
462
|
|
|
462
463
|
# The slot in this component's storage layout where the public keys map is stored.
|
|
463
464
|
# Map entries: [key_index, 0, 0, 0] => APPROVER_PUBLIC_KEY
|
|
464
|
-
const PUBLIC_KEYS_MAP_SLOT
|
|
465
|
+
const PUBLIC_KEYS_MAP_SLOT=word("openzeppelin::multisig::signer_public_keys")
|
|
465
466
|
|
|
466
467
|
# The slot in this component's storage layout where executed transactions are stored.
|
|
467
468
|
# Map entries: transaction_message => [is_executed, 0, 0, 0]
|
|
468
|
-
const EXECUTED_TXS_SLOT
|
|
469
|
+
const EXECUTED_TXS_SLOT=word("openzeppelin::multisig::executed_transactions")
|
|
469
470
|
|
|
470
471
|
# The slot in this component's storage layout where procedure thresholds are stored.
|
|
471
472
|
# Map entries: PROC_ROOT => [proc_threshold, 0, 0, 0]
|
|
472
|
-
const PROC_THRESHOLD_ROOTS_SLOT
|
|
473
|
+
const PROC_THRESHOLD_ROOTS_SLOT=word("openzeppelin::multisig::procedure_thresholds")
|
|
473
474
|
|
|
474
475
|
# Executed Transaction Flag Constant
|
|
475
|
-
const IS_EXECUTED_FLAG
|
|
476
|
+
const IS_EXECUTED_FLAG=[1, 0, 0, 0]
|
|
476
477
|
|
|
477
478
|
# ERRORS
|
|
478
|
-
const ERR_TX_ALREADY_EXECUTED
|
|
479
|
+
const ERR_TX_ALREADY_EXECUTED="failed to approve multisig transaction as it was already executed"
|
|
479
480
|
|
|
480
|
-
const ERR_MALFORMED_MULTISIG_CONFIG
|
|
481
|
+
const ERR_MALFORMED_MULTISIG_CONFIG="number of approvers must be equal to or greater than threshold"
|
|
481
482
|
|
|
482
|
-
const ERR_ZERO_IN_MULTISIG_CONFIG
|
|
483
|
+
const ERR_ZERO_IN_MULTISIG_CONFIG="number of approvers or threshold must not be zero"
|
|
483
484
|
|
|
484
485
|
# MULTISIG PROCEDURES
|
|
485
486
|
# =================================================================================================
|
|
@@ -498,14 +499,14 @@ proc assert_new_tx(msg: BeWord)
|
|
|
498
499
|
swapw
|
|
499
500
|
# => [MSG, IS_EXECUTED_FLAG]
|
|
500
501
|
|
|
501
|
-
push.EXECUTED_TXS_SLOT
|
|
502
|
-
# => [
|
|
502
|
+
push.EXECUTED_TXS_SLOT[0..2]
|
|
503
|
+
# => [txs_slot_prefix, txs_slot_suffix, MSG, IS_EXECUTED_FLAG]
|
|
503
504
|
|
|
504
505
|
# Set the key value pair in the map to mark transaction as executed
|
|
505
506
|
exec.native_account::set_map_item
|
|
506
|
-
# => [
|
|
507
|
+
# => [[0, 0, 0, is_executed]]
|
|
507
508
|
|
|
508
|
-
|
|
509
|
+
drop drop drop
|
|
509
510
|
# => [is_executed]
|
|
510
511
|
|
|
511
512
|
assertz.err=ERR_TX_ALREADY_EXECUTED
|
|
@@ -544,13 +545,13 @@ proc cleanup_pubkey_mapping(init_num_of_approvers: u32, new_num_of_approvers: u3
|
|
|
544
545
|
padw swapw
|
|
545
546
|
# => [[0, 0, 0, i-1], EMPTY_WORD, i-1, new_num_of_approvers]
|
|
546
547
|
|
|
547
|
-
push.PUBLIC_KEYS_MAP_SLOT
|
|
548
|
-
# => [
|
|
548
|
+
push.PUBLIC_KEYS_MAP_SLOT[0..2]
|
|
549
|
+
# => [pub_key_slot_prefix, pub_key_slot_suffix, [0, 0, 0, i-1], EMPTY_WORD, i-1, new_num_of_approvers]
|
|
549
550
|
|
|
550
551
|
exec.native_account::set_map_item
|
|
551
|
-
# => [
|
|
552
|
+
# => [OLD_MAP_VALUE, i-1, new_num_of_approvers]
|
|
552
553
|
|
|
553
|
-
dropw
|
|
554
|
+
dropw
|
|
554
555
|
# => [i-1, new_num_of_approvers]
|
|
555
556
|
|
|
556
557
|
dup.1 dup.1
|
|
@@ -580,7 +581,8 @@ end
|
|
|
580
581
|
#! Locals:
|
|
581
582
|
#! 0: new_num_of_approvers
|
|
582
583
|
#! 1: init_num_of_approvers
|
|
583
|
-
|
|
584
|
+
@locals(2)
|
|
585
|
+
pub proc update_signers_and_threshold(multisig_config_hash: BeWord)
|
|
584
586
|
adv.push_mapval
|
|
585
587
|
# => [MULTISIG_CONFIG_HASH, pad(12)]
|
|
586
588
|
|
|
@@ -607,8 +609,8 @@ pub proc update_signers_and_threshold.2(multisig_config_hash: BeWord)
|
|
|
607
609
|
eq.0 assertz.err=ERR_ZERO_IN_MULTISIG_CONFIG
|
|
608
610
|
# => [MULTISIG_CONFIG, pad(12)]
|
|
609
611
|
|
|
610
|
-
push.THRESHOLD_CONFIG_SLOT
|
|
611
|
-
# => [
|
|
612
|
+
push.THRESHOLD_CONFIG_SLOT[0..2]
|
|
613
|
+
# => [config_slot_prefix, config_slot_suffix, MULTISIG_CONFIG, pad(12)]
|
|
612
614
|
|
|
613
615
|
exec.native_account::set_item
|
|
614
616
|
# => [OLD_THRESHOLD_CONFIG, pad(12)]
|
|
@@ -634,13 +636,13 @@ pub proc update_signers_and_threshold.2(multisig_config_hash: BeWord)
|
|
|
634
636
|
swapw
|
|
635
637
|
# => [[0, 0, 0, i-1], PUB_KEY, i-1, pad(12)]
|
|
636
638
|
|
|
637
|
-
push.PUBLIC_KEYS_MAP_SLOT
|
|
638
|
-
# => [
|
|
639
|
+
push.PUBLIC_KEYS_MAP_SLOT[0..2]
|
|
640
|
+
# => [pub_key_slot_prefix, pub_key_slot_suffix, [0, 0, 0, i-1], PUB_KEY, i-1, pad(12)]
|
|
639
641
|
|
|
640
642
|
exec.native_account::set_map_item
|
|
641
|
-
# => [
|
|
643
|
+
# => [OLD_VALUE, i-1, pad(12)]
|
|
642
644
|
|
|
643
|
-
dropw
|
|
645
|
+
dropw
|
|
644
646
|
# => [i-1, pad(12)]
|
|
645
647
|
|
|
646
648
|
dup neq.0
|
|
@@ -667,7 +669,8 @@ end
|
|
|
667
669
|
#
|
|
668
670
|
#! Inputs: [default_threshold]
|
|
669
671
|
#! Outputs: [transaction_threshold]
|
|
670
|
-
|
|
672
|
+
@locals(1)
|
|
673
|
+
proc compute_transaction_threshold(default_threshold: u32) -> u32
|
|
671
674
|
# 1. initialize transaction_threshold = 0
|
|
672
675
|
# 2. iterate through all account procedures
|
|
673
676
|
# a. check if the procedure was called during the transaction
|
|
@@ -706,8 +709,8 @@ proc compute_transaction_threshold.1(default_threshold: u32) -> u32
|
|
|
706
709
|
if.true
|
|
707
710
|
# => [PROC_ROOT, num_procedures-1, transaction_threshold]
|
|
708
711
|
|
|
709
|
-
push.PROC_THRESHOLD_ROOTS_SLOT
|
|
710
|
-
# => [
|
|
712
|
+
push.PROC_THRESHOLD_ROOTS_SLOT[0..2]
|
|
713
|
+
# => [PROC_THRESHOLD_ROOTS_SLOT_prefix, PROC_THRESHOLD_ROOTS_SLOT_suffix, PROC_ROOT, num_procedures-1, transaction_threshold]
|
|
711
714
|
|
|
712
715
|
# 2b. get the override proc_threshold of that procedure
|
|
713
716
|
# if the procedure has no override threshold, the returned map item will be [0, 0, 0, 0]
|
|
@@ -784,7 +787,8 @@ end
|
|
|
784
787
|
#! - PSM signature verification fails (if PSM is enabled).
|
|
785
788
|
#!
|
|
786
789
|
#! Invocation: call
|
|
787
|
-
|
|
790
|
+
@locals(1)
|
|
791
|
+
pub proc auth_tx_ecdsa_multisig(salt: BeWord)
|
|
788
792
|
exec.native_account::incr_nonce drop
|
|
789
793
|
# => [SALT]
|
|
790
794
|
|
|
@@ -803,8 +807,8 @@ pub proc auth_tx_ecdsa_multisig.1(salt: BeWord)
|
|
|
803
807
|
|
|
804
808
|
# ------ Verifying approver signatures ------
|
|
805
809
|
|
|
806
|
-
push.THRESHOLD_CONFIG_SLOT
|
|
807
|
-
# => [
|
|
810
|
+
push.THRESHOLD_CONFIG_SLOT[0..2]
|
|
811
|
+
# => [config_slot_prefix, config_slot_suffix, TX_SUMMARY_COMMITMENT]
|
|
808
812
|
|
|
809
813
|
exec.active_account::get_initial_item
|
|
810
814
|
# => [0, 0, num_of_approvers, default_threshold, TX_SUMMARY_COMMITMENT]
|
|
@@ -815,10 +819,10 @@ pub proc auth_tx_ecdsa_multisig.1(salt: BeWord)
|
|
|
815
819
|
swap movdn.5
|
|
816
820
|
# => [num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
|
|
817
821
|
|
|
818
|
-
push.PUBLIC_KEYS_MAP_SLOT
|
|
819
|
-
# => [
|
|
822
|
+
push.PUBLIC_KEYS_MAP_SLOT[0..2]
|
|
823
|
+
# => [pub_key_slot_prefix, pub_key_slot_suffix, num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
|
|
820
824
|
|
|
821
|
-
exec.::miden::auth::ecdsa_k256_keccak::verify_signatures
|
|
825
|
+
exec.::miden::standards::auth::ecdsa_k256_keccak::verify_signatures
|
|
822
826
|
# => [num_verified_signatures, TX_SUMMARY_COMMITMENT, default_threshold]
|
|
823
827
|
|
|
824
828
|
# ------ Checking threshold is >= num_verified_signatures ------
|
|
@@ -852,10 +856,9 @@ export const PSM_MASM = `# Private State Manager (PSM) Authentication Component
|
|
|
852
856
|
# This component provides PSM signature verification for accounts.
|
|
853
857
|
# It can be used standalone or in conjunction with other auth components like multisig.
|
|
854
858
|
|
|
855
|
-
use miden::active_account
|
|
856
|
-
use miden::native_account
|
|
859
|
+
use miden::protocol::active_account
|
|
860
|
+
use miden::protocol::native_account
|
|
857
861
|
|
|
858
|
-
# Type definitions for v0.12 syntax
|
|
859
862
|
type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
|
|
860
863
|
|
|
861
864
|
# IMPORTANT SECURITY NOTES
|
|
@@ -897,22 +900,22 @@ type BeWord = struct @bigendian { a: felt, b: felt, c: felt, d: felt }
|
|
|
897
900
|
# CONSTANTS
|
|
898
901
|
# =================================================================================================
|
|
899
902
|
|
|
900
|
-
# Slot where the PSM selector flag is stored:
|
|
903
|
+
# Slot where the PSM selector flag is stored (using word() for named slot access):
|
|
901
904
|
# - PSM_ON => PSM signature required
|
|
902
905
|
# - PSM_OFF => PSM signature skipped
|
|
903
|
-
const PSM_SELECTOR_SLOT
|
|
906
|
+
const PSM_SELECTOR_SLOT=word("openzeppelin::psm::selector")
|
|
904
907
|
|
|
905
908
|
# Map slot for PSM public key
|
|
906
909
|
# Uses exactly one PSM public key at index [0, 0, 0, 0]
|
|
907
910
|
# [0, 0, 0, 0] => PSM_PUBLIC_KEY
|
|
908
|
-
const PSM_PUBLIC_KEY_MAP_SLOT
|
|
911
|
+
const PSM_PUBLIC_KEY_MAP_SLOT=word("openzeppelin::psm::public_key")
|
|
909
912
|
|
|
910
913
|
# Selector flag values
|
|
911
|
-
const PSM_ON
|
|
912
|
-
const PSM_OFF
|
|
914
|
+
const PSM_ON=[1, 0, 0, 0]
|
|
915
|
+
const PSM_OFF=[0, 0, 0, 0]
|
|
913
916
|
|
|
914
917
|
# The event emitted when a signature is not found for a required signer.
|
|
915
|
-
const AUTH_UNAUTHORIZED_EVENT
|
|
918
|
+
const AUTH_UNAUTHORIZED_EVENT=event("miden::auth::unauthorized")
|
|
916
919
|
|
|
917
920
|
# PSM PROCEDURES
|
|
918
921
|
# =================================================================================================
|
|
@@ -925,12 +928,12 @@ const AUTH_UNAUTHORIZED_EVENT = event("miden::auth::unauthorized")
|
|
|
925
928
|
#! Notes:
|
|
926
929
|
#! - Sets PSM_SELECTOR_SLOT to PSM_ON (1)
|
|
927
930
|
#! - After this, transactions will require PSM signature verification
|
|
928
|
-
proc
|
|
931
|
+
proc enable_psm
|
|
929
932
|
push.PSM_ON
|
|
930
933
|
# => [PSM_ON]
|
|
931
934
|
|
|
932
|
-
push.PSM_SELECTOR_SLOT
|
|
933
|
-
# => [
|
|
935
|
+
push.PSM_SELECTOR_SLOT[0..2]
|
|
936
|
+
# => [selector_slot_prefix, selector_slot_suffix, PSM_ON]
|
|
934
937
|
|
|
935
938
|
exec.native_account::set_item
|
|
936
939
|
# => [OLD_ROOT]
|
|
@@ -947,12 +950,12 @@ end
|
|
|
947
950
|
#! Notes:
|
|
948
951
|
#! - Sets PSM_SELECTOR_SLOT to PSM_OFF (0)
|
|
949
952
|
#! - After this, transactions will NOT require PSM signature verification
|
|
950
|
-
proc
|
|
953
|
+
proc disable_psm
|
|
951
954
|
push.PSM_OFF
|
|
952
955
|
# => [PSM_OFF]
|
|
953
956
|
|
|
954
|
-
push.PSM_SELECTOR_SLOT
|
|
955
|
-
# => [
|
|
957
|
+
push.PSM_SELECTOR_SLOT[0..2]
|
|
958
|
+
# => [selector_slot_prefix, selector_slot_suffix, PSM_OFF]
|
|
956
959
|
|
|
957
960
|
exec.native_account::set_item
|
|
958
961
|
# => [OLD_ROOT]
|
|
@@ -982,13 +985,13 @@ pub proc update_psm_public_key
|
|
|
982
985
|
# => [MAP_KEY, PUB_KEY]
|
|
983
986
|
# Note that MAP_KEY is [0, 0, 0, 0] for a single PSM_KEY
|
|
984
987
|
|
|
985
|
-
push.PSM_PUBLIC_KEY_MAP_SLOT
|
|
986
|
-
# => [
|
|
988
|
+
push.PSM_PUBLIC_KEY_MAP_SLOT[0..2]
|
|
989
|
+
# => [pub_key_slot_prefix, pub_key_slot_suffix, MAP_KEY, PUB_KEY]
|
|
987
990
|
|
|
988
991
|
exec.native_account::set_map_item
|
|
989
|
-
# => [
|
|
992
|
+
# => [OLD_MAP_VALUE]
|
|
990
993
|
|
|
991
|
-
dropw
|
|
994
|
+
dropw
|
|
992
995
|
# => []
|
|
993
996
|
end
|
|
994
997
|
|
|
@@ -1005,8 +1008,8 @@ end
|
|
|
1005
1008
|
#! - MSG is TX_SUMMARY_COMMITMENT provided by auth procedure
|
|
1006
1009
|
#! - If selector is OFF (0), PSM verification is skipped
|
|
1007
1010
|
#! - Selector value is read from initial storage state
|
|
1008
|
-
pub proc verify_psm_signature(msg: BeWord)
|
|
1009
|
-
push.PSM_SELECTOR_SLOT
|
|
1011
|
+
pub proc verify_psm_signature(msg: BeWord) -> BeWord
|
|
1012
|
+
push.PSM_SELECTOR_SLOT[0..2]
|
|
1010
1013
|
exec.active_account::get_item
|
|
1011
1014
|
drop drop drop
|
|
1012
1015
|
# => [selector, MSG]
|
|
@@ -1014,8 +1017,8 @@ pub proc verify_psm_signature(msg: BeWord)
|
|
|
1014
1017
|
push.1 eq
|
|
1015
1018
|
if.true
|
|
1016
1019
|
push.1
|
|
1017
|
-
push.PSM_PUBLIC_KEY_MAP_SLOT
|
|
1018
|
-
exec.::miden::auth::
|
|
1020
|
+
push.PSM_PUBLIC_KEY_MAP_SLOT[0..2]
|
|
1021
|
+
exec.::miden::standards::auth::falcon512_rpo::verify_signatures
|
|
1019
1022
|
push.1 neq
|
|
1020
1023
|
if.true
|
|
1021
1024
|
emit.AUTH_UNAUTHORIZED_EVENT
|
|
@@ -1028,5 +1031,5 @@ end
|
|
|
1028
1031
|
`;
|
|
1029
1032
|
export const PSM_ECDSA_MASM = PSM_MASM
|
|
1030
1033
|
.replaceAll('RPO Falcon 512', 'ECDSA secp256k1')
|
|
1031
|
-
.replace('exec.::miden::auth::
|
|
1034
|
+
.replace('exec.::miden::standards::auth::falcon512_rpo::verify_signatures', 'exec.::miden::standards::auth::ecdsa_k256_keccak::verify_signatures');
|
|
1032
1035
|
//# sourceMappingURL=masm.js.map
|
package/dist/account/masm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"masm.js","sourceRoot":"","sources":["../../src/account/masm.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"masm.js","sourceRoot":"","sources":["../../src/account/masm.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAya5B,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0alC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiLvB,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ;KACnC,UAAU,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;KAC/C,OAAO,CACN,iEAAiE,EACjE,qEAAqE,CACtE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MultisigConfig } from '../types.js';
|
|
2
|
-
import { StorageSlot } from '@
|
|
2
|
+
import { StorageSlot } from '@miden-sdk/miden-sdk';
|
|
3
3
|
export declare class StorageLayoutBuilder {
|
|
4
4
|
buildMultisigSlots(config: MultisigConfig): StorageSlot[];
|
|
5
5
|
buildPsmSlots(config: MultisigConfig): StorageSlot[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/account/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,WAAW,EAAoB,MAAM,
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/account/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,WAAW,EAAoB,MAAM,sBAAsB,CAAC;AAgBrE,qBAAa,oBAAoB;IAC/B,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,EAAE;IAqCzD,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,EAAE;CAarD;AAID,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,EAAE,CAE/E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,EAAE,CAE1E;AAED,eAAO,MAAM,oBAAoB,sBAAwB,CAAC"}
|
package/dist/account/storage.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import { StorageSlot, StorageMap, Word } from '@
|
|
1
|
+
import { StorageSlot, StorageMap, Word } from '@miden-sdk/miden-sdk';
|
|
2
2
|
import { normalizeHexWord } from '../utils/encoding.js';
|
|
3
3
|
import { getProcedureRoot } from '../procedures.js';
|
|
4
|
+
const MULTISIG_SLOT_NAMES = {
|
|
5
|
+
THRESHOLD_CONFIG: 'openzeppelin::multisig::threshold_config',
|
|
6
|
+
SIGNER_PUBLIC_KEYS: 'openzeppelin::multisig::signer_public_keys',
|
|
7
|
+
EXECUTED_TRANSACTIONS: 'openzeppelin::multisig::executed_transactions',
|
|
8
|
+
PROCEDURE_THRESHOLDS: 'openzeppelin::multisig::procedure_thresholds',
|
|
9
|
+
};
|
|
10
|
+
const PSM_SLOT_NAMES = {
|
|
11
|
+
SELECTOR: 'openzeppelin::psm::selector',
|
|
12
|
+
PUBLIC_KEY: 'openzeppelin::psm::public_key',
|
|
13
|
+
};
|
|
4
14
|
export class StorageLayoutBuilder {
|
|
5
15
|
buildMultisigSlots(config) {
|
|
6
16
|
const numSigners = config.signerCommitments.length;
|
|
@@ -10,15 +20,15 @@ export class StorageLayoutBuilder {
|
|
|
10
20
|
0n,
|
|
11
21
|
0n,
|
|
12
22
|
]));
|
|
13
|
-
const slot0 = StorageSlot.fromValue(slot0Word);
|
|
23
|
+
const slot0 = StorageSlot.fromValue(MULTISIG_SLOT_NAMES.THRESHOLD_CONFIG, slot0Word);
|
|
14
24
|
const signersMap = new StorageMap();
|
|
15
25
|
config.signerCommitments.forEach((commitment, index) => {
|
|
16
26
|
const key = new Word(new BigUint64Array([BigInt(index), 0n, 0n, 0n]));
|
|
17
27
|
const value = Word.fromHex(normalizeHexWord(commitment));
|
|
18
28
|
signersMap.insert(key, value);
|
|
19
29
|
});
|
|
20
|
-
const slot1 = StorageSlot.map(signersMap);
|
|
21
|
-
const slot2 = StorageSlot.map(new StorageMap());
|
|
30
|
+
const slot1 = StorageSlot.map(MULTISIG_SLOT_NAMES.SIGNER_PUBLIC_KEYS, signersMap);
|
|
31
|
+
const slot2 = StorageSlot.map(MULTISIG_SLOT_NAMES.EXECUTED_TRANSACTIONS, new StorageMap());
|
|
22
32
|
const procThresholdMap = new StorageMap();
|
|
23
33
|
if (config.procedureThresholds) {
|
|
24
34
|
const signatureScheme = config.signatureScheme ?? 'falcon';
|
|
@@ -29,18 +39,18 @@ export class StorageLayoutBuilder {
|
|
|
29
39
|
procThresholdMap.insert(key, value);
|
|
30
40
|
}
|
|
31
41
|
}
|
|
32
|
-
const slot3 = StorageSlot.map(procThresholdMap);
|
|
42
|
+
const slot3 = StorageSlot.map(MULTISIG_SLOT_NAMES.PROCEDURE_THRESHOLDS, procThresholdMap);
|
|
33
43
|
return [slot0, slot1, slot2, slot3];
|
|
34
44
|
}
|
|
35
45
|
buildPsmSlots(config) {
|
|
36
46
|
const selector = config.psmEnabled !== false ? 1n : 0n;
|
|
37
47
|
const selectorWord = new Word(new BigUint64Array([selector, 0n, 0n, 0n]));
|
|
38
|
-
const slot0 = StorageSlot.fromValue(selectorWord);
|
|
48
|
+
const slot0 = StorageSlot.fromValue(PSM_SLOT_NAMES.SELECTOR, selectorWord);
|
|
39
49
|
const psmKeyMap = new StorageMap();
|
|
40
50
|
const zeroKey = new Word(new BigUint64Array([0n, 0n, 0n, 0n]));
|
|
41
51
|
const psmKey = Word.fromHex(normalizeHexWord(config.psmCommitment));
|
|
42
52
|
psmKeyMap.insert(zeroKey, psmKey);
|
|
43
|
-
const slot1 = StorageSlot.map(psmKeyMap);
|
|
53
|
+
const slot1 = StorageSlot.map(PSM_SLOT_NAMES.PUBLIC_KEY, psmKeyMap);
|
|
44
54
|
return [slot0, slot1];
|
|
45
55
|
}
|
|
46
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/account/storage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/account/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type WebClient } from '@
|
|
1
|
+
import { type WebClient } from '@miden-sdk/miden-sdk';
|
|
2
2
|
import { PsmHttpClient, type SignatureScheme } from '@openzeppelin/psm-client';
|
|
3
3
|
import { Multisig } from './multisig.js';
|
|
4
4
|
import type { MultisigConfig, Signer } from './types.js';
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAsB,MAAM,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAsB,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,UAAU,CAAgB;gBAEtB,SAAS,EAAE,SAAS,EAAE,MAAM,GAAE,oBAAyB;IAKnE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIhC,UAAU,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAKrG,IAAI,SAAS,IAAI,aAAa,CAE7B;IAEK,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQjE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAsCjE"}
|
package/dist/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Account, AccountId } from '@
|
|
1
|
+
import { Account, AccountId } from '@miden-sdk/miden-sdk';
|
|
2
2
|
import { PsmHttpClient } from '@openzeppelin/psm-client';
|
|
3
3
|
import { Multisig } from './multisig.js';
|
|
4
4
|
import { createMultisigAccount } from './account/index.js';
|
|
@@ -52,7 +52,7 @@ export class MultisigClient {
|
|
|
52
52
|
if (!existingAccount) {
|
|
53
53
|
await this.webClient.newAccount(account, true);
|
|
54
54
|
}
|
|
55
|
-
return new Multisig(
|
|
55
|
+
return new Multisig(account, config, this._psmClient, signer, this.webClient, accountId);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,OAAO,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|