@miden-sdk/react 0.13.3 → 0.14.0
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/CLAUDE.md +2 -2
- package/README.md +111 -3
- package/dist/index.d.mts +339 -124
- package/dist/index.d.ts +339 -124
- package/dist/index.js +1124 -623
- package/dist/index.mjs +1043 -549
- package/package.json +9 -2
package/dist/index.js
CHANGED
|
@@ -30,10 +30,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
AuthScheme: () => import_miden_sdk4.AuthScheme,
|
|
33
34
|
DEFAULTS: () => DEFAULTS,
|
|
34
35
|
MidenError: () => MidenError,
|
|
35
36
|
MidenProvider: () => MidenProvider,
|
|
37
|
+
MultiSignerProvider: () => MultiSignerProvider,
|
|
36
38
|
SignerContext: () => SignerContext,
|
|
39
|
+
SignerSlot: () => SignerSlot,
|
|
37
40
|
accountIdsEqual: () => accountIdsEqual,
|
|
38
41
|
bigIntToBytes: () => bigIntToBytes,
|
|
39
42
|
bytesToBigInt: () => bytesToBigInt,
|
|
@@ -55,18 +58,24 @@ __export(index_exports, {
|
|
|
55
58
|
useConsume: () => useConsume,
|
|
56
59
|
useCreateFaucet: () => useCreateFaucet,
|
|
57
60
|
useCreateWallet: () => useCreateWallet,
|
|
61
|
+
useExecuteProgram: () => useExecuteProgram,
|
|
62
|
+
useExportNote: () => useExportNote,
|
|
63
|
+
useExportStore: () => useExportStore,
|
|
58
64
|
useImportAccount: () => useImportAccount,
|
|
59
|
-
|
|
65
|
+
useImportNote: () => useImportNote,
|
|
66
|
+
useImportStore: () => useImportStore,
|
|
60
67
|
useMiden: () => useMiden,
|
|
61
68
|
useMidenClient: () => useMidenClient,
|
|
62
69
|
useMint: () => useMint,
|
|
63
70
|
useMultiSend: () => useMultiSend,
|
|
71
|
+
useMultiSigner: () => useMultiSigner,
|
|
64
72
|
useNoteStream: () => useNoteStream,
|
|
65
73
|
useNotes: () => useNotes,
|
|
66
74
|
useSend: () => useSend,
|
|
67
75
|
useSessionAccount: () => useSessionAccount,
|
|
68
76
|
useSigner: () => useSigner,
|
|
69
77
|
useSwap: () => useSwap,
|
|
78
|
+
useSyncControl: () => useSyncControl,
|
|
70
79
|
useSyncState: () => useSyncState,
|
|
71
80
|
useTransaction: () => useTransaction,
|
|
72
81
|
useTransactionHistory: () => useTransactionHistory,
|
|
@@ -91,24 +100,33 @@ var initialSyncState = {
|
|
|
91
100
|
lastSyncTime: null,
|
|
92
101
|
error: null
|
|
93
102
|
};
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
function freshCachedState() {
|
|
104
|
+
return {
|
|
105
|
+
sync: { ...initialSyncState },
|
|
106
|
+
syncPaused: false,
|
|
107
|
+
accounts: [],
|
|
108
|
+
accountDetails: /* @__PURE__ */ new Map(),
|
|
109
|
+
notes: [],
|
|
110
|
+
consumableNotes: [],
|
|
111
|
+
assetMetadata: /* @__PURE__ */ new Map(),
|
|
112
|
+
noteFirstSeen: /* @__PURE__ */ new Map(),
|
|
113
|
+
isLoadingAccounts: false,
|
|
114
|
+
isLoadingNotes: false
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function freshState() {
|
|
118
|
+
return {
|
|
119
|
+
client: null,
|
|
120
|
+
isReady: false,
|
|
121
|
+
isInitializing: false,
|
|
122
|
+
initError: null,
|
|
123
|
+
config: {},
|
|
124
|
+
signerConnected: null,
|
|
125
|
+
...freshCachedState()
|
|
126
|
+
};
|
|
127
|
+
}
|
|
110
128
|
var useMidenStore = (0, import_zustand.create)()((set) => ({
|
|
111
|
-
...
|
|
129
|
+
...freshState(),
|
|
112
130
|
setClient: (client) => set({
|
|
113
131
|
client,
|
|
114
132
|
isReady: client !== null,
|
|
@@ -122,9 +140,11 @@ var useMidenStore = (0, import_zustand.create)()((set) => ({
|
|
|
122
140
|
isReady: false
|
|
123
141
|
}),
|
|
124
142
|
setConfig: (config) => set({ config }),
|
|
143
|
+
setSignerConnected: (signerConnected) => set({ signerConnected }),
|
|
125
144
|
setSyncState: (sync) => set((state) => ({
|
|
126
145
|
sync: { ...state.sync, ...sync }
|
|
127
146
|
})),
|
|
147
|
+
setSyncPaused: (syncPaused) => set({ syncPaused }),
|
|
128
148
|
setAccounts: (accounts) => set({ accounts }),
|
|
129
149
|
setAccountDetails: (accountId, account) => set((state) => {
|
|
130
150
|
const newMap = new Map(state.accountDetails);
|
|
@@ -206,7 +226,8 @@ var useMidenStore = (0, import_zustand.create)()((set) => ({
|
|
|
206
226
|
}),
|
|
207
227
|
setLoadingAccounts: (isLoadingAccounts) => set({ isLoadingAccounts }),
|
|
208
228
|
setLoadingNotes: (isLoadingNotes) => set({ isLoadingNotes }),
|
|
209
|
-
|
|
229
|
+
resetInMemoryState: () => set(freshCachedState()),
|
|
230
|
+
reset: () => set(freshState())
|
|
210
231
|
}));
|
|
211
232
|
var useSyncStateStore = () => useMidenStore((state) => state.sync);
|
|
212
233
|
var useAccountsStore = () => useMidenStore((state) => state.accounts);
|
|
@@ -231,11 +252,13 @@ var parseAccountIdFromString = (value) => {
|
|
|
231
252
|
return import_miden_sdk2.AccountId.fromHex(normalizeHexInput(value));
|
|
232
253
|
};
|
|
233
254
|
var parseAccountId = (value) => {
|
|
234
|
-
if (typeof value
|
|
235
|
-
return value;
|
|
255
|
+
if (typeof value === "string") {
|
|
256
|
+
return parseAccountIdFromString(normalizeAccountIdInput(value));
|
|
236
257
|
}
|
|
237
|
-
|
|
238
|
-
|
|
258
|
+
if (typeof value.id === "function") {
|
|
259
|
+
return value.id();
|
|
260
|
+
}
|
|
261
|
+
return value;
|
|
239
262
|
};
|
|
240
263
|
function isFaucetId(accountId) {
|
|
241
264
|
try {
|
|
@@ -251,6 +274,10 @@ function isFaucetId(accountId) {
|
|
|
251
274
|
}
|
|
252
275
|
}
|
|
253
276
|
var parseAddress = (value, accountId) => {
|
|
277
|
+
if (typeof value !== "string") {
|
|
278
|
+
const resolvedId = accountId ?? parseAccountId(value);
|
|
279
|
+
return import_miden_sdk2.Address.fromAccountId(resolvedId, "BasicWallet");
|
|
280
|
+
}
|
|
254
281
|
const normalized = normalizeAccountIdInput(value);
|
|
255
282
|
if (isBech32Input(normalized)) {
|
|
256
283
|
try {
|
|
@@ -354,16 +381,17 @@ var toBech32AccountId = (accountId) => {
|
|
|
354
381
|
|
|
355
382
|
// src/context/MidenProvider.tsx
|
|
356
383
|
var import_react2 = require("react");
|
|
357
|
-
var
|
|
384
|
+
var import_miden_sdk6 = require("@miden-sdk/miden-sdk");
|
|
358
385
|
|
|
359
386
|
// src/types/index.ts
|
|
387
|
+
var import_miden_sdk4 = require("@miden-sdk/miden-sdk");
|
|
360
388
|
var DEFAULTS = {
|
|
361
389
|
RPC_URL: void 0,
|
|
362
390
|
// Will use SDK's testnet default
|
|
363
391
|
AUTO_SYNC_INTERVAL: 15e3,
|
|
364
392
|
STORAGE_MODE: "private",
|
|
365
393
|
WALLET_MUTABLE: true,
|
|
366
|
-
AUTH_SCHEME:
|
|
394
|
+
AUTH_SCHEME: import_miden_sdk4.AuthScheme.AuthRpoFalcon512,
|
|
367
395
|
NOTE_TYPE: "private",
|
|
368
396
|
FAUCET_DECIMALS: 8
|
|
369
397
|
};
|
|
@@ -407,7 +435,7 @@ function resolveRpcUrl(rpcUrl) {
|
|
|
407
435
|
}
|
|
408
436
|
|
|
409
437
|
// src/utils/prover.ts
|
|
410
|
-
var
|
|
438
|
+
var import_miden_sdk5 = require("@miden-sdk/miden-sdk");
|
|
411
439
|
var DEFAULT_PROVER_URLS = {
|
|
412
440
|
devnet: "https://tx-prover.devnet.miden.io",
|
|
413
441
|
testnet: "https://tx-prover.testnet.miden.io"
|
|
@@ -417,34 +445,60 @@ function resolveTransactionProver(config) {
|
|
|
417
445
|
if (!prover) {
|
|
418
446
|
return null;
|
|
419
447
|
}
|
|
420
|
-
if (
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
448
|
+
if (isFallbackConfig(prover)) {
|
|
449
|
+
return resolveProverTarget(prover.primary, config);
|
|
450
|
+
}
|
|
451
|
+
return resolveProverTarget(prover, config);
|
|
452
|
+
}
|
|
453
|
+
async function proveWithFallback(proveFn, config) {
|
|
454
|
+
const primaryProver = resolveTransactionProver(config);
|
|
455
|
+
try {
|
|
456
|
+
return await proveFn(primaryProver ?? void 0);
|
|
457
|
+
} catch (primaryError) {
|
|
458
|
+
const { prover } = config;
|
|
459
|
+
if (!prover || !isFallbackConfig(prover) || !prover.fallback) {
|
|
460
|
+
throw primaryError;
|
|
461
|
+
}
|
|
462
|
+
if (prover.disableFallback?.()) {
|
|
463
|
+
throw primaryError;
|
|
464
|
+
}
|
|
465
|
+
const fallbackProver = resolveProverTarget(prover.fallback, config);
|
|
466
|
+
prover.onFallback?.();
|
|
467
|
+
return await proveFn(fallbackProver ?? void 0);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
function isFallbackConfig(prover) {
|
|
471
|
+
return typeof prover === "object" && "primary" in prover;
|
|
472
|
+
}
|
|
473
|
+
function resolveProverTarget(target, config) {
|
|
474
|
+
if (typeof target === "string") {
|
|
475
|
+
const normalized = target.trim().toLowerCase();
|
|
476
|
+
if (normalized === "local" || normalized === "localhost") {
|
|
477
|
+
return import_miden_sdk5.TransactionProver.newLocalProver();
|
|
424
478
|
}
|
|
425
479
|
if (normalized === "devnet" || normalized === "testnet") {
|
|
426
480
|
const url = config.proverUrls?.[normalized] ?? DEFAULT_PROVER_URLS[normalized] ?? null;
|
|
427
481
|
if (!url) {
|
|
428
482
|
throw new Error(`Missing ${normalized} prover URL`);
|
|
429
483
|
}
|
|
430
|
-
return
|
|
484
|
+
return import_miden_sdk5.TransactionProver.newRemoteProver(
|
|
431
485
|
url,
|
|
432
486
|
normalizeTimeout(config.proverTimeoutMs)
|
|
433
487
|
);
|
|
434
488
|
}
|
|
435
|
-
return
|
|
436
|
-
|
|
489
|
+
return import_miden_sdk5.TransactionProver.newRemoteProver(
|
|
490
|
+
target,
|
|
437
491
|
normalizeTimeout(config.proverTimeoutMs)
|
|
438
492
|
);
|
|
439
493
|
}
|
|
440
|
-
return createRemoteProver(
|
|
494
|
+
return createRemoteProver(target, config.proverTimeoutMs);
|
|
441
495
|
}
|
|
442
496
|
function createRemoteProver(config, fallbackTimeout) {
|
|
443
497
|
const { url, timeoutMs } = config;
|
|
444
498
|
if (!url) {
|
|
445
499
|
throw new Error("Remote prover requires a URL");
|
|
446
500
|
}
|
|
447
|
-
return
|
|
501
|
+
return import_miden_sdk5.TransactionProver.newRemoteProver(
|
|
448
502
|
url,
|
|
449
503
|
normalizeTimeout(timeoutMs ?? fallbackTimeout)
|
|
450
504
|
);
|
|
@@ -467,35 +521,41 @@ function useSigner() {
|
|
|
467
521
|
}
|
|
468
522
|
|
|
469
523
|
// src/utils/signerAccount.ts
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
return AccountType.FungibleFaucet;
|
|
479
|
-
case "NonFungibleFaucet":
|
|
480
|
-
return AccountType.NonFungibleFaucet;
|
|
481
|
-
default:
|
|
482
|
-
return AccountType.RegularAccountImmutableCode;
|
|
483
|
-
}
|
|
524
|
+
var WASM_ACCOUNT_TYPE = {
|
|
525
|
+
FungibleFaucet: 0,
|
|
526
|
+
NonFungibleFaucet: 1,
|
|
527
|
+
RegularAccountImmutableCode: 2,
|
|
528
|
+
RegularAccountUpdatableCode: 3
|
|
529
|
+
};
|
|
530
|
+
function getAccountType(accountType) {
|
|
531
|
+
return WASM_ACCOUNT_TYPE[accountType] ?? WASM_ACCOUNT_TYPE.RegularAccountImmutableCode;
|
|
484
532
|
}
|
|
485
533
|
function isPrivateStorageMode(storageMode) {
|
|
486
534
|
return storageMode.toString() === "private";
|
|
487
535
|
}
|
|
488
536
|
async function initializeSignerAccount(client, config) {
|
|
489
|
-
const { AccountBuilder, AccountComponent, Word: Word2 } = await import("@miden-sdk/miden-sdk");
|
|
537
|
+
const { AccountBuilder, AccountComponent, AuthScheme: AuthScheme2, Word: Word2 } = await import("@miden-sdk/miden-sdk");
|
|
490
538
|
await client.syncState();
|
|
539
|
+
if (config.importAccountId) {
|
|
540
|
+
const accountId2 = parseAccountId(config.importAccountId);
|
|
541
|
+
try {
|
|
542
|
+
await client.importAccountById(accountId2);
|
|
543
|
+
} catch (e) {
|
|
544
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
545
|
+
if (!msg.includes("already being tracked")) {
|
|
546
|
+
throw e;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
await client.syncState();
|
|
550
|
+
return config.importAccountId;
|
|
551
|
+
}
|
|
491
552
|
const commitmentWord = Word2.deserialize(config.publicKeyCommitment);
|
|
492
553
|
const seed = config.accountSeed ?? crypto.getRandomValues(new Uint8Array(32));
|
|
493
|
-
const accountType =
|
|
554
|
+
const accountType = getAccountType(config.accountType);
|
|
494
555
|
let builder = new AccountBuilder(seed).withAuthComponent(
|
|
495
556
|
AccountComponent.createAuthComponentFromCommitment(
|
|
496
557
|
commitmentWord,
|
|
497
|
-
|
|
498
|
-
// ECDSA auth scheme (K256/Keccak)
|
|
558
|
+
AuthScheme2.AuthEcdsaK256Keccak
|
|
499
559
|
)
|
|
500
560
|
).accountType(accountType).storageMode(config.storageMode).withBasicWalletComponent();
|
|
501
561
|
if (config.customComponents?.length) {
|
|
@@ -546,15 +606,19 @@ function MidenProvider({
|
|
|
546
606
|
isReady,
|
|
547
607
|
isInitializing,
|
|
548
608
|
initError,
|
|
609
|
+
signerConnected,
|
|
549
610
|
setClient,
|
|
550
611
|
setInitializing,
|
|
551
612
|
setInitError,
|
|
552
613
|
setConfig,
|
|
553
|
-
setSyncState
|
|
614
|
+
setSyncState,
|
|
615
|
+
setSignerConnected
|
|
554
616
|
} = useMidenStore();
|
|
555
617
|
const syncIntervalRef = (0, import_react2.useRef)(null);
|
|
556
618
|
const isInitializedRef = (0, import_react2.useRef)(false);
|
|
557
619
|
const clientLockRef = (0, import_react2.useRef)(new AsyncLock());
|
|
620
|
+
const currentStoreNameRef = (0, import_react2.useRef)(null);
|
|
621
|
+
const signCbRef = (0, import_react2.useRef)(null);
|
|
558
622
|
const signerContext = useSigner();
|
|
559
623
|
const [signerAccountId, setSignerAccountId] = (0, import_react2.useState)(null);
|
|
560
624
|
const resolvedConfig = (0, import_react2.useMemo)(
|
|
@@ -582,35 +646,62 @@ function MidenProvider({
|
|
|
582
646
|
const store = useMidenStore.getState();
|
|
583
647
|
if (store.sync.isSyncing) return;
|
|
584
648
|
setSyncState({ isSyncing: true, error: null });
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
649
|
+
try {
|
|
650
|
+
const summary = await client.syncState();
|
|
651
|
+
const syncHeight = summary.blockNum();
|
|
652
|
+
setSyncState({
|
|
653
|
+
syncHeight,
|
|
654
|
+
isSyncing: false,
|
|
655
|
+
lastSyncTime: Date.now(),
|
|
656
|
+
error: null
|
|
657
|
+
});
|
|
658
|
+
const accounts = await client.getAccounts();
|
|
659
|
+
useMidenStore.getState().setAccounts(accounts);
|
|
660
|
+
} catch (error) {
|
|
661
|
+
setSyncState({
|
|
662
|
+
isSyncing: false,
|
|
663
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
}, [client, isReady, setSyncState]);
|
|
667
|
+
const signerIsConnected = signerContext?.isConnected ?? null;
|
|
668
|
+
const signerStoreName = signerContext?.storeName ?? null;
|
|
669
|
+
const signerAccountType = signerContext?.accountConfig?.accountType ?? null;
|
|
670
|
+
const signerStorageMode = signerContext?.accountConfig?.storageMode?.toString() ?? null;
|
|
671
|
+
(0, import_react2.useEffect)(() => {
|
|
672
|
+
signCbRef.current = signerContext?.signCb ?? null;
|
|
673
|
+
}, [signerContext?.signCb]);
|
|
674
|
+
const wrappedSignCb = (0, import_react2.useCallback)(
|
|
675
|
+
async (pubKey, signingInputs) => {
|
|
676
|
+
const cb = signCbRef.current;
|
|
677
|
+
if (!cb) {
|
|
678
|
+
throw new Error("Signer is disconnected. Cannot sign.");
|
|
602
679
|
}
|
|
603
|
-
|
|
604
|
-
|
|
680
|
+
return cb(pubKey, signingInputs);
|
|
681
|
+
},
|
|
682
|
+
[]
|
|
683
|
+
);
|
|
605
684
|
(0, import_react2.useEffect)(() => {
|
|
606
|
-
if (
|
|
607
|
-
if (
|
|
608
|
-
|
|
609
|
-
|
|
685
|
+
if (signerIsConnected === null && isInitializedRef.current) return;
|
|
686
|
+
if (signerIsConnected === false) {
|
|
687
|
+
const store = useMidenStore.getState();
|
|
688
|
+
if (store.signerConnected !== false) {
|
|
689
|
+
setSignerConnected(false);
|
|
690
|
+
}
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
if (signerIsConnected === true && signerStoreName !== null) {
|
|
694
|
+
const store = useMidenStore.getState();
|
|
695
|
+
if (currentStoreNameRef.current === signerStoreName && store.client !== null) {
|
|
696
|
+
store.client.setSignCb(wrappedSignCb);
|
|
697
|
+
setSignerConnected(true);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
if (currentStoreNameRef.current !== null && currentStoreNameRef.current !== signerStoreName) {
|
|
701
|
+
store.resetInMemoryState();
|
|
610
702
|
setClient(null);
|
|
611
703
|
setSignerAccountId(null);
|
|
612
704
|
}
|
|
613
|
-
return;
|
|
614
705
|
}
|
|
615
706
|
let cancelled = false;
|
|
616
707
|
const initClient = async () => {
|
|
@@ -621,18 +712,17 @@ function MidenProvider({
|
|
|
621
712
|
try {
|
|
622
713
|
let webClient;
|
|
623
714
|
let didSignerInit = false;
|
|
624
|
-
if (signerContext &&
|
|
715
|
+
if (signerContext && signerIsConnected === true) {
|
|
625
716
|
const storeName = `MidenClientDB_${signerContext.storeName}`;
|
|
626
|
-
|
|
717
|
+
signCbRef.current = signerContext.signCb;
|
|
718
|
+
webClient = await import_miden_sdk6.WasmWebClient.createClientWithExternalKeystore(
|
|
627
719
|
resolvedConfig.rpcUrl,
|
|
628
720
|
resolvedConfig.noteTransportUrl,
|
|
629
721
|
resolvedConfig.seed,
|
|
630
722
|
storeName,
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
// insertKeyCb - not needed for public accounts
|
|
635
|
-
signerContext.signCb
|
|
723
|
+
signerContext.getKeyCb,
|
|
724
|
+
signerContext.insertKeyCb,
|
|
725
|
+
wrappedSignCb
|
|
636
726
|
);
|
|
637
727
|
if (cancelled) return;
|
|
638
728
|
const accountId = await initializeSignerAccount(
|
|
@@ -642,9 +732,10 @@ function MidenProvider({
|
|
|
642
732
|
if (cancelled) return;
|
|
643
733
|
setSignerAccountId(accountId);
|
|
644
734
|
didSignerInit = true;
|
|
735
|
+
currentStoreNameRef.current = signerContext.storeName;
|
|
645
736
|
} else {
|
|
646
737
|
const seed = resolvedConfig.seed;
|
|
647
|
-
webClient = await
|
|
738
|
+
webClient = await import_miden_sdk6.WasmWebClient.createClient(
|
|
648
739
|
resolvedConfig.rpcUrl,
|
|
649
740
|
resolvedConfig.noteTransportUrl,
|
|
650
741
|
seed
|
|
@@ -675,6 +766,9 @@ function MidenProvider({
|
|
|
675
766
|
isInitializedRef.current = true;
|
|
676
767
|
}
|
|
677
768
|
setClient(webClient);
|
|
769
|
+
if (signerIsConnected === true) {
|
|
770
|
+
setSignerConnected(true);
|
|
771
|
+
}
|
|
678
772
|
}
|
|
679
773
|
} catch (error) {
|
|
680
774
|
if (!cancelled) {
|
|
@@ -698,14 +792,26 @@ function MidenProvider({
|
|
|
698
792
|
setInitError,
|
|
699
793
|
setInitializing,
|
|
700
794
|
setSyncState,
|
|
701
|
-
|
|
795
|
+
setSignerConnected,
|
|
796
|
+
signerIsConnected,
|
|
797
|
+
signerStoreName,
|
|
798
|
+
signerAccountType,
|
|
799
|
+
signerStorageMode,
|
|
800
|
+
wrappedSignCb
|
|
801
|
+
// Note: signerContext is intentionally NOT a dep — we use stable primitives
|
|
802
|
+
// (signerIsConnected, signerStoreName, signerAccountType, signerStorageMode)
|
|
803
|
+
// to avoid re-running when the signer provider creates a new object ref.
|
|
804
|
+
// signCb changes are handled by the dedicated useEffect + signCbRef above,
|
|
805
|
+
// not by this effect.
|
|
702
806
|
]);
|
|
703
807
|
(0, import_react2.useEffect)(() => {
|
|
704
808
|
if (!isReady || !client) return;
|
|
705
809
|
const interval = config.autoSyncInterval ?? DEFAULTS.AUTO_SYNC_INTERVAL;
|
|
706
810
|
if (interval <= 0) return;
|
|
707
811
|
syncIntervalRef.current = setInterval(() => {
|
|
708
|
-
|
|
812
|
+
if (!useMidenStore.getState().syncPaused) {
|
|
813
|
+
sync();
|
|
814
|
+
}
|
|
709
815
|
}, interval);
|
|
710
816
|
return () => {
|
|
711
817
|
if (syncIntervalRef.current) {
|
|
@@ -714,6 +820,20 @@ function MidenProvider({
|
|
|
714
820
|
}
|
|
715
821
|
};
|
|
716
822
|
}, [isReady, client, config.autoSyncInterval, sync]);
|
|
823
|
+
(0, import_react2.useEffect)(() => {
|
|
824
|
+
if (!isReady || !client) return;
|
|
825
|
+
const unsubscribe = client.onStateChanged?.(async () => {
|
|
826
|
+
try {
|
|
827
|
+
const accounts = await client.getAccounts();
|
|
828
|
+
useMidenStore.getState().setAccounts(accounts);
|
|
829
|
+
setSyncState({ lastSyncTime: Date.now() });
|
|
830
|
+
} catch {
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
return () => {
|
|
834
|
+
unsubscribe?.();
|
|
835
|
+
};
|
|
836
|
+
}, [isReady, client, setSyncState]);
|
|
717
837
|
if (isInitializing && loadingComponent) {
|
|
718
838
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent });
|
|
719
839
|
}
|
|
@@ -731,7 +851,8 @@ function MidenProvider({
|
|
|
731
851
|
sync,
|
|
732
852
|
runExclusive,
|
|
733
853
|
prover: defaultProver,
|
|
734
|
-
signerAccountId
|
|
854
|
+
signerAccountId,
|
|
855
|
+
signerConnected
|
|
735
856
|
};
|
|
736
857
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MidenContext.Provider, { value: contextValue, children });
|
|
737
858
|
}
|
|
@@ -752,35 +873,183 @@ function useMidenClient() {
|
|
|
752
873
|
return client;
|
|
753
874
|
}
|
|
754
875
|
|
|
755
|
-
// src/
|
|
876
|
+
// src/context/MultiSignerProvider.tsx
|
|
756
877
|
var import_react3 = require("react");
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
var
|
|
878
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
879
|
+
var MultiSignerRegistryContext = (0, import_react3.createContext)(null);
|
|
880
|
+
var MultiSignerContext = (0, import_react3.createContext)(null);
|
|
881
|
+
function MultiSignerProvider({ children }) {
|
|
882
|
+
const signersRef = (0, import_react3.useRef)(/* @__PURE__ */ new Map());
|
|
883
|
+
const [signersSnapshot, setSignersSnapshot] = (0, import_react3.useState)(
|
|
884
|
+
[]
|
|
885
|
+
);
|
|
886
|
+
const [activeSignerName, setActiveSignerName] = (0, import_react3.useState)(null);
|
|
887
|
+
const activeSignerNameRef = (0, import_react3.useRef)(null);
|
|
888
|
+
const generationRef = (0, import_react3.useRef)(0);
|
|
889
|
+
const updateSnapshot = (0, import_react3.useCallback)(() => {
|
|
890
|
+
setSignersSnapshot(Array.from(signersRef.current.values()));
|
|
891
|
+
}, []);
|
|
892
|
+
const register = (0, import_react3.useCallback)(
|
|
893
|
+
(value) => {
|
|
894
|
+
const prev = signersRef.current.get(value.name);
|
|
895
|
+
signersRef.current.set(value.name, value);
|
|
896
|
+
if (!prev || prev.name !== value.name || prev.isConnected !== value.isConnected || prev.storeName !== value.storeName || prev.accountConfig !== value.accountConfig) {
|
|
897
|
+
updateSnapshot();
|
|
898
|
+
}
|
|
899
|
+
},
|
|
900
|
+
[updateSnapshot]
|
|
901
|
+
);
|
|
902
|
+
const unregister = (0, import_react3.useCallback)(
|
|
903
|
+
(name) => {
|
|
904
|
+
signersRef.current.delete(name);
|
|
905
|
+
setActiveSignerName((current) => current === name ? null : current);
|
|
906
|
+
updateSnapshot();
|
|
907
|
+
},
|
|
908
|
+
[updateSnapshot]
|
|
909
|
+
);
|
|
910
|
+
const registry = (0, import_react3.useMemo)(
|
|
911
|
+
() => ({ register, unregister }),
|
|
912
|
+
[register, unregister]
|
|
913
|
+
);
|
|
914
|
+
const activeSigner = activeSignerName ? signersSnapshot.find((s) => s.name === activeSignerName) ?? null : null;
|
|
915
|
+
const stableSignCb = (0, import_react3.useCallback)(
|
|
916
|
+
async (pubKey, signingInputs) => {
|
|
917
|
+
const name = activeSignerName;
|
|
918
|
+
if (!name) throw new Error("No active signer (signer was disconnected)");
|
|
919
|
+
const signer = signersRef.current.get(name);
|
|
920
|
+
if (!signer) throw new Error(`Signer "${name}" not found in registry`);
|
|
921
|
+
return signer.signCb(pubKey, signingInputs);
|
|
922
|
+
},
|
|
923
|
+
[activeSignerName]
|
|
924
|
+
);
|
|
925
|
+
const stableConnect = (0, import_react3.useCallback)(async () => {
|
|
926
|
+
const name = activeSignerName;
|
|
927
|
+
if (!name) throw new Error("No active signer (signer was disconnected)");
|
|
928
|
+
const signer = signersRef.current.get(name);
|
|
929
|
+
if (!signer) throw new Error(`Signer "${name}" not found in registry`);
|
|
930
|
+
return signer.connect();
|
|
931
|
+
}, [activeSignerName]);
|
|
932
|
+
const stableDisconnect = (0, import_react3.useCallback)(async () => {
|
|
933
|
+
const name = activeSignerName;
|
|
934
|
+
if (!name) throw new Error("No active signer (signer was disconnected)");
|
|
935
|
+
const signer = signersRef.current.get(name);
|
|
936
|
+
if (!signer) throw new Error(`Signer "${name}" not found in registry`);
|
|
937
|
+
return signer.disconnect();
|
|
938
|
+
}, [activeSignerName]);
|
|
939
|
+
const forwardedValue = (0, import_react3.useMemo)(() => {
|
|
940
|
+
if (!activeSigner) return null;
|
|
941
|
+
return {
|
|
942
|
+
name: activeSigner.name,
|
|
943
|
+
isConnected: activeSigner.isConnected,
|
|
944
|
+
storeName: activeSigner.storeName,
|
|
945
|
+
accountConfig: activeSigner.accountConfig,
|
|
946
|
+
signCb: stableSignCb,
|
|
947
|
+
connect: stableConnect,
|
|
948
|
+
disconnect: stableDisconnect
|
|
949
|
+
};
|
|
950
|
+
}, [
|
|
951
|
+
activeSigner?.name,
|
|
952
|
+
activeSigner?.isConnected,
|
|
953
|
+
activeSigner?.storeName,
|
|
954
|
+
activeSigner?.accountConfig,
|
|
955
|
+
stableSignCb,
|
|
956
|
+
stableConnect,
|
|
957
|
+
stableDisconnect
|
|
958
|
+
]);
|
|
959
|
+
const setActiveName = (0, import_react3.useCallback)((name) => {
|
|
960
|
+
activeSignerNameRef.current = name;
|
|
961
|
+
setActiveSignerName(name);
|
|
962
|
+
}, []);
|
|
963
|
+
const connectSigner = (0, import_react3.useCallback)(
|
|
964
|
+
async (name) => {
|
|
965
|
+
const currentName = activeSignerNameRef.current;
|
|
966
|
+
const currentSigner = currentName ? signersRef.current.get(currentName) : null;
|
|
967
|
+
if (currentName === name && currentSigner?.isConnected) return;
|
|
968
|
+
const newSigner = signersRef.current.get(name);
|
|
969
|
+
if (!newSigner) throw new Error(`Signer "${name}" not found`);
|
|
970
|
+
const generation = ++generationRef.current;
|
|
971
|
+
setActiveName(name);
|
|
972
|
+
if (currentSigner?.isConnected) {
|
|
973
|
+
currentSigner.disconnect().catch((err) => {
|
|
974
|
+
console.warn("Failed to disconnect previous signer:", err);
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
try {
|
|
978
|
+
await newSigner.connect();
|
|
979
|
+
if (generation !== generationRef.current) return;
|
|
980
|
+
} catch (err) {
|
|
981
|
+
if (generation !== generationRef.current) return;
|
|
982
|
+
setActiveName(null);
|
|
983
|
+
throw err;
|
|
984
|
+
}
|
|
985
|
+
},
|
|
986
|
+
[setActiveName]
|
|
987
|
+
);
|
|
988
|
+
const disconnectSigner = (0, import_react3.useCallback)(async () => {
|
|
989
|
+
++generationRef.current;
|
|
990
|
+
const currentName = activeSignerNameRef.current;
|
|
991
|
+
const signer = currentName ? signersRef.current.get(currentName) : null;
|
|
992
|
+
setActiveName(null);
|
|
993
|
+
if (signer?.isConnected) {
|
|
994
|
+
signer.disconnect().catch((err) => {
|
|
995
|
+
console.warn("Failed to disconnect signer:", err);
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
}, [setActiveName]);
|
|
999
|
+
const multiSignerValue = (0, import_react3.useMemo)(
|
|
1000
|
+
() => ({
|
|
1001
|
+
signers: signersSnapshot,
|
|
1002
|
+
activeSigner,
|
|
1003
|
+
connectSigner,
|
|
1004
|
+
disconnectSigner
|
|
1005
|
+
}),
|
|
1006
|
+
[signersSnapshot, activeSigner, connectSigner, disconnectSigner]
|
|
1007
|
+
);
|
|
1008
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SignerContext.Provider, { value: forwardedValue, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MultiSignerRegistryContext.Provider, { value: registry, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MultiSignerContext.Provider, { value: multiSignerValue, children }) }) });
|
|
1009
|
+
}
|
|
1010
|
+
function SignerSlot() {
|
|
1011
|
+
const signerValue = useSigner();
|
|
1012
|
+
const registry = (0, import_react3.useContext)(MultiSignerRegistryContext);
|
|
1013
|
+
const nameRef = (0, import_react3.useRef)();
|
|
1014
|
+
(0, import_react3.useEffect)(() => {
|
|
1015
|
+
if (!signerValue || !registry) return;
|
|
1016
|
+
nameRef.current = signerValue.name;
|
|
1017
|
+
registry.register(signerValue);
|
|
1018
|
+
}, [signerValue, registry]);
|
|
1019
|
+
(0, import_react3.useEffect)(() => {
|
|
1020
|
+
return () => {
|
|
1021
|
+
if (nameRef.current && registry) {
|
|
1022
|
+
registry.unregister(nameRef.current);
|
|
1023
|
+
}
|
|
1024
|
+
};
|
|
1025
|
+
}, [registry]);
|
|
1026
|
+
return null;
|
|
1027
|
+
}
|
|
1028
|
+
function useMultiSigner() {
|
|
1029
|
+
return (0, import_react3.useContext)(MultiSignerContext);
|
|
1030
|
+
}
|
|
760
1031
|
|
|
761
1032
|
// src/hooks/useAccounts.ts
|
|
1033
|
+
var import_react4 = require("react");
|
|
762
1034
|
function useAccounts() {
|
|
763
|
-
const { client, isReady
|
|
764
|
-
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
1035
|
+
const { client, isReady } = useMiden();
|
|
765
1036
|
const accounts = useAccountsStore();
|
|
766
1037
|
const isLoadingAccounts = useMidenStore((state) => state.isLoadingAccounts);
|
|
767
1038
|
const setLoadingAccounts = useMidenStore((state) => state.setLoadingAccounts);
|
|
768
1039
|
const setAccounts = useMidenStore((state) => state.setAccounts);
|
|
769
|
-
const refetch = (0,
|
|
1040
|
+
const refetch = (0, import_react4.useCallback)(async () => {
|
|
770
1041
|
if (!client || !isReady) return;
|
|
771
1042
|
setLoadingAccounts(true);
|
|
772
1043
|
try {
|
|
773
|
-
const fetchedAccounts = await
|
|
774
|
-
() => client.getAccounts()
|
|
775
|
-
);
|
|
1044
|
+
const fetchedAccounts = await client.getAccounts();
|
|
776
1045
|
setAccounts(fetchedAccounts);
|
|
777
1046
|
} catch (error) {
|
|
778
1047
|
console.error("Failed to fetch accounts:", error);
|
|
779
1048
|
} finally {
|
|
780
1049
|
setLoadingAccounts(false);
|
|
781
1050
|
}
|
|
782
|
-
}, [client, isReady,
|
|
783
|
-
(0,
|
|
1051
|
+
}, [client, isReady, setAccounts, setLoadingAccounts]);
|
|
1052
|
+
(0, import_react4.useEffect)(() => {
|
|
784
1053
|
if (isReady && accounts.length === 0) {
|
|
785
1054
|
refetch();
|
|
786
1055
|
}
|
|
@@ -806,11 +1075,11 @@ function useAccounts() {
|
|
|
806
1075
|
}
|
|
807
1076
|
|
|
808
1077
|
// src/hooks/useAccount.ts
|
|
809
|
-
var
|
|
1078
|
+
var import_react6 = require("react");
|
|
810
1079
|
|
|
811
1080
|
// src/hooks/useAssetMetadata.ts
|
|
812
|
-
var
|
|
813
|
-
var
|
|
1081
|
+
var import_react5 = require("react");
|
|
1082
|
+
var import_miden_sdk7 = require("@miden-sdk/miden-sdk");
|
|
814
1083
|
var inflight = /* @__PURE__ */ new Map();
|
|
815
1084
|
var rpcClients = /* @__PURE__ */ new Map();
|
|
816
1085
|
var getRpcClient = (rpcUrl) => {
|
|
@@ -818,8 +1087,8 @@ var getRpcClient = (rpcUrl) => {
|
|
|
818
1087
|
const existing = rpcClients.get(key);
|
|
819
1088
|
if (existing) return existing;
|
|
820
1089
|
try {
|
|
821
|
-
const endpoint = rpcUrl ? new
|
|
822
|
-
const client = new
|
|
1090
|
+
const endpoint = rpcUrl ? new import_miden_sdk7.Endpoint(rpcUrl) : import_miden_sdk7.Endpoint.testnet();
|
|
1091
|
+
const client = new import_miden_sdk7.RpcClient(endpoint);
|
|
823
1092
|
rpcClients.set(key, client);
|
|
824
1093
|
return client;
|
|
825
1094
|
} catch {
|
|
@@ -833,7 +1102,7 @@ var fetchAssetMetadata = async (rpcClient, assetId) => {
|
|
|
833
1102
|
const fetched = await rpcClient.getAccountDetails(accountId);
|
|
834
1103
|
const account = fetched.account?.();
|
|
835
1104
|
if (!account) return null;
|
|
836
|
-
const faucet =
|
|
1105
|
+
const faucet = import_miden_sdk7.BasicFungibleFaucetComponent.fromAccount(account);
|
|
837
1106
|
const symbol = faucet.symbol().toString();
|
|
838
1107
|
const decimals = faucet.decimals();
|
|
839
1108
|
return { assetId, symbol, decimals };
|
|
@@ -845,12 +1114,12 @@ function useAssetMetadata(assetIds = []) {
|
|
|
845
1114
|
const assetMetadata = useAssetMetadataStore();
|
|
846
1115
|
const setAssetMetadata = useMidenStore((state) => state.setAssetMetadata);
|
|
847
1116
|
const rpcUrl = useMidenStore((state) => state.config.rpcUrl);
|
|
848
|
-
const rpcClient = (0,
|
|
849
|
-
const uniqueAssetIds = (0,
|
|
1117
|
+
const rpcClient = (0, import_react5.useMemo)(() => getRpcClient(rpcUrl), [rpcUrl]);
|
|
1118
|
+
const uniqueAssetIds = (0, import_react5.useMemo)(
|
|
850
1119
|
() => Array.from(new Set(assetIds.filter(Boolean))),
|
|
851
1120
|
[assetIds]
|
|
852
1121
|
);
|
|
853
|
-
(0,
|
|
1122
|
+
(0, import_react5.useEffect)(() => {
|
|
854
1123
|
if (!rpcClient || uniqueAssetIds.length === 0) return;
|
|
855
1124
|
uniqueAssetIds.forEach((assetId) => {
|
|
856
1125
|
const existing = assetMetadata.get(assetId);
|
|
@@ -869,31 +1138,25 @@ function useAssetMetadata(assetIds = []) {
|
|
|
869
1138
|
|
|
870
1139
|
// src/hooks/useAccount.ts
|
|
871
1140
|
function useAccount(accountId) {
|
|
872
|
-
const { client, isReady
|
|
873
|
-
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
1141
|
+
const { client, isReady } = useMiden();
|
|
874
1142
|
const accountDetails = useMidenStore((state) => state.accountDetails);
|
|
875
1143
|
const setAccountDetails = useMidenStore((state) => state.setAccountDetails);
|
|
876
1144
|
const { lastSyncTime } = useSyncStateStore();
|
|
877
|
-
const [isLoading, setIsLoading] = (0,
|
|
878
|
-
const [error, setError] = (0,
|
|
879
|
-
const accountIdStr = (0,
|
|
1145
|
+
const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
|
|
1146
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
1147
|
+
const accountIdStr = (0, import_react6.useMemo)(() => {
|
|
880
1148
|
if (!accountId) return void 0;
|
|
881
1149
|
if (typeof accountId === "string") return accountId;
|
|
882
|
-
|
|
883
|
-
return accountId.toString();
|
|
884
|
-
}
|
|
885
|
-
return String(accountId);
|
|
1150
|
+
return parseAccountId(accountId).toString();
|
|
886
1151
|
}, [accountId]);
|
|
887
1152
|
const account = accountIdStr ? accountDetails.get(accountIdStr) ?? null : null;
|
|
888
|
-
const refetch = (0,
|
|
1153
|
+
const refetch = (0, import_react6.useCallback)(async () => {
|
|
889
1154
|
if (!client || !isReady || !accountIdStr) return;
|
|
890
1155
|
setIsLoading(true);
|
|
891
1156
|
setError(null);
|
|
892
1157
|
try {
|
|
893
1158
|
const accountIdObj = parseAccountId(accountIdStr);
|
|
894
|
-
const fetchedAccount = await
|
|
895
|
-
() => client.getAccount(accountIdObj)
|
|
896
|
-
);
|
|
1159
|
+
const fetchedAccount = await client.getAccount(accountIdObj);
|
|
897
1160
|
if (fetchedAccount) {
|
|
898
1161
|
ensureAccountBech32(fetchedAccount);
|
|
899
1162
|
setAccountDetails(accountIdStr, fetchedAccount);
|
|
@@ -903,17 +1166,17 @@ function useAccount(accountId) {
|
|
|
903
1166
|
} finally {
|
|
904
1167
|
setIsLoading(false);
|
|
905
1168
|
}
|
|
906
|
-
}, [client, isReady,
|
|
907
|
-
(0,
|
|
1169
|
+
}, [client, isReady, accountIdStr, setAccountDetails]);
|
|
1170
|
+
(0, import_react6.useEffect)(() => {
|
|
908
1171
|
if (isReady && accountIdStr && !account) {
|
|
909
1172
|
refetch();
|
|
910
1173
|
}
|
|
911
1174
|
}, [isReady, accountIdStr, account, refetch]);
|
|
912
|
-
(0,
|
|
1175
|
+
(0, import_react6.useEffect)(() => {
|
|
913
1176
|
if (!isReady || !accountIdStr || !lastSyncTime) return;
|
|
914
1177
|
refetch();
|
|
915
1178
|
}, [isReady, accountIdStr, lastSyncTime, refetch]);
|
|
916
|
-
const rawAssets = (0,
|
|
1179
|
+
const rawAssets = (0, import_react6.useMemo)(() => {
|
|
917
1180
|
if (!account) return [];
|
|
918
1181
|
try {
|
|
919
1182
|
const vault = account.vault();
|
|
@@ -930,12 +1193,12 @@ function useAccount(accountId) {
|
|
|
930
1193
|
return [];
|
|
931
1194
|
}
|
|
932
1195
|
}, [account]);
|
|
933
|
-
const assetIds = (0,
|
|
1196
|
+
const assetIds = (0, import_react6.useMemo)(
|
|
934
1197
|
() => rawAssets.map((asset) => asset.assetId),
|
|
935
1198
|
[rawAssets]
|
|
936
1199
|
);
|
|
937
1200
|
const { assetMetadata } = useAssetMetadata(assetIds);
|
|
938
|
-
const assets = (0,
|
|
1201
|
+
const assets = (0, import_react6.useMemo)(
|
|
939
1202
|
() => rawAssets.map((asset) => {
|
|
940
1203
|
const metadata = assetMetadata.get(asset.assetId);
|
|
941
1204
|
return {
|
|
@@ -946,7 +1209,7 @@ function useAccount(accountId) {
|
|
|
946
1209
|
}),
|
|
947
1210
|
[rawAssets, assetMetadata]
|
|
948
1211
|
);
|
|
949
|
-
const getBalance = (0,
|
|
1212
|
+
const getBalance = (0, import_react6.useCallback)(
|
|
950
1213
|
(assetId) => {
|
|
951
1214
|
const asset = assets.find((a) => a.assetId === assetId);
|
|
952
1215
|
return asset?.amount ?? 0n;
|
|
@@ -964,17 +1227,18 @@ function useAccount(accountId) {
|
|
|
964
1227
|
}
|
|
965
1228
|
|
|
966
1229
|
// src/hooks/useNotes.ts
|
|
967
|
-
var
|
|
968
|
-
var
|
|
1230
|
+
var import_react7 = require("react");
|
|
1231
|
+
var import_miden_sdk9 = require("@miden-sdk/miden-sdk");
|
|
969
1232
|
|
|
970
1233
|
// src/utils/amounts.ts
|
|
971
1234
|
var formatAssetAmount = (amount, decimals) => {
|
|
1235
|
+
const amt = BigInt(amount);
|
|
972
1236
|
if (!decimals || decimals <= 0) {
|
|
973
|
-
return
|
|
1237
|
+
return amt.toString();
|
|
974
1238
|
}
|
|
975
1239
|
const factor = 10n ** BigInt(decimals);
|
|
976
|
-
const whole =
|
|
977
|
-
const fraction =
|
|
1240
|
+
const whole = amt / factor;
|
|
1241
|
+
const fraction = amt % factor;
|
|
978
1242
|
if (fraction === 0n) {
|
|
979
1243
|
return whole.toString();
|
|
980
1244
|
}
|
|
@@ -1069,30 +1333,30 @@ function accountIdsEqual(a, b) {
|
|
|
1069
1333
|
}
|
|
1070
1334
|
|
|
1071
1335
|
// src/utils/noteFilters.ts
|
|
1072
|
-
var
|
|
1336
|
+
var import_miden_sdk8 = require("@miden-sdk/miden-sdk");
|
|
1073
1337
|
function getNoteFilterType(status) {
|
|
1074
1338
|
switch (status) {
|
|
1075
1339
|
case "consumed":
|
|
1076
|
-
return
|
|
1340
|
+
return import_miden_sdk8.NoteFilterTypes.Consumed;
|
|
1077
1341
|
case "committed":
|
|
1078
|
-
return
|
|
1342
|
+
return import_miden_sdk8.NoteFilterTypes.Committed;
|
|
1079
1343
|
case "expected":
|
|
1080
|
-
return
|
|
1344
|
+
return import_miden_sdk8.NoteFilterTypes.Expected;
|
|
1081
1345
|
case "processing":
|
|
1082
|
-
return
|
|
1346
|
+
return import_miden_sdk8.NoteFilterTypes.Processing;
|
|
1083
1347
|
case "all":
|
|
1084
1348
|
default:
|
|
1085
|
-
return
|
|
1349
|
+
return import_miden_sdk8.NoteFilterTypes.All;
|
|
1086
1350
|
}
|
|
1087
1351
|
}
|
|
1088
1352
|
function getNoteType(type) {
|
|
1089
1353
|
switch (type) {
|
|
1090
1354
|
case "private":
|
|
1091
|
-
return
|
|
1355
|
+
return import_miden_sdk8.NoteType.Private;
|
|
1092
1356
|
case "public":
|
|
1093
|
-
return
|
|
1357
|
+
return import_miden_sdk8.NoteType.Public;
|
|
1094
1358
|
default:
|
|
1095
|
-
return
|
|
1359
|
+
return import_miden_sdk8.NoteType.Private;
|
|
1096
1360
|
}
|
|
1097
1361
|
}
|
|
1098
1362
|
async function waitForTransactionCommit(client, runExclusiveSafe, txIdHex, maxWaitMs = 1e4, delayMs = 1e3) {
|
|
@@ -1101,7 +1365,7 @@ async function waitForTransactionCommit(client, runExclusiveSafe, txIdHex, maxWa
|
|
|
1101
1365
|
while (Date.now() < deadline) {
|
|
1102
1366
|
await runExclusiveSafe(() => client.syncState());
|
|
1103
1367
|
const records = await runExclusiveSafe(
|
|
1104
|
-
() => client.getTransactions(
|
|
1368
|
+
() => client.getTransactions(import_miden_sdk8.TransactionFilter.all())
|
|
1105
1369
|
);
|
|
1106
1370
|
const record = records.find(
|
|
1107
1371
|
(r) => normalizeHex(r.id().toHex()) === targetHex
|
|
@@ -1127,8 +1391,7 @@ function normalizeHex(value) {
|
|
|
1127
1391
|
|
|
1128
1392
|
// src/hooks/useNotes.ts
|
|
1129
1393
|
function useNotes(options) {
|
|
1130
|
-
const { client, isReady
|
|
1131
|
-
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
1394
|
+
const { client, isReady } = useMiden();
|
|
1132
1395
|
const notes = useNotesStore();
|
|
1133
1396
|
const consumableNotes = useConsumableNotesStore();
|
|
1134
1397
|
const isLoadingNotes = useMidenStore((state) => state.isLoadingNotes);
|
|
@@ -1138,30 +1401,22 @@ function useNotes(options) {
|
|
|
1138
1401
|
(state) => state.setConsumableNotesIfChanged
|
|
1139
1402
|
);
|
|
1140
1403
|
const { lastSyncTime } = useSyncStateStore();
|
|
1141
|
-
const [error, setError] = (0,
|
|
1142
|
-
const refetch = (0,
|
|
1404
|
+
const [error, setError] = (0, import_react7.useState)(null);
|
|
1405
|
+
const refetch = (0, import_react7.useCallback)(async () => {
|
|
1143
1406
|
if (!client || !isReady) return;
|
|
1144
1407
|
setLoadingNotes(true);
|
|
1145
1408
|
setError(null);
|
|
1146
1409
|
try {
|
|
1147
|
-
const
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
consumableResult = await client.getConsumableNotes();
|
|
1158
|
-
}
|
|
1159
|
-
return {
|
|
1160
|
-
fetchedNotes: notesResult,
|
|
1161
|
-
fetchedConsumable: consumableResult
|
|
1162
|
-
};
|
|
1163
|
-
}
|
|
1164
|
-
);
|
|
1410
|
+
const filterType = getNoteFilterType(options?.status);
|
|
1411
|
+
const filter = new import_miden_sdk9.NoteFilter(filterType);
|
|
1412
|
+
const fetchedNotes = await client.getInputNotes(filter);
|
|
1413
|
+
let fetchedConsumable;
|
|
1414
|
+
if (options?.accountId) {
|
|
1415
|
+
const accountIdObj = parseAccountId(options.accountId);
|
|
1416
|
+
fetchedConsumable = await client.getConsumableNotes(accountIdObj);
|
|
1417
|
+
} else {
|
|
1418
|
+
fetchedConsumable = await client.getConsumableNotes();
|
|
1419
|
+
}
|
|
1165
1420
|
setNotesIfChanged(fetchedNotes);
|
|
1166
1421
|
setConsumableNotesIfChanged(fetchedConsumable);
|
|
1167
1422
|
} catch (err) {
|
|
@@ -1172,23 +1427,22 @@ function useNotes(options) {
|
|
|
1172
1427
|
}, [
|
|
1173
1428
|
client,
|
|
1174
1429
|
isReady,
|
|
1175
|
-
runExclusive,
|
|
1176
1430
|
options?.status,
|
|
1177
1431
|
options?.accountId,
|
|
1178
1432
|
setLoadingNotes,
|
|
1179
1433
|
setNotesIfChanged,
|
|
1180
1434
|
setConsumableNotesIfChanged
|
|
1181
1435
|
]);
|
|
1182
|
-
(0,
|
|
1436
|
+
(0, import_react7.useEffect)(() => {
|
|
1183
1437
|
if (isReady && notes.length === 0) {
|
|
1184
1438
|
refetch();
|
|
1185
1439
|
}
|
|
1186
1440
|
}, [isReady, notes.length, refetch]);
|
|
1187
|
-
(0,
|
|
1441
|
+
(0, import_react7.useEffect)(() => {
|
|
1188
1442
|
if (!isReady || !lastSyncTime) return;
|
|
1189
1443
|
refetch();
|
|
1190
1444
|
}, [isReady, lastSyncTime, refetch]);
|
|
1191
|
-
const noteAssetIds = (0,
|
|
1445
|
+
const noteAssetIds = (0, import_react7.useMemo)(() => {
|
|
1192
1446
|
const ids = /* @__PURE__ */ new Set();
|
|
1193
1447
|
const collect = (note) => {
|
|
1194
1448
|
const summary = getNoteSummary(note);
|
|
@@ -1200,11 +1454,11 @@ function useNotes(options) {
|
|
|
1200
1454
|
return Array.from(ids);
|
|
1201
1455
|
}, [notes, consumableNotes]);
|
|
1202
1456
|
const { assetMetadata } = useAssetMetadata(noteAssetIds);
|
|
1203
|
-
const getMetadata = (0,
|
|
1457
|
+
const getMetadata = (0, import_react7.useCallback)(
|
|
1204
1458
|
(assetId) => assetMetadata.get(assetId),
|
|
1205
1459
|
[assetMetadata]
|
|
1206
1460
|
);
|
|
1207
|
-
const normalizedSender = (0,
|
|
1461
|
+
const normalizedSender = (0, import_react7.useMemo)(() => {
|
|
1208
1462
|
if (!options?.sender) return null;
|
|
1209
1463
|
try {
|
|
1210
1464
|
return normalizeAccountId(options.sender);
|
|
@@ -1212,11 +1466,11 @@ function useNotes(options) {
|
|
|
1212
1466
|
return options.sender;
|
|
1213
1467
|
}
|
|
1214
1468
|
}, [options?.sender]);
|
|
1215
|
-
const excludeIdsKey = (0,
|
|
1469
|
+
const excludeIdsKey = (0, import_react7.useMemo)(() => {
|
|
1216
1470
|
if (!options?.excludeIds || options.excludeIds.length === 0) return "";
|
|
1217
1471
|
return [...options.excludeIds].sort().join("\0");
|
|
1218
1472
|
}, [options?.excludeIds]);
|
|
1219
|
-
const filterBySender = (0,
|
|
1473
|
+
const filterBySender = (0, import_react7.useCallback)(
|
|
1220
1474
|
(summaries, target) => {
|
|
1221
1475
|
const cache = /* @__PURE__ */ new Map();
|
|
1222
1476
|
return summaries.filter((s) => {
|
|
@@ -1235,7 +1489,7 @@ function useNotes(options) {
|
|
|
1235
1489
|
},
|
|
1236
1490
|
[]
|
|
1237
1491
|
);
|
|
1238
|
-
const noteSummaries = (0,
|
|
1492
|
+
const noteSummaries = (0, import_react7.useMemo)(() => {
|
|
1239
1493
|
let summaries = notes.map((note) => getNoteSummary(note, getMetadata)).filter(Boolean);
|
|
1240
1494
|
if (normalizedSender) {
|
|
1241
1495
|
summaries = filterBySender(summaries, normalizedSender);
|
|
@@ -1246,7 +1500,7 @@ function useNotes(options) {
|
|
|
1246
1500
|
}
|
|
1247
1501
|
return summaries;
|
|
1248
1502
|
}, [notes, getMetadata, normalizedSender, excludeIdsKey, filterBySender]);
|
|
1249
|
-
const consumableNoteSummaries = (0,
|
|
1503
|
+
const consumableNoteSummaries = (0, import_react7.useMemo)(() => {
|
|
1250
1504
|
let summaries = consumableNotes.map((note) => getNoteSummary(note, getMetadata)).filter(Boolean);
|
|
1251
1505
|
if (normalizedSender) {
|
|
1252
1506
|
summaries = filterBySender(summaries, normalizedSender);
|
|
@@ -1275,11 +1529,11 @@ function useNotes(options) {
|
|
|
1275
1529
|
}
|
|
1276
1530
|
|
|
1277
1531
|
// src/hooks/useNoteStream.ts
|
|
1278
|
-
var
|
|
1279
|
-
var
|
|
1532
|
+
var import_react8 = require("react");
|
|
1533
|
+
var import_miden_sdk11 = require("@miden-sdk/miden-sdk");
|
|
1280
1534
|
|
|
1281
1535
|
// src/utils/noteAttachment.ts
|
|
1282
|
-
var
|
|
1536
|
+
var import_miden_sdk10 = require("@miden-sdk/miden-sdk");
|
|
1283
1537
|
function readNoteAttachment(note) {
|
|
1284
1538
|
try {
|
|
1285
1539
|
const metadata = note.metadata?.();
|
|
@@ -1288,8 +1542,8 @@ function readNoteAttachment(note) {
|
|
|
1288
1542
|
if (!attachment) return null;
|
|
1289
1543
|
const kind = attachment.kind?.();
|
|
1290
1544
|
if (!kind) return null;
|
|
1291
|
-
if (kind ===
|
|
1292
|
-
if (kind ===
|
|
1545
|
+
if (kind === import_miden_sdk10.NoteAttachmentKind.None) return null;
|
|
1546
|
+
if (kind === import_miden_sdk10.NoteAttachmentKind.Word) {
|
|
1293
1547
|
const word = attachment.asWord?.();
|
|
1294
1548
|
if (!word) return null;
|
|
1295
1549
|
const u64s = word.toU64s();
|
|
@@ -1298,7 +1552,7 @@ function readNoteAttachment(note) {
|
|
|
1298
1552
|
);
|
|
1299
1553
|
return { values, kind: "word" };
|
|
1300
1554
|
}
|
|
1301
|
-
if (kind ===
|
|
1555
|
+
if (kind === import_miden_sdk10.NoteAttachmentKind.Array) {
|
|
1302
1556
|
const arr = attachment.asArray?.();
|
|
1303
1557
|
if (!arr) return null;
|
|
1304
1558
|
const u64s = arr.toU64s();
|
|
@@ -1318,82 +1572,79 @@ function createNoteAttachment(values) {
|
|
|
1318
1572
|
bigints.push(BigInt(values[i]));
|
|
1319
1573
|
}
|
|
1320
1574
|
if (bigints.length === 0) {
|
|
1321
|
-
return new
|
|
1575
|
+
return new import_miden_sdk10.NoteAttachment();
|
|
1322
1576
|
}
|
|
1323
|
-
const scheme =
|
|
1577
|
+
const scheme = import_miden_sdk10.NoteAttachmentScheme.none();
|
|
1324
1578
|
if (bigints.length <= 4) {
|
|
1325
1579
|
while (bigints.length < 4) {
|
|
1326
1580
|
bigints.push(0n);
|
|
1327
1581
|
}
|
|
1328
|
-
const word = new
|
|
1329
|
-
return
|
|
1582
|
+
const word = new import_miden_sdk10.Word(BigUint64Array.from(bigints));
|
|
1583
|
+
return import_miden_sdk10.NoteAttachment.newWord(scheme, word);
|
|
1330
1584
|
}
|
|
1331
1585
|
while (bigints.length % 4 !== 0) {
|
|
1332
1586
|
bigints.push(0n);
|
|
1333
1587
|
}
|
|
1334
1588
|
const words = [];
|
|
1335
1589
|
for (let i = 0; i < bigints.length; i += 4) {
|
|
1336
|
-
words.push(new
|
|
1590
|
+
words.push(new import_miden_sdk10.Word(BigUint64Array.from(bigints.slice(i, i + 4))));
|
|
1337
1591
|
}
|
|
1338
|
-
const newArray =
|
|
1592
|
+
const newArray = import_miden_sdk10.NoteAttachment["newArray"];
|
|
1339
1593
|
if (typeof newArray !== "function") {
|
|
1340
1594
|
throw new Error(
|
|
1341
1595
|
"NoteAttachment.newArray is not available. Ensure @miden-sdk/miden-sdk >= 0.13.1."
|
|
1342
1596
|
);
|
|
1343
1597
|
}
|
|
1344
|
-
return newArray.call(
|
|
1598
|
+
return newArray.call(import_miden_sdk10.NoteAttachment, scheme, words);
|
|
1345
1599
|
}
|
|
1346
1600
|
|
|
1347
1601
|
// src/hooks/useNoteStream.ts
|
|
1348
1602
|
function useNoteStream(options = {}) {
|
|
1349
|
-
const { client, isReady
|
|
1350
|
-
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
1603
|
+
const { client, isReady } = useMiden();
|
|
1351
1604
|
const allNotes = useNotesStore();
|
|
1352
1605
|
const noteFirstSeen = useNoteFirstSeenStore();
|
|
1353
1606
|
const { lastSyncTime } = useSyncStateStore();
|
|
1354
1607
|
const setNotesIfChanged = useMidenStore((state) => state.setNotesIfChanged);
|
|
1355
|
-
const [isLoading, setIsLoading] = (0,
|
|
1356
|
-
const [error, setError] = (0,
|
|
1357
|
-
const handledIdsRef = (0,
|
|
1358
|
-
const [handledVersion, setHandledVersion] = (0,
|
|
1608
|
+
const [isLoading, setIsLoading] = (0, import_react8.useState)(false);
|
|
1609
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
1610
|
+
const handledIdsRef = (0, import_react8.useRef)(/* @__PURE__ */ new Set());
|
|
1611
|
+
const [handledVersion, setHandledVersion] = (0, import_react8.useState)(0);
|
|
1359
1612
|
const status = options.status ?? "committed";
|
|
1360
1613
|
const sender = options.sender ?? null;
|
|
1361
1614
|
const since = options.since;
|
|
1362
|
-
const amountFilterRef = (0,
|
|
1615
|
+
const amountFilterRef = (0, import_react8.useRef)(options.amountFilter);
|
|
1363
1616
|
amountFilterRef.current = options.amountFilter;
|
|
1364
|
-
const excludeIdsKey = (0,
|
|
1617
|
+
const excludeIdsKey = (0, import_react8.useMemo)(() => {
|
|
1365
1618
|
if (!options.excludeIds) return "";
|
|
1366
1619
|
if (options.excludeIds instanceof Set)
|
|
1367
1620
|
return Array.from(options.excludeIds).sort().join("\0");
|
|
1368
1621
|
return [...options.excludeIds].sort().join("\0");
|
|
1369
1622
|
}, [options.excludeIds]);
|
|
1370
|
-
const excludeIdSet = (0,
|
|
1623
|
+
const excludeIdSet = (0, import_react8.useMemo)(() => {
|
|
1371
1624
|
if (!excludeIdsKey) return null;
|
|
1372
1625
|
return new Set(excludeIdsKey.split("\0"));
|
|
1373
1626
|
}, [excludeIdsKey]);
|
|
1374
|
-
const refetch = (0,
|
|
1627
|
+
const refetch = (0, import_react8.useCallback)(async () => {
|
|
1375
1628
|
if (!client || !isReady) return;
|
|
1376
1629
|
setIsLoading(true);
|
|
1377
1630
|
setError(null);
|
|
1378
1631
|
try {
|
|
1379
1632
|
const filterType = getNoteFilterType(status);
|
|
1380
|
-
const filter = new
|
|
1381
|
-
const fetched = await
|
|
1382
|
-
() => client.getInputNotes(filter)
|
|
1383
|
-
);
|
|
1633
|
+
const filter = new import_miden_sdk11.NoteFilter(filterType);
|
|
1634
|
+
const fetched = await client.getInputNotes(filter);
|
|
1384
1635
|
setNotesIfChanged(fetched);
|
|
1385
1636
|
} catch (err) {
|
|
1386
1637
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1387
1638
|
} finally {
|
|
1388
1639
|
setIsLoading(false);
|
|
1389
1640
|
}
|
|
1390
|
-
}, [client, isReady,
|
|
1391
|
-
(0,
|
|
1641
|
+
}, [client, isReady, status, setNotesIfChanged]);
|
|
1642
|
+
(0, import_react8.useEffect)(() => {
|
|
1392
1643
|
if (isReady) {
|
|
1393
1644
|
refetch();
|
|
1394
1645
|
}
|
|
1395
1646
|
}, [isReady, lastSyncTime, refetch]);
|
|
1396
|
-
const streamedNotes = (0,
|
|
1647
|
+
const streamedNotes = (0, import_react8.useMemo)(() => {
|
|
1397
1648
|
void handledVersion;
|
|
1398
1649
|
const result = [];
|
|
1399
1650
|
let normalizedSender = null;
|
|
@@ -1418,15 +1669,15 @@ function useNoteStream(options = {}) {
|
|
|
1418
1669
|
result.sort((a, b) => a.firstSeenAt - b.firstSeenAt);
|
|
1419
1670
|
return result;
|
|
1420
1671
|
}, [allNotes, noteFirstSeen, excludeIdSet, sender, since, handledVersion]);
|
|
1421
|
-
const latest = (0,
|
|
1672
|
+
const latest = (0, import_react8.useMemo)(
|
|
1422
1673
|
() => streamedNotes.length > 0 ? streamedNotes[streamedNotes.length - 1] : null,
|
|
1423
1674
|
[streamedNotes]
|
|
1424
1675
|
);
|
|
1425
|
-
const markHandled = (0,
|
|
1676
|
+
const markHandled = (0, import_react8.useCallback)((noteId) => {
|
|
1426
1677
|
handledIdsRef.current = new Set(handledIdsRef.current).add(noteId);
|
|
1427
1678
|
setHandledVersion((v) => v + 1);
|
|
1428
1679
|
}, []);
|
|
1429
|
-
const markAllHandled = (0,
|
|
1680
|
+
const markAllHandled = (0, import_react8.useCallback)(() => {
|
|
1430
1681
|
const newSet = new Set(handledIdsRef.current);
|
|
1431
1682
|
for (const note of streamedNotes) {
|
|
1432
1683
|
newSet.add(note.id);
|
|
@@ -1434,7 +1685,7 @@ function useNoteStream(options = {}) {
|
|
|
1434
1685
|
handledIdsRef.current = newSet;
|
|
1435
1686
|
setHandledVersion((v) => v + 1);
|
|
1436
1687
|
}, [streamedNotes]);
|
|
1437
|
-
const snapshot = (0,
|
|
1688
|
+
const snapshot = (0, import_react8.useCallback)(() => {
|
|
1438
1689
|
const ids = /* @__PURE__ */ new Set();
|
|
1439
1690
|
for (const note of streamedNotes) {
|
|
1440
1691
|
ids.add(note.id);
|
|
@@ -1490,21 +1741,20 @@ function buildStreamedNote(record, noteFirstSeen) {
|
|
|
1490
1741
|
}
|
|
1491
1742
|
|
|
1492
1743
|
// src/hooks/useTransactionHistory.ts
|
|
1493
|
-
var
|
|
1494
|
-
var
|
|
1744
|
+
var import_react9 = require("react");
|
|
1745
|
+
var import_miden_sdk12 = require("@miden-sdk/miden-sdk");
|
|
1495
1746
|
function useTransactionHistory(options = {}) {
|
|
1496
|
-
const { client, isReady
|
|
1497
|
-
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
1747
|
+
const { client, isReady } = useMiden();
|
|
1498
1748
|
const { lastSyncTime } = useSyncStateStore();
|
|
1499
|
-
const [records, setRecords] = (0,
|
|
1500
|
-
const [isLoading, setIsLoading] = (0,
|
|
1501
|
-
const [error, setError] = (0,
|
|
1502
|
-
const rawIds = (0,
|
|
1749
|
+
const [records, setRecords] = (0, import_react9.useState)([]);
|
|
1750
|
+
const [isLoading, setIsLoading] = (0, import_react9.useState)(false);
|
|
1751
|
+
const [error, setError] = (0, import_react9.useState)(null);
|
|
1752
|
+
const rawIds = (0, import_react9.useMemo)(() => {
|
|
1503
1753
|
if (options.id) return [options.id];
|
|
1504
1754
|
if (options.ids && options.ids.length > 0) return options.ids;
|
|
1505
1755
|
return null;
|
|
1506
1756
|
}, [options.id, options.ids]);
|
|
1507
|
-
const idsHex = (0,
|
|
1757
|
+
const idsHex = (0, import_react9.useMemo)(() => {
|
|
1508
1758
|
if (!rawIds) return null;
|
|
1509
1759
|
return rawIds.map(
|
|
1510
1760
|
(id) => normalizeHex2(typeof id === "string" ? id : id.toHex())
|
|
@@ -1512,7 +1762,7 @@ function useTransactionHistory(options = {}) {
|
|
|
1512
1762
|
}, [rawIds]);
|
|
1513
1763
|
const filter = options.filter;
|
|
1514
1764
|
const refreshOnSync = options.refreshOnSync !== false;
|
|
1515
|
-
const refetch = (0,
|
|
1765
|
+
const refetch = (0, import_react9.useCallback)(async () => {
|
|
1516
1766
|
if (!client || !isReady) return;
|
|
1517
1767
|
setIsLoading(true);
|
|
1518
1768
|
setError(null);
|
|
@@ -1522,9 +1772,7 @@ function useTransactionHistory(options = {}) {
|
|
|
1522
1772
|
rawIds,
|
|
1523
1773
|
idsHex
|
|
1524
1774
|
);
|
|
1525
|
-
const fetched = await
|
|
1526
|
-
() => client.getTransactions(resolvedFilter)
|
|
1527
|
-
);
|
|
1775
|
+
const fetched = await client.getTransactions(resolvedFilter);
|
|
1528
1776
|
const filtered = localFilterHexes ? fetched.filter(
|
|
1529
1777
|
(record2) => localFilterHexes.includes(normalizeHex2(record2.id().toHex()))
|
|
1530
1778
|
) : fetched;
|
|
@@ -1534,20 +1782,20 @@ function useTransactionHistory(options = {}) {
|
|
|
1534
1782
|
} finally {
|
|
1535
1783
|
setIsLoading(false);
|
|
1536
1784
|
}
|
|
1537
|
-
}, [client, isReady,
|
|
1538
|
-
(0,
|
|
1785
|
+
}, [client, isReady, filter, rawIds, idsHex]);
|
|
1786
|
+
(0, import_react9.useEffect)(() => {
|
|
1539
1787
|
if (!isReady) return;
|
|
1540
1788
|
refetch();
|
|
1541
1789
|
}, [isReady, refetch]);
|
|
1542
|
-
(0,
|
|
1790
|
+
(0, import_react9.useEffect)(() => {
|
|
1543
1791
|
if (!isReady || !refreshOnSync || !lastSyncTime) return;
|
|
1544
1792
|
refetch();
|
|
1545
1793
|
}, [isReady, lastSyncTime, refreshOnSync, refetch]);
|
|
1546
|
-
const record = (0,
|
|
1794
|
+
const record = (0, import_react9.useMemo)(() => {
|
|
1547
1795
|
if (!idsHex || idsHex.length !== 1) return null;
|
|
1548
1796
|
return records.find((item) => normalizeHex2(item.id().toHex()) === idsHex[0]) ?? null;
|
|
1549
1797
|
}, [records, idsHex]);
|
|
1550
|
-
const status = (0,
|
|
1798
|
+
const status = (0, import_react9.useMemo)(() => {
|
|
1551
1799
|
if (!record) return null;
|
|
1552
1800
|
const current = record.transactionStatus();
|
|
1553
1801
|
if (current.isCommitted()) return "committed";
|
|
@@ -1569,14 +1817,14 @@ function buildFilter(filter, ids, idsHex) {
|
|
|
1569
1817
|
return { filter };
|
|
1570
1818
|
}
|
|
1571
1819
|
if (!ids || ids.length === 0) {
|
|
1572
|
-
return { filter:
|
|
1820
|
+
return { filter: import_miden_sdk12.TransactionFilter.all() };
|
|
1573
1821
|
}
|
|
1574
1822
|
const allTransactionIds = ids.every((id) => typeof id !== "string");
|
|
1575
1823
|
if (allTransactionIds) {
|
|
1576
|
-
return { filter:
|
|
1824
|
+
return { filter: import_miden_sdk12.TransactionFilter.ids(ids) };
|
|
1577
1825
|
}
|
|
1578
1826
|
return {
|
|
1579
|
-
filter:
|
|
1827
|
+
filter: import_miden_sdk12.TransactionFilter.all(),
|
|
1580
1828
|
localFilterHexes: idsHex ?? []
|
|
1581
1829
|
};
|
|
1582
1830
|
}
|
|
@@ -1587,11 +1835,11 @@ function normalizeHex2(value) {
|
|
|
1587
1835
|
}
|
|
1588
1836
|
|
|
1589
1837
|
// src/hooks/useSyncState.ts
|
|
1590
|
-
var
|
|
1838
|
+
var import_react10 = require("react");
|
|
1591
1839
|
function useSyncState() {
|
|
1592
1840
|
const { sync: triggerSync } = useMiden();
|
|
1593
1841
|
const syncState = useSyncStateStore();
|
|
1594
|
-
const sync = (0,
|
|
1842
|
+
const sync = (0, import_react10.useCallback)(async () => {
|
|
1595
1843
|
await triggerSync();
|
|
1596
1844
|
}, [triggerSync]);
|
|
1597
1845
|
return {
|
|
@@ -1601,21 +1849,25 @@ function useSyncState() {
|
|
|
1601
1849
|
}
|
|
1602
1850
|
|
|
1603
1851
|
// src/hooks/useCreateWallet.ts
|
|
1604
|
-
var
|
|
1605
|
-
var
|
|
1852
|
+
var import_react11 = require("react");
|
|
1853
|
+
var import_miden_sdk13 = require("@miden-sdk/miden-sdk");
|
|
1854
|
+
|
|
1855
|
+
// src/utils/runExclusive.ts
|
|
1856
|
+
var runExclusiveDirect = async (fn) => fn();
|
|
1857
|
+
|
|
1858
|
+
// src/hooks/useCreateWallet.ts
|
|
1606
1859
|
function useCreateWallet() {
|
|
1607
|
-
const { client, isReady,
|
|
1860
|
+
const { client, isReady, runExclusive } = useMiden();
|
|
1608
1861
|
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
1609
1862
|
const setAccounts = useMidenStore((state) => state.setAccounts);
|
|
1610
|
-
const [wallet, setWallet] = (0,
|
|
1611
|
-
const [isCreating, setIsCreating] = (0,
|
|
1612
|
-
const [error, setError] = (0,
|
|
1613
|
-
const createWallet = (0,
|
|
1863
|
+
const [wallet, setWallet] = (0, import_react11.useState)(null);
|
|
1864
|
+
const [isCreating, setIsCreating] = (0, import_react11.useState)(false);
|
|
1865
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
1866
|
+
const createWallet = (0, import_react11.useCallback)(
|
|
1614
1867
|
async (options = {}) => {
|
|
1615
1868
|
if (!client || !isReady) {
|
|
1616
1869
|
throw new Error("Miden client is not ready");
|
|
1617
1870
|
}
|
|
1618
|
-
await sync();
|
|
1619
1871
|
setIsCreating(true);
|
|
1620
1872
|
setError(null);
|
|
1621
1873
|
try {
|
|
@@ -1648,7 +1900,7 @@ function useCreateWallet() {
|
|
|
1648
1900
|
},
|
|
1649
1901
|
[client, isReady, runExclusive, setAccounts]
|
|
1650
1902
|
);
|
|
1651
|
-
const reset = (0,
|
|
1903
|
+
const reset = (0, import_react11.useCallback)(() => {
|
|
1652
1904
|
setWallet(null);
|
|
1653
1905
|
setIsCreating(false);
|
|
1654
1906
|
setError(null);
|
|
@@ -1664,27 +1916,27 @@ function useCreateWallet() {
|
|
|
1664
1916
|
function getStorageMode(mode) {
|
|
1665
1917
|
switch (mode) {
|
|
1666
1918
|
case "private":
|
|
1667
|
-
return
|
|
1919
|
+
return import_miden_sdk13.AccountStorageMode.private();
|
|
1668
1920
|
case "public":
|
|
1669
|
-
return
|
|
1921
|
+
return import_miden_sdk13.AccountStorageMode.public();
|
|
1670
1922
|
case "network":
|
|
1671
|
-
return
|
|
1923
|
+
return import_miden_sdk13.AccountStorageMode.network();
|
|
1672
1924
|
default:
|
|
1673
|
-
return
|
|
1925
|
+
return import_miden_sdk13.AccountStorageMode.private();
|
|
1674
1926
|
}
|
|
1675
1927
|
}
|
|
1676
1928
|
|
|
1677
1929
|
// src/hooks/useCreateFaucet.ts
|
|
1678
|
-
var
|
|
1679
|
-
var
|
|
1930
|
+
var import_react12 = require("react");
|
|
1931
|
+
var import_miden_sdk14 = require("@miden-sdk/miden-sdk");
|
|
1680
1932
|
function useCreateFaucet() {
|
|
1681
1933
|
const { client, isReady, runExclusive } = useMiden();
|
|
1682
1934
|
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
1683
1935
|
const setAccounts = useMidenStore((state) => state.setAccounts);
|
|
1684
|
-
const [faucet, setFaucet] = (0,
|
|
1685
|
-
const [isCreating, setIsCreating] = (0,
|
|
1686
|
-
const [error, setError] = (0,
|
|
1687
|
-
const createFaucet = (0,
|
|
1936
|
+
const [faucet, setFaucet] = (0, import_react12.useState)(null);
|
|
1937
|
+
const [isCreating, setIsCreating] = (0, import_react12.useState)(false);
|
|
1938
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1939
|
+
const createFaucet = (0, import_react12.useCallback)(
|
|
1688
1940
|
async (options) => {
|
|
1689
1941
|
if (!client || !isReady) {
|
|
1690
1942
|
throw new Error("Miden client is not ready");
|
|
@@ -1704,7 +1956,7 @@ function useCreateFaucet() {
|
|
|
1704
1956
|
// nonFungible - currently only fungible faucets supported
|
|
1705
1957
|
options.tokenSymbol,
|
|
1706
1958
|
decimals,
|
|
1707
|
-
options.maxSupply,
|
|
1959
|
+
BigInt(options.maxSupply),
|
|
1708
1960
|
authScheme
|
|
1709
1961
|
);
|
|
1710
1962
|
const accounts = await client.getAccounts();
|
|
@@ -1723,7 +1975,7 @@ function useCreateFaucet() {
|
|
|
1723
1975
|
},
|
|
1724
1976
|
[client, isReady, runExclusive, setAccounts]
|
|
1725
1977
|
);
|
|
1726
|
-
const reset = (0,
|
|
1978
|
+
const reset = (0, import_react12.useCallback)(() => {
|
|
1727
1979
|
setFaucet(null);
|
|
1728
1980
|
setIsCreating(false);
|
|
1729
1981
|
setError(null);
|
|
@@ -1739,51 +1991,105 @@ function useCreateFaucet() {
|
|
|
1739
1991
|
function getStorageMode2(mode) {
|
|
1740
1992
|
switch (mode) {
|
|
1741
1993
|
case "private":
|
|
1742
|
-
return
|
|
1994
|
+
return import_miden_sdk14.AccountStorageMode.private();
|
|
1743
1995
|
case "public":
|
|
1744
|
-
return
|
|
1996
|
+
return import_miden_sdk14.AccountStorageMode.public();
|
|
1745
1997
|
case "network":
|
|
1746
|
-
return
|
|
1998
|
+
return import_miden_sdk14.AccountStorageMode.network();
|
|
1747
1999
|
default:
|
|
1748
|
-
return
|
|
2000
|
+
return import_miden_sdk14.AccountStorageMode.private();
|
|
1749
2001
|
}
|
|
1750
2002
|
}
|
|
1751
2003
|
|
|
1752
2004
|
// src/hooks/useImportAccount.ts
|
|
1753
|
-
var
|
|
1754
|
-
var
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
2005
|
+
var import_react13 = require("react");
|
|
2006
|
+
var import_miden_sdk15 = require("@miden-sdk/miden-sdk");
|
|
2007
|
+
|
|
2008
|
+
// src/utils/errors.ts
|
|
2009
|
+
var MidenError = class extends Error {
|
|
2010
|
+
constructor(message, options) {
|
|
2011
|
+
super(message);
|
|
2012
|
+
this.name = "MidenError";
|
|
2013
|
+
this.code = options?.code ?? "UNKNOWN";
|
|
2014
|
+
if (options?.cause !== void 0) {
|
|
2015
|
+
this.cause = options.cause;
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
};
|
|
2019
|
+
var ERROR_PATTERNS = [
|
|
2020
|
+
{
|
|
2021
|
+
test: (msg) => msg.includes("_assertClass") || msg.includes("expected instance of"),
|
|
2022
|
+
code: "WASM_CLASS_MISMATCH",
|
|
2023
|
+
message: "WASM class identity mismatch. This usually means multiple copies of @miden-sdk/miden-sdk are bundled. Ensure your bundler deduplicates the package. For Vite: add resolve.dedupe and optimizeDeps.exclude for @miden-sdk/miden-sdk."
|
|
2024
|
+
},
|
|
2025
|
+
{
|
|
2026
|
+
test: (msg) => msg.includes("null pointer") || msg.includes("already been freed") || msg.includes("dereferencing a null"),
|
|
2027
|
+
code: "WASM_POINTER_CONSUMED",
|
|
2028
|
+
message: "WASM object was already consumed. Some WASM-bound objects can only be passed once \u2014 if you need to reuse a value, create a fresh instance before each call."
|
|
2029
|
+
},
|
|
2030
|
+
{
|
|
2031
|
+
test: (msg) => msg.includes("not initialized") || msg.includes("Cannot read properties of null"),
|
|
2032
|
+
code: "WASM_NOT_INITIALIZED",
|
|
2033
|
+
message: "Miden client is not initialized. Ensure you are inside a <MidenProvider> and the client is ready before calling SDK methods."
|
|
2034
|
+
},
|
|
2035
|
+
{
|
|
2036
|
+
test: (msg) => msg.includes("state commitment mismatch") || msg.includes("stale state"),
|
|
2037
|
+
code: "WASM_SYNC_REQUIRED",
|
|
2038
|
+
message: "Account state is stale. Call sync() before executing transactions, or ensure no concurrent transactions are running against the same account."
|
|
2039
|
+
}
|
|
2040
|
+
];
|
|
2041
|
+
function assertSignerConnected(signerConnected) {
|
|
2042
|
+
if (signerConnected === false) {
|
|
2043
|
+
throw new Error(
|
|
2044
|
+
"Signer is disconnected. Reconnect your wallet to perform transactions."
|
|
2045
|
+
);
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
function wrapWasmError(e) {
|
|
2049
|
+
if (e instanceof MidenError) return e;
|
|
2050
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2051
|
+
for (const pattern of ERROR_PATTERNS) {
|
|
2052
|
+
if (pattern.test(msg)) {
|
|
2053
|
+
return new MidenError(pattern.message, { cause: e, code: pattern.code });
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
if (e instanceof Error) return e;
|
|
2057
|
+
return new Error(msg);
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
// src/hooks/useImportAccount.ts
|
|
2061
|
+
function useImportAccount() {
|
|
2062
|
+
const { client, isReady, signerConnected } = useMiden();
|
|
2063
|
+
const setAccounts = useMidenStore((state) => state.setAccounts);
|
|
2064
|
+
const [account, setAccount] = (0, import_react13.useState)(null);
|
|
2065
|
+
const [isImporting, setIsImporting] = (0, import_react13.useState)(false);
|
|
2066
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
2067
|
+
const importAccount = (0, import_react13.useCallback)(
|
|
2068
|
+
async (options) => {
|
|
2069
|
+
if (!client || !isReady) {
|
|
2070
|
+
throw new Error("Miden client is not ready");
|
|
2071
|
+
}
|
|
2072
|
+
assertSignerConnected(signerConnected);
|
|
2073
|
+
setIsImporting(true);
|
|
2074
|
+
setError(null);
|
|
2075
|
+
try {
|
|
2076
|
+
let accountsAfter = null;
|
|
2077
|
+
const imported = await (async () => {
|
|
2078
|
+
switch (options.type) {
|
|
2079
|
+
case "file": {
|
|
2080
|
+
const accountsBefore = await client.getAccounts();
|
|
2081
|
+
const accountFile = await resolveAccountFile(options.file);
|
|
2082
|
+
const accountFileWithAccount = accountFile;
|
|
2083
|
+
const fileBytes = getAccountFileBytes(
|
|
2084
|
+
accountFileWithAccount,
|
|
2085
|
+
options.file
|
|
2086
|
+
);
|
|
2087
|
+
const accountFromFile = typeof accountFileWithAccount.account === "function" ? accountFileWithAccount.account() : null;
|
|
2088
|
+
const accountIdFromFile = accountFromFile === null && typeof accountFileWithAccount.accountId === "function" ? accountFileWithAccount.accountId() : null;
|
|
2089
|
+
try {
|
|
2090
|
+
await client.importAccountFile(accountFile);
|
|
2091
|
+
} catch (err) {
|
|
2092
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1787
2093
|
if (!message.includes("already being tracked")) {
|
|
1788
2094
|
throw err;
|
|
1789
2095
|
}
|
|
@@ -1820,7 +2126,7 @@ function useImportAccount() {
|
|
|
1820
2126
|
throw new Error("Account not found after import");
|
|
1821
2127
|
}
|
|
1822
2128
|
case "id": {
|
|
1823
|
-
const accountId =
|
|
2129
|
+
const accountId = parseAccountId(options.accountId);
|
|
1824
2130
|
await client.importAccountById(accountId);
|
|
1825
2131
|
const fetchedAccount = await client.getAccount(accountId);
|
|
1826
2132
|
if (!fetchedAccount) {
|
|
@@ -1838,7 +2144,7 @@ function useImportAccount() {
|
|
|
1838
2144
|
);
|
|
1839
2145
|
}
|
|
1840
2146
|
}
|
|
1841
|
-
});
|
|
2147
|
+
})();
|
|
1842
2148
|
ensureAccountBech32(imported);
|
|
1843
2149
|
const accounts = accountsAfter ?? await client.getAccounts();
|
|
1844
2150
|
setAccounts(accounts);
|
|
@@ -1852,9 +2158,9 @@ function useImportAccount() {
|
|
|
1852
2158
|
setIsImporting(false);
|
|
1853
2159
|
}
|
|
1854
2160
|
},
|
|
1855
|
-
[client, isReady,
|
|
2161
|
+
[client, isReady, setAccounts, signerConnected]
|
|
1856
2162
|
);
|
|
1857
|
-
const reset = (0,
|
|
2163
|
+
const reset = (0, import_react13.useCallback)(() => {
|
|
1858
2164
|
setAccount(null);
|
|
1859
2165
|
setIsImporting(false);
|
|
1860
2166
|
setError(null);
|
|
@@ -1867,15 +2173,12 @@ function useImportAccount() {
|
|
|
1867
2173
|
reset
|
|
1868
2174
|
};
|
|
1869
2175
|
}
|
|
1870
|
-
function resolveAccountId(accountId) {
|
|
1871
|
-
return parseAccountId(accountId);
|
|
1872
|
-
}
|
|
1873
2176
|
async function resolveAccountFile(file) {
|
|
1874
2177
|
if (file instanceof Uint8Array) {
|
|
1875
|
-
return
|
|
2178
|
+
return import_miden_sdk15.AccountFile.deserialize(file);
|
|
1876
2179
|
}
|
|
1877
2180
|
if (file instanceof ArrayBuffer) {
|
|
1878
|
-
return
|
|
2181
|
+
return import_miden_sdk15.AccountFile.deserialize(new Uint8Array(file));
|
|
1879
2182
|
}
|
|
1880
2183
|
return file;
|
|
1881
2184
|
}
|
|
@@ -1904,64 +2207,17 @@ function bytesEqual(left, right) {
|
|
|
1904
2207
|
}
|
|
1905
2208
|
|
|
1906
2209
|
// src/hooks/useSend.ts
|
|
1907
|
-
var
|
|
1908
|
-
var
|
|
1909
|
-
|
|
1910
|
-
// src/utils/errors.ts
|
|
1911
|
-
var MidenError = class extends Error {
|
|
1912
|
-
constructor(message, options) {
|
|
1913
|
-
super(message);
|
|
1914
|
-
this.name = "MidenError";
|
|
1915
|
-
this.code = options?.code ?? "UNKNOWN";
|
|
1916
|
-
if (options?.cause !== void 0) {
|
|
1917
|
-
this.cause = options.cause;
|
|
1918
|
-
}
|
|
1919
|
-
}
|
|
1920
|
-
};
|
|
1921
|
-
var ERROR_PATTERNS = [
|
|
1922
|
-
{
|
|
1923
|
-
test: (msg) => msg.includes("_assertClass") || msg.includes("expected instance of"),
|
|
1924
|
-
code: "WASM_CLASS_MISMATCH",
|
|
1925
|
-
message: "WASM class identity mismatch. This usually means multiple copies of @miden-sdk/miden-sdk are bundled. Ensure your bundler deduplicates the package. For Vite: add resolve.dedupe and optimizeDeps.exclude for @miden-sdk/miden-sdk."
|
|
1926
|
-
},
|
|
1927
|
-
{
|
|
1928
|
-
test: (msg) => msg.includes("null pointer") || msg.includes("already been freed") || msg.includes("dereferencing a null"),
|
|
1929
|
-
code: "WASM_POINTER_CONSUMED",
|
|
1930
|
-
message: "WASM object was already consumed. Some WASM-bound objects can only be passed once \u2014 if you need to reuse a value, create a fresh instance before each call."
|
|
1931
|
-
},
|
|
1932
|
-
{
|
|
1933
|
-
test: (msg) => msg.includes("not initialized") || msg.includes("Cannot read properties of null"),
|
|
1934
|
-
code: "WASM_NOT_INITIALIZED",
|
|
1935
|
-
message: "Miden client is not initialized. Ensure you are inside a <MidenProvider> and the client is ready before calling SDK methods."
|
|
1936
|
-
},
|
|
1937
|
-
{
|
|
1938
|
-
test: (msg) => msg.includes("state commitment mismatch") || msg.includes("stale state"),
|
|
1939
|
-
code: "WASM_SYNC_REQUIRED",
|
|
1940
|
-
message: "Account state is stale. Call sync() before executing transactions, or ensure no concurrent transactions are running against the same account."
|
|
1941
|
-
}
|
|
1942
|
-
];
|
|
1943
|
-
function wrapWasmError(e) {
|
|
1944
|
-
if (e instanceof MidenError) return e;
|
|
1945
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
1946
|
-
for (const pattern of ERROR_PATTERNS) {
|
|
1947
|
-
if (pattern.test(msg)) {
|
|
1948
|
-
return new MidenError(pattern.message, { cause: e, code: pattern.code });
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
if (e instanceof Error) return e;
|
|
1952
|
-
return new Error(msg);
|
|
1953
|
-
}
|
|
1954
|
-
|
|
1955
|
-
// src/hooks/useSend.ts
|
|
2210
|
+
var import_react14 = require("react");
|
|
2211
|
+
var import_miden_sdk16 = require("@miden-sdk/miden-sdk");
|
|
1956
2212
|
function useSend() {
|
|
1957
2213
|
const { client, isReady, sync, runExclusive, prover } = useMiden();
|
|
1958
2214
|
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
1959
|
-
const isBusyRef = (0,
|
|
1960
|
-
const [result, setResult] = (0,
|
|
1961
|
-
const [isLoading, setIsLoading] = (0,
|
|
1962
|
-
const [stage, setStage] = (0,
|
|
1963
|
-
const [error, setError] = (0,
|
|
1964
|
-
const send = (0,
|
|
2215
|
+
const isBusyRef = (0, import_react14.useRef)(false);
|
|
2216
|
+
const [result, setResult] = (0, import_react14.useState)(null);
|
|
2217
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
|
|
2218
|
+
const [stage, setStage] = (0, import_react14.useState)("idle");
|
|
2219
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
2220
|
+
const send = (0, import_react14.useCallback)(
|
|
1965
2221
|
async (options) => {
|
|
1966
2222
|
if (!client || !isReady) {
|
|
1967
2223
|
throw new Error("Miden client is not ready");
|
|
@@ -2003,6 +2259,7 @@ function useSend() {
|
|
|
2003
2259
|
if (amount === void 0 || amount === null) {
|
|
2004
2260
|
throw new Error("Amount is required (provide amount or sendAll)");
|
|
2005
2261
|
}
|
|
2262
|
+
amount = BigInt(amount);
|
|
2006
2263
|
const assetId = options.assetId ?? options.faucetId ?? null;
|
|
2007
2264
|
if (!assetId) {
|
|
2008
2265
|
throw new Error("Asset ID is required");
|
|
@@ -2013,6 +2270,35 @@ function useSend() {
|
|
|
2013
2270
|
"recallHeight and timelockHeight are not supported when attachment is provided"
|
|
2014
2271
|
);
|
|
2015
2272
|
}
|
|
2273
|
+
if (options.returnNote === true) {
|
|
2274
|
+
const returnResult = await runExclusiveSafe(async () => {
|
|
2275
|
+
const fromId = parseAccountId(options.from);
|
|
2276
|
+
const toId = parseAccountId(options.to);
|
|
2277
|
+
const assetObj = parseAccountId(assetId);
|
|
2278
|
+
const assets = new import_miden_sdk16.NoteAssets([
|
|
2279
|
+
new import_miden_sdk16.FungibleAsset(assetObj, BigInt(amount))
|
|
2280
|
+
]);
|
|
2281
|
+
const p2idNote = import_miden_sdk16.Note.createP2IDNote(
|
|
2282
|
+
fromId,
|
|
2283
|
+
toId,
|
|
2284
|
+
assets,
|
|
2285
|
+
noteType,
|
|
2286
|
+
new import_miden_sdk16.NoteAttachment()
|
|
2287
|
+
);
|
|
2288
|
+
const txRequest = new import_miden_sdk16.TransactionRequestBuilder().withOwnOutputNotes(new import_miden_sdk16.NoteArray([p2idNote])).build();
|
|
2289
|
+
const execFromId = parseAccountId(options.from);
|
|
2290
|
+
const txId = prover ? await client.submitNewTransactionWithProver(
|
|
2291
|
+
execFromId,
|
|
2292
|
+
txRequest,
|
|
2293
|
+
prover
|
|
2294
|
+
) : await client.submitNewTransaction(execFromId, txRequest);
|
|
2295
|
+
return { txId: txId.toString(), note: p2idNote };
|
|
2296
|
+
});
|
|
2297
|
+
setStage("complete");
|
|
2298
|
+
setResult(returnResult);
|
|
2299
|
+
await sync();
|
|
2300
|
+
return returnResult;
|
|
2301
|
+
}
|
|
2016
2302
|
const txResult = await runExclusiveSafe(async () => {
|
|
2017
2303
|
const fromAccountId = parseAccountId(options.from);
|
|
2018
2304
|
const toAccountId = parseAccountId(options.to);
|
|
@@ -2020,17 +2306,17 @@ function useSend() {
|
|
|
2020
2306
|
let txRequest;
|
|
2021
2307
|
if (hasAttachment) {
|
|
2022
2308
|
const attachment = createNoteAttachment(options.attachment);
|
|
2023
|
-
const assets = new
|
|
2024
|
-
new
|
|
2309
|
+
const assets = new import_miden_sdk16.NoteAssets([
|
|
2310
|
+
new import_miden_sdk16.FungibleAsset(assetIdObj, amount)
|
|
2025
2311
|
]);
|
|
2026
|
-
const note =
|
|
2312
|
+
const note = import_miden_sdk16.Note.createP2IDNote(
|
|
2027
2313
|
fromAccountId,
|
|
2028
2314
|
toAccountId,
|
|
2029
2315
|
assets,
|
|
2030
2316
|
noteType,
|
|
2031
2317
|
attachment
|
|
2032
2318
|
);
|
|
2033
|
-
txRequest = new
|
|
2319
|
+
txRequest = new import_miden_sdk16.TransactionRequestBuilder().withOwnOutputNotes(new import_miden_sdk16.NoteArray([note])).build();
|
|
2034
2320
|
} else {
|
|
2035
2321
|
txRequest = client.newSendTransactionRequest(
|
|
2036
2322
|
fromAccountId,
|
|
@@ -2046,8 +2332,12 @@ function useSend() {
|
|
|
2046
2332
|
return await client.executeTransaction(execAccountId, txRequest);
|
|
2047
2333
|
});
|
|
2048
2334
|
setStage("proving");
|
|
2049
|
-
const
|
|
2050
|
-
|
|
2335
|
+
const proverConfig = useMidenStore.getState().config;
|
|
2336
|
+
const provenTransaction = await proveWithFallback(
|
|
2337
|
+
(resolvedProver) => runExclusiveSafe(
|
|
2338
|
+
() => client.proveTransaction(txResult, resolvedProver)
|
|
2339
|
+
),
|
|
2340
|
+
proverConfig
|
|
2051
2341
|
);
|
|
2052
2342
|
setStage("submitting");
|
|
2053
2343
|
const submissionHeight = await runExclusiveSafe(
|
|
@@ -2056,13 +2346,13 @@ function useSend() {
|
|
|
2056
2346
|
const txIdHex = txResult.id().toHex();
|
|
2057
2347
|
const txIdString = txResult.id().toString();
|
|
2058
2348
|
let fullNote = null;
|
|
2059
|
-
if (noteType ===
|
|
2349
|
+
if (noteType === import_miden_sdk16.NoteType.Private) {
|
|
2060
2350
|
fullNote = extractFullNote(txResult);
|
|
2061
2351
|
}
|
|
2062
2352
|
await runExclusiveSafe(
|
|
2063
2353
|
() => client.applyTransaction(txResult, submissionHeight)
|
|
2064
2354
|
);
|
|
2065
|
-
if (noteType ===
|
|
2355
|
+
if (noteType === import_miden_sdk16.NoteType.Private) {
|
|
2066
2356
|
if (!fullNote) {
|
|
2067
2357
|
throw new Error("Missing full note for private send");
|
|
2068
2358
|
}
|
|
@@ -2077,11 +2367,14 @@ function useSend() {
|
|
|
2077
2367
|
() => client.sendPrivateNote(fullNote, recipientAddress)
|
|
2078
2368
|
);
|
|
2079
2369
|
}
|
|
2080
|
-
const
|
|
2370
|
+
const sendResult = {
|
|
2371
|
+
txId: txIdString,
|
|
2372
|
+
note: null
|
|
2373
|
+
};
|
|
2081
2374
|
setStage("complete");
|
|
2082
|
-
setResult(
|
|
2375
|
+
setResult(sendResult);
|
|
2083
2376
|
await sync();
|
|
2084
|
-
return
|
|
2377
|
+
return sendResult;
|
|
2085
2378
|
} catch (err) {
|
|
2086
2379
|
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
2087
2380
|
setError(error2);
|
|
@@ -2094,7 +2387,7 @@ function useSend() {
|
|
|
2094
2387
|
},
|
|
2095
2388
|
[client, isReady, prover, runExclusive, sync]
|
|
2096
2389
|
);
|
|
2097
|
-
const reset = (0,
|
|
2390
|
+
const reset = (0, import_react14.useCallback)(() => {
|
|
2098
2391
|
setResult(null);
|
|
2099
2392
|
setIsLoading(false);
|
|
2100
2393
|
setStage("idle");
|
|
@@ -2121,21 +2414,21 @@ function extractFullNote(txResult) {
|
|
|
2121
2414
|
}
|
|
2122
2415
|
|
|
2123
2416
|
// src/hooks/useMultiSend.ts
|
|
2124
|
-
var
|
|
2125
|
-
var
|
|
2417
|
+
var import_react15 = require("react");
|
|
2418
|
+
var import_miden_sdk17 = require("@miden-sdk/miden-sdk");
|
|
2126
2419
|
function useMultiSend() {
|
|
2127
|
-
const { client, isReady, sync,
|
|
2128
|
-
const
|
|
2129
|
-
const
|
|
2130
|
-
const [
|
|
2131
|
-
const [
|
|
2132
|
-
const [
|
|
2133
|
-
const
|
|
2134
|
-
const sendMany = (0, import_react14.useCallback)(
|
|
2420
|
+
const { client, isReady, sync, prover, signerConnected } = useMiden();
|
|
2421
|
+
const isBusyRef = (0, import_react15.useRef)(false);
|
|
2422
|
+
const [result, setResult] = (0, import_react15.useState)(null);
|
|
2423
|
+
const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
|
|
2424
|
+
const [stage, setStage] = (0, import_react15.useState)("idle");
|
|
2425
|
+
const [error, setError] = (0, import_react15.useState)(null);
|
|
2426
|
+
const sendMany = (0, import_react15.useCallback)(
|
|
2135
2427
|
async (options) => {
|
|
2136
2428
|
if (!client || !isReady) {
|
|
2137
2429
|
throw new Error("Miden client is not ready");
|
|
2138
2430
|
}
|
|
2431
|
+
assertSignerConnected(signerConnected);
|
|
2139
2432
|
if (options.recipients.length === 0) {
|
|
2140
2433
|
throw new Error("No recipients provided");
|
|
2141
2434
|
}
|
|
@@ -2159,12 +2452,12 @@ function useMultiSend() {
|
|
|
2159
2452
|
const iterSenderId = parseAccountId(options.from);
|
|
2160
2453
|
const iterAssetId = parseAccountId(options.assetId);
|
|
2161
2454
|
const receiverId = parseAccountId(to);
|
|
2162
|
-
const assets = new
|
|
2163
|
-
new
|
|
2455
|
+
const assets = new import_miden_sdk17.NoteAssets([
|
|
2456
|
+
new import_miden_sdk17.FungibleAsset(iterAssetId, BigInt(amount))
|
|
2164
2457
|
]);
|
|
2165
2458
|
const resolvedNoteType = recipientNoteType ? getNoteType(recipientNoteType) : noteType;
|
|
2166
|
-
const noteAttachment = attachment !== void 0 && attachment !== null ? createNoteAttachment(attachment) : new
|
|
2167
|
-
const note =
|
|
2459
|
+
const noteAttachment = attachment !== void 0 && attachment !== null ? createNoteAttachment(attachment) : new import_miden_sdk17.NoteAttachment();
|
|
2460
|
+
const note = import_miden_sdk17.Note.createP2IDNote(
|
|
2168
2461
|
iterSenderId,
|
|
2169
2462
|
receiverId,
|
|
2170
2463
|
assets,
|
|
@@ -2173,44 +2466,43 @@ function useMultiSend() {
|
|
|
2173
2466
|
);
|
|
2174
2467
|
const recipientAddress = parseAddress(to, receiverId);
|
|
2175
2468
|
return {
|
|
2176
|
-
outputNote: import_miden_sdk16.OutputNote.full(note),
|
|
2177
2469
|
note,
|
|
2178
2470
|
recipientAddress,
|
|
2179
2471
|
noteType: resolvedNoteType
|
|
2180
2472
|
};
|
|
2181
2473
|
}
|
|
2182
2474
|
);
|
|
2183
|
-
const txRequest = new
|
|
2184
|
-
new import_miden_sdk16.OutputNoteArray(outputs.map((o) => o.outputNote))
|
|
2185
|
-
).build();
|
|
2475
|
+
const txRequest = new import_miden_sdk17.TransactionRequestBuilder().withOwnOutputNotes(new import_miden_sdk17.NoteArray(outputs.map((o) => o.note))).build();
|
|
2186
2476
|
const txSenderId = parseAccountId(options.from);
|
|
2187
|
-
const txResult = await
|
|
2188
|
-
() => client.executeTransaction(txSenderId, txRequest)
|
|
2189
|
-
);
|
|
2477
|
+
const txResult = await client.executeTransaction(txSenderId, txRequest);
|
|
2190
2478
|
setStage("proving");
|
|
2191
|
-
const
|
|
2192
|
-
|
|
2479
|
+
const proverConfig = useMidenStore.getState().config;
|
|
2480
|
+
const provenTransaction = await proveWithFallback(
|
|
2481
|
+
(resolvedProver) => runExclusiveDirect(
|
|
2482
|
+
() => client.proveTransaction(txResult, resolvedProver)
|
|
2483
|
+
),
|
|
2484
|
+
proverConfig
|
|
2193
2485
|
);
|
|
2194
2486
|
setStage("submitting");
|
|
2195
|
-
const submissionHeight = await
|
|
2196
|
-
|
|
2487
|
+
const submissionHeight = await client.submitProvenTransaction(
|
|
2488
|
+
provenTransaction,
|
|
2489
|
+
txResult
|
|
2197
2490
|
);
|
|
2198
2491
|
const txIdHex = txResult.id().toHex();
|
|
2199
2492
|
const txIdString = txResult.id().toString();
|
|
2200
|
-
await
|
|
2201
|
-
|
|
2202
|
-
);
|
|
2203
|
-
const hasPrivate = outputs.some((o) => o.noteType === import_miden_sdk16.NoteType.Private);
|
|
2493
|
+
await client.applyTransaction(txResult, submissionHeight);
|
|
2494
|
+
const hasPrivate = outputs.some((o) => o.noteType === import_miden_sdk17.NoteType.Private);
|
|
2204
2495
|
if (hasPrivate) {
|
|
2205
2496
|
await waitForTransactionCommit(
|
|
2206
2497
|
client,
|
|
2207
|
-
|
|
2498
|
+
runExclusiveDirect,
|
|
2208
2499
|
txIdHex
|
|
2209
2500
|
);
|
|
2210
2501
|
for (const output of outputs) {
|
|
2211
|
-
if (output.noteType ===
|
|
2212
|
-
await
|
|
2213
|
-
|
|
2502
|
+
if (output.noteType === import_miden_sdk17.NoteType.Private) {
|
|
2503
|
+
await client.sendPrivateNote(
|
|
2504
|
+
output.note,
|
|
2505
|
+
output.recipientAddress
|
|
2214
2506
|
);
|
|
2215
2507
|
}
|
|
2216
2508
|
}
|
|
@@ -2230,144 +2522,7 @@ function useMultiSend() {
|
|
|
2230
2522
|
isBusyRef.current = false;
|
|
2231
2523
|
}
|
|
2232
2524
|
},
|
|
2233
|
-
[client, isReady, prover,
|
|
2234
|
-
);
|
|
2235
|
-
const reset = (0, import_react14.useCallback)(() => {
|
|
2236
|
-
setResult(null);
|
|
2237
|
-
setIsLoading(false);
|
|
2238
|
-
setStage("idle");
|
|
2239
|
-
setError(null);
|
|
2240
|
-
}, []);
|
|
2241
|
-
return {
|
|
2242
|
-
sendMany,
|
|
2243
|
-
result,
|
|
2244
|
-
isLoading,
|
|
2245
|
-
stage,
|
|
2246
|
-
error,
|
|
2247
|
-
reset
|
|
2248
|
-
};
|
|
2249
|
-
}
|
|
2250
|
-
|
|
2251
|
-
// src/hooks/useInternalTransfer.ts
|
|
2252
|
-
var import_react15 = require("react");
|
|
2253
|
-
var import_miden_sdk17 = require("@miden-sdk/miden-sdk");
|
|
2254
|
-
function useInternalTransfer() {
|
|
2255
|
-
const { client, isReady, sync, runExclusive, prover } = useMiden();
|
|
2256
|
-
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
2257
|
-
const [result, setResult] = (0, import_react15.useState)(null);
|
|
2258
|
-
const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
|
|
2259
|
-
const [stage, setStage] = (0, import_react15.useState)("idle");
|
|
2260
|
-
const [error, setError] = (0, import_react15.useState)(null);
|
|
2261
|
-
const transferOnce = (0, import_react15.useCallback)(
|
|
2262
|
-
async (options) => {
|
|
2263
|
-
if (!client || !isReady) {
|
|
2264
|
-
throw new Error("Miden client is not ready");
|
|
2265
|
-
}
|
|
2266
|
-
const noteType = getNoteType(options.noteType ?? DEFAULTS.NOTE_TYPE);
|
|
2267
|
-
const senderId = parseAccountId(options.from);
|
|
2268
|
-
const receiverId = parseAccountId(options.to);
|
|
2269
|
-
const assetId = parseAccountId(options.assetId);
|
|
2270
|
-
const assets = new import_miden_sdk17.NoteAssets([
|
|
2271
|
-
new import_miden_sdk17.FungibleAsset(assetId, options.amount)
|
|
2272
|
-
]);
|
|
2273
|
-
const note = import_miden_sdk17.Note.createP2IDNote(
|
|
2274
|
-
senderId,
|
|
2275
|
-
receiverId,
|
|
2276
|
-
assets,
|
|
2277
|
-
noteType,
|
|
2278
|
-
new import_miden_sdk17.NoteAttachment()
|
|
2279
|
-
);
|
|
2280
|
-
const noteId = note.id().toString();
|
|
2281
|
-
const createRequest = new import_miden_sdk17.TransactionRequestBuilder().withOwnOutputNotes(new import_miden_sdk17.OutputNoteArray([import_miden_sdk17.OutputNote.full(note)])).build();
|
|
2282
|
-
const createTxId = await runExclusiveSafe(
|
|
2283
|
-
() => prover ? client.submitNewTransactionWithProver(
|
|
2284
|
-
senderId,
|
|
2285
|
-
createRequest,
|
|
2286
|
-
prover
|
|
2287
|
-
) : client.submitNewTransaction(senderId, createRequest)
|
|
2288
|
-
);
|
|
2289
|
-
const consumeRequest = new import_miden_sdk17.TransactionRequestBuilder().withInputNotes(new import_miden_sdk17.NoteAndArgsArray([new import_miden_sdk17.NoteAndArgs(note, null)])).build();
|
|
2290
|
-
const consumeTxId = await runExclusiveSafe(
|
|
2291
|
-
() => prover ? client.submitNewTransactionWithProver(
|
|
2292
|
-
receiverId,
|
|
2293
|
-
consumeRequest,
|
|
2294
|
-
prover
|
|
2295
|
-
) : client.submitNewTransaction(receiverId, consumeRequest)
|
|
2296
|
-
);
|
|
2297
|
-
return {
|
|
2298
|
-
createTransactionId: createTxId.toString(),
|
|
2299
|
-
consumeTransactionId: consumeTxId.toString(),
|
|
2300
|
-
noteId
|
|
2301
|
-
};
|
|
2302
|
-
},
|
|
2303
|
-
[client, isReady, prover, runExclusiveSafe]
|
|
2304
|
-
);
|
|
2305
|
-
const transfer = (0, import_react15.useCallback)(
|
|
2306
|
-
async (options) => {
|
|
2307
|
-
if (!client || !isReady) {
|
|
2308
|
-
throw new Error("Miden client is not ready");
|
|
2309
|
-
}
|
|
2310
|
-
setIsLoading(true);
|
|
2311
|
-
setStage("executing");
|
|
2312
|
-
setError(null);
|
|
2313
|
-
try {
|
|
2314
|
-
setStage("proving");
|
|
2315
|
-
const txResult = await transferOnce(options);
|
|
2316
|
-
setStage("complete");
|
|
2317
|
-
setResult(txResult);
|
|
2318
|
-
await sync();
|
|
2319
|
-
return txResult;
|
|
2320
|
-
} catch (err) {
|
|
2321
|
-
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
2322
|
-
setError(error2);
|
|
2323
|
-
setStage("idle");
|
|
2324
|
-
throw error2;
|
|
2325
|
-
} finally {
|
|
2326
|
-
setIsLoading(false);
|
|
2327
|
-
}
|
|
2328
|
-
},
|
|
2329
|
-
[client, isReady, sync, transferOnce]
|
|
2330
|
-
);
|
|
2331
|
-
const transferChain = (0, import_react15.useCallback)(
|
|
2332
|
-
async (options) => {
|
|
2333
|
-
if (!client || !isReady) {
|
|
2334
|
-
throw new Error("Miden client is not ready");
|
|
2335
|
-
}
|
|
2336
|
-
if (options.recipients.length === 0) {
|
|
2337
|
-
throw new Error("No recipients provided");
|
|
2338
|
-
}
|
|
2339
|
-
setIsLoading(true);
|
|
2340
|
-
setStage("executing");
|
|
2341
|
-
setError(null);
|
|
2342
|
-
try {
|
|
2343
|
-
const results = [];
|
|
2344
|
-
let currentSender = options.from;
|
|
2345
|
-
for (const recipient of options.recipients) {
|
|
2346
|
-
setStage("proving");
|
|
2347
|
-
const txResult = await transferOnce({
|
|
2348
|
-
from: currentSender,
|
|
2349
|
-
to: recipient,
|
|
2350
|
-
assetId: options.assetId,
|
|
2351
|
-
amount: options.amount,
|
|
2352
|
-
noteType: options.noteType
|
|
2353
|
-
});
|
|
2354
|
-
results.push(txResult);
|
|
2355
|
-
currentSender = recipient;
|
|
2356
|
-
}
|
|
2357
|
-
setStage("complete");
|
|
2358
|
-
setResult(results);
|
|
2359
|
-
await sync();
|
|
2360
|
-
return results;
|
|
2361
|
-
} catch (err) {
|
|
2362
|
-
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
2363
|
-
setError(error2);
|
|
2364
|
-
setStage("idle");
|
|
2365
|
-
throw error2;
|
|
2366
|
-
} finally {
|
|
2367
|
-
setIsLoading(false);
|
|
2368
|
-
}
|
|
2369
|
-
},
|
|
2370
|
-
[client, isReady, sync, transferOnce]
|
|
2525
|
+
[client, isReady, prover, signerConnected, sync]
|
|
2371
2526
|
);
|
|
2372
2527
|
const reset = (0, import_react15.useCallback)(() => {
|
|
2373
2528
|
setResult(null);
|
|
@@ -2376,8 +2531,7 @@ function useInternalTransfer() {
|
|
|
2376
2531
|
setError(null);
|
|
2377
2532
|
}, []);
|
|
2378
2533
|
return {
|
|
2379
|
-
|
|
2380
|
-
transferChain,
|
|
2534
|
+
sendMany,
|
|
2381
2535
|
result,
|
|
2382
2536
|
isLoading,
|
|
2383
2537
|
stage,
|
|
@@ -2390,8 +2544,7 @@ function useInternalTransfer() {
|
|
|
2390
2544
|
var import_react16 = require("react");
|
|
2391
2545
|
var import_miden_sdk18 = require("@miden-sdk/miden-sdk");
|
|
2392
2546
|
function useWaitForCommit() {
|
|
2393
|
-
const { client, isReady
|
|
2394
|
-
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
2547
|
+
const { client, isReady } = useMiden();
|
|
2395
2548
|
const waitForCommit = (0, import_react16.useCallback)(
|
|
2396
2549
|
async (txId, options) => {
|
|
2397
2550
|
if (!client || !isReady) {
|
|
@@ -2404,13 +2557,9 @@ function useWaitForCommit() {
|
|
|
2404
2557
|
);
|
|
2405
2558
|
const deadline = Date.now() + timeoutMs;
|
|
2406
2559
|
while (Date.now() < deadline) {
|
|
2407
|
-
await
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
const records = await runExclusiveSafe(
|
|
2411
|
-
() => client.getTransactions(
|
|
2412
|
-
typeof txId === "string" ? import_miden_sdk18.TransactionFilter.all() : import_miden_sdk18.TransactionFilter.ids([txId])
|
|
2413
|
-
)
|
|
2560
|
+
await client.syncState();
|
|
2561
|
+
const records = await client.getTransactions(
|
|
2562
|
+
typeof txId === "string" ? import_miden_sdk18.TransactionFilter.all() : import_miden_sdk18.TransactionFilter.ids([txId])
|
|
2414
2563
|
);
|
|
2415
2564
|
const record = records.find(
|
|
2416
2565
|
(item) => normalizeHex3(item.id().toHex()) === targetHex
|
|
@@ -2428,7 +2577,7 @@ function useWaitForCommit() {
|
|
|
2428
2577
|
}
|
|
2429
2578
|
throw new Error("Timeout waiting for transaction commit");
|
|
2430
2579
|
},
|
|
2431
|
-
[client, isReady
|
|
2580
|
+
[client, isReady]
|
|
2432
2581
|
);
|
|
2433
2582
|
return { waitForCommit };
|
|
2434
2583
|
}
|
|
@@ -2457,11 +2606,11 @@ function useWaitForNotes() {
|
|
|
2457
2606
|
await runExclusiveSafe(
|
|
2458
2607
|
() => client.syncState()
|
|
2459
2608
|
);
|
|
2460
|
-
const
|
|
2609
|
+
const consumable = await runExclusiveSafe(
|
|
2461
2610
|
() => client.getConsumableNotes(accountId)
|
|
2462
2611
|
);
|
|
2463
|
-
if (
|
|
2464
|
-
return
|
|
2612
|
+
if (consumable.length >= minCount) {
|
|
2613
|
+
return consumable;
|
|
2465
2614
|
}
|
|
2466
2615
|
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
2467
2616
|
waited += intervalMs;
|
|
@@ -2500,7 +2649,7 @@ function useMint() {
|
|
|
2500
2649
|
targetAccountIdObj,
|
|
2501
2650
|
faucetIdObj,
|
|
2502
2651
|
noteType,
|
|
2503
|
-
options.amount
|
|
2652
|
+
BigInt(options.amount)
|
|
2504
2653
|
);
|
|
2505
2654
|
const txId = prover ? await client.submitNewTransactionWithProver(
|
|
2506
2655
|
faucetIdObj,
|
|
@@ -2555,8 +2704,8 @@ function useConsume() {
|
|
|
2555
2704
|
if (!client || !isReady) {
|
|
2556
2705
|
throw new Error("Miden client is not ready");
|
|
2557
2706
|
}
|
|
2558
|
-
if (options.
|
|
2559
|
-
throw new Error("No
|
|
2707
|
+
if (options.notes.length === 0) {
|
|
2708
|
+
throw new Error("No notes provided");
|
|
2560
2709
|
}
|
|
2561
2710
|
setIsLoading(true);
|
|
2562
2711
|
setStage("executing");
|
|
@@ -2565,16 +2714,47 @@ function useConsume() {
|
|
|
2565
2714
|
const accountIdObj = parseAccountId(options.accountId);
|
|
2566
2715
|
setStage("proving");
|
|
2567
2716
|
const txResult = await runExclusiveSafe(async () => {
|
|
2568
|
-
const
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2717
|
+
const resolved = new Array(options.notes.length);
|
|
2718
|
+
const lookupIndices = [];
|
|
2719
|
+
const lookupIds = [];
|
|
2720
|
+
for (let i = 0; i < options.notes.length; i++) {
|
|
2721
|
+
const item = options.notes[i];
|
|
2722
|
+
if (typeof item === "string") {
|
|
2723
|
+
lookupIndices.push(i);
|
|
2724
|
+
lookupIds.push(import_miden_sdk19.NoteId.fromHex(item));
|
|
2725
|
+
} else if (item !== null && typeof item === "object" && typeof item.toNote === "function") {
|
|
2726
|
+
resolved[i] = item.toNote();
|
|
2727
|
+
} else if (item !== null && typeof item === "object" && typeof item.id === "function") {
|
|
2728
|
+
resolved[i] = item;
|
|
2729
|
+
} else {
|
|
2730
|
+
lookupIndices.push(i);
|
|
2731
|
+
lookupIds.push(item);
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
if (lookupIds.length > 0) {
|
|
2735
|
+
const filter = new import_miden_sdk19.NoteFilter(import_miden_sdk19.NoteFilterTypes.List, lookupIds);
|
|
2736
|
+
const noteRecords = await client.getInputNotes(filter);
|
|
2737
|
+
if (noteRecords.length !== lookupIds.length) {
|
|
2738
|
+
throw new Error("Some notes could not be found for provided IDs");
|
|
2739
|
+
}
|
|
2740
|
+
const recordById = new Map(
|
|
2741
|
+
noteRecords.map((r) => [r.id().toString(), r])
|
|
2742
|
+
);
|
|
2743
|
+
for (let j = 0; j < lookupIndices.length; j++) {
|
|
2744
|
+
const record = recordById.get(lookupIds[j].toString());
|
|
2745
|
+
if (!record) {
|
|
2746
|
+
throw new Error(
|
|
2747
|
+
"Some notes could not be found for provided IDs"
|
|
2748
|
+
);
|
|
2749
|
+
}
|
|
2750
|
+
resolved[lookupIndices[j]] = record.toNote();
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
const notes = resolved;
|
|
2574
2754
|
if (notes.length === 0) {
|
|
2575
2755
|
throw new Error("No notes found for provided IDs");
|
|
2576
2756
|
}
|
|
2577
|
-
if (notes.length !== options.
|
|
2757
|
+
if (notes.length !== options.notes.length) {
|
|
2578
2758
|
throw new Error("Some notes could not be found for provided IDs");
|
|
2579
2759
|
}
|
|
2580
2760
|
const txRequest = client.newConsumeTransactionRequest(notes);
|
|
@@ -2646,9 +2826,9 @@ function useSwap() {
|
|
|
2646
2826
|
const txRequest = client.newSwapTransactionRequest(
|
|
2647
2827
|
accountIdObj,
|
|
2648
2828
|
offeredFaucetIdObj,
|
|
2649
|
-
options.offeredAmount,
|
|
2829
|
+
BigInt(options.offeredAmount),
|
|
2650
2830
|
requestedFaucetIdObj,
|
|
2651
|
-
options.requestedAmount,
|
|
2831
|
+
BigInt(options.requestedAmount),
|
|
2652
2832
|
noteType,
|
|
2653
2833
|
paybackNoteType
|
|
2654
2834
|
);
|
|
@@ -2692,8 +2872,50 @@ function useSwap() {
|
|
|
2692
2872
|
|
|
2693
2873
|
// src/hooks/useTransaction.ts
|
|
2694
2874
|
var import_react21 = require("react");
|
|
2875
|
+
|
|
2876
|
+
// src/utils/transactions.ts
|
|
2877
|
+
var import_miden_sdk20 = require("@miden-sdk/miden-sdk");
|
|
2878
|
+
async function waitForTransactionCommit2(client, runExclusiveSafe, txId, maxWaitMs = 1e4, delayMs = 1e3) {
|
|
2879
|
+
let waited = 0;
|
|
2880
|
+
while (waited < maxWaitMs) {
|
|
2881
|
+
await runExclusiveSafe(() => client.syncState());
|
|
2882
|
+
const [record] = await runExclusiveSafe(
|
|
2883
|
+
() => client.getTransactions(import_miden_sdk20.TransactionFilter.ids([txId]))
|
|
2884
|
+
);
|
|
2885
|
+
if (record) {
|
|
2886
|
+
const status = record.transactionStatus();
|
|
2887
|
+
if (status.isCommitted()) {
|
|
2888
|
+
return;
|
|
2889
|
+
}
|
|
2890
|
+
if (status.isDiscarded()) {
|
|
2891
|
+
throw new Error("Transaction was discarded before commit");
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
2895
|
+
waited += delayMs;
|
|
2896
|
+
}
|
|
2897
|
+
throw new Error("Timeout waiting for transaction commit");
|
|
2898
|
+
}
|
|
2899
|
+
function extractFullNotes(txResult) {
|
|
2900
|
+
try {
|
|
2901
|
+
const executedTx = txResult.executedTransaction?.();
|
|
2902
|
+
const notes = executedTx?.outputNotes?.().notes?.() ?? [];
|
|
2903
|
+
const result = [];
|
|
2904
|
+
for (const note of notes) {
|
|
2905
|
+
if (note.noteType?.() === import_miden_sdk20.NoteType.Private) {
|
|
2906
|
+
const full = note.intoFull?.();
|
|
2907
|
+
if (full) result.push(full);
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
return result;
|
|
2911
|
+
} catch {
|
|
2912
|
+
return [];
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2915
|
+
|
|
2916
|
+
// src/hooks/useTransaction.ts
|
|
2695
2917
|
function useTransaction() {
|
|
2696
|
-
const { client, isReady, sync, runExclusive
|
|
2918
|
+
const { client, isReady, sync, runExclusive } = useMiden();
|
|
2697
2919
|
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
2698
2920
|
const isBusyRef = (0, import_react21.useRef)(false);
|
|
2699
2921
|
const [result, setResult] = (0, import_react21.useState)(null);
|
|
@@ -2720,20 +2942,41 @@ function useTransaction() {
|
|
|
2720
2942
|
await sync();
|
|
2721
2943
|
}
|
|
2722
2944
|
const txRequest = await resolveRequest(options.request, client);
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
const txId = prover ? await client.submitNewTransactionWithProver(
|
|
2727
|
-
accountIdObj,
|
|
2728
|
-
txRequest,
|
|
2729
|
-
prover
|
|
2730
|
-
) : await client.submitNewTransaction(accountIdObj, txRequest);
|
|
2731
|
-
return { transactionId: txId.toString() };
|
|
2945
|
+
const txResult = await runExclusiveSafe(() => {
|
|
2946
|
+
const accountIdObj = parseAccountId(options.accountId);
|
|
2947
|
+
return client.executeTransaction(accountIdObj, txRequest);
|
|
2732
2948
|
});
|
|
2949
|
+
setStage("proving");
|
|
2950
|
+
const proverConfig = useMidenStore.getState().config;
|
|
2951
|
+
const provenTransaction = await proveWithFallback(
|
|
2952
|
+
(resolvedProver) => runExclusiveSafe(
|
|
2953
|
+
() => client.proveTransaction(txResult, resolvedProver)
|
|
2954
|
+
),
|
|
2955
|
+
proverConfig
|
|
2956
|
+
);
|
|
2957
|
+
setStage("submitting");
|
|
2958
|
+
const submissionHeight = await runExclusiveSafe(
|
|
2959
|
+
() => client.submitProvenTransaction(provenTransaction, txResult)
|
|
2960
|
+
);
|
|
2961
|
+
await runExclusiveSafe(
|
|
2962
|
+
() => client.applyTransaction(txResult, submissionHeight)
|
|
2963
|
+
);
|
|
2964
|
+
const txId = txResult.id();
|
|
2965
|
+
if (options.privateNoteTarget != null) {
|
|
2966
|
+
await waitForTransactionCommit2(client, runExclusiveSafe, txId);
|
|
2967
|
+
const targetAddress = parseAddress(options.privateNoteTarget);
|
|
2968
|
+
const fullNotes = extractFullNotes(txResult);
|
|
2969
|
+
for (const note of fullNotes) {
|
|
2970
|
+
await runExclusiveSafe(
|
|
2971
|
+
() => client.sendPrivateNote(note, targetAddress)
|
|
2972
|
+
);
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
const txSummary = { transactionId: txId.toString() };
|
|
2733
2976
|
setStage("complete");
|
|
2734
|
-
setResult(
|
|
2977
|
+
setResult(txSummary);
|
|
2735
2978
|
await sync();
|
|
2736
|
-
return
|
|
2979
|
+
return txSummary;
|
|
2737
2980
|
} catch (err) {
|
|
2738
2981
|
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
2739
2982
|
setError(error2);
|
|
@@ -2744,7 +2987,7 @@ function useTransaction() {
|
|
|
2744
2987
|
isBusyRef.current = false;
|
|
2745
2988
|
}
|
|
2746
2989
|
},
|
|
2747
|
-
[client, isReady,
|
|
2990
|
+
[client, isReady, runExclusive, sync]
|
|
2748
2991
|
);
|
|
2749
2992
|
const reset = (0, import_react21.useCallback)(() => {
|
|
2750
2993
|
setResult(null);
|
|
@@ -2761,9 +3004,6 @@ function useTransaction() {
|
|
|
2761
3004
|
reset
|
|
2762
3005
|
};
|
|
2763
3006
|
}
|
|
2764
|
-
function resolveAccountId2(accountId) {
|
|
2765
|
-
return parseAccountId(accountId);
|
|
2766
|
-
}
|
|
2767
3007
|
async function resolveRequest(request, client) {
|
|
2768
3008
|
if (typeof request === "function") {
|
|
2769
3009
|
return await request(client);
|
|
@@ -2771,27 +3011,112 @@ async function resolveRequest(request, client) {
|
|
|
2771
3011
|
return request;
|
|
2772
3012
|
}
|
|
2773
3013
|
|
|
2774
|
-
// src/hooks/
|
|
3014
|
+
// src/hooks/useExecuteProgram.ts
|
|
2775
3015
|
var import_react22 = require("react");
|
|
2776
|
-
var
|
|
2777
|
-
function
|
|
3016
|
+
var import_miden_sdk21 = require("@miden-sdk/miden-sdk");
|
|
3017
|
+
function isForeignAccountWrapper(fa) {
|
|
3018
|
+
return fa !== null && typeof fa === "object" && "id" in fa && typeof fa.id !== "function";
|
|
3019
|
+
}
|
|
3020
|
+
function useExecuteProgram() {
|
|
2778
3021
|
const { client, isReady, sync, runExclusive } = useMiden();
|
|
2779
3022
|
const runExclusiveSafe = runExclusive ?? runExclusiveDirect;
|
|
2780
|
-
const setAccounts = useMidenStore((state) => state.setAccounts);
|
|
2781
|
-
const [sessionAccountId, setSessionAccountId] = (0, import_react22.useState)(null);
|
|
2782
|
-
const [step, setStep] = (0, import_react22.useState)("idle");
|
|
2783
|
-
const [error, setError] = (0, import_react22.useState)(null);
|
|
2784
|
-
const cancelledRef = (0, import_react22.useRef)(false);
|
|
2785
3023
|
const isBusyRef = (0, import_react22.useRef)(false);
|
|
3024
|
+
const [result, setResult] = (0, import_react22.useState)(null);
|
|
3025
|
+
const [isLoading, setIsLoading] = (0, import_react22.useState)(false);
|
|
3026
|
+
const [error, setError] = (0, import_react22.useState)(null);
|
|
3027
|
+
const execute = (0, import_react22.useCallback)(
|
|
3028
|
+
async (options) => {
|
|
3029
|
+
if (!client || !isReady) {
|
|
3030
|
+
throw new Error("Miden client is not ready");
|
|
3031
|
+
}
|
|
3032
|
+
if (isBusyRef.current) {
|
|
3033
|
+
throw new MidenError(
|
|
3034
|
+
"A program execution is already in progress. Await the previous call before starting another.",
|
|
3035
|
+
{ code: "OPERATION_BUSY" }
|
|
3036
|
+
);
|
|
3037
|
+
}
|
|
3038
|
+
isBusyRef.current = true;
|
|
3039
|
+
setIsLoading(true);
|
|
3040
|
+
setError(null);
|
|
3041
|
+
try {
|
|
3042
|
+
if (!options.skipSync) {
|
|
3043
|
+
await sync();
|
|
3044
|
+
}
|
|
3045
|
+
const programResult = await runExclusiveSafe(async () => {
|
|
3046
|
+
const accountIdObj = parseAccountId(options.accountId);
|
|
3047
|
+
const adviceInputs = options.adviceInputs ?? new import_miden_sdk21.AdviceInputs();
|
|
3048
|
+
let foreignAccountsArray;
|
|
3049
|
+
if (options.foreignAccounts?.length) {
|
|
3050
|
+
const accounts = options.foreignAccounts.map((fa) => {
|
|
3051
|
+
const wrapper = isForeignAccountWrapper(fa);
|
|
3052
|
+
const id = parseAccountId(wrapper ? fa.id : fa);
|
|
3053
|
+
const storage = wrapper && fa.storage ? fa.storage : new import_miden_sdk21.AccountStorageRequirements();
|
|
3054
|
+
return import_miden_sdk21.ForeignAccount.public(id, storage);
|
|
3055
|
+
});
|
|
3056
|
+
foreignAccountsArray = new import_miden_sdk21.ForeignAccountArray(accounts);
|
|
3057
|
+
} else {
|
|
3058
|
+
foreignAccountsArray = new import_miden_sdk21.ForeignAccountArray();
|
|
3059
|
+
}
|
|
3060
|
+
const feltArray = await client.executeProgram(
|
|
3061
|
+
accountIdObj,
|
|
3062
|
+
options.script,
|
|
3063
|
+
adviceInputs,
|
|
3064
|
+
foreignAccountsArray
|
|
3065
|
+
);
|
|
3066
|
+
const stack = [];
|
|
3067
|
+
const len = feltArray.length();
|
|
3068
|
+
for (let i = 0; i < len; i++) {
|
|
3069
|
+
stack.push(feltArray.get(i).asInt());
|
|
3070
|
+
}
|
|
3071
|
+
return { stack };
|
|
3072
|
+
});
|
|
3073
|
+
setResult(programResult);
|
|
3074
|
+
return programResult;
|
|
3075
|
+
} catch (err) {
|
|
3076
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
3077
|
+
setError(error2);
|
|
3078
|
+
throw error2;
|
|
3079
|
+
} finally {
|
|
3080
|
+
setIsLoading(false);
|
|
3081
|
+
isBusyRef.current = false;
|
|
3082
|
+
}
|
|
3083
|
+
},
|
|
3084
|
+
[client, isReady, runExclusive, sync]
|
|
3085
|
+
);
|
|
3086
|
+
const reset = (0, import_react22.useCallback)(() => {
|
|
3087
|
+
setResult(null);
|
|
3088
|
+
setIsLoading(false);
|
|
3089
|
+
setError(null);
|
|
3090
|
+
}, []);
|
|
3091
|
+
return {
|
|
3092
|
+
execute,
|
|
3093
|
+
result,
|
|
3094
|
+
isLoading,
|
|
3095
|
+
error,
|
|
3096
|
+
reset
|
|
3097
|
+
};
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
// src/hooks/useSessionAccount.ts
|
|
3101
|
+
var import_react23 = require("react");
|
|
3102
|
+
var import_miden_sdk22 = require("@miden-sdk/miden-sdk");
|
|
3103
|
+
function useSessionAccount(options) {
|
|
3104
|
+
const { client, isReady, sync } = useMiden();
|
|
3105
|
+
const setAccounts = useMidenStore((state) => state.setAccounts);
|
|
3106
|
+
const [sessionAccountId, setSessionAccountId] = (0, import_react23.useState)(null);
|
|
3107
|
+
const [step, setStep] = (0, import_react23.useState)("idle");
|
|
3108
|
+
const [error, setError] = (0, import_react23.useState)(null);
|
|
3109
|
+
const cancelledRef = (0, import_react23.useRef)(false);
|
|
3110
|
+
const isBusyRef = (0, import_react23.useRef)(false);
|
|
2786
3111
|
const storagePrefix = options.storagePrefix ?? "miden-session";
|
|
2787
3112
|
const pollIntervalMs = options.pollIntervalMs ?? 3e3;
|
|
2788
3113
|
const maxWaitMs = options.maxWaitMs ?? 6e4;
|
|
2789
3114
|
const storageMode = options.walletOptions?.storageMode ?? "public";
|
|
2790
3115
|
const mutable = options.walletOptions?.mutable ?? DEFAULTS.WALLET_MUTABLE;
|
|
2791
3116
|
const authScheme = options.walletOptions?.authScheme ?? DEFAULTS.AUTH_SCHEME;
|
|
2792
|
-
const fundRef = (0,
|
|
3117
|
+
const fundRef = (0, import_react23.useRef)(options.fund);
|
|
2793
3118
|
fundRef.current = options.fund;
|
|
2794
|
-
(0,
|
|
3119
|
+
(0, import_react23.useEffect)(() => {
|
|
2795
3120
|
try {
|
|
2796
3121
|
const stored = localStorage.getItem(`${storagePrefix}:accountId`);
|
|
2797
3122
|
const storedReady = localStorage.getItem(`${storagePrefix}:ready`);
|
|
@@ -2808,7 +3133,7 @@ function useSessionAccount(options) {
|
|
|
2808
3133
|
localStorage.removeItem(`${storagePrefix}:ready`);
|
|
2809
3134
|
}
|
|
2810
3135
|
}, [storagePrefix]);
|
|
2811
|
-
const initialize = (0,
|
|
3136
|
+
const initialize = (0, import_react23.useCallback)(async () => {
|
|
2812
3137
|
if (!client || !isReady) {
|
|
2813
3138
|
throw new Error("Miden client is not ready");
|
|
2814
3139
|
}
|
|
@@ -2826,17 +3151,14 @@ function useSessionAccount(options) {
|
|
|
2826
3151
|
if (!walletId) {
|
|
2827
3152
|
setStep("creating");
|
|
2828
3153
|
const resolvedStorageMode = getStorageMode3(storageMode);
|
|
2829
|
-
const wallet = await
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
setAccounts(accounts);
|
|
2838
|
-
return w;
|
|
2839
|
-
});
|
|
3154
|
+
const wallet = await client.newWallet(
|
|
3155
|
+
resolvedStorageMode,
|
|
3156
|
+
mutable,
|
|
3157
|
+
authScheme
|
|
3158
|
+
);
|
|
3159
|
+
ensureAccountBech32(wallet);
|
|
3160
|
+
const accounts = await client.getAccounts();
|
|
3161
|
+
setAccounts(accounts);
|
|
2840
3162
|
if (cancelledRef.current) return;
|
|
2841
3163
|
walletId = wallet.id().toString();
|
|
2842
3164
|
setSessionAccountId(walletId);
|
|
@@ -2848,7 +3170,6 @@ function useSessionAccount(options) {
|
|
|
2848
3170
|
setStep("consuming");
|
|
2849
3171
|
await waitAndConsume(
|
|
2850
3172
|
client,
|
|
2851
|
-
runExclusiveSafe,
|
|
2852
3173
|
walletId,
|
|
2853
3174
|
pollIntervalMs,
|
|
2854
3175
|
maxWaitMs,
|
|
@@ -2872,7 +3193,6 @@ function useSessionAccount(options) {
|
|
|
2872
3193
|
client,
|
|
2873
3194
|
isReady,
|
|
2874
3195
|
sync,
|
|
2875
|
-
runExclusiveSafe,
|
|
2876
3196
|
sessionAccountId,
|
|
2877
3197
|
storageMode,
|
|
2878
3198
|
mutable,
|
|
@@ -2882,7 +3202,7 @@ function useSessionAccount(options) {
|
|
|
2882
3202
|
maxWaitMs,
|
|
2883
3203
|
setAccounts
|
|
2884
3204
|
]);
|
|
2885
|
-
const reset = (0,
|
|
3205
|
+
const reset = (0, import_react23.useCallback)(() => {
|
|
2886
3206
|
cancelledRef.current = true;
|
|
2887
3207
|
isBusyRef.current = false;
|
|
2888
3208
|
setSessionAccountId(null);
|
|
@@ -2903,37 +3223,209 @@ function useSessionAccount(options) {
|
|
|
2903
3223
|
function getStorageMode3(mode) {
|
|
2904
3224
|
switch (mode) {
|
|
2905
3225
|
case "private":
|
|
2906
|
-
return
|
|
3226
|
+
return import_miden_sdk22.AccountStorageMode.private();
|
|
2907
3227
|
case "public":
|
|
2908
|
-
return
|
|
3228
|
+
return import_miden_sdk22.AccountStorageMode.public();
|
|
2909
3229
|
default:
|
|
2910
|
-
return
|
|
3230
|
+
return import_miden_sdk22.AccountStorageMode.public();
|
|
2911
3231
|
}
|
|
2912
3232
|
}
|
|
2913
|
-
async function waitAndConsume(client,
|
|
3233
|
+
async function waitAndConsume(client, walletId, pollIntervalMs, maxWaitMs, cancelledRef) {
|
|
2914
3234
|
const deadline = Date.now() + maxWaitMs;
|
|
2915
3235
|
while (Date.now() < deadline) {
|
|
2916
3236
|
if (cancelledRef.current) return;
|
|
2917
|
-
await
|
|
2918
|
-
() => client.syncState()
|
|
2919
|
-
);
|
|
3237
|
+
await client.syncState();
|
|
2920
3238
|
if (cancelledRef.current) return;
|
|
2921
|
-
const
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
if (consumable.length === 0) return false;
|
|
3239
|
+
const accountIdObj = parseAccountId(walletId);
|
|
3240
|
+
const consumable = await client.getConsumableNotes(accountIdObj);
|
|
3241
|
+
if (consumable.length > 0) {
|
|
2925
3242
|
const notes = consumable.map((c) => c.inputNoteRecord().toNote());
|
|
2926
3243
|
const txRequest = client.newConsumeTransactionRequest(notes);
|
|
2927
3244
|
const freshAccountId = parseAccountId(walletId);
|
|
2928
3245
|
await client.submitNewTransaction(freshAccountId, txRequest);
|
|
2929
|
-
return
|
|
2930
|
-
}
|
|
2931
|
-
if (consumed) return;
|
|
3246
|
+
return;
|
|
3247
|
+
}
|
|
2932
3248
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
2933
3249
|
}
|
|
2934
3250
|
throw new Error("Timeout waiting for session wallet funding");
|
|
2935
3251
|
}
|
|
2936
3252
|
|
|
3253
|
+
// src/hooks/useExportStore.ts
|
|
3254
|
+
var import_react24 = require("react");
|
|
3255
|
+
var import_miden_sdk23 = require("@miden-sdk/miden-sdk");
|
|
3256
|
+
function useExportStore() {
|
|
3257
|
+
const { client, isReady, runExclusive } = useMiden();
|
|
3258
|
+
const [isExporting, setIsExporting] = (0, import_react24.useState)(false);
|
|
3259
|
+
const [error, setError] = (0, import_react24.useState)(null);
|
|
3260
|
+
const exportStore = (0, import_react24.useCallback)(async () => {
|
|
3261
|
+
if (!client || !isReady) {
|
|
3262
|
+
throw new Error("Miden client is not ready");
|
|
3263
|
+
}
|
|
3264
|
+
setIsExporting(true);
|
|
3265
|
+
setError(null);
|
|
3266
|
+
try {
|
|
3267
|
+
const storeName = client.storeIdentifier();
|
|
3268
|
+
const snapshot = await runExclusive(() => (0, import_miden_sdk23.exportStore)(storeName));
|
|
3269
|
+
return snapshot;
|
|
3270
|
+
} catch (err) {
|
|
3271
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
3272
|
+
setError(error2);
|
|
3273
|
+
throw error2;
|
|
3274
|
+
} finally {
|
|
3275
|
+
setIsExporting(false);
|
|
3276
|
+
}
|
|
3277
|
+
}, [client, isReady, runExclusive]);
|
|
3278
|
+
const reset = (0, import_react24.useCallback)(() => {
|
|
3279
|
+
setIsExporting(false);
|
|
3280
|
+
setError(null);
|
|
3281
|
+
}, []);
|
|
3282
|
+
return {
|
|
3283
|
+
exportStore,
|
|
3284
|
+
isExporting,
|
|
3285
|
+
error,
|
|
3286
|
+
reset
|
|
3287
|
+
};
|
|
3288
|
+
}
|
|
3289
|
+
|
|
3290
|
+
// src/hooks/useImportStore.ts
|
|
3291
|
+
var import_react25 = require("react");
|
|
3292
|
+
var import_miden_sdk24 = require("@miden-sdk/miden-sdk");
|
|
3293
|
+
function useImportStore() {
|
|
3294
|
+
const { client, isReady, runExclusive, sync } = useMiden();
|
|
3295
|
+
const [isImporting, setIsImporting] = (0, import_react25.useState)(false);
|
|
3296
|
+
const [error, setError] = (0, import_react25.useState)(null);
|
|
3297
|
+
const importStore = (0, import_react25.useCallback)(
|
|
3298
|
+
async (storeDump, storeName, options) => {
|
|
3299
|
+
if (!client || !isReady) {
|
|
3300
|
+
throw new Error("Miden client is not ready");
|
|
3301
|
+
}
|
|
3302
|
+
setIsImporting(true);
|
|
3303
|
+
setError(null);
|
|
3304
|
+
try {
|
|
3305
|
+
await runExclusive(() => (0, import_miden_sdk24.importStore)(storeName, storeDump));
|
|
3306
|
+
if (!options?.skipSync) {
|
|
3307
|
+
await sync();
|
|
3308
|
+
}
|
|
3309
|
+
} catch (err) {
|
|
3310
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
3311
|
+
setError(error2);
|
|
3312
|
+
throw error2;
|
|
3313
|
+
} finally {
|
|
3314
|
+
setIsImporting(false);
|
|
3315
|
+
}
|
|
3316
|
+
},
|
|
3317
|
+
[client, isReady, runExclusive, sync]
|
|
3318
|
+
);
|
|
3319
|
+
const reset = (0, import_react25.useCallback)(() => {
|
|
3320
|
+
setIsImporting(false);
|
|
3321
|
+
setError(null);
|
|
3322
|
+
}, []);
|
|
3323
|
+
return {
|
|
3324
|
+
importStore,
|
|
3325
|
+
isImporting,
|
|
3326
|
+
error,
|
|
3327
|
+
reset
|
|
3328
|
+
};
|
|
3329
|
+
}
|
|
3330
|
+
|
|
3331
|
+
// src/hooks/useImportNote.ts
|
|
3332
|
+
var import_react26 = require("react");
|
|
3333
|
+
var import_miden_sdk25 = require("@miden-sdk/miden-sdk");
|
|
3334
|
+
function useImportNote() {
|
|
3335
|
+
const { client, isReady, runExclusive, sync } = useMiden();
|
|
3336
|
+
const [isImporting, setIsImporting] = (0, import_react26.useState)(false);
|
|
3337
|
+
const [error, setError] = (0, import_react26.useState)(null);
|
|
3338
|
+
const importNote = (0, import_react26.useCallback)(
|
|
3339
|
+
async (noteBytes) => {
|
|
3340
|
+
if (!client || !isReady) {
|
|
3341
|
+
throw new Error("Miden client is not ready");
|
|
3342
|
+
}
|
|
3343
|
+
setIsImporting(true);
|
|
3344
|
+
setError(null);
|
|
3345
|
+
try {
|
|
3346
|
+
const noteFile = import_miden_sdk25.NoteFile.deserialize(noteBytes);
|
|
3347
|
+
const noteId = await runExclusive(
|
|
3348
|
+
() => client.importNoteFile(noteFile)
|
|
3349
|
+
);
|
|
3350
|
+
await sync();
|
|
3351
|
+
return noteId.toString();
|
|
3352
|
+
} catch (err) {
|
|
3353
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
3354
|
+
setError(error2);
|
|
3355
|
+
throw error2;
|
|
3356
|
+
} finally {
|
|
3357
|
+
setIsImporting(false);
|
|
3358
|
+
}
|
|
3359
|
+
},
|
|
3360
|
+
[client, isReady, runExclusive, sync]
|
|
3361
|
+
);
|
|
3362
|
+
const reset = (0, import_react26.useCallback)(() => {
|
|
3363
|
+
setIsImporting(false);
|
|
3364
|
+
setError(null);
|
|
3365
|
+
}, []);
|
|
3366
|
+
return {
|
|
3367
|
+
importNote,
|
|
3368
|
+
isImporting,
|
|
3369
|
+
error,
|
|
3370
|
+
reset
|
|
3371
|
+
};
|
|
3372
|
+
}
|
|
3373
|
+
|
|
3374
|
+
// src/hooks/useExportNote.ts
|
|
3375
|
+
var import_react27 = require("react");
|
|
3376
|
+
var import_miden_sdk26 = require("@miden-sdk/miden-sdk");
|
|
3377
|
+
function useExportNote() {
|
|
3378
|
+
const { client, isReady, runExclusive } = useMiden();
|
|
3379
|
+
const [isExporting, setIsExporting] = (0, import_react27.useState)(false);
|
|
3380
|
+
const [error, setError] = (0, import_react27.useState)(null);
|
|
3381
|
+
const exportNote = (0, import_react27.useCallback)(
|
|
3382
|
+
async (noteId) => {
|
|
3383
|
+
if (!client || !isReady) {
|
|
3384
|
+
throw new Error("Miden client is not ready");
|
|
3385
|
+
}
|
|
3386
|
+
setIsExporting(true);
|
|
3387
|
+
setError(null);
|
|
3388
|
+
try {
|
|
3389
|
+
const noteFile = await runExclusive(
|
|
3390
|
+
() => client.exportNoteFile(noteId, import_miden_sdk26.NoteExportFormat.Full)
|
|
3391
|
+
);
|
|
3392
|
+
return noteFile.serialize();
|
|
3393
|
+
} catch (err) {
|
|
3394
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
3395
|
+
setError(error2);
|
|
3396
|
+
throw error2;
|
|
3397
|
+
} finally {
|
|
3398
|
+
setIsExporting(false);
|
|
3399
|
+
}
|
|
3400
|
+
},
|
|
3401
|
+
[client, isReady, runExclusive]
|
|
3402
|
+
);
|
|
3403
|
+
const reset = (0, import_react27.useCallback)(() => {
|
|
3404
|
+
setIsExporting(false);
|
|
3405
|
+
setError(null);
|
|
3406
|
+
}, []);
|
|
3407
|
+
return {
|
|
3408
|
+
exportNote,
|
|
3409
|
+
isExporting,
|
|
3410
|
+
error,
|
|
3411
|
+
reset
|
|
3412
|
+
};
|
|
3413
|
+
}
|
|
3414
|
+
|
|
3415
|
+
// src/hooks/useSyncControl.ts
|
|
3416
|
+
var import_react28 = require("react");
|
|
3417
|
+
function useSyncControl() {
|
|
3418
|
+
const isPaused = useMidenStore((state) => state.syncPaused);
|
|
3419
|
+
const setSyncPaused = useMidenStore((state) => state.setSyncPaused);
|
|
3420
|
+
const pauseSync = (0, import_react28.useCallback)(() => setSyncPaused(true), [setSyncPaused]);
|
|
3421
|
+
const resumeSync = (0, import_react28.useCallback)(() => setSyncPaused(false), [setSyncPaused]);
|
|
3422
|
+
return {
|
|
3423
|
+
pauseSync,
|
|
3424
|
+
resumeSync,
|
|
3425
|
+
isPaused
|
|
3426
|
+
};
|
|
3427
|
+
}
|
|
3428
|
+
|
|
2937
3429
|
// src/utils/bytes.ts
|
|
2938
3430
|
function bytesToBigInt(bytes) {
|
|
2939
3431
|
let result = 0n;
|
|
@@ -3085,10 +3577,13 @@ function createMidenStorage(prefix) {
|
|
|
3085
3577
|
installAccountBech32();
|
|
3086
3578
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3087
3579
|
0 && (module.exports = {
|
|
3580
|
+
AuthScheme,
|
|
3088
3581
|
DEFAULTS,
|
|
3089
3582
|
MidenError,
|
|
3090
3583
|
MidenProvider,
|
|
3584
|
+
MultiSignerProvider,
|
|
3091
3585
|
SignerContext,
|
|
3586
|
+
SignerSlot,
|
|
3092
3587
|
accountIdsEqual,
|
|
3093
3588
|
bigIntToBytes,
|
|
3094
3589
|
bytesToBigInt,
|
|
@@ -3110,18 +3605,24 @@ installAccountBech32();
|
|
|
3110
3605
|
useConsume,
|
|
3111
3606
|
useCreateFaucet,
|
|
3112
3607
|
useCreateWallet,
|
|
3608
|
+
useExecuteProgram,
|
|
3609
|
+
useExportNote,
|
|
3610
|
+
useExportStore,
|
|
3113
3611
|
useImportAccount,
|
|
3114
|
-
|
|
3612
|
+
useImportNote,
|
|
3613
|
+
useImportStore,
|
|
3115
3614
|
useMiden,
|
|
3116
3615
|
useMidenClient,
|
|
3117
3616
|
useMint,
|
|
3118
3617
|
useMultiSend,
|
|
3618
|
+
useMultiSigner,
|
|
3119
3619
|
useNoteStream,
|
|
3120
3620
|
useNotes,
|
|
3121
3621
|
useSend,
|
|
3122
3622
|
useSessionAccount,
|
|
3123
3623
|
useSigner,
|
|
3124
3624
|
useSwap,
|
|
3625
|
+
useSyncControl,
|
|
3125
3626
|
useSyncState,
|
|
3126
3627
|
useTransaction,
|
|
3127
3628
|
useTransactionHistory,
|