@openzeppelin/miden-multisig-client 0.13.1 → 0.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/README.md +98 -119
  2. package/dist/account/builder.d.ts +18 -0
  3. package/dist/account/builder.d.ts.map +1 -1
  4. package/dist/account/builder.js +59 -29
  5. package/dist/account/builder.js.map +1 -1
  6. package/dist/account/builder.test.js +108 -32
  7. package/dist/account/builder.test.js.map +1 -1
  8. package/dist/account/index.d.ts +1 -1
  9. package/dist/account/index.d.ts.map +1 -1
  10. package/dist/account/index.js +1 -1
  11. package/dist/account/index.js.map +1 -1
  12. package/dist/account/masm/account-components/auth.d.ts +5 -0
  13. package/dist/account/masm/account-components/auth.d.ts.map +1 -0
  14. package/dist/account/masm/account-components/auth.js +67 -0
  15. package/dist/account/masm/account-components/auth.js.map +1 -0
  16. package/dist/account/masm/auth.d.ts +5 -0
  17. package/dist/account/masm/auth.d.ts.map +1 -0
  18. package/dist/account/masm/auth.js +1395 -0
  19. package/dist/account/masm/auth.js.map +1 -0
  20. package/dist/account/masm/index.d.ts +3 -0
  21. package/dist/account/masm/index.d.ts.map +1 -0
  22. package/dist/account/masm/index.js +5 -0
  23. package/dist/account/masm/index.js.map +1 -0
  24. package/dist/account/masm.d.ts +1 -4
  25. package/dist/account/masm.d.ts.map +1 -1
  26. package/dist/account/masm.js +3 -1034
  27. package/dist/account/masm.js.map +1 -1
  28. package/dist/account/storage.d.ts +2 -2
  29. package/dist/account/storage.d.ts.map +1 -1
  30. package/dist/account/storage.js +18 -16
  31. package/dist/account/storage.js.map +1 -1
  32. package/dist/client.d.ts +67 -9
  33. package/dist/client.d.ts.map +1 -1
  34. package/dist/client.js +73 -22
  35. package/dist/client.js.map +1 -1
  36. package/dist/client.test.js +31 -32
  37. package/dist/client.test.js.map +1 -1
  38. package/dist/index.d.ts +54 -12
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +53 -9
  41. package/dist/index.js.map +1 -1
  42. package/dist/inspector.d.ts +32 -6
  43. package/dist/inspector.d.ts.map +1 -1
  44. package/dist/inspector.js +58 -23
  45. package/dist/inspector.js.map +1 -1
  46. package/dist/inspector.test.js +18 -18
  47. package/dist/inspector.test.js.map +1 -1
  48. package/dist/multisig/proposal/execution.d.ts +4 -4
  49. package/dist/multisig/proposal/execution.d.ts.map +1 -1
  50. package/dist/multisig/proposal/execution.js +42 -31
  51. package/dist/multisig/proposal/execution.js.map +1 -1
  52. package/dist/multisig/proposal/parser.d.ts +3 -3
  53. package/dist/multisig/proposal/parser.d.ts.map +1 -1
  54. package/dist/multisig/proposal/parser.js +23 -23
  55. package/dist/multisig/proposal/parser.js.map +1 -1
  56. package/dist/multisig/signing.d.ts +3 -3
  57. package/dist/multisig/signing.d.ts.map +1 -1
  58. package/dist/multisig/signing.js +3 -3
  59. package/dist/multisig/signing.js.map +1 -1
  60. package/dist/multisig.d.ts +188 -48
  61. package/dist/multisig.d.ts.map +1 -1
  62. package/dist/multisig.js +650 -308
  63. package/dist/multisig.js.map +1 -1
  64. package/dist/multisig.test.js +1680 -241
  65. package/dist/multisig.test.js.map +1 -1
  66. package/dist/procedures.d.ts +46 -24
  67. package/dist/procedures.d.ts.map +1 -1
  68. package/dist/procedures.js +46 -21
  69. package/dist/procedures.js.map +1 -1
  70. package/dist/proposal/factory.d.ts +18 -0
  71. package/dist/proposal/factory.d.ts.map +1 -0
  72. package/dist/proposal/factory.js +99 -0
  73. package/dist/proposal/factory.js.map +1 -0
  74. package/dist/proposal/metadata.d.ts +5 -12
  75. package/dist/proposal/metadata.d.ts.map +1 -1
  76. package/dist/proposal/metadata.js +118 -174
  77. package/dist/proposal/metadata.js.map +1 -1
  78. package/dist/proposal/signatures.d.ts +10 -0
  79. package/dist/proposal/signatures.d.ts.map +1 -0
  80. package/dist/proposal/signatures.js +54 -0
  81. package/dist/proposal/signatures.js.map +1 -0
  82. package/dist/signer.d.ts +2 -0
  83. package/dist/signer.d.ts.map +1 -1
  84. package/dist/signer.js +2 -0
  85. package/dist/signer.js.map +1 -1
  86. package/dist/signers/ecdsa.d.ts +3 -0
  87. package/dist/signers/ecdsa.d.ts.map +1 -1
  88. package/dist/signers/ecdsa.js +8 -4
  89. package/dist/signers/ecdsa.js.map +1 -1
  90. package/dist/signers/ecdsa.test.d.ts +2 -0
  91. package/dist/signers/ecdsa.test.d.ts.map +1 -0
  92. package/dist/signers/ecdsa.test.js +65 -0
  93. package/dist/signers/ecdsa.test.js.map +1 -0
  94. package/dist/signers/falcon.d.ts +3 -0
  95. package/dist/signers/falcon.d.ts.map +1 -1
  96. package/dist/signers/falcon.js +8 -4
  97. package/dist/signers/falcon.js.map +1 -1
  98. package/dist/signers/falcon.test.js +12 -0
  99. package/dist/signers/falcon.test.js.map +1 -1
  100. package/dist/signers/miden-wallet.d.ts +3 -1
  101. package/dist/signers/miden-wallet.d.ts.map +1 -1
  102. package/dist/signers/miden-wallet.js +11 -2
  103. package/dist/signers/miden-wallet.js.map +1 -1
  104. package/dist/signers/miden-wallet.test.js +26 -0
  105. package/dist/signers/miden-wallet.test.js.map +1 -1
  106. package/dist/signers/para.d.ts +3 -3
  107. package/dist/signers/para.d.ts.map +1 -1
  108. package/dist/signers/para.js +15 -6
  109. package/dist/signers/para.js.map +1 -1
  110. package/dist/signers/para.test.js +39 -0
  111. package/dist/signers/para.test.js.map +1 -1
  112. package/dist/transaction/consumeNotes.d.ts.map +1 -1
  113. package/dist/transaction/consumeNotes.js +1 -0
  114. package/dist/transaction/consumeNotes.js.map +1 -1
  115. package/dist/transaction/index.d.ts +2 -1
  116. package/dist/transaction/index.d.ts.map +1 -1
  117. package/dist/transaction/index.js +2 -1
  118. package/dist/transaction/index.js.map +1 -1
  119. package/dist/transaction/options.d.ts +1 -1
  120. package/dist/transaction/options.d.ts.map +1 -1
  121. package/dist/transaction/p2id.d.ts +1 -0
  122. package/dist/transaction/p2id.d.ts.map +1 -1
  123. package/dist/transaction/p2id.js +9 -3
  124. package/dist/transaction/p2id.js.map +1 -1
  125. package/dist/transaction/updateGuardian.d.ts +7 -0
  126. package/dist/transaction/updateGuardian.d.ts.map +1 -0
  127. package/dist/transaction/{updatePsm.js → updateGuardian.js} +15 -29
  128. package/dist/transaction/updateGuardian.js.map +1 -0
  129. package/dist/transaction/updateProcedureThreshold.d.ts +9 -0
  130. package/dist/transaction/updateProcedureThreshold.d.ts.map +1 -0
  131. package/dist/transaction/updateProcedureThreshold.js +55 -0
  132. package/dist/transaction/updateProcedureThreshold.js.map +1 -0
  133. package/dist/transaction/updateSigners.d.ts.map +1 -1
  134. package/dist/transaction/updateSigners.js +5 -23
  135. package/dist/transaction/updateSigners.js.map +1 -1
  136. package/dist/transaction.d.ts +2 -1
  137. package/dist/transaction.d.ts.map +1 -1
  138. package/dist/transaction.js +2 -1
  139. package/dist/transaction.js.map +1 -1
  140. package/dist/types/proposal.d.ts +32 -15
  141. package/dist/types/proposal.d.ts.map +1 -1
  142. package/dist/types.d.ts +24 -7
  143. package/dist/types.d.ts.map +1 -1
  144. package/dist/utils/digest.d.ts +5 -0
  145. package/dist/utils/digest.d.ts.map +1 -1
  146. package/dist/utils/digest.js +34 -1
  147. package/dist/utils/digest.js.map +1 -1
  148. package/dist/utils/digest.test.d.ts +2 -0
  149. package/dist/utils/digest.test.d.ts.map +1 -0
  150. package/dist/utils/digest.test.js +48 -0
  151. package/dist/utils/digest.test.js.map +1 -0
  152. package/dist/utils/signature.d.ts +3 -1
  153. package/dist/utils/signature.d.ts.map +1 -1
  154. package/dist/utils/signature.js +31 -6
  155. package/dist/utils/signature.js.map +1 -1
  156. package/dist/utils/word.test.js +1 -52
  157. package/dist/utils/word.test.js.map +1 -1
  158. package/masm/account_components/auth/multisig.masm +13 -0
  159. package/masm/account_components/auth/multisig_ecdsa.masm +13 -0
  160. package/masm/account_components/auth/multisig_guardian.masm +17 -0
  161. package/masm/account_components/auth/multisig_guardian_ecdsa.masm +17 -0
  162. package/masm/auth/guardian.masm +177 -0
  163. package/masm/auth/guardian_ecdsa.masm +178 -0
  164. package/masm/{multisig.masm → auth/multisig.masm} +149 -55
  165. package/masm/{multisig_ecdsa.masm → auth/multisig_ecdsa.masm} +148 -56
  166. package/package.json +11 -9
  167. package/src/account/builder.test.ts +165 -0
  168. package/src/account/builder.ts +71 -34
  169. package/src/account/index.ts +1 -1
  170. package/src/account/masm/account-components/auth.ts +70 -0
  171. package/src/account/masm/auth.ts +1398 -0
  172. package/src/account/masm/index.ts +5 -0
  173. package/src/account/masm.ts +3 -1040
  174. package/src/account/storage.ts +18 -16
  175. package/src/client.test.ts +31 -35
  176. package/src/client.ts +98 -26
  177. package/src/index.ts +84 -22
  178. package/src/inspector.test.ts +17 -17
  179. package/src/inspector.ts +63 -29
  180. package/src/multisig/proposal/execution.ts +66 -49
  181. package/src/multisig/proposal/parser.ts +26 -26
  182. package/src/multisig/signing.ts +4 -4
  183. package/src/multisig.test.ts +2097 -248
  184. package/src/multisig.ts +882 -388
  185. package/src/procedures.ts +50 -26
  186. package/src/proposal/factory.ts +171 -0
  187. package/src/proposal/metadata.ts +165 -0
  188. package/src/proposal/signatures.ts +68 -0
  189. package/src/signer.ts +2 -0
  190. package/src/signers/ecdsa.test.ts +80 -0
  191. package/src/signers/ecdsa.ts +15 -4
  192. package/src/signers/falcon.test.ts +19 -0
  193. package/src/signers/falcon.ts +16 -5
  194. package/src/signers/miden-wallet.test.ts +47 -0
  195. package/src/signers/miden-wallet.ts +18 -1
  196. package/src/signers/para.test.ts +57 -0
  197. package/src/signers/para.ts +26 -7
  198. package/src/transaction/consumeNotes.ts +1 -0
  199. package/src/transaction/index.ts +2 -2
  200. package/src/transaction/options.ts +1 -2
  201. package/src/transaction/p2id.test.ts +190 -0
  202. package/src/transaction/p2id.ts +11 -5
  203. package/src/transaction/rpoRandomCoin.test.ts +64 -0
  204. package/src/transaction/rpoRandomCoin.ts +24 -0
  205. package/src/transaction/{updatePsm.ts → updateGuardian.ts} +19 -32
  206. package/src/transaction/updateProcedureThreshold.ts +97 -0
  207. package/src/transaction/updateSigners.ts +12 -27
  208. package/src/transaction.ts +5 -3
  209. package/src/types/proposal.ts +43 -11
  210. package/src/types.ts +29 -11
  211. package/src/utils/digest.test.ts +55 -0
  212. package/src/utils/digest.ts +51 -1
  213. package/src/utils/signature.ts +47 -9
  214. package/src/utils/word.test.ts +1 -55
  215. package/dist/account.d.ts +0 -104
  216. package/dist/account.d.ts.map +0 -1
  217. package/dist/account.js +0 -136
  218. package/dist/account.js.map +0 -1
  219. package/dist/builder.d.ts +0 -54
  220. package/dist/builder.d.ts.map +0 -1
  221. package/dist/builder.js +0 -78
  222. package/dist/builder.js.map +0 -1
  223. package/dist/http.d.ts +0 -64
  224. package/dist/http.d.ts.map +0 -1
  225. package/dist/http.js +0 -162
  226. package/dist/http.js.map +0 -1
  227. package/dist/keystore.d.ts +0 -65
  228. package/dist/keystore.d.ts.map +0 -1
  229. package/dist/keystore.js +0 -121
  230. package/dist/keystore.js.map +0 -1
  231. package/dist/miden.d.ts +0 -9
  232. package/dist/miden.d.ts.map +0 -1
  233. package/dist/miden.js +0 -26
  234. package/dist/miden.js.map +0 -1
  235. package/dist/multisig/metadata.d.ts +0 -18
  236. package/dist/multisig/metadata.d.ts.map +0 -1
  237. package/dist/multisig/metadata.js +0 -100
  238. package/dist/multisig/metadata.js.map +0 -1
  239. package/dist/multisig/metadata.test.d.ts +0 -2
  240. package/dist/multisig/metadata.test.d.ts.map +0 -1
  241. package/dist/multisig/metadata.test.js +0 -323
  242. package/dist/multisig/metadata.test.js.map +0 -1
  243. package/dist/proposal/exported.d.ts +0 -12
  244. package/dist/proposal/exported.d.ts.map +0 -1
  245. package/dist/proposal/exported.js +0 -88
  246. package/dist/proposal/exported.js.map +0 -1
  247. package/dist/signer.test.d.ts +0 -2
  248. package/dist/signer.test.d.ts.map +0 -1
  249. package/dist/signer.test.js +0 -123
  250. package/dist/signer.test.js.map +0 -1
  251. package/dist/transaction/p2id.interop.test.d.ts +0 -2
  252. package/dist/transaction/p2id.interop.test.d.ts.map +0 -1
  253. package/dist/transaction/p2id.interop.test.js +0 -36
  254. package/dist/transaction/p2id.interop.test.js.map +0 -1
  255. package/dist/transaction/updatePsm.d.ts +0 -7
  256. package/dist/transaction/updatePsm.d.ts.map +0 -1
  257. package/dist/transaction/updatePsm.js.map +0 -1
  258. package/dist/transport/http.d.ts +0 -64
  259. package/dist/transport/http.d.ts.map +0 -1
  260. package/dist/transport/http.js +0 -162
  261. package/dist/transport/http.js.map +0 -1
  262. package/dist/transport/index.d.ts +0 -5
  263. package/dist/transport/index.d.ts.map +0 -1
  264. package/dist/transport/index.js +0 -5
  265. package/dist/transport/index.js.map +0 -1
  266. package/dist/utils/state-validation.d.ts +0 -5
  267. package/dist/utils/state-validation.d.ts.map +0 -1
  268. package/dist/utils/state-validation.js +0 -30
  269. package/dist/utils/state-validation.js.map +0 -1
  270. package/dist/utils/validation.d.ts +0 -6
  271. package/dist/utils/validation.d.ts.map +0 -1
  272. package/dist/utils/validation.js +0 -52
  273. package/dist/utils/validation.js.map +0 -1
  274. package/masm/psm.masm +0 -178
  275. package/masm/psm_ecdsa.masm +0 -179
