@miden-sdk/react 0.13.0 → 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/dist/index.mjs CHANGED
@@ -36,7 +36,7 @@ var useMidenStore = create()((set) => ({
36
36
  ...initialState,
37
37
  setClient: (client) => set({
38
38
  client,
39
- isReady: true,
39
+ isReady: client !== null,
40
40
  isInitializing: false,
41
41
  initError: null
42
42
  }),
@@ -199,12 +199,13 @@ var toBech32AccountId = (accountId) => {
199
199
 
200
200
  // src/context/MidenProvider.tsx
201
201
  import {
202
- createContext,
203
- useContext,
202
+ createContext as createContext2,
203
+ useContext as useContext2,
204
204
  useEffect,
205
205
  useRef,
206
206
  useCallback,
207
- useMemo
207
+ useMemo,
208
+ useState
208
209
  } from "react";
209
210
  import { WebClient } from "@miden-sdk/miden-sdk";
210
211
 
@@ -311,9 +312,72 @@ function normalizeTimeout(timeoutMs) {
311
312
  return typeof timeoutMs === "bigint" ? timeoutMs : BigInt(timeoutMs);
312
313
  }
313
314
 
315
+ // src/context/SignerContext.ts
316
+ import { createContext, useContext } from "react";
317
+ var SignerContext = createContext(null);
318
+ function useSigner() {
319
+ return useContext(SignerContext);
320
+ }
321
+
322
+ // src/utils/signerAccount.ts
323
+ async function getAccountType(accountType) {
324
+ const { AccountType } = await import("@miden-sdk/miden-sdk");
325
+ switch (accountType) {
326
+ case "RegularAccountImmutableCode":
327
+ return AccountType.RegularAccountImmutableCode;
328
+ case "RegularAccountUpdatableCode":
329
+ return AccountType.RegularAccountUpdatableCode;
330
+ case "FungibleFaucet":
331
+ return AccountType.FungibleFaucet;
332
+ case "NonFungibleFaucet":
333
+ return AccountType.NonFungibleFaucet;
334
+ default:
335
+ return AccountType.RegularAccountImmutableCode;
336
+ }
337
+ }
338
+ function isPrivateStorageMode(storageMode) {
339
+ return storageMode.toString() === "private";
340
+ }
341
+ async function initializeSignerAccount(client, config) {
342
+ const { AccountBuilder, AccountComponent, Word } = await import("@miden-sdk/miden-sdk");
343
+ await client.syncState();
344
+ const commitmentWord = Word.deserialize(config.publicKeyCommitment);
345
+ const seed = config.accountSeed ?? crypto.getRandomValues(new Uint8Array(32));
346
+ const accountType = await getAccountType(config.accountType);
347
+ const builder = new AccountBuilder(seed);
348
+ const buildResult = builder.withAuthComponent(
349
+ AccountComponent.createAuthComponentFromCommitment(
350
+ commitmentWord,
351
+ 1
352
+ // ECDSA auth scheme (K256/Keccak)
353
+ )
354
+ ).accountType(accountType).storageMode(config.storageMode).withBasicWalletComponent().build();
355
+ const account = buildResult.account;
356
+ const accountId = account.id();
357
+ if (!isPrivateStorageMode(config.storageMode)) {
358
+ try {
359
+ await client.importAccountById(accountId);
360
+ await client.syncState();
361
+ return accountId.toString();
362
+ } catch {
363
+ }
364
+ }
365
+ try {
366
+ const existing = await client.getAccount(accountId);
367
+ if (existing) {
368
+ await client.syncState();
369
+ return accountId.toString();
370
+ }
371
+ } catch {
372
+ }
373
+ await client.newAccount(account, false);
374
+ await client.syncState();
375
+ return accountId.toString();
376
+ }
377
+
314
378
  // src/context/MidenProvider.tsx
315
379
  import { Fragment, jsx } from "react/jsx-runtime";
316
- var MidenContext = createContext(null);
380
+ var MidenContext = createContext2(null);
317
381
  function MidenProvider({
318
382
  children,
319
383
  config = {},
@@ -334,6 +398,8 @@ function MidenProvider({
334
398
  const syncIntervalRef = useRef(null);
335
399
  const isInitializedRef = useRef(false);
336
400
  const clientLockRef = useRef(new AsyncLock());
401
+ const signerContext = useSigner();
402
+ const [signerAccountId, setSignerAccountId] = useState(null);
337
403
  const resolvedConfig = useMemo(
338
404
  () => ({
339
405
  ...config,
@@ -380,18 +446,49 @@ function MidenProvider({
380
446
  });
381
447
  }, [client, isReady, runExclusive, setSyncState]);
382
448
  useEffect(() => {
383
- if (isInitializedRef.current) return;
384
- isInitializedRef.current = true;
449
+ if (!signerContext && isInitializedRef.current) return;
450
+ if (signerContext && !signerContext.isConnected) {
451
+ if (client) {
452
+ useMidenStore.getState().reset();
453
+ setClient(null);
454
+ setSignerAccountId(null);
455
+ }
456
+ return;
457
+ }
458
+ if (!signerContext) {
459
+ isInitializedRef.current = true;
460
+ }
385
461
  const initClient = async () => {
386
462
  setInitializing(true);
387
463
  setConfig(resolvedConfig);
388
464
  try {
389
- const seed = resolvedConfig.seed;
390
- const webClient = await WebClient.createClient(
391
- resolvedConfig.rpcUrl,
392
- resolvedConfig.noteTransportUrl,
393
- seed
394
- );
465
+ let webClient;
466
+ if (signerContext && signerContext.isConnected) {
467
+ const storeName = `MidenClientDB_${signerContext.storeName}`;
468
+ webClient = await WebClient.createClientWithExternalKeystore(
469
+ resolvedConfig.rpcUrl,
470
+ resolvedConfig.noteTransportUrl,
471
+ resolvedConfig.seed,
472
+ storeName,
473
+ void 0,
474
+ // getKeyCb - not needed for public accounts
475
+ void 0,
476
+ // insertKeyCb - not needed for public accounts
477
+ signerContext.signCb
478
+ );
479
+ const accountId = await initializeSignerAccount(
480
+ webClient,
481
+ signerContext.accountConfig
482
+ );
483
+ setSignerAccountId(accountId);
484
+ } else {
485
+ const seed = resolvedConfig.seed;
486
+ webClient = await WebClient.createClient(
487
+ resolvedConfig.rpcUrl,
488
+ resolvedConfig.noteTransportUrl,
489
+ seed
490
+ );
491
+ }
395
492
  setClient(webClient);
396
493
  try {
397
494
  const summary = await runExclusive(() => webClient.syncState());
@@ -399,6 +496,8 @@ function MidenProvider({
399
496
  syncHeight: summary.blockNum(),
400
497
  lastSyncTime: Date.now()
401
498
  });
499
+ const accounts = await webClient.getAccounts();
500
+ useMidenStore.getState().setAccounts(accounts);
402
501
  } catch {
403
502
  }
404
503
  } catch (error) {
@@ -413,7 +512,9 @@ function MidenProvider({
413
512
  setConfig,
414
513
  setInitError,
415
514
  setInitializing,
416
- setSyncState
515
+ setSyncState,
516
+ signerContext,
517
+ client
417
518
  ]);
418
519
  useEffect(() => {
419
520
  if (!isReady || !client) return;
@@ -445,12 +546,13 @@ function MidenProvider({
445
546
  error: initError,
446
547
  sync,
447
548
  runExclusive,
448
- prover: defaultProver
549
+ prover: defaultProver,
550
+ signerAccountId
449
551
  };
450
552
  return /* @__PURE__ */ jsx(MidenContext.Provider, { value: contextValue, children });
451
553
  }
452
554
  function useMiden() {
453
- const context = useContext(MidenContext);
555
+ const context = useContext2(MidenContext);
454
556
  if (!context) {
455
557
  throw new Error("useMiden must be used within a MidenProvider");
456
558
  }
@@ -530,7 +632,7 @@ function isFaucetId(accountId) {
530
632
  }
531
633
 
532
634
  // src/hooks/useAccount.ts
533
- import { useCallback as useCallback3, useEffect as useEffect4, useState, useMemo as useMemo3 } from "react";
635
+ import { useCallback as useCallback3, useEffect as useEffect4, useState as useState2, useMemo as useMemo3 } from "react";
534
636
 
535
637
  // src/hooks/useAssetMetadata.ts
536
638
  import { useEffect as useEffect3, useMemo as useMemo2 } from "react";
@@ -622,8 +724,8 @@ function useAccount(accountId) {
622
724
  const accountDetails = useMidenStore((state) => state.accountDetails);
623
725
  const setAccountDetails = useMidenStore((state) => state.setAccountDetails);
624
726
  const { lastSyncTime } = useSyncStateStore();
625
- const [isLoading, setIsLoading] = useState(false);
626
- const [error, setError] = useState(null);
727
+ const [isLoading, setIsLoading] = useState2(false);
728
+ const [error, setError] = useState2(null);
627
729
  const accountIdStr = useMemo3(() => {
628
730
  if (!accountId) return void 0;
629
731
  if (typeof accountId === "string") return accountId;
@@ -712,7 +814,7 @@ function useAccount(accountId) {
712
814
  }
713
815
 
714
816
  // src/hooks/useNotes.ts
715
- import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo4, useState as useState2 } from "react";
817
+ import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo4, useState as useState3 } from "react";
716
818
  import { NoteFilter, NoteFilterTypes } from "@miden-sdk/miden-sdk";
717
819
 
718
820
  // src/utils/amounts.ts
@@ -808,7 +910,7 @@ function useNotes(options) {
808
910
  const setNotes = useMidenStore((state) => state.setNotes);
809
911
  const setConsumableNotes = useMidenStore((state) => state.setConsumableNotes);
810
912
  const { lastSyncTime } = useSyncStateStore();
811
- const [error, setError] = useState2(null);
913
+ const [error, setError] = useState3(null);
812
914
  const refetch = useCallback4(async () => {
813
915
  if (!client || !isReady) return;
814
916
  setLoadingNotes(true);
@@ -909,15 +1011,15 @@ function getNoteFilterType(status) {
909
1011
  }
910
1012
 
911
1013
  // src/hooks/useTransactionHistory.ts
912
- import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo5, useState as useState3 } from "react";
1014
+ import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo5, useState as useState4 } from "react";
913
1015
  import { TransactionFilter } from "@miden-sdk/miden-sdk";
914
1016
  function useTransactionHistory(options = {}) {
915
1017
  const { client, isReady, runExclusive } = useMiden();
916
1018
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
917
1019
  const { lastSyncTime } = useSyncStateStore();
918
- const [records, setRecords] = useState3([]);
919
- const [isLoading, setIsLoading] = useState3(false);
920
- const [error, setError] = useState3(null);
1020
+ const [records, setRecords] = useState4([]);
1021
+ const [isLoading, setIsLoading] = useState4(false);
1022
+ const [error, setError] = useState4(null);
921
1023
  const rawIds = useMemo5(() => {
922
1024
  if (options.id) return [options.id];
923
1025
  if (options.ids && options.ids.length > 0) return options.ids;
@@ -1020,15 +1122,15 @@ function useSyncState() {
1020
1122
  }
1021
1123
 
1022
1124
  // src/hooks/useCreateWallet.ts
1023
- import { useCallback as useCallback7, useState as useState4 } from "react";
1125
+ import { useCallback as useCallback7, useState as useState5 } from "react";
1024
1126
  import { AccountStorageMode } from "@miden-sdk/miden-sdk";
1025
1127
  function useCreateWallet() {
1026
1128
  const { client, isReady, sync, runExclusive } = useMiden();
1027
1129
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
1028
1130
  const setAccounts = useMidenStore((state) => state.setAccounts);
1029
- const [wallet, setWallet] = useState4(null);
1030
- const [isCreating, setIsCreating] = useState4(false);
1031
- const [error, setError] = useState4(null);
1131
+ const [wallet, setWallet] = useState5(null);
1132
+ const [isCreating, setIsCreating] = useState5(false);
1133
+ const [error, setError] = useState5(null);
1032
1134
  const createWallet = useCallback7(
1033
1135
  async (options = {}) => {
1034
1136
  if (!client || !isReady) {
@@ -1094,15 +1196,15 @@ function getStorageMode(mode) {
1094
1196
  }
1095
1197
 
1096
1198
  // src/hooks/useCreateFaucet.ts
1097
- import { useCallback as useCallback8, useState as useState5 } from "react";
1199
+ import { useCallback as useCallback8, useState as useState6 } from "react";
1098
1200
  import { AccountStorageMode as AccountStorageMode2 } from "@miden-sdk/miden-sdk";
1099
1201
  function useCreateFaucet() {
1100
1202
  const { client, isReady, runExclusive } = useMiden();
1101
1203
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
1102
1204
  const setAccounts = useMidenStore((state) => state.setAccounts);
1103
- const [faucet, setFaucet] = useState5(null);
1104
- const [isCreating, setIsCreating] = useState5(false);
1105
- const [error, setError] = useState5(null);
1205
+ const [faucet, setFaucet] = useState6(null);
1206
+ const [isCreating, setIsCreating] = useState6(false);
1207
+ const [error, setError] = useState6(null);
1106
1208
  const createFaucet = useCallback8(
1107
1209
  async (options) => {
1108
1210
  if (!client || !isReady) {
@@ -1169,15 +1271,15 @@ function getStorageMode2(mode) {
1169
1271
  }
1170
1272
 
1171
1273
  // src/hooks/useImportAccount.ts
1172
- import { useCallback as useCallback9, useState as useState6 } from "react";
1274
+ import { useCallback as useCallback9, useState as useState7 } from "react";
1173
1275
  import { AccountFile } from "@miden-sdk/miden-sdk";
1174
1276
  function useImportAccount() {
1175
1277
  const { client, isReady, runExclusive } = useMiden();
1176
1278
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
1177
1279
  const setAccounts = useMidenStore((state) => state.setAccounts);
1178
- const [account, setAccount] = useState6(null);
1179
- const [isImporting, setIsImporting] = useState6(false);
1180
- const [error, setError] = useState6(null);
1280
+ const [account, setAccount] = useState7(null);
1281
+ const [isImporting, setIsImporting] = useState7(false);
1282
+ const [error, setError] = useState7(null);
1181
1283
  const importAccount = useCallback9(
1182
1284
  async (options) => {
1183
1285
  if (!client || !isReady) {
@@ -1323,15 +1425,15 @@ function bytesEqual(left, right) {
1323
1425
  }
1324
1426
 
1325
1427
  // src/hooks/useSend.ts
1326
- import { useCallback as useCallback10, useState as useState7 } from "react";
1428
+ import { useCallback as useCallback10, useState as useState8 } from "react";
1327
1429
  import { NoteType, TransactionFilter as TransactionFilter2 } from "@miden-sdk/miden-sdk";
1328
1430
  function useSend() {
1329
1431
  const { client, isReady, sync, runExclusive, prover } = useMiden();
1330
1432
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
1331
- const [result, setResult] = useState7(null);
1332
- const [isLoading, setIsLoading] = useState7(false);
1333
- const [stage, setStage] = useState7("idle");
1334
- const [error, setError] = useState7(null);
1433
+ const [result, setResult] = useState8(null);
1434
+ const [isLoading, setIsLoading] = useState8(false);
1435
+ const [stage, setStage] = useState8("idle");
1436
+ const [error, setError] = useState8(null);
1335
1437
  const send = useCallback10(
1336
1438
  async (options) => {
1337
1439
  if (!client || !isReady) {
@@ -1460,7 +1562,7 @@ function extractFullNote(txResult) {
1460
1562
  }
1461
1563
 
1462
1564
  // src/hooks/useMultiSend.ts
1463
- import { useCallback as useCallback11, useState as useState8 } from "react";
1565
+ import { useCallback as useCallback11, useState as useState9 } from "react";
1464
1566
  import {
1465
1567
  FungibleAsset,
1466
1568
  Note,
@@ -1475,10 +1577,10 @@ import {
1475
1577
  function useMultiSend() {
1476
1578
  const { client, isReady, sync, runExclusive, prover } = useMiden();
1477
1579
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
1478
- const [result, setResult] = useState8(null);
1479
- const [isLoading, setIsLoading] = useState8(false);
1480
- const [stage, setStage] = useState8("idle");
1481
- const [error, setError] = useState8(null);
1580
+ const [result, setResult] = useState9(null);
1581
+ const [isLoading, setIsLoading] = useState9(false);
1582
+ const [stage, setStage] = useState9("idle");
1583
+ const [error, setError] = useState9(null);
1482
1584
  const sendMany = useCallback11(
1483
1585
  async (options) => {
1484
1586
  if (!client || !isReady) {
@@ -1607,7 +1709,7 @@ async function waitForTransactionCommit2(client, runExclusiveSafe, txId, maxWait
1607
1709
  }
1608
1710
 
1609
1711
  // src/hooks/useInternalTransfer.ts
1610
- import { useCallback as useCallback12, useState as useState9 } from "react";
1712
+ import { useCallback as useCallback12, useState as useState10 } from "react";
1611
1713
  import {
1612
1714
  FungibleAsset as FungibleAsset2,
1613
1715
  Note as Note2,
@@ -1623,10 +1725,10 @@ import {
1623
1725
  function useInternalTransfer() {
1624
1726
  const { client, isReady, sync, runExclusive, prover } = useMiden();
1625
1727
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
1626
- const [result, setResult] = useState9(null);
1627
- const [isLoading, setIsLoading] = useState9(false);
1628
- const [stage, setStage] = useState9("idle");
1629
- const [error, setError] = useState9(null);
1728
+ const [result, setResult] = useState10(null);
1729
+ const [isLoading, setIsLoading] = useState10(false);
1730
+ const [stage, setStage] = useState10("idle");
1731
+ const [error, setError] = useState10(null);
1630
1732
  const transferOnce = useCallback12(
1631
1733
  async (options) => {
1632
1734
  if (!client || !isReady) {
@@ -1854,15 +1956,15 @@ function useWaitForNotes() {
1854
1956
  }
1855
1957
 
1856
1958
  // src/hooks/useMint.ts
1857
- import { useCallback as useCallback15, useState as useState10 } from "react";
1959
+ import { useCallback as useCallback15, useState as useState11 } from "react";
1858
1960
  import { NoteType as NoteType4 } from "@miden-sdk/miden-sdk";
1859
1961
  function useMint() {
1860
1962
  const { client, isReady, sync, runExclusive, prover } = useMiden();
1861
1963
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
1862
- const [result, setResult] = useState10(null);
1863
- const [isLoading, setIsLoading] = useState10(false);
1864
- const [stage, setStage] = useState10("idle");
1865
- const [error, setError] = useState10(null);
1964
+ const [result, setResult] = useState11(null);
1965
+ const [isLoading, setIsLoading] = useState11(false);
1966
+ const [stage, setStage] = useState11("idle");
1967
+ const [error, setError] = useState11(null);
1866
1968
  const mint = useCallback15(
1867
1969
  async (options) => {
1868
1970
  if (!client || !isReady) {
@@ -1934,15 +2036,15 @@ function getNoteType4(type) {
1934
2036
  }
1935
2037
 
1936
2038
  // src/hooks/useConsume.ts
1937
- import { useCallback as useCallback16, useState as useState11 } from "react";
2039
+ import { useCallback as useCallback16, useState as useState12 } from "react";
1938
2040
  import { NoteFilter as NoteFilter2, NoteFilterTypes as NoteFilterTypes2, NoteId } from "@miden-sdk/miden-sdk";
1939
2041
  function useConsume() {
1940
2042
  const { client, isReady, sync, runExclusive, prover } = useMiden();
1941
2043
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
1942
- const [result, setResult] = useState11(null);
1943
- const [isLoading, setIsLoading] = useState11(false);
1944
- const [stage, setStage] = useState11("idle");
1945
- const [error, setError] = useState11(null);
2044
+ const [result, setResult] = useState12(null);
2045
+ const [isLoading, setIsLoading] = useState12(false);
2046
+ const [stage, setStage] = useState12("idle");
2047
+ const [error, setError] = useState12(null);
1946
2048
  const consume = useCallback16(
1947
2049
  async (options) => {
1948
2050
  if (!client || !isReady) {
@@ -2010,15 +2112,15 @@ function useConsume() {
2010
2112
  }
2011
2113
 
2012
2114
  // src/hooks/useSwap.ts
2013
- import { useCallback as useCallback17, useState as useState12 } from "react";
2115
+ import { useCallback as useCallback17, useState as useState13 } from "react";
2014
2116
  import { NoteType as NoteType5 } from "@miden-sdk/miden-sdk";
2015
2117
  function useSwap() {
2016
2118
  const { client, isReady, sync, runExclusive, prover } = useMiden();
2017
2119
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
2018
- const [result, setResult] = useState12(null);
2019
- const [isLoading, setIsLoading] = useState12(false);
2020
- const [stage, setStage] = useState12("idle");
2021
- const [error, setError] = useState12(null);
2120
+ const [result, setResult] = useState13(null);
2121
+ const [isLoading, setIsLoading] = useState13(false);
2122
+ const [stage, setStage] = useState13("idle");
2123
+ const [error, setError] = useState13(null);
2022
2124
  const swap = useCallback17(
2023
2125
  async (options) => {
2024
2126
  if (!client || !isReady) {
@@ -2097,14 +2199,14 @@ function getNoteType5(type) {
2097
2199
  }
2098
2200
 
2099
2201
  // src/hooks/useTransaction.ts
2100
- import { useCallback as useCallback18, useState as useState13 } from "react";
2202
+ import { useCallback as useCallback18, useState as useState14 } from "react";
2101
2203
  function useTransaction() {
2102
2204
  const { client, isReady, sync, runExclusive, prover } = useMiden();
2103
2205
  const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
2104
- const [result, setResult] = useState13(null);
2105
- const [isLoading, setIsLoading] = useState13(false);
2106
- const [stage, setStage] = useState13("idle");
2107
- const [error, setError] = useState13(null);
2206
+ const [result, setResult] = useState14(null);
2207
+ const [isLoading, setIsLoading] = useState14(false);
2208
+ const [stage, setStage] = useState14("idle");
2209
+ const [error, setError] = useState14(null);
2108
2210
  const execute = useCallback18(
2109
2211
  async (options) => {
2110
2212
  if (!client || !isReady) {
@@ -2170,6 +2272,7 @@ installAccountBech32();
2170
2272
  export {
2171
2273
  DEFAULTS,
2172
2274
  MidenProvider,
2275
+ SignerContext,
2173
2276
  formatAssetAmount,
2174
2277
  formatNoteSummary,
2175
2278
  getNoteSummary,
@@ -2189,6 +2292,7 @@ export {
2189
2292
  useMultiSend,
2190
2293
  useNotes,
2191
2294
  useSend,
2295
+ useSigner,
2192
2296
  useSwap,
2193
2297
  useSyncState,
2194
2298
  useTransaction,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miden-sdk/react",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "React hooks library for Miden Web Client",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",