@@ -1,8 +1,9 @@
1
1
  import type { MultisigConfig } from '../types.js';
2
2
  import { StorageSlot, StorageMap, Word } from '@miden-sdk/miden-sdk';
3
- import { normalizeHexWord } from '../utils/encoding.js';
3
+ import { ensureHexPrefix } from '../utils/encoding.js';
4
4
  import { getProcedureRoot } from '../procedures.js';
5
5
 
6
+ // Storage slot names matching the MASM definitions
6
7
  const MULTISIG_SLOT_NAMES = {
7
8
  THRESHOLD_CONFIG: 'openzeppelin::multisig::threshold_config',
8
9
  SIGNER_PUBLIC_KEYS: 'openzeppelin::multisig::signer_public_keys',
@@ -10,9 +11,9 @@ const MULTISIG_SLOT_NAMES = {
10
11
  PROCEDURE_THRESHOLDS: 'openzeppelin::multisig::procedure_thresholds',
11
12
  } as const;
12
13
 
13
- const PSM_SLOT_NAMES = {
14
- SELECTOR: 'openzeppelin::psm::selector',
15
- PUBLIC_KEY: 'openzeppelin::psm::public_key',
14
+ const GUARDIAN_SLOT_NAMES = {
15
+ SELECTOR: 'openzeppelin::guardian::selector',
16
+ PUBLIC_KEY: 'openzeppelin::guardian::public_key',
16
17
  } as const;
17
18
 
18
19
  export class StorageLayoutBuilder {
@@ -31,18 +32,19 @@ export class StorageLayoutBuilder {
31
32
  const signersMap = new StorageMap();
32
33
  config.signerCommitments.forEach((commitment, index) => {
33
34
  const key = new Word(new BigUint64Array([BigInt(index), 0n, 0n, 0n]));
34
- const value = Word.fromHex(normalizeHexWord(commitment));
35
+ const value = Word.fromHex(ensureHexPrefix(commitment));
35
36
  signersMap.insert(key, value);
36
37
  });
37
38
  const slot1 = StorageSlot.map(MULTISIG_SLOT_NAMES.SIGNER_PUBLIC_KEYS, signersMap);
38
39
 
39
40
  const slot2 = StorageSlot.map(MULTISIG_SLOT_NAMES.EXECUTED_TRANSACTIONS, new StorageMap());
40
41
 
42
+ // Map entries: PROC_ROOT => [proc_threshold, 0, 0, 0]
43
+ // Use SDK's Word.fromHex to match how account code procedure roots are represented
41
44
  const procThresholdMap = new StorageMap();
42
45
  if (config.procedureThresholds) {
43
- const signatureScheme = config.signatureScheme ?? 'falcon';
44
46
  for (const pt of config.procedureThresholds) {
45
- const rootHex = getProcedureRoot(pt.procedure, signatureScheme);
47
+ const rootHex = getProcedureRoot(pt.procedure);
46
48
  const key = Word.fromHex(rootHex);
47
49
  const value = new Word(new BigUint64Array([BigInt(pt.threshold), 0n, 0n, 0n]));
48
50
  procThresholdMap.insert(key, value);
@@ -53,16 +55,16 @@ export class StorageLayoutBuilder {
53
55
  return [slot0, slot1, slot2, slot3];
54
56
  }
55
57
 
56
- buildPsmSlots(config: MultisigConfig): StorageSlot[] {
57
- const selector = config.psmEnabled !== false ? 1n : 0n;
58
+ buildGuardianSlots(config: MultisigConfig): StorageSlot[] {
59
+ const selector = config.guardianEnabled !== false ? 1n : 0n;
58
60
  const selectorWord = new Word(new BigUint64Array([selector, 0n, 0n, 0n]));
59
- const slot0 = StorageSlot.fromValue(PSM_SLOT_NAMES.SELECTOR, selectorWord);
61
+ const slot0 = StorageSlot.fromValue(GUARDIAN_SLOT_NAMES.SELECTOR, selectorWord);
60
62
 
61
- const psmKeyMap = new StorageMap();
63
+ const guardianKeyMap = new StorageMap();
62
64
  const zeroKey = new Word(new BigUint64Array([0n, 0n, 0n, 0n]));
63
- const psmKey = Word.fromHex(normalizeHexWord(config.psmCommitment));
64
- psmKeyMap.insert(zeroKey, psmKey);
65
- const slot1 = StorageSlot.map(PSM_SLOT_NAMES.PUBLIC_KEY, psmKeyMap);
65
+ const guardianKey = Word.fromHex(ensureHexPrefix(config.guardianCommitment));
66
+ guardianKeyMap.insert(zeroKey, guardianKey);
67
+ const slot1 = StorageSlot.map(GUARDIAN_SLOT_NAMES.PUBLIC_KEY, guardianKeyMap);
66
68
 
67
69
  return [slot0, slot1];
68
70
  }
@@ -74,8 +76,8 @@ export function buildMultisigStorageSlots(config: MultisigConfig): StorageSlot[]
74
76
  return defaultStorageBuilder.buildMultisigSlots(config);
75
77
  }
76
78
 
77
- export function buildPsmStorageSlots(config: MultisigConfig): StorageSlot[] {
78
- return defaultStorageBuilder.buildPsmSlots(config);
79
+ export function buildGuardianStorageSlots(config: MultisigConfig): StorageSlot[] {
80
+ return defaultStorageBuilder.buildGuardianSlots(config);
79
81
  }
80
82
 
81
83
  export const storageLayoutBuilder = defaultStorageBuilder;
@@ -14,6 +14,7 @@ vi.mock('@miden-sdk/miden-sdk', () => ({
14
14
  prefix: () => ({ asInt: () => BigInt(1) }),
15
15
  suffix: () => ({ asInt: () => BigInt(2) }),
16
16
  }),
17
+ serialize: () => new Uint8Array([1, 2, 3]),
17
18
  storage: vi.fn(),
18
19
  vault: vi.fn(),
19
20
  })),
@@ -27,8 +28,8 @@ vi.mock('./inspector.js', () => ({
27
28
  threshold: 2,
28
29
  numSigners: 2,
29
30
  signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
30
- psmEnabled: true,
31
- psmCommitment: '0x' + 'c'.repeat(64),
31
+ guardianEnabled: true,
32
+ guardianCommitment: '0x' + 'c'.repeat(64),
32
33
  vaultBalances: [],
33
34
  procedureThresholds: new Map(),
34
35
  })),
@@ -50,7 +51,7 @@ vi.mock('./account/index.js', () => ({
50
51
  }),
51
52
  }));
52
53
 
53
- // Mock fetch for PSM client
54
+ // Mock fetch for GUARDIAN client
54
55
  const mockFetch = vi.fn();
55
56
  vi.stubGlobal('fetch', mockFetch);
56
57
 
@@ -73,30 +74,31 @@ describe('MultisigClient', () => {
73
74
  };
74
75
 
75
76
  mockSigner = {
76
- scheme: 'falcon',
77
77
  commitment: '0x' + '1'.repeat(64),
78
78
  publicKey: '0x' + '2'.repeat(64),
79
+ scheme: 'falcon',
79
80
  signAccountIdWithTimestamp: vi.fn().mockResolvedValue('0x' + 'a'.repeat(128)),
80
- signCommitment: vi.fn().mockResolvedValue('0x' + 'b'.repeat(128)),
81
+ signRequest: vi.fn().mockReturnValue('0x' + 'a'.repeat(128)),
82
+ signCommitment: vi.fn().mockReturnValue('0x' + 'b'.repeat(128)),
81
83
  };
82
84
  });
83
85
 
84
86
  describe('constructor', () => {
85
- it('should create client with default PSM endpoint', () => {
87
+ it('should create client with default GUARDIAN endpoint', () => {
86
88
  const client = new MultisigClient(webClient);
87
89
  expect(client).toBeInstanceOf(MultisigClient);
88
90
  });
89
91
 
90
- it('should create client with custom PSM endpoint', () => {
91
- const client = new MultisigClient(webClient, { psmEndpoint: 'http://custom:8080' });
92
+ it('should create client with custom GUARDIAN endpoint', () => {
93
+ const client = new MultisigClient(webClient, { guardianEndpoint: 'http://custom:8080' });
92
94
  expect(client).toBeInstanceOf(MultisigClient);
93
95
  });
94
96
  });
95
97
 
96
- describe('psmClient getter', () => {
97
- it('should expose PSM client for getting pubkey', () => {
98
+ describe('guardianClient getter', () => {
99
+ it('should expose GUARDIAN client for getting pubkey', () => {
98
100
  const client = new MultisigClient(webClient);
99
- expect(client.psmClient).toBeDefined();
101
+ expect(client.guardianClient).toBeDefined();
100
102
  });
101
103
  });
102
104
 
@@ -107,7 +109,7 @@ describe('MultisigClient', () => {
107
109
  const config = {
108
110
  threshold: 2,
109
111
  signerCommitments: ['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)],
110
- psmCommitment: '0x' + 'c'.repeat(64),
112
+ guardianCommitment: '0x' + 'c'.repeat(64),
111
113
  };
112
114
 
113
115
  const multisig = await client.create(config, mockSigner);
@@ -115,16 +117,16 @@ describe('MultisigClient', () => {
115
117
  expect(multisig).toBeDefined();
116
118
  expect(multisig.threshold).toBe(2);
117
119
  expect(multisig.signerCommitments).toEqual(config.signerCommitments);
118
- expect(multisig.psmCommitment).toBe(config.psmCommitment);
120
+ expect(multisig.guardianCommitment).toBe(config.guardianCommitment);
119
121
  });
120
122
 
121
- it('should set signer on PSM client', async () => {
123
+ it('should set signer on GUARDIAN client', async () => {
122
124
  const client = new MultisigClient(webClient);
123
125
 
124
126
  const config = {
125
127
  threshold: 1,
126
128
  signerCommitments: ['0x' + 'a'.repeat(64)],
127
- psmCommitment: '0x' + 'c'.repeat(64),
129
+ guardianCommitment: '0x' + 'c'.repeat(64),
128
130
  };
129
131
 
130
132
  const multisig = await client.create(config, mockSigner);
@@ -156,11 +158,11 @@ describe('MultisigClient', () => {
156
158
  // Config is detected from account storage via AccountInspector
157
159
  expect(multisig.threshold).toBe(2);
158
160
  expect(multisig.signerCommitments).toEqual(['0x' + 'a'.repeat(64), '0x' + 'b'.repeat(64)]);
159
- expect(multisig.psmCommitment).toBe('0x' + 'c'.repeat(64));
161
+ expect(multisig.guardianCommitment).toBe('0x' + 'c'.repeat(64));
160
162
  expect(multisig.account).not.toBeNull();
161
163
  });
162
164
 
163
- it('should throw if account not found on PSM', async () => {
165
+ it('should throw if account not found on GUARDIAN', async () => {
164
166
  const client = new MultisigClient(webClient);
165
167
 
166
168
  mockFetch.mockResolvedValueOnce({
@@ -174,40 +176,34 @@ describe('MultisigClient', () => {
174
176
  client.load('0xnonexistent', mockSigner)
175
177
  ).rejects.toThrow();
176
178
  });
177
- });
178
179
 
179
- describe('initialize', () => {
180
- it('should fetch PSM pubkey and return commitment', async () => {
180
+ it('should allow registerOnGuardian after load without explicit initial state', async () => {
181
181
  const client = new MultisigClient(webClient);
182
182
 
183
183
  mockFetch.mockResolvedValueOnce({
184
184
  ok: true,
185
185
  json: async () => ({
186
- commitment: '0x' + 'f'.repeat(64),
187
- pubkey: '0x' + 'e'.repeat(64),
186
+ account_id: '0x' + 'd'.repeat(30),
187
+ commitment: '0x' + 'e'.repeat(64),
188
+ state_json: { data: 'base64state' },
189
+ created_at: '2024-01-01T00:00:00Z',
190
+ updated_at: '2024-01-02T00:00:00Z',
188
191
  }),
189
192
  });
190
193
 
191
- const result = await client.initialize('falcon');
192
-
193
- expect(result.psmCommitment).toBe('0x' + 'f'.repeat(64));
194
- expect(result.psmPublicKey).toBe('0x' + 'e'.repeat(64));
195
- });
196
-
197
- it('should work without specifying scheme', async () => {
198
- const client = new MultisigClient(webClient);
199
-
200
194
  mockFetch.mockResolvedValueOnce({
201
195
  ok: true,
202
196
  json: async () => ({
203
- commitment: '0x' + 'f'.repeat(64),
197
+ success: true,
198
+ message: 'Account configured',
199
+ ack_pubkey: '0x' + 'f'.repeat(64),
204
200
  }),
205
201
  });
206
202
 
207
- const result = await client.initialize();
203
+ const accountId = '0x' + 'd'.repeat(30);
204
+ const multisig = await client.load(accountId, mockSigner);
208
205
 
209
- expect(result.psmCommitment).toBe('0x' + 'f'.repeat(64));
210
- expect(result.psmPublicKey).toBeUndefined();
206
+ await expect(multisig.registerOnGuardian()).resolves.toBeUndefined();
211
207
  });
212
208
  });
213
209
  });
package/src/client.ts CHANGED
@@ -1,52 +1,119 @@
1
+ /**
2
+ * MultisigClient - Factory for creating and loading multisig accounts.
3
+ *
4
+ * This is the main entry point for the multisig SDK. It provides methods
5
+ * to create new multisig accounts and load existing ones.
6
+ */
7
+
1
8
  import { type WebClient, Account, AccountId } from '@miden-sdk/miden-sdk';
2
- import { PsmHttpClient, type SignatureScheme } from '@openzeppelin/psm-client';
9
+ import { GuardianHttpClient } from '@openzeppelin/guardian-client';
3
10
  import { Multisig } from './multisig.js';
4
11
  import { createMultisigAccount } from './account/index.js';
5
12
  import { AccountInspector } from './inspector.js';
6
13
  import type { MultisigConfig, Signer } from './types.js';
7
14
 
15
+ /**
16
+ * Configuration for MultisigClient.
17
+ */
8
18
  export interface MultisigClientConfig {
9
- psmEndpoint?: string;
19
+ /** GUARDIAN server endpoint */
20
+ guardianEndpoint?: string;
21
+ /** Miden node RPC endpoint used for state commitment verification */
22
+ midenRpcEndpoint?: string;
10
23
  }
11
24
 
25
+ /**
26
+ * Client for creating and loading multisig accounts.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import { MultisigClient, FalconSigner } from '@openzeppelin/miden-multisig-client';
31
+ * import { WebClient, SecretKey } from '@miden-sdk/miden-sdk';
32
+ *
33
+ * // Initialize
34
+ * const webClient = await WebClient.createClient('https://rpc.testnet.miden.io:443');
35
+ * const secretKey = SecretKey.rpoFalconWithRNG(seed);
36
+ * const signer = new FalconSigner(secretKey);
37
+ *
38
+ * // Create client
39
+ * const client = new MultisigClient(webClient, {
40
+ * guardianEndpoint: 'http://localhost:3000',
41
+ * midenRpcEndpoint: 'https://rpc.testnet.miden.io:443',
42
+ * });
43
+ *
44
+ * // Get GUARDIAN pubkey for config
45
+ * const guardianCommitment = await client.guardianClient.getPubkey();
46
+ *
47
+ * // Create multisig
48
+ * const config = { threshold: 2, signerCommitments: [...], guardianCommitment };
49
+ * const multisig = await client.create(config, signer);
50
+ * ```
51
+ */
12
52
  export class MultisigClient {
13
53
  private readonly webClient: WebClient;
14
- private _psmClient: PsmHttpClient;
54
+ private readonly midenRpcEndpoint?: string;
55
+ private _guardianClient: GuardianHttpClient;
15
56
 
16
57
  constructor(webClient: WebClient, config: MultisigClientConfig = {}) {
17
58
  this.webClient = webClient;
18
- this._psmClient = new PsmHttpClient(config.psmEndpoint ?? 'http://localhost:3000');
19
- }
20
-
21
- setPsmEndpoint(endpoint: string): void {
22
- this._psmClient = new PsmHttpClient(endpoint);
59
+ this.midenRpcEndpoint = config.midenRpcEndpoint;
60
+ this._guardianClient = new GuardianHttpClient(config.guardianEndpoint ?? 'http://localhost:3000');
23
61
  }
24
62
 
25
- async initialize(scheme?: SignatureScheme): Promise<{ psmCommitment: string; psmPublicKey?: string }> {
26
- const { commitment, pubkey } = await this._psmClient.getPubkey(scheme);
27
- return { psmCommitment: commitment, psmPublicKey: pubkey };
63
+ /**
64
+ * Change the GUARDIAN endpoint.
65
+ *
66
+ * @param endpoint - The new GUARDIAN server endpoint URL
67
+ */
68
+ setGuardianEndpoint(endpoint: string): void {
69
+ this._guardianClient = new GuardianHttpClient(endpoint);
28
70
  }
29
71
 
30
- get psmClient(): PsmHttpClient {
31
- return this._psmClient;
72
+ /**
73
+ * Access the internal GUARDIAN client.
74
+ */
75
+ get guardianClient(): GuardianHttpClient {
76
+ return this._guardianClient;
32
77
  }
33
78
 
79
+ /**
80
+ * Create a new multisig account.
81
+ *
82
+ * @param config - Multisig configuration (threshold, signers, GUARDIAN commitment)
83
+ * @param signer - The signer for this client (one of the cosigners)
84
+ * @returns A Multisig instance wrapping the created account
85
+ */
34
86
  async create(config: MultisigConfig, signer: Signer): Promise<Multisig> {
35
- this._psmClient.setSigner(signer);
87
+ this._guardianClient.setSigner(signer);
36
88
 
37
89
  const { account } = await createMultisigAccount(this.webClient, config);
38
90
 
39
- return new Multisig(account, config, this._psmClient, signer, this.webClient);
91
+ return new Multisig(
92
+ account,
93
+ config,
94
+ this._guardianClient,
95
+ signer,
96
+ this.webClient,
97
+ undefined,
98
+ this.midenRpcEndpoint
99
+ );
40
100
  }
41
101
 
102
+ /**
103
+ * Load an existing multisig account from GUARDIAN.
104
+ *
105
+ * @param accountId - The account ID to load
106
+ * @param signer - The signer for this client
107
+ * @returns A Multisig instance for the loaded account
108
+ */
42
109
  async load(accountId: string, signer: Signer): Promise<Multisig> {
43
- this._psmClient.setSigner(signer);
110
+ this._guardianClient.setSigner(signer);
44
111
 
45
- const stateResponse = await this._psmClient.getState(accountId);
112
+ const stateResponse = await this._guardianClient.getState(accountId);
46
113
 
47
114
  const accountBase64 = stateResponse.stateJson.data;
48
115
  if (!accountBase64) {
49
- throw new Error('No account data found in PSM state');
116
+ throw new Error('No account data found in GUARDIAN state');
50
117
  }
51
118
 
52
119
  const binaryString = atob(accountBase64);
@@ -56,15 +123,12 @@ export class MultisigClient {
56
123
  }
57
124
  const account = Account.deserialize(accountBytes);
58
125
 
59
- const detectedScheme: SignatureScheme = signer.scheme;
60
-
61
- const detected = AccountInspector.fromAccount(account, detectedScheme);
126
+ const detected = AccountInspector.fromAccount(account);
62
127
  const config: MultisigConfig = {
63
128
  threshold: detected.threshold,
64
129
  signerCommitments: detected.signerCommitments,
65
- psmCommitment: detected.psmCommitment ?? '',
66
- psmEnabled: detected.psmEnabled,
67
- signatureScheme: detected.signatureScheme,
130
+ guardianCommitment: detected.guardianCommitment ?? '',
131
+ guardianEnabled: detected.guardianEnabled,
68
132
  procedureThresholds: Array.from(detected.procedureThresholds.entries()).map(
69
133
  ([procedure, threshold]) => ({ procedure, threshold })
70
134
  ),
@@ -72,9 +136,17 @@ export class MultisigClient {
72
136
 
73
137
  const existingAccount = await this.webClient.getAccount(AccountId.fromHex(accountId));
74
138
  if (!existingAccount) {
75
- await this.webClient.newAccount(account, true);
139
+ await this.webClient.newAccount(account, true);
76
140
  }
77
141
 
78
- return new Multisig(account, config, this._psmClient, signer, this.webClient, accountId);
142
+ return new Multisig(
143
+ account,
144
+ config,
145
+ this._guardianClient,
146
+ signer,
147
+ this.webClient,
148
+ accountId,
149
+ this.midenRpcEndpoint
150
+ );
79
151
  }
80
152
  }
package/src/index.ts CHANGED
@@ -1,38 +1,87 @@
1
+ /**
2
+ * @openzeppelin/miden-multisig-client
3
+ *
4
+ * TypeScript SDK for Miden multisig accounts with Guardian integration.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import {
9
+ * MultisigClient,
10
+ * FalconSigner,
11
+ * } from '@openzeppelin/miden-multisig-client';
12
+ * import { WebClient, SecretKey } from '@miden-sdk/miden-sdk';
13
+ *
14
+ * // Initialize WebClient
15
+ * const webClient = await WebClient.createClient('https://rpc.testnet.miden.io:443');
16
+ * await webClient.syncState();
17
+ *
18
+ * // Generate a key dynamically
19
+ * const seed = new Uint8Array(32);
20
+ * crypto.getRandomValues(seed);
21
+ * const secretKey = SecretKey.rpoFalconWithRNG(seed);
22
+ *
23
+ * // Store in miden-sdk's keystore
24
+ * await webClient.addAccountSecretKeyToWebStore(secretKey);
25
+ *
26
+ * // Create a signer
27
+ * const signer = new FalconSigner(secretKey);
28
+ *
29
+ * // Create multisig client
30
+ * const client = new MultisigClient(webClient, {
31
+ * guardianEndpoint: 'http://localhost:3000',
32
+ * midenRpcEndpoint: 'https://rpc.testnet.miden.io:443',
33
+ * });
34
+ *
35
+ * // Get GUARDIAN pubkey for config
36
+ * const guardianCommitment = await client.guardianClient.getPubkey();
37
+ *
38
+ * // Create multisig account
39
+ * const config = { threshold: 2, signerCommitments: [signer.commitment, ...], guardianCommitment };
40
+ * const multisig = await client.create(config, signer);
41
+ *
42
+ * // Register on GUARDIAN and work with proposals
43
+ * await multisig.registerOnGuardian();
44
+ * await multisig.syncProposals();
45
+ * ```
46
+ */
47
+
1
48
  export { MultisigClient, type MultisigClientConfig } from './client.js';
2
49
  export { Multisig, type AccountState } from './multisig.js';
3
50
  export { AccountInspector, type DetectedMultisigConfig, type VaultBalance } from './inspector.js';
4
51
  export {
5
52
  executeForSummary,
6
53
  buildUpdateSignersTransactionRequest,
7
- buildUpdatePsmTransactionRequest,
54
+ buildUpdateProcedureThresholdTransactionRequest,
55
+ buildUpdateGuardianTransactionRequest,
8
56
  buildConsumeNotesTransactionRequest,
9
57
  buildP2idTransactionRequest,
10
58
  } from './transaction.js';
11
59
 
12
- export { PsmHttpClient, PsmHttpError } from '@openzeppelin/psm-client';
60
+ export { GuardianHttpClient, GuardianHttpError } from '@openzeppelin/guardian-client';
13
61
 
14
- export { FalconSigner, EcdsaSigner, ParaSigner, MidenWalletSigner } from './signers/index.js';
15
- export type { ParaSigningContext } from './signers/para.js';
16
- export type { WalletSigningContext } from './signers/miden-wallet.js';
17
- export { AuthDigest } from './utils/digest.js';
18
- export { EcdsaFormat } from './utils/ecdsa.js';
62
+ export {
63
+ FalconSigner,
64
+ EcdsaSigner,
65
+ ParaSigner,
66
+ MidenWalletSigner,
67
+ type ParaSigningContext,
68
+ type WalletSigningContext,
69
+ } from './signer.js';
19
70
  export { PublicKeyFormat } from './utils/key.js';
20
- export { wordToBytes } from './utils/word.js';
21
- export { tryComputeEcdsaCommitmentHex, tryComputeCommitmentHex } from './utils/signature.js';
71
+ export { EcdsaFormat } from './utils/ecdsa.js';
72
+ export { tryComputeEcdsaCommitmentHex } from './utils/signature.js';
22
73
 
23
74
  export {
24
75
  createMultisigAccount,
25
76
  validateMultisigConfig,
26
77
  buildMultisigStorageSlots,
27
- buildPsmStorageSlots,
78
+ buildGuardianStorageSlots,
28
79
  storageLayoutBuilder,
29
80
  StorageLayoutBuilder,
30
81
  } from './account/index.js';
31
82
 
32
83
  export {
33
84
  PROCEDURE_ROOTS,
34
- PROCEDURE_ROOTS_FALCON,
35
- PROCEDURE_ROOTS_ECDSA,
36
85
  getProcedureRoot,
37
86
  isProcedureName,
38
87
  getProcedureNames,
@@ -40,32 +89,45 @@ export {
40
89
  } from './procedures.js';
41
90
 
42
91
  export type {
92
+ // Account types
43
93
  MultisigAccountState,
44
94
  MultisigConfig,
45
95
  CreateAccountResult,
46
96
  ProcedureThreshold,
47
- TransactionProposal,
48
- TransactionProposalStatus,
49
- TransactionProposalSignature,
50
- ExportedTransactionProposal,
51
- SignTransactionProposalParams,
52
- SyncResult,
53
- TransactionProposalResult,
97
+
98
+ // Proposal types
99
+ Proposal,
100
+ ProposalStatus,
101
+ ProposalSignatureEntry,
54
102
  ProposalMetadata,
55
103
  ProposalType,
104
+ ExportedProposal,
105
+ ExportedTransactionProposal,
106
+ SignTransactionProposalParams,
107
+ TransactionProposal,
108
+ TransactionProposalSignature,
109
+ TransactionProposalStatus,
110
+
111
+ // Transaction types
56
112
  TransactionType,
113
+
114
+ // Note types
57
115
  ConsumableNote,
58
116
  NoteAsset,
117
+
118
+ // Signature types
59
119
  FalconSignature,
60
- EcdsaSignature,
61
- ProposalSignature,
62
- SignatureScheme,
63
120
  Signer,
121
+ SignatureScheme,
122
+
123
+ // GUARDIAN API types
64
124
  AuthConfig,
65
125
  DeltaObject,
66
126
  DeltaStatus,
67
127
  StateObject,
68
128
  CosignerSignature,
129
+
130
+ // Request/Response types
69
131
  ConfigureRequest,
70
132
  ConfigureResponse,
71
133
  DeltaProposalRequest,
@@ -9,9 +9,9 @@ const MULTISIG_SLOT_NAMES = {
9
9
  PROCEDURE_THRESHOLDS: 'openzeppelin::multisig::procedure_thresholds',
10
10
  } as const;
11
11
 
12
- const PSM_SLOT_NAMES = {
13
- SELECTOR: 'openzeppelin::psm::selector',
14
- PUBLIC_KEY: 'openzeppelin::psm::public_key',
12
+ const GUARDIAN_SLOT_NAMES = {
13
+ SELECTOR: 'openzeppelin::guardian::selector',
14
+ PUBLIC_KEY: 'openzeppelin::guardian::public_key',
15
15
  } as const;
16
16
 
17
17
  // Mock the Miden SDK
@@ -44,25 +44,25 @@ vi.mock('@miden-sdk/miden-sdk', () => {
44
44
  Account: {
45
45
  deserialize: vi.fn((bytes: Uint8Array) => {
46
46
  // Return different mocked accounts based on test scenario
47
- // Default: 2-of-3 multisig with PSM enabled
47
+ // Default: 2-of-3 multisig with GUARDIAN enabled
48
48
  const slot0 = createMockWord([2n, 3n, 0n, 0n]); // threshold=2, numSigners=3
49
- const slot4 = createMockWord([1n, 0n, 0n, 0n]); // PSM enabled
49
+ const slot4 = createMockWord([1n, 0n, 0n, 0n]); // GUARDIAN enabled
50
50
 
51
51
  const signerMap = new Map<string, any>();
52
52
  signerMap.set('0', createMockWord([BigInt('0x1111111111111111'), BigInt('0x2222222222222222'), BigInt('0x3333333333333333'), BigInt('0x4444444444444444')]));
53
53
  signerMap.set('1', createMockWord([BigInt('0x5555555555555555'), BigInt('0x6666666666666666'), BigInt('0x7777777777777777'), BigInt('0x8888888888888888')]));
54
54
  signerMap.set('2', createMockWord([BigInt('0xaaaaaaaaaaaaaaaa'), BigInt('0xbbbbbbbbbbbbbbbb'), BigInt('0xcccccccccccccccc'), BigInt('0xdddddddddddddddd')]));
55
55
 
56
- const psmMap = new Map<string, any>();
57
- psmMap.set('0', createMockWord([BigInt('0xeeeeeeeeeeeeeeee'), BigInt('0xffffffffffffffff'), BigInt('0x0000000000000001'), BigInt('0x0000000000000002')]));
56
+ const guardianMap = new Map<string, any>();
57
+ guardianMap.set('0', createMockWord([BigInt('0xeeeeeeeeeeeeeeee'), BigInt('0xffffffffffffffff'), BigInt('0x0000000000000001'), BigInt('0x0000000000000002')]));
58
58
 
59
59
  const slots = new Map<string, any>();
60
60
  slots.set('openzeppelin::multisig::threshold_config', slot0);
61
- slots.set('openzeppelin::psm::selector', slot4);
61
+ slots.set('openzeppelin::guardian::selector', slot4);
62
62
 
63
63
  const maps = new Map<string, Map<string, any>>();
64
64
  maps.set('openzeppelin::multisig::signer_public_keys', signerMap);
65
- maps.set('openzeppelin::psm::public_key', psmMap);
65
+ maps.set('openzeppelin::guardian::public_key', guardianMap);
66
66
 
67
67
  return {
68
68
  storage: () => createMockStorage(slots, maps),
@@ -94,12 +94,12 @@ describe('AccountInspector', () => {
94
94
  expect(config.numSigners).toBe(3);
95
95
  });
96
96
 
97
- it('extracts PSM status', () => {
97
+ it('extracts GUARDIAN status', () => {
98
98
  const base64 = btoa(String.fromCharCode(...new Uint8Array([1, 2, 3])));
99
99
  const config = AccountInspector.fromBase64(base64);
100
100
 
101
- expect(config.psmEnabled).toBe(true);
102
- expect(config.psmCommitment).toMatch(/^0x[a-f0-9]+$/);
101
+ expect(config.guardianEnabled).toBe(true);
102
+ expect(config.guardianCommitment).toMatch(/^0x[a-f0-9]+$/);
103
103
  });
104
104
 
105
105
  it('extracts signer commitments', () => {
@@ -146,7 +146,7 @@ describe('AccountInspector edge cases', () => {
146
146
  vi.clearAllMocks();
147
147
  });
148
148
 
149
- it('handles account with PSM disabled', async () => {
149
+ it('handles account with GUARDIAN disabled', async () => {
150
150
  const { Account } = await import('@miden-sdk/miden-sdk');
151
151
 
152
152
  // Override mock for this test
@@ -154,7 +154,7 @@ describe('AccountInspector edge cases', () => {
154
154
  storage: () => ({
155
155
  getItem: (slotName: string) => {
156
156
  if (slotName === 'openzeppelin::multisig::threshold_config') return { toU64s: () => [1n, 1n, 0n, 0n] };
157
- if (slotName === 'openzeppelin::psm::selector') return { toU64s: () => [0n, 0n, 0n, 0n] }; // PSM disabled
157
+ if (slotName === 'openzeppelin::guardian::selector') return { toU64s: () => [0n, 0n, 0n, 0n] }; // GUARDIAN disabled
158
158
  return { toU64s: () => [0n, 0n, 0n, 0n] };
159
159
  },
160
160
  getMapItem: (slotName: string, key: any) => {
@@ -175,8 +175,8 @@ describe('AccountInspector edge cases', () => {
175
175
  const account = Account.deserialize(new Uint8Array([1, 2, 3]));
176
176
  const config = AccountInspector.fromAccount(account);
177
177
 
178
- expect(config.psmEnabled).toBe(false);
179
- expect(config.psmCommitment).toBeNull();
178
+ expect(config.guardianEnabled).toBe(false);
179
+ expect(config.guardianCommitment).toBeNull();
180
180
  });
181
181
 
182
182
  it('handles account with empty vault', async () => {
@@ -207,7 +207,7 @@ describe('AccountInspector edge cases', () => {
207
207
  storage: () => ({
208
208
  getItem: (slotName: string) => {
209
209
  if (slotName === 'openzeppelin::multisig::threshold_config') return { toU64s: () => [2n, 5n, 0n, 0n] }; // threshold=2, numSigners=5
210
- if (slotName === 'openzeppelin::psm::selector') return { toU64s: () => [0n, 0n, 0n, 0n] };
210
+ if (slotName === 'openzeppelin::guardian::selector') return { toU64s: () => [0n, 0n, 0n, 0n] };
211
211
  return { toU64s: () => [0n, 0n, 0n, 0n] };
212
212
  },
213
213
  getMapItem: () => {