@oasisprotocol/privana-sdk 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunk4IW4V7YJ_cjs = require('./chunk-4IW4V7YJ.cjs');
4
+ var chunk7KEQHWZB_cjs = require('./chunk-7KEQHWZB.cjs');
5
5
  var react = require('react');
6
6
  var reactQuery = require('@tanstack/react-query');
7
7
  var wagmi = require('wagmi');
@@ -35,18 +35,18 @@ var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive)
35
35
 
36
36
  // src/sdk/hooks/use-privana-client.ts
37
37
  function usePrivanaClient() {
38
- const { client } = chunk4IW4V7YJ_cjs.usePrivanaContext();
38
+ const { client } = chunk7KEQHWZB_cjs.usePrivanaContext();
39
39
  return client;
40
40
  }
41
41
  var hostedAuthExchangeInflight = /* @__PURE__ */ new Map();
42
42
  function normalizeHostedAuthError(error) {
43
- if (error instanceof chunk4IW4V7YJ_cjs.AccountingApiError && error.detail) {
44
- return new chunk4IW4V7YJ_cjs.HostedAuthError(error.detail);
43
+ if (error instanceof chunk7KEQHWZB_cjs.AccountingApiError && error.detail) {
44
+ return new chunk7KEQHWZB_cjs.HostedAuthError(error.detail);
45
45
  }
46
46
  if (error instanceof Error) {
47
47
  return error;
48
48
  }
49
- return new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted authentication failed.");
49
+ return new chunk7KEQHWZB_cjs.HostedAuthError("Hosted authentication failed.");
50
50
  }
51
51
  function useHostedRedirectAuth() {
52
52
  const {
@@ -57,30 +57,30 @@ function useHostedRedirectAuth() {
57
57
  setHostedAuthSession,
58
58
  clearHostedAuthSession,
59
59
  refreshHostedAuthSession
60
- } = chunk4IW4V7YJ_cjs.usePrivanaContext();
60
+ } = chunk7KEQHWZB_cjs.usePrivanaContext();
61
61
  const [error, setError] = react.useState(null);
62
62
  const [isLoading, setIsLoading] = react.useState(false);
63
63
  const loginInflight = react.useRef(null);
64
64
  const completionInflight = react.useRef(null);
65
65
  const pendingStorageKey = react.useMemo(
66
- () => hostedAuthConfig ? chunk4IW4V7YJ_cjs.createHostedAuthPendingStorageKey(client.getBaseUrl(), hostedAuthConfig) : null,
66
+ () => hostedAuthConfig ? chunk7KEQHWZB_cjs.createHostedAuthPendingStorageKey(client.getBaseUrl(), hostedAuthConfig) : null,
67
67
  [client, hostedAuthConfig]
68
68
  );
69
69
  const clearPendingLogin = react.useCallback(() => {
70
70
  if (!pendingStorageKey || typeof window === "undefined") return;
71
- chunk4IW4V7YJ_cjs.clearHostedAuthPendingTransaction(window.sessionStorage, pendingStorageKey);
71
+ chunk7KEQHWZB_cjs.clearHostedAuthPendingTransaction(window.sessionStorage, pendingStorageKey);
72
72
  }, [pendingStorageKey]);
73
73
  const login = react.useCallback(async () => {
74
74
  if (!hostedAuthConfig) {
75
- throw new chunk4IW4V7YJ_cjs.HostedAuthRequiredError(
75
+ throw new chunk7KEQHWZB_cjs.HostedAuthRequiredError(
76
76
  "Hosted redirect authentication is not configured for this provider."
77
77
  );
78
78
  }
79
79
  if (typeof window === "undefined") {
80
- throw new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted redirect authentication requires a browser environment.");
80
+ throw new chunk7KEQHWZB_cjs.HostedAuthError("Hosted redirect authentication requires a browser environment.");
81
81
  }
82
82
  if (!pendingStorageKey) {
83
- throw new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted redirect authentication storage is not configured.");
83
+ throw new chunk7KEQHWZB_cjs.HostedAuthError("Hosted redirect authentication storage is not configured.");
84
84
  }
85
85
  if (loginInflight.current) {
86
86
  return loginInflight.current;
@@ -89,10 +89,10 @@ function useHostedRedirectAuth() {
89
89
  setIsLoading(true);
90
90
  setError(null);
91
91
  try {
92
- const verifier = chunk4IW4V7YJ_cjs.createPkceVerifier();
93
- const codeChallenge = await chunk4IW4V7YJ_cjs.createPkceChallenge(verifier);
94
- const state = chunk4IW4V7YJ_cjs.createHostedAuthState();
95
- chunk4IW4V7YJ_cjs.persistHostedAuthPendingTransaction(window.sessionStorage, pendingStorageKey, {
92
+ const verifier = chunk7KEQHWZB_cjs.createPkceVerifier();
93
+ const codeChallenge = await chunk7KEQHWZB_cjs.createPkceChallenge(verifier);
94
+ const state = chunk7KEQHWZB_cjs.createHostedAuthState();
95
+ chunk7KEQHWZB_cjs.persistHostedAuthPendingTransaction(window.sessionStorage, pendingStorageKey, {
96
96
  codeVerifier: verifier,
97
97
  state
98
98
  });
@@ -121,15 +121,15 @@ function useHostedRedirectAuth() {
121
121
  }, [clearPendingLogin, client, hostedAuthConfig, networkConfig.chainId, pendingStorageKey]);
122
122
  const completeLogin = react.useCallback(async () => {
123
123
  if (!hostedAuthConfig) {
124
- throw new chunk4IW4V7YJ_cjs.HostedAuthRequiredError(
124
+ throw new chunk7KEQHWZB_cjs.HostedAuthRequiredError(
125
125
  "Hosted redirect authentication is not configured for this provider."
126
126
  );
127
127
  }
128
128
  if (typeof window === "undefined") {
129
- throw new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted redirect authentication requires a browser environment.");
129
+ throw new chunk7KEQHWZB_cjs.HostedAuthError("Hosted redirect authentication requires a browser environment.");
130
130
  }
131
131
  if (!pendingStorageKey) {
132
- throw new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted redirect authentication storage is not configured.");
132
+ throw new chunk7KEQHWZB_cjs.HostedAuthError("Hosted redirect authentication storage is not configured.");
133
133
  }
134
134
  if (completionInflight.current) {
135
135
  return completionInflight.current;
@@ -139,30 +139,30 @@ function useHostedRedirectAuth() {
139
139
  setError(null);
140
140
  const callbackUrl = new URL(window.location.href);
141
141
  const cleanupCallbackUrl = () => {
142
- window.history.replaceState(null, "", chunk4IW4V7YJ_cjs.stripHostedAuthCallbackParams(callbackUrl));
142
+ window.history.replaceState(null, "", chunk7KEQHWZB_cjs.stripHostedAuthCallbackParams(callbackUrl));
143
143
  };
144
144
  try {
145
- const callback = chunk4IW4V7YJ_cjs.parseHostedAuthCallback(callbackUrl, hostedAuthConfig.redirectUri);
145
+ const callback = chunk7KEQHWZB_cjs.parseHostedAuthCallback(callbackUrl, hostedAuthConfig.redirectUri);
146
146
  if (!callback) {
147
147
  return null;
148
148
  }
149
- const pending = chunk4IW4V7YJ_cjs.readHostedAuthPendingTransaction(window.sessionStorage, pendingStorageKey);
149
+ const pending = chunk7KEQHWZB_cjs.readHostedAuthPendingTransaction(window.sessionStorage, pendingStorageKey);
150
150
  if (!pending) {
151
151
  clearPendingLogin();
152
152
  cleanupCallbackUrl();
153
- throw new chunk4IW4V7YJ_cjs.HostedAuthError(
153
+ throw new chunk7KEQHWZB_cjs.HostedAuthError(
154
154
  "Hosted authentication response could not be matched to a pending login request."
155
155
  );
156
156
  }
157
157
  if (!callback.state || callback.state !== pending.state) {
158
158
  clearPendingLogin();
159
159
  cleanupCallbackUrl();
160
- throw new chunk4IW4V7YJ_cjs.HostedAuthStateMismatchError();
160
+ throw new chunk7KEQHWZB_cjs.HostedAuthStateMismatchError();
161
161
  }
162
162
  if ("error" in callback) {
163
163
  clearPendingLogin();
164
164
  cleanupCallbackUrl();
165
- throw new chunk4IW4V7YJ_cjs.HostedAuthError(
165
+ throw new chunk7KEQHWZB_cjs.HostedAuthError(
166
166
  callback.errorDescription || callback.error || "Hosted authentication failed."
167
167
  );
168
168
  }
@@ -177,7 +177,7 @@ function useHostedRedirectAuth() {
177
177
  client_id: hostedAuthConfig.clientId,
178
178
  redirect_uri: hostedAuthConfig.redirectUri
179
179
  });
180
- const session = chunk4IW4V7YJ_cjs.buildHostedAuthSession(response, hostedAuthConfig);
180
+ const session = chunk7KEQHWZB_cjs.buildHostedAuthSession(response, hostedAuthConfig);
181
181
  setHostedAuthSession(session);
182
182
  clearPendingLogin();
183
183
  cleanupCallbackUrl();
@@ -222,7 +222,7 @@ function useHostedRedirectAuth() {
222
222
  try {
223
223
  return await refreshHostedAuthSession();
224
224
  } catch (refreshError) {
225
- const normalizedError = refreshError instanceof Error ? refreshError : new chunk4IW4V7YJ_cjs.HostedAuthError("Hosted authentication refresh failed.");
225
+ const normalizedError = refreshError instanceof Error ? refreshError : new chunk7KEQHWZB_cjs.HostedAuthError("Hosted authentication refresh failed.");
226
226
  setError(normalizedError);
227
227
  throw normalizedError;
228
228
  } finally {
@@ -242,12 +242,12 @@ function useHostedRedirectAuth() {
242
242
  }
243
243
  function useBalance(options = {}) {
244
244
  const queryClient = react.useContext(reactQuery.QueryClientContext);
245
- const accountingContext = chunk4IW4V7YJ_cjs.useSafePrivanaContext();
245
+ const accountingContext = chunk7KEQHWZB_cjs.useSafePrivanaContext();
246
246
  const hasProviders = !!queryClient && !!accountingContext;
247
247
  const client = accountingContext?.client;
248
248
  const defaultToken = accountingContext?.defaultToken;
249
249
  const pollingInterval = accountingContext?.pollingInterval ?? 1e4;
250
- const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
250
+ const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
251
251
  const tokenId = options.tokenId ?? defaultToken?.id;
252
252
  const query = reactQuery.useQuery({
253
253
  queryKey: ["accounting-balance", ...privateReadQueryScope, tokenId],
@@ -255,7 +255,7 @@ function useBalance(options = {}) {
255
255
  if (!privateReadAddress) throw new Error("No authenticated account available");
256
256
  if (!tokenId) throw new Error("No token ID provided");
257
257
  if (!client) throw new Error("No accounting client");
258
- return executePrivateRead(() => client.getBalance(tokenId));
258
+ return executePrivateRead((readClient) => readClient.getBalance(tokenId));
259
259
  },
260
260
  enabled: hasProviders && (options.enabled ?? true) && privateReadReady && !!privateReadAddress && !!tokenId && !!client,
261
261
  refetchInterval: pollingInterval
@@ -264,7 +264,7 @@ function useBalance(options = {}) {
264
264
  return {
265
265
  balance: balanceWei,
266
266
  balanceWei,
267
- balanceFormatted: chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei),
267
+ balanceFormatted: chunk7KEQHWZB_cjs.formatTokenAmount(balanceWei),
268
268
  tokenSymbol: query.data?.token_symbol ?? "",
269
269
  chainId: query.data?.chain_id ?? "",
270
270
  isLoading: query.isPending || query.isLoading,
@@ -274,13 +274,15 @@ function useBalance(options = {}) {
274
274
  };
275
275
  }
276
276
  function useBatchBalances(options) {
277
- const { client, pollingInterval } = chunk4IW4V7YJ_cjs.usePrivanaContext();
278
- const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
277
+ const { client, pollingInterval } = chunk7KEQHWZB_cjs.usePrivanaContext();
278
+ const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
279
279
  const query = reactQuery.useQuery({
280
280
  queryKey: ["accounting-batch-balances", ...privateReadQueryScope, options.tokenIds],
281
281
  queryFn: async () => {
282
282
  if (!privateReadAddress) throw new Error("No authenticated account available");
283
- return executePrivateRead(() => client.getBatchBalances({ token_ids: options.tokenIds }));
283
+ return executePrivateRead(
284
+ (readClient) => readClient.getBatchBalances({ token_ids: options.tokenIds })
285
+ );
284
286
  },
285
287
  enabled: (options.enabled ?? true) && privateReadReady && !!privateReadAddress && options.tokenIds.length > 0 && !!client,
286
288
  refetchInterval: pollingInterval
@@ -298,17 +300,17 @@ function storageKey(address) {
298
300
  return `privana:pending-deposit:${address.toLowerCase()}`;
299
301
  }
300
302
  function savePendingDeposit(address, data) {
301
- const stored = chunk4IW4V7YJ_cjs.setBrowserStorageItem(storageKey(address), JSON.stringify(data));
303
+ const stored = chunk7KEQHWZB_cjs.setBrowserStorageItem(storageKey(address), JSON.stringify(data));
302
304
  if (!stored && data.signedLock) {
303
305
  throw new Error("Unable to persist pending locked deposit for recovery");
304
306
  }
305
307
  }
306
308
  function loadPendingDeposit(address) {
307
309
  try {
308
- const raw = chunk4IW4V7YJ_cjs.getBrowserStorageItem(storageKey(address));
310
+ const raw = chunk7KEQHWZB_cjs.getBrowserStorageItem(storageKey(address));
309
311
  if (!raw) return null;
310
312
  const data = JSON.parse(raw);
311
- if (Date.now() - data.savedAt > STALE_MS && !(data.signedLock && chunk4IW4V7YJ_cjs.isSignedLockUsable(data.signedLock))) {
313
+ if (Date.now() - data.savedAt > STALE_MS && !(data.signedLock && chunk7KEQHWZB_cjs.isSignedLockUsable(data.signedLock))) {
312
314
  clearPendingDeposit(address);
313
315
  return null;
314
316
  }
@@ -320,21 +322,23 @@ function loadPendingDeposit(address) {
320
322
  function clearPendingDeposit(address, onlyForTxHash) {
321
323
  if (onlyForTxHash) {
322
324
  try {
323
- const raw = chunk4IW4V7YJ_cjs.getBrowserStorageItem(storageKey(address));
325
+ const raw = chunk7KEQHWZB_cjs.getBrowserStorageItem(storageKey(address));
324
326
  const recordTxHash = raw ? JSON.parse(raw).txHash : void 0;
325
327
  if (recordTxHash && recordTxHash !== onlyForTxHash) return;
326
328
  } catch {
327
329
  }
328
330
  }
329
- chunk4IW4V7YJ_cjs.removeBrowserStorageItem(storageKey(address));
331
+ chunk7KEQHWZB_cjs.removeBrowserStorageItem(storageKey(address));
330
332
  }
331
333
  function useDeposit(options = {}) {
332
334
  const { address } = wagmi.useAccount();
333
- const { client, enabledTokens, getChainById: getChainById2, networkConfig, serviceAddress } = chunk4IW4V7YJ_cjs.usePrivanaContext();
335
+ const { client, enabledTokens, getChainById: getChainById2, networkConfig, serviceAddress } = chunk7KEQHWZB_cjs.usePrivanaContext();
334
336
  const { data: walletClient } = wagmi.useWalletClient();
335
337
  const queryClient = reactQuery.useQueryClient();
336
338
  const config = wagmi.useConfig();
337
- const { executePrivateRead } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
339
+ const { executePrivateRead, privateReadAddress } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
340
+ const privateReadAddressRef = react.useRef(privateReadAddress);
341
+ privateReadAddressRef.current = privateReadAddress;
338
342
  const confirmations = options.confirmations ?? 15;
339
343
  const [depositAddress, setDepositAddress] = react.useState(null);
340
344
  const [txHash, setTxHash] = react.useState();
@@ -370,12 +374,12 @@ function useDeposit(options = {}) {
370
374
  ]);
371
375
  const pendingLockRef = react.useRef(null);
372
376
  const submitPendingLockAfterCredit = react.useCallback(
373
- async (signedLock, response) => {
377
+ async (signedLock, creditedAmount) => {
374
378
  try {
375
- const result = await chunk4IW4V7YJ_cjs.submitPendingLock({
379
+ const result = await chunk7KEQHWZB_cjs.submitPendingLock({
376
380
  client,
377
381
  payload: signedLock,
378
- creditedAmount: response.amount != null ? BigInt(response.amount) : void 0
382
+ creditedAmount
379
383
  });
380
384
  queryClient.invalidateQueries({ queryKey: ["accounting-balance"] });
381
385
  queryClient.invalidateQueries({ queryKey: ["accounting-locked-funds"] });
@@ -383,11 +387,11 @@ function useDeposit(options = {}) {
383
387
  queryClient.invalidateQueries({ queryKey: ["accounting-history"] });
384
388
  onLockSubmittedRef.current?.(result);
385
389
  } catch (err) {
386
- const error2 = err instanceof chunk4IW4V7YJ_cjs.PostDepositLockError ? err : new chunk4IW4V7YJ_cjs.PostDepositLockError(
390
+ const error2 = err instanceof chunk7KEQHWZB_cjs.PostDepositLockError ? err : new chunk7KEQHWZB_cjs.PostDepositLockError(
387
391
  err instanceof Error ? err.message : "Lock submission failed",
388
392
  "submission-failed",
389
393
  BigInt(signedLock.amount),
390
- void 0,
394
+ creditedAmount,
391
395
  { cause: err }
392
396
  );
393
397
  (onLockFailedRef.current ?? onErrorRef.current)?.(error2);
@@ -402,15 +406,15 @@ function useDeposit(options = {}) {
402
406
  error: verificationError,
403
407
  verify,
404
408
  reset: resetVerification
405
- } = chunk4IW4V7YJ_cjs.useDepositVerification({
409
+ } = chunk7KEQHWZB_cjs.useDepositVerification({
406
410
  pollInterval: options.pollInterval,
407
411
  pollTimeout: options.pollTimeout,
408
- onCredited: (hash, response) => {
412
+ onCredited: (hash, response, creditedAmount) => {
409
413
  verificationContextRef.current = null;
410
414
  const signedLock = pendingLockRef.current;
411
415
  pendingLockRef.current = null;
412
416
  if (signedLock) {
413
- void submitPendingLockAfterCredit(signedLock, response).finally(() => {
417
+ void submitPendingLockAfterCredit(signedLock, creditedAmount).finally(() => {
414
418
  if (address) clearPendingDeposit(address, hash);
415
419
  });
416
420
  } else if (address) {
@@ -428,7 +432,7 @@ function useDeposit(options = {}) {
428
432
  const addressMutation = reactQuery.useMutation({
429
433
  mutationFn: async () => {
430
434
  if (!address) throw new Error("No wallet connected");
431
- return executePrivateRead(() => client.getDepositAddress());
435
+ return executePrivateRead((readClient) => readClient.getDepositAddress());
432
436
  },
433
437
  onSuccess: (data) => {
434
438
  setDepositAddress(data);
@@ -452,7 +456,7 @@ function useDeposit(options = {}) {
452
456
  } = wagmi.useSendTransaction();
453
457
  const isSendingTx = isWritingContract || isSendingNative;
454
458
  const sendError = writeError ?? sendNativeError;
455
- const { ensureCorrectChain } = chunk4IW4V7YJ_cjs.useEnsureCorrectChain();
459
+ const { ensureCorrectChain } = chunk7KEQHWZB_cjs.useEnsureCorrectChain();
456
460
  const invalidateGeneration = react.useCallback(() => {
457
461
  generationRef.current++;
458
462
  }, []);
@@ -500,12 +504,16 @@ function useDeposit(options = {}) {
500
504
  try {
501
505
  let confirmed = false;
502
506
  try {
503
- await chunk4IW4V7YJ_cjs.getTransactionReceipt(config, { hash, chainId: persisted.chainId });
504
- confirmed = true;
507
+ const receipt = await chunk7KEQHWZB_cjs.getTransactionReceipt(config, {
508
+ hash,
509
+ chainId: persisted.chainId
510
+ });
511
+ const blockNumber = await chunk7KEQHWZB_cjs.getBlockNumber(config, { chainId: persisted.chainId });
512
+ confirmed = blockNumber - receipt.blockNumber + 1n >= BigInt(confirmations);
505
513
  } catch {
506
514
  }
507
515
  if (!confirmed) {
508
- await chunk4IW4V7YJ_cjs.waitForTransactionReceipt(config, {
516
+ await chunk7KEQHWZB_cjs.waitForTransactionReceipt(config, {
509
517
  hash,
510
518
  chainId: persisted.chainId,
511
519
  confirmations
@@ -556,12 +564,13 @@ function useDeposit(options = {}) {
556
564
  `Amount is below the minimum deposit (${minAmountStr}) for ${isNative ? "native" : "ERC-20"} on chain ${sourceChain.id}`
557
565
  );
558
566
  }
559
- if (params.postDepositLock && !chunk4IW4V7YJ_cjs.canUseBrowserStorage()) {
567
+ if (params.postDepositLock && !chunk7KEQHWZB_cjs.canUseBrowserStorage()) {
560
568
  throw new Error("Browser storage is required for locked deposit recovery");
561
569
  }
562
- const lockAmount = chunk4IW4V7YJ_cjs.clampLockAmount(params.amount, params.postDepositLock?.maxAmount);
570
+ const lockAmount = chunk7KEQHWZB_cjs.clampLockAmount(params.amount, params.postDepositLock?.maxAmount);
563
571
  let signedLock;
564
572
  if (params.postDepositLock) {
573
+ const lockOwner = chunk7KEQHWZB_cjs.requireDepositLockOwner(address, privateReadAddress);
565
574
  setIsSwitchingChain(true);
566
575
  try {
567
576
  await ensureCorrectChain(networkConfig.chainId);
@@ -569,21 +578,24 @@ function useDeposit(options = {}) {
569
578
  if (!isStale()) setIsSwitchingChain(false);
570
579
  }
571
580
  if (isStale()) return;
572
- const signingWalletClient = await chunk4IW4V7YJ_cjs.getWalletClient(config, {
581
+ const signingWalletClient = await chunk7KEQHWZB_cjs.getWalletClient(config, {
573
582
  chainId: networkConfig.chainId
574
583
  });
575
- signedLock = await chunk4IW4V7YJ_cjs.createSignedLockRequest({
584
+ signedLock = await chunk7KEQHWZB_cjs.createSignedLockRequest({
576
585
  client,
577
586
  walletClient: signingWalletClient,
578
- userAddress: address,
587
+ userAddress: lockOwner,
579
588
  networkConfig,
580
- serviceAddress: requireServiceAddress(
589
+ serviceAddress: chunk7KEQHWZB_cjs.requireServiceAddress(
581
590
  params.postDepositLock.serviceAddress ?? serviceAddress
582
591
  ),
583
592
  tokenId: params.tokenId,
584
593
  amount: lockAmount,
585
594
  lockDuration: params.postDepositLock.lockDuration
586
595
  });
596
+ if (privateReadAddressRef.current?.toLowerCase() !== lockOwner.toLowerCase()) {
597
+ throw new Error("Authenticated deposit account changed while signing");
598
+ }
587
599
  }
588
600
  if (isStale()) return;
589
601
  setIsSwitchingChain(true);
@@ -628,7 +640,7 @@ function useDeposit(options = {}) {
628
640
  try {
629
641
  setIsWaitingForConfirmation(true);
630
642
  try {
631
- await chunk4IW4V7YJ_cjs.waitForTransactionReceipt(config, {
643
+ await chunk7KEQHWZB_cjs.waitForTransactionReceipt(config, {
632
644
  hash,
633
645
  chainId: sourceChain.id,
634
646
  confirmations
@@ -666,6 +678,7 @@ function useDeposit(options = {}) {
666
678
  enabledTokens,
667
679
  ensureCorrectChain,
668
680
  networkConfig,
681
+ privateReadAddress,
669
682
  queryClient,
670
683
  serviceAddress,
671
684
  writeContractAsync,
@@ -702,29 +715,24 @@ function useDeposit(options = {}) {
702
715
  reset
703
716
  };
704
717
  }
705
- function requireServiceAddress(serviceAddress) {
706
- if (!serviceAddress) {
707
- throw new Error("Service address not configured");
708
- }
709
- return serviceAddress;
710
- }
711
718
  function useDepositAddress(options = {}) {
712
719
  const queryClient = react.useContext(reactQuery.QueryClientContext);
713
- const accountingContext = chunk4IW4V7YJ_cjs.useSafePrivanaContext();
720
+ const accountingContext = chunk7KEQHWZB_cjs.useSafePrivanaContext();
714
721
  const hasProviders = !!queryClient && !!accountingContext;
715
722
  const client = accountingContext?.client;
716
- const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
723
+ const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
717
724
  const isReady = hasProviders && privateReadReady && !!privateReadAddress && !!client;
718
725
  const query = reactQuery.useQuery({
719
726
  queryKey: ["accounting-deposit-address", ...privateReadQueryScope],
720
727
  queryFn: async () => {
721
728
  if (!privateReadAddress) throw new Error("No authenticated account available");
722
729
  if (!client) throw new Error("No accounting client");
723
- return executePrivateRead(() => client.getDepositAddress());
730
+ return executePrivateRead((readClient) => readClient.getDepositAddress());
724
731
  },
725
732
  enabled: isReady && (options.enabled ?? true)
726
733
  });
727
734
  return {
735
+ response: query.data,
728
736
  depositAddress: query.data?.deposit_address ?? null,
729
737
  isReady,
730
738
  isLoading: query.isLoading,
@@ -736,9 +744,9 @@ function useDepositAddress(options = {}) {
736
744
  function useWithdraw(options = {}) {
737
745
  const { address } = wagmi.useAccount();
738
746
  const { data: walletClient } = wagmi.useWalletClient();
739
- const { client, networkConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
747
+ const { client, networkConfig } = chunk7KEQHWZB_cjs.usePrivanaContext();
740
748
  const queryClient = reactQuery.useQueryClient();
741
- const { chainId, ensureCorrectChain } = chunk4IW4V7YJ_cjs.useEnsureCorrectChain();
749
+ const { chainId, ensureCorrectChain } = chunk7KEQHWZB_cjs.useEnsureCorrectChain();
742
750
  const pollInterval = options.pollInterval ?? 3e3;
743
751
  const pollTimeout = options.pollTimeout ?? 18e4;
744
752
  const [currentStep, setCurrentStep] = react.useState("idle");
@@ -806,7 +814,7 @@ function useWithdraw(options = {}) {
806
814
  if (isStale()) return void 0;
807
815
  const nonce = BigInt(nonceResponse.nonce);
808
816
  setCurrentStep("signing");
809
- const signature = await chunk4IW4V7YJ_cjs.signWithdrawMessage({
817
+ const signature = await chunk7KEQHWZB_cjs.signWithdrawMessage({
810
818
  walletClient,
811
819
  chainId: signingChainId,
812
820
  verifyingContract: networkConfig.accountingContract,
@@ -935,7 +943,7 @@ function useWithdraw(options = {}) {
935
943
  function useLockFunds(options = {}) {
936
944
  const { address } = wagmi.useAccount();
937
945
  const { data: walletClient } = wagmi.useWalletClient();
938
- const { client, networkConfig, serviceAddress } = chunk4IW4V7YJ_cjs.usePrivanaContext();
946
+ const { client, networkConfig, serviceAddress } = chunk7KEQHWZB_cjs.usePrivanaContext();
939
947
  const queryClient = reactQuery.useQueryClient();
940
948
  const mutation = reactQuery.useMutation({
941
949
  mutationFn: async (params) => {
@@ -946,7 +954,7 @@ function useLockFunds(options = {}) {
946
954
  throw new Error("Service address not configured");
947
955
  }
948
956
  const { nonce } = await client.getLockNonce(address);
949
- const signature = await chunk4IW4V7YJ_cjs.signLockMessage({
957
+ const signature = await chunk7KEQHWZB_cjs.signLockMessage({
950
958
  walletClient,
951
959
  chainId: networkConfig.chainId,
952
960
  verifyingContract: networkConfig.accountingContract,
@@ -994,7 +1002,7 @@ function useLockFunds(options = {}) {
994
1002
  }
995
1003
  function useUnlockFunds(options = {}) {
996
1004
  const { address } = wagmi.useAccount();
997
- const { client } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1005
+ const { client } = chunk7KEQHWZB_cjs.usePrivanaContext();
998
1006
  const queryClient = reactQuery.useQueryClient();
999
1007
  const unlockMutation = reactQuery.useMutation({
1000
1008
  mutationFn: async (params) => {
@@ -1064,7 +1072,7 @@ function useUnlockFunds(options = {}) {
1064
1072
  function useTransfer(options = {}) {
1065
1073
  const { address } = wagmi.useAccount();
1066
1074
  const { data: walletClient } = wagmi.useWalletClient();
1067
- const { client, networkConfig, serviceAddress } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1075
+ const { client, networkConfig, serviceAddress } = chunk7KEQHWZB_cjs.usePrivanaContext();
1068
1076
  const queryClient = reactQuery.useQueryClient();
1069
1077
  const transferMutation = reactQuery.useMutation({
1070
1078
  mutationFn: async (params) => {
@@ -1072,7 +1080,7 @@ function useTransfer(options = {}) {
1072
1080
  throw new Error("Wallet not connected");
1073
1081
  }
1074
1082
  const { nonce } = await client.getTransferNonce(address);
1075
- const signature = await chunk4IW4V7YJ_cjs.signTransferMessage({
1083
+ const signature = await chunk7KEQHWZB_cjs.signTransferMessage({
1076
1084
  walletClient,
1077
1085
  chainId: networkConfig.chainId,
1078
1086
  verifyingContract: networkConfig.accountingContract,
@@ -1109,7 +1117,7 @@ function useTransfer(options = {}) {
1109
1117
  throw new Error("Service address not configured");
1110
1118
  }
1111
1119
  const { nonce } = await client.getTransferLockedNonce(serviceAddress);
1112
- const signature = await chunk4IW4V7YJ_cjs.signTransferLockedMessage({
1120
+ const signature = await chunk7KEQHWZB_cjs.signTransferLockedMessage({
1113
1121
  walletClient,
1114
1122
  chainId: networkConfig.chainId,
1115
1123
  verifyingContract: networkConfig.accountingContract,
@@ -1169,13 +1177,13 @@ function useTransfer(options = {}) {
1169
1177
  };
1170
1178
  }
1171
1179
  function useLockedFunds(options = {}) {
1172
- const { client, pollingInterval, serviceAddress } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1173
- const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
1180
+ const { client, pollingInterval, serviceAddress } = chunk7KEQHWZB_cjs.usePrivanaContext();
1181
+ const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
1174
1182
  const query = reactQuery.useQuery({
1175
1183
  queryKey: ["accounting-locked-funds", ...privateReadQueryScope, serviceAddress ?? null],
1176
1184
  queryFn: async () => {
1177
1185
  if (!privateReadAddress) throw new Error("No authenticated account available");
1178
- return executePrivateRead(() => client.getLockedFunds(serviceAddress));
1186
+ return executePrivateRead((readClient) => readClient.getLockedFunds(serviceAddress));
1179
1187
  },
1180
1188
  enabled: (options.enabled ?? true) && privateReadReady && !!privateReadAddress && !!client,
1181
1189
  refetchInterval: pollingInterval,
@@ -1192,15 +1200,15 @@ function useLockedFunds(options = {}) {
1192
1200
  };
1193
1201
  }
1194
1202
  function useTotalLockedBalance(options = {}) {
1195
- const { client, pollingInterval, defaultToken } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1196
- const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
1203
+ const { client, pollingInterval, defaultToken } = chunk7KEQHWZB_cjs.usePrivanaContext();
1204
+ const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
1197
1205
  const tokenId = options.tokenId ?? defaultToken?.id;
1198
1206
  const query = reactQuery.useQuery({
1199
1207
  queryKey: ["accounting-total-locked-balance", ...privateReadQueryScope, tokenId],
1200
1208
  queryFn: async () => {
1201
1209
  if (!privateReadAddress) throw new Error("No authenticated account available");
1202
1210
  if (!tokenId) throw new Error("No token ID provided");
1203
- return executePrivateRead(() => client.getTotalLockedBalance(tokenId));
1211
+ return executePrivateRead((readClient) => readClient.getTotalLockedBalance(tokenId));
1204
1212
  },
1205
1213
  enabled: (options.enabled ?? true) && privateReadReady && !!privateReadAddress && !!tokenId && !!client,
1206
1214
  refetchInterval: pollingInterval
@@ -1214,13 +1222,13 @@ function useTotalLockedBalance(options = {}) {
1214
1222
  };
1215
1223
  }
1216
1224
  function useExpiredLocks(options = {}) {
1217
- const { client, pollingInterval } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1218
- const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
1225
+ const { client, pollingInterval } = chunk7KEQHWZB_cjs.usePrivanaContext();
1226
+ const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
1219
1227
  const query = reactQuery.useQuery({
1220
1228
  queryKey: ["accounting-expired-locks", ...privateReadQueryScope],
1221
1229
  queryFn: async () => {
1222
1230
  if (!privateReadAddress) throw new Error("No authenticated account available");
1223
- return executePrivateRead(() => client.getExpiredLocks());
1231
+ return executePrivateRead((readClient) => readClient.getExpiredLocks());
1224
1232
  },
1225
1233
  enabled: (options.enabled ?? true) && privateReadReady && !!privateReadAddress && !!client,
1226
1234
  refetchInterval: pollingInterval
@@ -1236,14 +1244,14 @@ function useExpiredLocks(options = {}) {
1236
1244
  };
1237
1245
  }
1238
1246
  function statusCodeOf(error) {
1239
- return error instanceof chunk4IW4V7YJ_cjs.AccountingApiError ? error.statusCode : void 0;
1247
+ return error instanceof chunk7KEQHWZB_cjs.AccountingApiError ? error.statusCode : void 0;
1240
1248
  }
1241
1249
  function usePendingDeposits(options = {}) {
1242
1250
  const queryClient = react.useContext(reactQuery.QueryClientContext);
1243
- const accountingContext = chunk4IW4V7YJ_cjs.useSafePrivanaContext();
1251
+ const accountingContext = chunk7KEQHWZB_cjs.useSafePrivanaContext();
1244
1252
  const hasProviders = !!queryClient && !!accountingContext;
1245
1253
  const client = accountingContext?.client;
1246
- const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
1254
+ const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
1247
1255
  const { chainId, tokenAddress, lookbackBlocks } = options;
1248
1256
  const query = reactQuery.useQuery({
1249
1257
  queryKey: ["accounting-pending-deposits", ...privateReadQueryScope, chainId, tokenAddress],
@@ -1253,7 +1261,7 @@ function usePendingDeposits(options = {}) {
1253
1261
  if (!client) throw new Error("No accounting client");
1254
1262
  try {
1255
1263
  return await executePrivateRead(
1256
- () => client.getPendingDeposits({
1264
+ (readClient) => readClient.getPendingDeposits({
1257
1265
  chain_id: chainId,
1258
1266
  token_address: tokenAddress,
1259
1267
  lookback_blocks: lookbackBlocks
@@ -1290,7 +1298,7 @@ function usePendingDeposits(options = {}) {
1290
1298
  }
1291
1299
  function usePendingWithdrawals(options = {}) {
1292
1300
  const { address, isConnected } = wagmi.useAccount();
1293
- const { client, pollingInterval } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1301
+ const { client, pollingInterval } = chunk7KEQHWZB_cjs.usePrivanaContext();
1294
1302
  const query = reactQuery.useQuery({
1295
1303
  queryKey: ["accounting-pending-withdrawals", address],
1296
1304
  queryFn: async () => {
@@ -1326,15 +1334,15 @@ function usePendingWithdrawals(options = {}) {
1326
1334
  };
1327
1335
  }
1328
1336
  function useHistory(options = {}) {
1329
- const { client, pollingInterval } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1330
- const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk4IW4V7YJ_cjs.usePrivateReadRequest();
1337
+ const { client, pollingInterval } = chunk7KEQHWZB_cjs.usePrivanaContext();
1338
+ const { executePrivateRead, privateReadAddress, privateReadQueryScope, privateReadReady } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
1331
1339
  const offset = options.offset ?? -1;
1332
1340
  const limit = options.limit ?? 50;
1333
1341
  const query = reactQuery.useQuery({
1334
1342
  queryKey: ["accounting-history", ...privateReadQueryScope, offset, limit],
1335
1343
  queryFn: async () => {
1336
1344
  if (!privateReadAddress) throw new Error("No authenticated account available");
1337
- return executePrivateRead(() => client.getHistory({ offset, limit }));
1345
+ return executePrivateRead((readClient) => readClient.getHistory({ offset, limit }));
1338
1346
  },
1339
1347
  enabled: (options.enabled ?? true) && privateReadReady && !!privateReadAddress && !!client,
1340
1348
  refetchInterval: pollingInterval,
@@ -1351,7 +1359,7 @@ function useHistory(options = {}) {
1351
1359
  };
1352
1360
  }
1353
1361
  function useTokenInfo(options = {}) {
1354
- const { client } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1362
+ const { client } = chunk7KEQHWZB_cjs.usePrivanaContext();
1355
1363
  const { tokenId } = options;
1356
1364
  const query = reactQuery.useQuery({
1357
1365
  queryKey: ["accounting-token-info", tokenId],
@@ -1371,7 +1379,7 @@ function useTokenInfo(options = {}) {
1371
1379
  };
1372
1380
  }
1373
1381
  function useTokenList(options = {}) {
1374
- const { client } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1382
+ const { client } = chunk7KEQHWZB_cjs.usePrivanaContext();
1375
1383
  const query = reactQuery.useQuery({
1376
1384
  queryKey: ["accounting-token-list"],
1377
1385
  queryFn: () => client.listTokens(),
@@ -1389,7 +1397,7 @@ function useTokenList(options = {}) {
1389
1397
  function useModifyLock(options = {}) {
1390
1398
  const { address } = wagmi.useAccount();
1391
1399
  const { data: walletClient } = wagmi.useWalletClient();
1392
- const { client, networkConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
1400
+ const { client, networkConfig } = chunk7KEQHWZB_cjs.usePrivanaContext();
1393
1401
  const queryClient = reactQuery.useQueryClient();
1394
1402
  const mutation = reactQuery.useMutation({
1395
1403
  mutationFn: async (params) => {
@@ -1397,7 +1405,7 @@ function useModifyLock(options = {}) {
1397
1405
  throw new Error("Wallet not connected");
1398
1406
  }
1399
1407
  const { nonce } = await client.getModifyLockNonce(address);
1400
- const signature = await chunk4IW4V7YJ_cjs.signModifyLockMessage({
1408
+ const signature = await chunk7KEQHWZB_cjs.signModifyLockMessage({
1401
1409
  walletClient,
1402
1410
  chainId: networkConfig.chainId,
1403
1411
  verifyingContract: networkConfig.accountingContract,
@@ -1456,7 +1464,7 @@ function DialogOverlay({
1456
1464
  {
1457
1465
  "data-slot": "dialog-overlay",
1458
1466
  "data-privana": true,
1459
- className: chunk4IW4V7YJ_cjs.cn(
1467
+ className: chunk7KEQHWZB_cjs.cn(
1460
1468
  "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
1461
1469
  className
1462
1470
  ),
@@ -1478,7 +1486,7 @@ function DialogContent({
1478
1486
  {
1479
1487
  "data-slot": "dialog-content",
1480
1488
  "data-privana": true,
1481
- className: chunk4IW4V7YJ_cjs.cn(
1489
+ className: chunk7KEQHWZB_cjs.cn(
1482
1490
  "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
1483
1491
  className
1484
1492
  ),
@@ -1506,7 +1514,7 @@ function DialogHeader({ className, ...props }) {
1506
1514
  "div",
1507
1515
  {
1508
1516
  "data-slot": "dialog-header",
1509
- className: chunk4IW4V7YJ_cjs.cn("flex flex-col gap-2 text-center sm:text-left", className),
1517
+ className: chunk7KEQHWZB_cjs.cn("flex flex-col gap-2 text-center sm:text-left", className),
1510
1518
  ...props
1511
1519
  }
1512
1520
  );
@@ -1516,7 +1524,7 @@ function DialogTitle({ className, ...props }) {
1516
1524
  DialogPrimitive__namespace.Title,
1517
1525
  {
1518
1526
  "data-slot": "dialog-title",
1519
- className: chunk4IW4V7YJ_cjs.cn("text-lg leading-none font-semibold", className),
1527
+ className: chunk7KEQHWZB_cjs.cn("text-lg leading-none font-semibold", className),
1520
1528
  ...props
1521
1529
  }
1522
1530
  );
@@ -1529,7 +1537,7 @@ function DialogDescription({
1529
1537
  DialogPrimitive__namespace.Description,
1530
1538
  {
1531
1539
  "data-slot": "dialog-description",
1532
- className: chunk4IW4V7YJ_cjs.cn("text-muted-foreground text-sm", className),
1540
+ className: chunk7KEQHWZB_cjs.cn("text-muted-foreground text-sm", className),
1533
1541
  ...props
1534
1542
  }
1535
1543
  );
@@ -1724,7 +1732,7 @@ function ChevronDownIcon({
1724
1732
  height: "16",
1725
1733
  viewBox: "0 0 16 16",
1726
1734
  fill: "none",
1727
- className: chunk4IW4V7YJ_cjs.cn(
1735
+ className: chunk7KEQHWZB_cjs.cn(
1728
1736
  "transition-transform",
1729
1737
  direction === "right" && "-rotate-90",
1730
1738
  direction === "up" && "rotate-180",
@@ -1921,7 +1929,16 @@ function WarningIcon() {
1921
1929
  }
1922
1930
  ) });
1923
1931
  }
1924
- function TransactionWarningView({ title, message, onDone }) {
1932
+ function TransactionWarningView({
1933
+ title,
1934
+ message,
1935
+ onDone,
1936
+ actionLabel = "Done",
1937
+ pendingLabel = actionLabel,
1938
+ isPending = false,
1939
+ onDismiss,
1940
+ dismissLabel = "Dismiss"
1941
+ }) {
1925
1942
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-col gap-4", children: [
1926
1943
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
1927
1944
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-amber-500/10 text-amber-400", children: /* @__PURE__ */ jsxRuntime.jsx(WarningIcon, {}) }),
@@ -1930,14 +1947,26 @@ function TransactionWarningView({ title, message, onDone }) {
1930
1947
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: message })
1931
1948
  ] })
1932
1949
  ] }),
1933
- /* @__PURE__ */ jsxRuntime.jsx(
1934
- "button",
1935
- {
1936
- onClick: onDone,
1937
- className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors",
1938
- children: "Done"
1939
- }
1940
- )
1950
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
1951
+ onDismiss && /* @__PURE__ */ jsxRuntime.jsx(
1952
+ "button",
1953
+ {
1954
+ onClick: onDismiss,
1955
+ disabled: isPending,
1956
+ className: "border-border text-foreground hover:bg-secondary flex h-10 flex-1 cursor-pointer items-center justify-center rounded-[10px] border px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
1957
+ children: dismissLabel
1958
+ }
1959
+ ),
1960
+ /* @__PURE__ */ jsxRuntime.jsx(
1961
+ "button",
1962
+ {
1963
+ onClick: onDone,
1964
+ disabled: isPending,
1965
+ className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 flex-1 cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
1966
+ children: isPending ? pendingLabel : actionLabel
1967
+ }
1968
+ )
1969
+ ] })
1941
1970
  ] });
1942
1971
  }
1943
1972
  function TransactionErrorView({
@@ -1947,7 +1976,9 @@ function TransactionErrorView({
1947
1976
  explorerLabel,
1948
1977
  onRetry,
1949
1978
  onDismiss,
1950
- isRetrying
1979
+ isRetrying,
1980
+ retryLabel = "Retry Verification",
1981
+ dismissLabel = "Close"
1951
1982
  }) {
1952
1983
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-col gap-4", children: [
1953
1984
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
@@ -1971,13 +2002,13 @@ function TransactionErrorView({
1971
2002
  }
1972
2003
  ),
1973
2004
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
1974
- /* @__PURE__ */ jsxRuntime.jsx(
2005
+ onDismiss && /* @__PURE__ */ jsxRuntime.jsx(
1975
2006
  "button",
1976
2007
  {
1977
2008
  onClick: onDismiss,
1978
2009
  disabled: isRetrying,
1979
2010
  className: "border-border text-foreground hover:bg-secondary flex h-10 flex-1 cursor-pointer items-center justify-center rounded-[10px] border px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
1980
- children: "Close"
2011
+ children: dismissLabel
1981
2012
  }
1982
2013
  ),
1983
2014
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1986,7 +2017,7 @@ function TransactionErrorView({
1986
2017
  onClick: onRetry,
1987
2018
  disabled: isRetrying,
1988
2019
  className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 flex-1 cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
1989
- children: isRetrying ? "Retrying..." : "Retry Verification"
2020
+ children: isRetrying ? "Retrying\u2026" : retryLabel
1990
2021
  }
1991
2022
  )
1992
2023
  ] })
@@ -2000,7 +2031,7 @@ function DepositForm({
2000
2031
  onSuccess
2001
2032
  }) {
2002
2033
  const { isConnected, address } = wagmi.useAccount();
2003
- const { chains, getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
2034
+ const { chains, getChainById: getChainById2 } = chunk7KEQHWZB_cjs.usePrivanaContext();
2004
2035
  const [amount, setAmount] = react.useState("");
2005
2036
  const [showSuccess, setShowSuccess] = react.useState(false);
2006
2037
  const [showTimeout, setShowTimeout] = react.useState(false);
@@ -2025,7 +2056,7 @@ function DepositForm({
2025
2056
  }
2026
2057
  });
2027
2058
  const walletBalance = isNative ? nativeBalanceData?.value : erc20Balance;
2028
- const formattedWalletBalance = walletBalance ? chunk4IW4V7YJ_cjs.formatTokenAmount(walletBalance.toString(), selectedToken.decimals) : "0.00";
2059
+ const formattedWalletBalance = walletBalance ? chunk7KEQHWZB_cjs.formatTokenAmount(walletBalance.toString(), selectedToken.decimals) : "0.00";
2029
2060
  const handleMaxClick = () => {
2030
2061
  if (formattedWalletBalance && parseFloat(formattedWalletBalance) > 0) {
2031
2062
  setAmount(formattedWalletBalance.replace(/[\s\u2009]/g, ""));
@@ -2033,7 +2064,7 @@ function DepositForm({
2033
2064
  };
2034
2065
  const hasValidAmount = amount && parseFloat(amount) > 0;
2035
2066
  const tooManyDecimals = hasValidAmount && amount.includes(".") && amount.split(".")[1].length > selectedToken.decimals;
2036
- const exceedsBalance = hasValidAmount && !tooManyDecimals && walletBalance != null && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals) > walletBalance;
2067
+ const exceedsBalance = hasValidAmount && !tooManyDecimals && walletBalance != null && chunk7KEQHWZB_cjs.parseTokenAmount(amount, selectedToken.decimals) > walletBalance;
2037
2068
  const {
2038
2069
  txHash,
2039
2070
  isGettingAddress,
@@ -2118,7 +2149,7 @@ function DepositForm({
2118
2149
  const handleSubmit = async () => {
2119
2150
  if (!amount || !selectedToken || exceedsBalance) return;
2120
2151
  setCancelled(false);
2121
- const amountInWei = chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals);
2152
+ const amountInWei = chunk7KEQHWZB_cjs.parseTokenAmount(amount, selectedToken.decimals);
2122
2153
  await deposit({
2123
2154
  tokenId: selectedToken.id,
2124
2155
  amount: amountInWei
@@ -2126,7 +2157,7 @@ function DepositForm({
2126
2157
  };
2127
2158
  const getButtonText = () => {
2128
2159
  if (!isConnected) return "Connect Wallet";
2129
- if (isSwitchingChain) return "Switching...";
2160
+ if (isSwitchingChain) return "Switching\u2026";
2130
2161
  return "Deposit";
2131
2162
  };
2132
2163
  if (showSuccess) {
@@ -2150,7 +2181,7 @@ function DepositForm({
2150
2181
  );
2151
2182
  }
2152
2183
  if (verificationFailed) {
2153
- const baseMessage = "Your transfer was sent on-chain but we could not verify the deposit. The funds are already at the deposit address \u2014 retry verification instead of starting a new deposit.";
2184
+ const baseMessage = "Your transfer was sent on-chain but we could not verify the deposit. The funds are already at the deposit address. Retry verification instead of starting a new deposit.";
2154
2185
  const detail = error?.message;
2155
2186
  const message = detail ? `${baseMessage} (${detail})` : baseMessage;
2156
2187
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2170,7 +2201,7 @@ function DepositForm({
2170
2201
  return /* @__PURE__ */ jsxRuntime.jsx(
2171
2202
  TransactionProgressView,
2172
2203
  {
2173
- title: "Depositing...",
2204
+ title: "Depositing\u2026",
2174
2205
  steps: depositSteps,
2175
2206
  onCancel: canCancel ? handleCancel : void 0
2176
2207
  }
@@ -2221,7 +2252,7 @@ function DepositForm({
2221
2252
  setAmount(value);
2222
2253
  }
2223
2254
  },
2224
- className: chunk4IW4V7YJ_cjs.cn(
2255
+ className: chunk7KEQHWZB_cjs.cn(
2225
2256
  "text-foreground flex-1 bg-transparent text-sm outline-none",
2226
2257
  "placeholder:text-muted-foreground/50"
2227
2258
  )
@@ -2248,7 +2279,7 @@ function DepositForm({
2248
2279
  {
2249
2280
  onClick: handleSubmit,
2250
2281
  disabled: !isConnected || !hasValidAmount || tooManyDecimals || !!exceedsBalance || isPending,
2251
- className: chunk4IW4V7YJ_cjs.cn(
2282
+ className: chunk7KEQHWZB_cjs.cn(
2252
2283
  "flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors",
2253
2284
  "bg-primary text-primary-foreground hover:bg-primary/90",
2254
2285
  "disabled:cursor-not-allowed disabled:opacity-50"
@@ -2265,7 +2296,7 @@ function WithdrawForm({
2265
2296
  onUnsafeToCloseChange
2266
2297
  }) {
2267
2298
  const { isConnected, address } = wagmi.useAccount();
2268
- const { chains, getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
2299
+ const { chains, getChainById: getChainById2 } = chunk7KEQHWZB_cjs.usePrivanaContext();
2269
2300
  const [amount, setAmount] = react.useState("");
2270
2301
  const [showSuccess, setShowSuccess] = react.useState(false);
2271
2302
  const [showTimeout, setShowTimeout] = react.useState(false);
@@ -2278,7 +2309,7 @@ function WithdrawForm({
2278
2309
  } = useBalance({
2279
2310
  tokenId: selectedToken.id
2280
2311
  });
2281
- const formattedBalance = chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei, selectedToken.decimals);
2312
+ const formattedBalance = chunk7KEQHWZB_cjs.formatTokenAmount(balanceWei, selectedToken.decimals);
2282
2313
  const { withdraw, isPending, currentStep, error, reset } = useWithdraw({
2283
2314
  onProcessingSuccess: () => {
2284
2315
  setAmount("");
@@ -2289,7 +2320,7 @@ function WithdrawForm({
2289
2320
  setShowTimeout(true);
2290
2321
  }
2291
2322
  });
2292
- const explorerUrl = address && targetChain ? chunk4IW4V7YJ_cjs.getExplorerAddressUrl(targetChain.id, address) : void 0;
2323
+ const explorerUrl = address && targetChain ? chunk7KEQHWZB_cjs.getExplorerAddressUrl(targetChain.id, address) : void 0;
2293
2324
  const getStepStatus = (step, after) => {
2294
2325
  if (currentStep === step) return "active";
2295
2326
  if (after.includes(currentStep)) return "completed";
@@ -2333,7 +2364,7 @@ function WithdrawForm({
2333
2364
  const handleWithdraw = async () => {
2334
2365
  if (!amount || !selectedToken || exceedsBalance) return;
2335
2366
  setCancelled(false);
2336
- const amountInWei = chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals);
2367
+ const amountInWei = chunk7KEQHWZB_cjs.parseTokenAmount(amount, selectedToken.decimals);
2337
2368
  await withdraw({
2338
2369
  tokenId: selectedToken.id,
2339
2370
  amount: amountInWei
@@ -2346,7 +2377,7 @@ function WithdrawForm({
2346
2377
  };
2347
2378
  const hasValidAmount = amount && parseFloat(amount) > 0;
2348
2379
  const tooManyDecimals = hasValidAmount && amount.includes(".") && amount.split(".")[1].length > selectedToken.decimals;
2349
- const exceedsBalance = hasValidAmount && !tooManyDecimals && !isBalanceLoading && !isBalanceError && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals) > BigInt(balanceWei);
2380
+ const exceedsBalance = hasValidAmount && !tooManyDecimals && !isBalanceLoading && !isBalanceError && chunk7KEQHWZB_cjs.parseTokenAmount(amount, selectedToken.decimals) > BigInt(balanceWei);
2350
2381
  const getButtonText = () => {
2351
2382
  if (!isConnected) return "Connect Wallet";
2352
2383
  return "Withdraw";
@@ -2358,7 +2389,7 @@ function WithdrawForm({
2358
2389
  title: "Withdrawal Complete",
2359
2390
  message: `Your ${selectedToken.symbol} withdrawal has been processed. Funds should appear in your wallet shortly.`,
2360
2391
  explorerUrl,
2361
- explorerLabel: targetChain ? chunk4IW4V7YJ_cjs.getExplorerLabel(targetChain.id) : void 0,
2392
+ explorerLabel: targetChain ? chunk7KEQHWZB_cjs.getExplorerLabel(targetChain.id) : void 0,
2362
2393
  onDone: handleDone
2363
2394
  }
2364
2395
  );
@@ -2429,7 +2460,7 @@ function WithdrawForm({
2429
2460
  setAmount(value);
2430
2461
  }
2431
2462
  },
2432
- className: chunk4IW4V7YJ_cjs.cn(
2463
+ className: chunk7KEQHWZB_cjs.cn(
2433
2464
  "text-foreground flex-1 bg-transparent text-sm outline-none",
2434
2465
  "placeholder:text-muted-foreground/50"
2435
2466
  )
@@ -2456,7 +2487,7 @@ function WithdrawForm({
2456
2487
  {
2457
2488
  onClick: handleWithdraw,
2458
2489
  disabled: !isConnected || !hasValidAmount || tooManyDecimals || !!exceedsBalance || isPending,
2459
- className: chunk4IW4V7YJ_cjs.cn(
2490
+ className: chunk7KEQHWZB_cjs.cn(
2460
2491
  "flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors",
2461
2492
  "bg-primary text-primary-foreground hover:bg-primary/90",
2462
2493
  "disabled:cursor-not-allowed disabled:opacity-50"
@@ -2477,15 +2508,15 @@ function BalanceCards({
2477
2508
  tokenId: selectedToken.id
2478
2509
  });
2479
2510
  const { totalLocked, isLoading: lockedLoading } = useLockedFunds({ enabled: showLockedFunds });
2480
- const formattedBalance = chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei, selectedToken.decimals);
2481
- const formattedLocked = showLockedFunds ? chunk4IW4V7YJ_cjs.formatTokenAmount(String(totalLocked), selectedToken.decimals) : "0.00";
2482
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunk4IW4V7YJ_cjs.cn("flex gap-2", disabled && "opacity-50"), children: [
2511
+ const formattedBalance = chunk7KEQHWZB_cjs.formatTokenAmount(balanceWei, selectedToken.decimals);
2512
+ const formattedLocked = showLockedFunds ? chunk7KEQHWZB_cjs.formatTokenAmount(String(totalLocked), selectedToken.decimals) : "0.00";
2513
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunk7KEQHWZB_cjs.cn("flex gap-2", disabled && "opacity-50"), children: [
2483
2514
  /* @__PURE__ */ jsxRuntime.jsxs(
2484
2515
  "button",
2485
2516
  {
2486
2517
  onClick: onBalanceClick,
2487
2518
  disabled,
2488
- className: chunk4IW4V7YJ_cjs.cn(
2519
+ className: chunk7KEQHWZB_cjs.cn(
2489
2520
  "bg-muted flex flex-1 flex-col gap-2 rounded-[10px] p-5 text-left transition-colors",
2490
2521
  disabled ? "cursor-not-allowed" : "hover:bg-muted/80 cursor-pointer"
2491
2522
  ),
@@ -2506,7 +2537,7 @@ function BalanceCards({
2506
2537
  {
2507
2538
  onClick: onLockedFundsClick,
2508
2539
  disabled,
2509
- className: chunk4IW4V7YJ_cjs.cn(
2540
+ className: chunk7KEQHWZB_cjs.cn(
2510
2541
  "bg-muted flex flex-1 flex-col gap-2 rounded-[10px] p-5 text-left transition-colors",
2511
2542
  disabled ? "cursor-not-allowed" : "hover:bg-muted/80 cursor-pointer"
2512
2543
  ),
@@ -2532,7 +2563,7 @@ function Tabs({
2532
2563
  return /* @__PURE__ */ jsxRuntime.jsxs(
2533
2564
  "div",
2534
2565
  {
2535
- className: chunk4IW4V7YJ_cjs.cn(
2566
+ className: chunk7KEQHWZB_cjs.cn(
2536
2567
  "bg-muted relative flex gap-2 overflow-hidden rounded-[10px] p-1",
2537
2568
  disabled && "opacity-50"
2538
2569
  ),
@@ -2540,7 +2571,7 @@ function Tabs({
2540
2571
  /* @__PURE__ */ jsxRuntime.jsx(
2541
2572
  "div",
2542
2573
  {
2543
- className: chunk4IW4V7YJ_cjs.cn(
2574
+ className: chunk7KEQHWZB_cjs.cn(
2544
2575
  "bg-input absolute top-1 bottom-1 left-1 w-[calc(50%-8px)] rounded-md transition-transform duration-200",
2545
2576
  activeTab === "withdraw" && "translate-x-[calc(100%+8px)]"
2546
2577
  )
@@ -2551,7 +2582,7 @@ function Tabs({
2551
2582
  {
2552
2583
  onClick: () => !disabled && onTabChange("deposit"),
2553
2584
  disabled,
2554
- className: chunk4IW4V7YJ_cjs.cn(
2585
+ className: chunk7KEQHWZB_cjs.cn(
2555
2586
  "relative z-10 flex-1 rounded-md px-3 py-[9px] text-sm transition-colors",
2556
2587
  activeTab === "deposit" ? "text-foreground" : "text-muted-foreground",
2557
2588
  disabled ? "cursor-not-allowed" : "cursor-pointer"
@@ -2564,7 +2595,7 @@ function Tabs({
2564
2595
  {
2565
2596
  onClick: () => !disabled && onTabChange("withdraw"),
2566
2597
  disabled,
2567
- className: chunk4IW4V7YJ_cjs.cn(
2598
+ className: chunk7KEQHWZB_cjs.cn(
2568
2599
  "relative z-10 flex-1 rounded-md px-3 py-[9px] text-sm transition-colors",
2569
2600
  activeTab === "withdraw" ? "text-foreground" : "text-muted-foreground",
2570
2601
  disabled ? "cursor-not-allowed" : "cursor-pointer"
@@ -2577,14 +2608,14 @@ function Tabs({
2577
2608
  );
2578
2609
  }
2579
2610
  function LockedFundsView({ onBack }) {
2580
- const { getTokenById } = chunk4IW4V7YJ_cjs.usePrivanaContext();
2611
+ const { getTokenById } = chunk7KEQHWZB_cjs.usePrivanaContext();
2581
2612
  const { locks, isLoading } = useLockedFunds();
2582
2613
  const { unlockFunds, unlockAllExpired, isPending } = useUnlockFunds();
2583
2614
  const [collapsedSections, setCollapsedSections] = react.useState({});
2584
2615
  const sections = react.useMemo(() => {
2585
2616
  const sectionMap = {};
2586
2617
  locks.forEach((lock) => {
2587
- const serviceName = chunk4IW4V7YJ_cjs.shortenAddress(lock.service_address);
2618
+ const serviceName = chunk7KEQHWZB_cjs.shortenAddress(lock.service_address);
2588
2619
  if (!sectionMap[lock.service_address]) {
2589
2620
  sectionMap[lock.service_address] = {
2590
2621
  title: `Service ${serviceName}`,
@@ -2593,9 +2624,9 @@ function LockedFundsView({ onBack }) {
2593
2624
  }
2594
2625
  sectionMap[lock.service_address].items.push({
2595
2626
  lockId: lock.lock_id,
2596
- amount: chunk4IW4V7YJ_cjs.formatTokenAmount(String(lock.amount), getTokenById(lock.token_id)?.decimals ?? 18),
2627
+ amount: chunk7KEQHWZB_cjs.formatTokenAmount(String(lock.amount), getTokenById(lock.token_id)?.decimals ?? 18),
2597
2628
  serviceAddress: lock.service_address,
2598
- time: lock.is_expired ? "Click to unlock" : chunk4IW4V7YJ_cjs.formatTimeRemaining(lock.expiry),
2629
+ time: lock.is_expired ? "Click to unlock" : chunk7KEQHWZB_cjs.formatTimeRemaining(lock.expiry),
2599
2630
  isExpired: lock.is_expired
2600
2631
  });
2601
2632
  });
@@ -2647,7 +2678,7 @@ function LockedFundsView({ onBack }) {
2647
2678
  !collapsedSections[section.title] && section.items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
2648
2679
  "div",
2649
2680
  {
2650
- className: chunk4IW4V7YJ_cjs.cn(
2681
+ className: chunk7KEQHWZB_cjs.cn(
2651
2682
  "flex items-center justify-between gap-3 rounded-lg p-3",
2652
2683
  item.isExpired && "bg-secondary"
2653
2684
  ),
@@ -2661,7 +2692,7 @@ function LockedFundsView({ onBack }) {
2661
2692
  ] }),
2662
2693
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-xs", children: [
2663
2694
  "Service: ",
2664
- chunk4IW4V7YJ_cjs.shortenAddress(item.serviceAddress)
2695
+ chunk7KEQHWZB_cjs.shortenAddress(item.serviceAddress)
2665
2696
  ] })
2666
2697
  ] })
2667
2698
  ] }),
@@ -2702,7 +2733,7 @@ function BalanceTokenRow({ token }) {
2702
2733
  const { balanceWei, isLoading } = useBalance({
2703
2734
  tokenId: token.id
2704
2735
  });
2705
- const formattedBalance = chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei, token.decimals);
2736
+ const formattedBalance = chunk7KEQHWZB_cjs.formatTokenAmount(balanceWei, token.decimals);
2706
2737
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-2 rounded-lg px-3 py-2.5", children: [
2707
2738
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[18px] w-[18px] overflow-hidden rounded-full", children: getTokenIcon(token.symbol, 18) }),
2708
2739
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground flex-1 text-sm", children: token.symbol }),
@@ -2710,7 +2741,7 @@ function BalanceTokenRow({ token }) {
2710
2741
  ] });
2711
2742
  }
2712
2743
  function BalanceDetailsView({ onBack }) {
2713
- const { enabledTokens, chains } = chunk4IW4V7YJ_cjs.usePrivanaContext();
2744
+ const { enabledTokens, chains } = chunk7KEQHWZB_cjs.usePrivanaContext();
2714
2745
  const [selectedChainId, setSelectedChainId] = react.useState(chains[0]?.id ?? 84532);
2715
2746
  const chainTokens = react.useMemo(() => {
2716
2747
  return enabledTokens.filter((t) => t.chainId === selectedChainId);
@@ -2736,7 +2767,7 @@ function BalanceDetailsView({ onBack }) {
2736
2767
  "button",
2737
2768
  {
2738
2769
  onClick: () => setSelectedChainId(chain.id),
2739
- className: chunk4IW4V7YJ_cjs.cn(
2770
+ className: chunk7KEQHWZB_cjs.cn(
2740
2771
  "hover:bg-secondary flex w-full cursor-pointer items-center gap-2 rounded-lg px-3 py-2.5 text-left transition-colors",
2741
2772
  isSelected && "bg-secondary"
2742
2773
  ),
@@ -2777,12 +2808,12 @@ function TokenRow({
2777
2808
  query: { enabled: !!address && !isNative }
2778
2809
  });
2779
2810
  const walletBalance = isNative ? nativeBalanceData?.value : erc20Balance;
2780
- const formattedBalance = walletBalance ? chunk4IW4V7YJ_cjs.formatTokenAmount(walletBalance.toString(), token.decimals) : "0.00";
2811
+ const formattedBalance = walletBalance ? chunk7KEQHWZB_cjs.formatTokenAmount(walletBalance.toString(), token.decimals) : "0.00";
2781
2812
  return /* @__PURE__ */ jsxRuntime.jsxs(
2782
2813
  "button",
2783
2814
  {
2784
2815
  onClick,
2785
- className: chunk4IW4V7YJ_cjs.cn(
2816
+ className: chunk7KEQHWZB_cjs.cn(
2786
2817
  "hover:bg-secondary flex w-full cursor-pointer items-center gap-2 rounded-lg px-3 py-2.5 text-left transition-colors",
2787
2818
  isSelected && "bg-secondary"
2788
2819
  ),
@@ -2799,7 +2830,7 @@ function TokenSelectorView({
2799
2830
  onSelect,
2800
2831
  selectedTokenId
2801
2832
  }) {
2802
- const { enabledTokens, chains } = chunk4IW4V7YJ_cjs.usePrivanaContext();
2833
+ const { enabledTokens, chains } = chunk7KEQHWZB_cjs.usePrivanaContext();
2803
2834
  const [selectedChainId, setSelectedChainId] = react.useState(chains[0]?.id ?? 84532);
2804
2835
  const chainTokens = react.useMemo(() => {
2805
2836
  return enabledTokens.filter((t) => t.chainId === selectedChainId);
@@ -2829,7 +2860,7 @@ function TokenSelectorView({
2829
2860
  "button",
2830
2861
  {
2831
2862
  onClick: () => setSelectedChainId(chain.id),
2832
- className: chunk4IW4V7YJ_cjs.cn(
2863
+ className: chunk7KEQHWZB_cjs.cn(
2833
2864
  "hover:bg-secondary flex w-full cursor-pointer items-center gap-2 rounded-lg px-3 py-2.5 text-left transition-colors",
2834
2865
  isSelected && "bg-secondary"
2835
2866
  ),
@@ -2864,7 +2895,7 @@ function ModalBody({
2864
2895
  defaultTab = "deposit",
2865
2896
  onDepositSuccess
2866
2897
  }) {
2867
- const { defaultToken, tokensStatus } = chunk4IW4V7YJ_cjs.usePrivanaContext();
2898
+ const { defaultToken, tokensStatus } = chunk7KEQHWZB_cjs.usePrivanaContext();
2868
2899
  const [selectedToken, setSelectedToken] = react.useState(defaultToken);
2869
2900
  const [activeTab, setActiveTab] = react.useState(defaultTab);
2870
2901
  const [currentView, setCurrentView] = react.useState("main");
@@ -2922,7 +2953,7 @@ function ModalBody({
2922
2953
  );
2923
2954
  }
2924
2955
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 pb-4", children: [
2925
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunk4IW4V7YJ_cjs.cn(isInteractionPending && "pointer-events-none"), children: /* @__PURE__ */ jsxRuntime.jsx(
2956
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunk7KEQHWZB_cjs.cn(isInteractionPending && "pointer-events-none"), children: /* @__PURE__ */ jsxRuntime.jsx(
2926
2957
  BalanceCards,
2927
2958
  {
2928
2959
  selectedToken,
@@ -2932,7 +2963,7 @@ function ModalBody({
2932
2963
  disabled: isInteractionPending
2933
2964
  }
2934
2965
  ) }),
2935
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunk4IW4V7YJ_cjs.cn(isInteractionPending && "pointer-events-none"), children: /* @__PURE__ */ jsxRuntime.jsx(Tabs, { activeTab, onTabChange: setActiveTab, disabled: isInteractionPending }) }),
2966
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunk7KEQHWZB_cjs.cn(isInteractionPending && "pointer-events-none"), children: /* @__PURE__ */ jsxRuntime.jsx(Tabs, { activeTab, onTabChange: setActiveTab, disabled: isInteractionPending }) }),
2936
2967
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted rounded-[10px] p-5", children: activeTab === "deposit" ? /* @__PURE__ */ jsxRuntime.jsx(
2937
2968
  DepositForm,
2938
2969
  {
@@ -2993,7 +3024,7 @@ function PrivanaModal({
2993
3024
  onClick: handleClose,
2994
3025
  disabled: isCloseBlocked,
2995
3026
  "aria-label": "Close",
2996
- className: chunk4IW4V7YJ_cjs.cn(
3027
+ className: chunk7KEQHWZB_cjs.cn(
2997
3028
  "absolute top-6 right-5 z-20 flex h-6 w-6 items-center justify-center transition-colors",
2998
3029
  isCloseBlocked ? "text-muted-foreground/40 cursor-not-allowed" : "text-muted-foreground hover:text-foreground cursor-pointer"
2999
3030
  ),
@@ -3049,7 +3080,7 @@ function PrivanaInlineModal({
3049
3080
  "div",
3050
3081
  {
3051
3082
  "data-privana": true,
3052
- className: chunk4IW4V7YJ_cjs.cn(
3083
+ className: chunk7KEQHWZB_cjs.cn(
3053
3084
  "bg-card flex w-[560px] max-w-full flex-col gap-2 overflow-hidden rounded-2xl p-2 shadow-lg",
3054
3085
  className
3055
3086
  ),
@@ -3084,12 +3115,12 @@ function PrivanaButton({
3084
3115
  }
3085
3116
  const handleClick = () => setModalOpen(true);
3086
3117
  const buttonElement = renderButton ? renderButton({ onClick: handleClick, isOpen: modalOpen }) : /* @__PURE__ */ jsxRuntime.jsx(
3087
- chunk4IW4V7YJ_cjs.Button,
3118
+ chunk7KEQHWZB_cjs.Button,
3088
3119
  {
3089
3120
  variant,
3090
3121
  size,
3091
3122
  asChild,
3092
- className: chunk4IW4V7YJ_cjs.cn(className),
3123
+ className: chunk7KEQHWZB_cjs.cn(className),
3093
3124
  onClick: handleClick,
3094
3125
  disabled: !isConnected,
3095
3126
  ...buttonProps,
@@ -3110,6 +3141,745 @@ function PrivanaButton({
3110
3141
  )
3111
3142
  ] });
3112
3143
  }
3144
+
3145
+ // src/sdk/hooks/external-deposit-lock.ts
3146
+ var ACTIVE_SESSION_PREFIX = "privana:external-deposit-lock:active:";
3147
+ var SESSION_PREFIX = "privana:external-deposit-lock:session:";
3148
+ var ExternalDepositLockSessionChangedError = class _ExternalDepositLockSessionChangedError extends Error {
3149
+ constructor() {
3150
+ super("External deposit lock session changed");
3151
+ this.name = "ExternalDepositLockSessionChangedError";
3152
+ Object.setPrototypeOf(this, _ExternalDepositLockSessionChangedError.prototype);
3153
+ }
3154
+ };
3155
+ function externalDepositSessionId(chainId, tokenId) {
3156
+ return `${chainId}:${tokenId.toLowerCase()}`;
3157
+ }
3158
+ function isExternalDepositBlockInSession(session, blockNumber) {
3159
+ return Number.isSafeInteger(blockNumber) && blockNumber > session.startBlock;
3160
+ }
3161
+ function isCurrentExternalDepositVerification(session, txHash) {
3162
+ return session.creditedAmount === void 0 && session.verification?.hash.toLowerCase() === txHash.toLowerCase();
3163
+ }
3164
+ function getExternalDepositMinimum(response, chainId) {
3165
+ const value = response?.min_deposit?.[String(chainId)]?.erc20;
3166
+ if (value === void 0) return void 0;
3167
+ try {
3168
+ const amount = BigInt(value);
3169
+ return amount >= 0n ? amount : void 0;
3170
+ } catch {
3171
+ return void 0;
3172
+ }
3173
+ }
3174
+ function activeSessionKey(owner) {
3175
+ return `${ACTIVE_SESSION_PREFIX}${owner.toLowerCase()}`;
3176
+ }
3177
+ function sessionKey(owner, sessionId) {
3178
+ return `${SESSION_PREFIX}${owner.toLowerCase()}:${sessionId}`;
3179
+ }
3180
+ function activeSessionId(owner) {
3181
+ const value = chunk7KEQHWZB_cjs.getSharedBrowserStorageItem(activeSessionKey(owner));
3182
+ return value || void 0;
3183
+ }
3184
+ function isPositiveIntegerString(value) {
3185
+ if (typeof value !== "string") return false;
3186
+ try {
3187
+ return BigInt(value) > 0n;
3188
+ } catch {
3189
+ return false;
3190
+ }
3191
+ }
3192
+ function isSessionRecord(value) {
3193
+ if (!value || typeof value !== "object") return false;
3194
+ const record = value;
3195
+ if (record.version !== 1 || typeof record.owner !== "string" || typeof record.serviceAddress !== "string" || !Number.isInteger(record.chainId) || (record.chainId ?? 0) <= 0 || typeof record.tokenId !== "string" || !Number.isSafeInteger(record.startBlock) || (record.startBlock ?? -1) < 0 || !isPositiveIntegerString(record.depositAmount) || !isPositiveIntegerString(record.maxLockAmount) || !Number.isInteger(record.lockDuration) || (record.lockDuration ?? 0) <= 0 || typeof record.generation !== "string" || !record.generation || record.submissionAmbiguous !== void 0 && typeof record.submissionAmbiguous !== "boolean" || record.creditedAmount !== void 0 && !isPositiveIntegerString(record.creditedAmount)) {
3196
+ return false;
3197
+ }
3198
+ if (record.verification && (typeof record.verification.hash !== "string" || record.verification.chainId !== record.chainId || !isPositiveIntegerString(record.verification.amount) || record.verification.logIndex !== void 0 && (!Number.isInteger(record.verification.logIndex) || record.verification.logIndex < 0))) {
3199
+ return false;
3200
+ }
3201
+ if (record.verification && record.creditedAmount !== void 0) return false;
3202
+ if (record.submissionAmbiguous && record.creditedAmount === void 0) return false;
3203
+ if (!record.payload) {
3204
+ return record.creditedAmount !== void 0 && !record.submissionAmbiguous;
3205
+ }
3206
+ if (typeof record.payload.signature !== "string" || typeof record.payload.token_id !== "string" || typeof record.payload.service_address !== "string" || record.payload.signature !== record.generation || record.payload.token_id.toLowerCase() !== record.tokenId.toLowerCase() || record.payload.service_address.toLowerCase() !== record.serviceAddress.toLowerCase() || !isPositiveIntegerString(record.payload.amount)) {
3207
+ return false;
3208
+ }
3209
+ return BigInt(record.payload.amount) <= BigInt(record.maxLockAmount);
3210
+ }
3211
+ function writeSessionRecord(session) {
3212
+ const id = externalDepositSessionId(session.chainId, session.tokenId);
3213
+ return chunk7KEQHWZB_cjs.setSharedBrowserStorageItem(sessionKey(session.owner, id), JSON.stringify(session));
3214
+ }
3215
+ function saveExternalDepositLockSession(session, expectedSession = null) {
3216
+ if (!isSessionRecord(session)) throw new Error("Invalid external deposit lock session");
3217
+ const current = loadExternalDepositLockSession(session.owner);
3218
+ if (expectedSession === null && current || expectedSession !== null && (!current || !isSameSessionSnapshot(current, expectedSession))) {
3219
+ throw new ExternalDepositLockSessionChangedError();
3220
+ }
3221
+ const nextId = externalDepositSessionId(session.chainId, session.tokenId);
3222
+ const previousId = activeSessionId(session.owner);
3223
+ if (!writeSessionRecord(session)) {
3224
+ throw new Error("Unable to persist external deposit lock session");
3225
+ }
3226
+ if (previousId !== nextId) {
3227
+ if (!chunk7KEQHWZB_cjs.setSharedBrowserStorageItem(activeSessionKey(session.owner), nextId)) {
3228
+ chunk7KEQHWZB_cjs.removeSharedBrowserStorageItem(sessionKey(session.owner, nextId));
3229
+ throw new Error("Unable to persist external deposit lock session");
3230
+ }
3231
+ if (previousId) {
3232
+ chunk7KEQHWZB_cjs.removeSharedBrowserStorageItem(sessionKey(session.owner, previousId));
3233
+ }
3234
+ }
3235
+ }
3236
+ function loadExternalDepositLockSession(owner) {
3237
+ const id = activeSessionId(owner);
3238
+ if (!id) return void 0;
3239
+ const key = sessionKey(owner, id);
3240
+ try {
3241
+ const raw = chunk7KEQHWZB_cjs.getSharedBrowserStorageItem(key);
3242
+ const parsed = raw ? JSON.parse(raw) : void 0;
3243
+ if (!isSessionRecord(parsed) || parsed.owner.toLowerCase() !== owner.toLowerCase() || externalDepositSessionId(parsed.chainId, parsed.tokenId) !== id) {
3244
+ chunk7KEQHWZB_cjs.removeSharedBrowserStorageItem(key);
3245
+ chunk7KEQHWZB_cjs.removeSharedBrowserStorageItem(activeSessionKey(owner));
3246
+ return void 0;
3247
+ }
3248
+ return parsed;
3249
+ } catch {
3250
+ chunk7KEQHWZB_cjs.removeSharedBrowserStorageItem(key);
3251
+ chunk7KEQHWZB_cjs.removeSharedBrowserStorageItem(activeSessionKey(owner));
3252
+ return void 0;
3253
+ }
3254
+ }
3255
+ function subscribeExternalDepositLockSession(owner, onChange) {
3256
+ if (typeof window === "undefined") return () => void 0;
3257
+ let localStorage;
3258
+ try {
3259
+ localStorage = window.localStorage;
3260
+ } catch {
3261
+ return () => void 0;
3262
+ }
3263
+ const activeKey = activeSessionKey(owner);
3264
+ const ownerSessionPrefix = `${SESSION_PREFIX}${owner.toLowerCase()}:`;
3265
+ const handleStorage = (event) => {
3266
+ if (event.storageArea !== localStorage) return;
3267
+ if (event.key !== null && event.key !== activeKey && !event.key.startsWith(ownerSessionPrefix)) {
3268
+ return;
3269
+ }
3270
+ onChange(loadExternalDepositLockSession(owner));
3271
+ };
3272
+ window.addEventListener("storage", handleStorage);
3273
+ return () => window.removeEventListener("storage", handleStorage);
3274
+ }
3275
+ function clearExternalDepositLockSession(owner, expectedSessionId, expectedGeneration) {
3276
+ const id = activeSessionId(owner);
3277
+ if (!id || expectedSessionId && id !== expectedSessionId) return;
3278
+ if (expectedGeneration) {
3279
+ const current = loadExternalDepositLockSession(owner);
3280
+ if (!current || current.generation !== expectedGeneration) return;
3281
+ }
3282
+ chunk7KEQHWZB_cjs.removeSharedBrowserStorageItem(sessionKey(owner, id));
3283
+ chunk7KEQHWZB_cjs.removeSharedBrowserStorageItem(activeSessionKey(owner));
3284
+ }
3285
+ function isSameVerification(left, right) {
3286
+ if (!left || !right) return left === right;
3287
+ return left.hash.toLowerCase() === right.hash.toLowerCase() && left.chainId === right.chainId && left.amount === right.amount && (left.logIndex ?? 0) === (right.logIndex ?? 0);
3288
+ }
3289
+ function isSamePayload(left, right) {
3290
+ if (!left || !right) return left === right;
3291
+ return left.service_address.toLowerCase() === right.service_address.toLowerCase() && left.token_id.toLowerCase() === right.token_id.toLowerCase() && left.amount === right.amount && left.expiry === right.expiry && left.nonce === right.nonce && left.signature === right.signature;
3292
+ }
3293
+ function isSameSessionSnapshot(left, right) {
3294
+ return left.version === right.version && left.owner.toLowerCase() === right.owner.toLowerCase() && left.serviceAddress.toLowerCase() === right.serviceAddress.toLowerCase() && left.chainId === right.chainId && left.tokenId.toLowerCase() === right.tokenId.toLowerCase() && left.startBlock === right.startBlock && left.depositAmount === right.depositAmount && left.maxLockAmount === right.maxLockAmount && left.lockDuration === right.lockDuration && left.generation === right.generation && left.creditedAmount === right.creditedAmount && left.submissionAmbiguous === right.submissionAmbiguous && isSameVerification(left.verification, right.verification) && isSamePayload(left.payload, right.payload);
3295
+ }
3296
+ function isSameExternalDepositLockSession(left, right) {
3297
+ return isSameSessionSnapshot(left, right);
3298
+ }
3299
+ function clearExternalDepositVerification(session) {
3300
+ if (!session.verification || session.creditedAmount) return void 0;
3301
+ const current = loadExternalDepositLockSession(session.owner);
3302
+ if (!current || current.generation !== session.generation || current.creditedAmount || !isSameVerification(current.verification, session.verification)) {
3303
+ return void 0;
3304
+ }
3305
+ const next = { ...current, verification: void 0 };
3306
+ if (!writeSessionRecord(next)) {
3307
+ throw new Error("Unable to clear failed deposit verification");
3308
+ }
3309
+ return next;
3310
+ }
3311
+ function discardExternalDepositLockSession(session) {
3312
+ const current = loadExternalDepositLockSession(session.owner);
3313
+ if (!current) return true;
3314
+ if (!isSameSessionSnapshot(current, session)) return false;
3315
+ clearExternalDepositLockSession(
3316
+ current.owner,
3317
+ externalDepositSessionId(current.chainId, current.tokenId),
3318
+ current.generation
3319
+ );
3320
+ return loadExternalDepositLockSession(current.owner) === void 0;
3321
+ }
3322
+ function clearSubmittedPayload(session, signature, clearAmbiguous = false) {
3323
+ const current = loadExternalDepositLockSession(session.owner);
3324
+ if (!current?.payload || current.payload.signature !== signature || current.submissionAmbiguous && !clearAmbiguous) {
3325
+ return false;
3326
+ }
3327
+ return writeSessionRecord({ ...current, submissionAmbiguous: void 0, payload: void 0 });
3328
+ }
3329
+ function markSubmissionAmbiguous(session, signature) {
3330
+ const current = loadExternalDepositLockSession(session.owner);
3331
+ if (!current?.payload || current.payload.signature !== signature) return false;
3332
+ if (current.submissionAmbiguous) return true;
3333
+ return writeSessionRecord({ ...current, submissionAmbiguous: true });
3334
+ }
3335
+ function ambiguousSubmissionError(error) {
3336
+ return new chunk7KEQHWZB_cjs.PostDepositLockError(
3337
+ "Lock submission could not be confirmed. Retry only the saved signature, or check locked funds before stopping recovery.",
3338
+ error.reason,
3339
+ error.signedAmount,
3340
+ error.creditedAmount,
3341
+ {
3342
+ cause: error.cause,
3343
+ submissionMayHaveSucceeded: true
3344
+ }
3345
+ );
3346
+ }
3347
+ function isDefinitiveSubmissionFailure(error) {
3348
+ const cause = error.cause;
3349
+ return cause instanceof chunk7KEQHWZB_cjs.AccountingApiError && cause.statusCode !== 408 && cause.statusCode < 500;
3350
+ }
3351
+ function submissionLockName(session) {
3352
+ return `privana:external-deposit-lock:submit:${session.owner.toLowerCase()}:${externalDepositSessionId(session.chainId, session.tokenId)}`;
3353
+ }
3354
+ async function withSubmissionLock(session, task) {
3355
+ const locks = typeof navigator === "undefined" ? void 0 : navigator.locks;
3356
+ if (!locks) return task(false);
3357
+ return locks.request(submissionLockName(session), () => task(true));
3358
+ }
3359
+ function externalDepositRetryAmount(session) {
3360
+ if (!session.creditedAmount) throw new Error("No credited external deposit to recover");
3361
+ const creditedAmount = BigInt(session.creditedAmount);
3362
+ const maxLockAmount = BigInt(session.maxLockAmount);
3363
+ return creditedAmount < maxLockAmount ? creditedAmount : maxLockAmount;
3364
+ }
3365
+ async function submitExternalDepositLock(client, session) {
3366
+ return withSubmissionLock(session, async (crossTabExclusive) => {
3367
+ const current = loadExternalDepositLockSession(session.owner);
3368
+ if (!current || current.generation !== session.generation) {
3369
+ throw new chunk7KEQHWZB_cjs.PostDepositLockError(
3370
+ "External deposit lock session changed before submission",
3371
+ "not-found",
3372
+ BigInt(session.maxLockAmount),
3373
+ session.creditedAmount ? BigInt(session.creditedAmount) : void 0
3374
+ );
3375
+ }
3376
+ const result = await submitExternalDepositLockAttempt(client, current, crossTabExclusive);
3377
+ clearExternalDepositLockSession(
3378
+ current.owner,
3379
+ externalDepositSessionId(current.chainId, current.tokenId),
3380
+ current.generation
3381
+ );
3382
+ return result;
3383
+ });
3384
+ }
3385
+ async function submitExternalDepositLockAttempt(client, session, crossTabExclusive) {
3386
+ const creditedAmount = session.creditedAmount ? BigInt(session.creditedAmount) : void 0;
3387
+ if (!creditedAmount) {
3388
+ throw new chunk7KEQHWZB_cjs.PostDepositLockError(
3389
+ "External deposit has not been credited",
3390
+ "submission-failed",
3391
+ BigInt(session.maxLockAmount)
3392
+ );
3393
+ }
3394
+ const payload = session.payload;
3395
+ if (!payload) {
3396
+ throw new chunk7KEQHWZB_cjs.PostDepositLockError(
3397
+ "No persisted signed policy found for this deposit session",
3398
+ "not-found",
3399
+ BigInt(session.maxLockAmount),
3400
+ creditedAmount
3401
+ );
3402
+ }
3403
+ try {
3404
+ return await chunk7KEQHWZB_cjs.submitPendingLock({
3405
+ client,
3406
+ payload,
3407
+ creditedAmount,
3408
+ beforeSubmit: () => {
3409
+ if (!markSubmissionAmbiguous(session, payload.signature)) {
3410
+ throw new Error("Unable to persist lock submission recovery state");
3411
+ }
3412
+ }
3413
+ });
3414
+ } catch (err) {
3415
+ if (err instanceof chunk7KEQHWZB_cjs.PostDepositLockError && err.reason === "submission-failed" && crossTabExclusive && !session.submissionAmbiguous && isDefinitiveSubmissionFailure(err)) {
3416
+ if (!clearSubmittedPayload(session, payload.signature, true)) {
3417
+ const latest = loadExternalDepositLockSession(session.owner);
3418
+ if (latest?.submissionAmbiguous) throw ambiguousSubmissionError(err);
3419
+ }
3420
+ } else if (err instanceof chunk7KEQHWZB_cjs.PostDepositLockError && err.reason === "submission-failed") {
3421
+ const ambiguous = markSubmissionAmbiguous(session, payload.signature) || loadExternalDepositLockSession(session.owner)?.submissionAmbiguous === true;
3422
+ if (ambiguous) throw ambiguousSubmissionError(err);
3423
+ } else {
3424
+ const current = loadExternalDepositLockSession(session.owner);
3425
+ if (session.submissionAmbiguous || current?.submissionAmbiguous) {
3426
+ if (err instanceof chunk7KEQHWZB_cjs.PostDepositLockError) throw ambiguousSubmissionError(err);
3427
+ throw err;
3428
+ }
3429
+ if (!clearSubmittedPayload(session, payload.signature)) {
3430
+ const latest = loadExternalDepositLockSession(session.owner);
3431
+ if (latest?.submissionAmbiguous && err instanceof chunk7KEQHWZB_cjs.PostDepositLockError) {
3432
+ throw ambiguousSubmissionError(err);
3433
+ }
3434
+ }
3435
+ }
3436
+ throw err;
3437
+ }
3438
+ }
3439
+ function useExternalDepositLock({
3440
+ allowance,
3441
+ onLockSubmitted,
3442
+ onLockFailed
3443
+ }) {
3444
+ const { client, networkConfig, serviceAddress, getTokenById, tokensStatus } = chunk7KEQHWZB_cjs.usePrivanaContext();
3445
+ const config = wagmi.useConfig();
3446
+ const queryClient = reactQuery.useQueryClient();
3447
+ const { address } = wagmi.useAccount();
3448
+ const { privateReadAddress } = chunk7KEQHWZB_cjs.usePrivateReadRequest();
3449
+ const { ensureCorrectChain } = chunk7KEQHWZB_cjs.useEnsureCorrectChain();
3450
+ const [isSigning, setIsSigning] = react.useState(false);
3451
+ const [isSubmittingLock, setIsSubmittingLock] = react.useState(false);
3452
+ const [session, setSession] = react.useState(null);
3453
+ const sessionRef = react.useRef(null);
3454
+ const signingRef = react.useRef(false);
3455
+ const settlingRef = react.useRef(false);
3456
+ const pendingCreditedTransitionRef = react.useRef(null);
3457
+ const hydratedScopeRef = react.useRef(null);
3458
+ const beneficiaryRef = react.useRef(privateReadAddress);
3459
+ beneficiaryRef.current = privateReadAddress;
3460
+ const onLockSubmittedRef = react.useRef(onLockSubmitted);
3461
+ const onLockFailedRef = react.useRef(onLockFailed);
3462
+ react.useEffect(() => {
3463
+ onLockSubmittedRef.current = onLockSubmitted;
3464
+ onLockFailedRef.current = onLockFailed;
3465
+ }, [onLockSubmitted, onLockFailed]);
3466
+ const installSession = react.useCallback((next) => {
3467
+ sessionRef.current = next;
3468
+ setSession(next);
3469
+ }, []);
3470
+ const preserveCreditedFallback = react.useCallback(
3471
+ (durable) => {
3472
+ const pending = pendingCreditedTransitionRef.current;
3473
+ if (pending && durable && isSameExternalDepositLockSession(durable, pending.predecessor)) {
3474
+ return pending.credited;
3475
+ }
3476
+ pendingCreditedTransitionRef.current = null;
3477
+ return durable;
3478
+ },
3479
+ []
3480
+ );
3481
+ const notifyFailure = react.useCallback((error) => {
3482
+ onLockFailedRef.current?.(error);
3483
+ }, []);
3484
+ const submitSession = react.useCallback(
3485
+ async (active) => {
3486
+ if (settlingRef.current) return;
3487
+ settlingRef.current = true;
3488
+ setIsSubmittingLock(true);
3489
+ let result;
3490
+ try {
3491
+ let submission = active;
3492
+ const storedBeforeSubmit = loadExternalDepositLockSession(active.owner);
3493
+ if (storedBeforeSubmit?.generation === active.generation) {
3494
+ if (active.creditedAmount && !storedBeforeSubmit.creditedAmount) {
3495
+ const pending = pendingCreditedTransitionRef.current;
3496
+ if (!pending || !isSameExternalDepositLockSession(active, pending.credited) || !isSameExternalDepositLockSession(storedBeforeSubmit, pending.predecessor)) {
3497
+ throw new ExternalDepositLockSessionChangedError();
3498
+ }
3499
+ saveExternalDepositLockSession(pending.credited, pending.predecessor);
3500
+ pendingCreditedTransitionRef.current = null;
3501
+ submission = pending.credited;
3502
+ } else {
3503
+ submission = storedBeforeSubmit;
3504
+ }
3505
+ }
3506
+ result = await submitExternalDepositLock(client, submission);
3507
+ } catch (err) {
3508
+ const stored = loadExternalDepositLockSession(active.owner);
3509
+ const error = err instanceof chunk7KEQHWZB_cjs.PostDepositLockError ? err : new chunk7KEQHWZB_cjs.PostDepositLockError(
3510
+ err instanceof Error ? err.message : "Lock submission failed",
3511
+ "submission-failed",
3512
+ BigInt(active.maxLockAmount),
3513
+ active.creditedAmount ? BigInt(active.creditedAmount) : void 0,
3514
+ { cause: err }
3515
+ );
3516
+ if (err instanceof ExternalDepositLockSessionChangedError) {
3517
+ pendingCreditedTransitionRef.current = null;
3518
+ installSession(stored ?? null);
3519
+ return;
3520
+ }
3521
+ if (!stored || stored.generation !== active.generation) {
3522
+ pendingCreditedTransitionRef.current = null;
3523
+ installSession(stored ?? null);
3524
+ return;
3525
+ }
3526
+ if (active.creditedAmount && !stored.creditedAmount) {
3527
+ const pending = pendingCreditedTransitionRef.current;
3528
+ if (pending && isSameExternalDepositLockSession(active, pending.credited) && isSameExternalDepositLockSession(stored, pending.predecessor)) {
3529
+ installSession(pending.credited);
3530
+ notifyFailure(error);
3531
+ return;
3532
+ }
3533
+ pendingCreditedTransitionRef.current = null;
3534
+ installSession(stored);
3535
+ return;
3536
+ }
3537
+ installSession(active.creditedAmount && !stored.creditedAmount ? active : stored);
3538
+ notifyFailure(error);
3539
+ return;
3540
+ } finally {
3541
+ settlingRef.current = false;
3542
+ setIsSubmittingLock(false);
3543
+ }
3544
+ installSession(loadExternalDepositLockSession(active.owner) ?? null);
3545
+ queryClient.invalidateQueries({ queryKey: ["accounting-balance"] });
3546
+ queryClient.invalidateQueries({ queryKey: ["accounting-locked-funds"] });
3547
+ queryClient.invalidateQueries({ queryKey: ["accounting-total-locked-balance"] });
3548
+ queryClient.invalidateQueries({ queryKey: ["accounting-history"] });
3549
+ onLockSubmittedRef.current?.(result);
3550
+ },
3551
+ [client, installSession, notifyFailure, queryClient]
3552
+ );
3553
+ const validateRestoredSession = react.useCallback(
3554
+ (restored) => {
3555
+ if (!restored || !serviceAddress) return null;
3556
+ const token = getTokenById(restored.tokenId);
3557
+ const invalid = restored.serviceAddress.toLowerCase() !== serviceAddress.toLowerCase() || !token || token.chainId !== restored.chainId || token.contract === viem.zeroAddress || !restored.creditedAmount && !restored.payload;
3558
+ if (!invalid) return restored;
3559
+ clearExternalDepositLockSession(
3560
+ restored.owner,
3561
+ externalDepositSessionId(restored.chainId, restored.tokenId),
3562
+ restored.generation
3563
+ );
3564
+ return null;
3565
+ },
3566
+ [getTokenById, serviceAddress]
3567
+ );
3568
+ react.useEffect(() => {
3569
+ if (!privateReadAddress || !serviceAddress || tokensStatus !== "ready") {
3570
+ setSession(null);
3571
+ return;
3572
+ }
3573
+ const hydrationKey = `${privateReadAddress.toLowerCase()}:${serviceAddress.toLowerCase()}`;
3574
+ const shouldResume = hydratedScopeRef.current !== hydrationKey;
3575
+ hydratedScopeRef.current = hydrationKey;
3576
+ const restored = preserveCreditedFallback(
3577
+ validateRestoredSession(loadExternalDepositLockSession(privateReadAddress))
3578
+ );
3579
+ installSession(restored);
3580
+ if (!restored) {
3581
+ return;
3582
+ }
3583
+ if (!shouldResume) return;
3584
+ if (restored.creditedAmount && restored.payload) {
3585
+ void submitSession(restored);
3586
+ } else if (restored.creditedAmount) {
3587
+ notifyFailure(
3588
+ new chunk7KEQHWZB_cjs.PostDepositLockError(
3589
+ "Deposit credited; sign a fresh policy to lock the funds",
3590
+ "not-found",
3591
+ BigInt(restored.maxLockAmount),
3592
+ BigInt(restored.creditedAmount)
3593
+ )
3594
+ );
3595
+ }
3596
+ }, [
3597
+ installSession,
3598
+ notifyFailure,
3599
+ privateReadAddress,
3600
+ preserveCreditedFallback,
3601
+ serviceAddress,
3602
+ submitSession,
3603
+ tokensStatus,
3604
+ validateRestoredSession
3605
+ ]);
3606
+ react.useEffect(() => {
3607
+ if (!privateReadAddress || !serviceAddress || tokensStatus !== "ready") return;
3608
+ const reconcile = (restored) => {
3609
+ installSession(preserveCreditedFallback(validateRestoredSession(restored)));
3610
+ };
3611
+ const unsubscribe = subscribeExternalDepositLockSession(privateReadAddress, reconcile);
3612
+ reconcile(loadExternalDepositLockSession(privateReadAddress));
3613
+ return unsubscribe;
3614
+ }, [
3615
+ installSession,
3616
+ preserveCreditedFallback,
3617
+ privateReadAddress,
3618
+ serviceAddress,
3619
+ tokensStatus,
3620
+ validateRestoredSession
3621
+ ]);
3622
+ const signAndPersist = react.useCallback(
3623
+ async ({ tokenId, amount }) => {
3624
+ if (!allowance) throw new Error("No allowance configured for this deposit");
3625
+ if (signingRef.current || settlingRef.current) {
3626
+ throw new Error("A policy operation is already in progress");
3627
+ }
3628
+ if (!chunk7KEQHWZB_cjs.canUseSharedBrowserStorage()) {
3629
+ throw new Error("Browser storage is required for locked deposit recovery");
3630
+ }
3631
+ const owner = chunk7KEQHWZB_cjs.requireDepositLockOwner(address, privateReadAddress);
3632
+ if (sessionRef.current || loadExternalDepositLockSession(owner)) {
3633
+ throw new Error("Finish or cancel the active external deposit before starting another");
3634
+ }
3635
+ const token = getTokenById(tokenId);
3636
+ if (!token) throw new Error(`Unknown token ID: ${tokenId}`);
3637
+ if (token.contract === viem.zeroAddress) {
3638
+ throw new Error("External deposits support ERC20 tokens only");
3639
+ }
3640
+ const targetService = chunk7KEQHWZB_cjs.requireServiceAddress(serviceAddress);
3641
+ const lockDuration = allowance.lockDuration ?? chunk7KEQHWZB_cjs.DEFAULT_LOCK_DURATION_SECONDS;
3642
+ signingRef.current = true;
3643
+ setIsSigning(true);
3644
+ try {
3645
+ await ensureCorrectChain(networkConfig.chainId);
3646
+ const signingWalletClient = await chunk7KEQHWZB_cjs.getWalletClient(config, {
3647
+ chainId: networkConfig.chainId
3648
+ });
3649
+ const payload = await chunk7KEQHWZB_cjs.createSignedLockRequest({
3650
+ client,
3651
+ walletClient: signingWalletClient,
3652
+ userAddress: owner,
3653
+ networkConfig,
3654
+ serviceAddress: targetService,
3655
+ tokenId: token.id,
3656
+ amount: chunk7KEQHWZB_cjs.clampLockAmount(amount, BigInt(allowance.value)),
3657
+ lockDuration
3658
+ });
3659
+ const startBlock = await chunk7KEQHWZB_cjs.getBlockNumber(config, { chainId: token.chainId });
3660
+ if (startBlock > BigInt(Number.MAX_SAFE_INTEGER)) {
3661
+ throw new Error("Source-chain block number exceeds the supported range");
3662
+ }
3663
+ if (beneficiaryRef.current?.toLowerCase() !== owner.toLowerCase()) {
3664
+ throw new Error("Authenticated deposit account changed while signing");
3665
+ }
3666
+ const next = {
3667
+ version: 1,
3668
+ owner,
3669
+ serviceAddress: targetService,
3670
+ chainId: token.chainId,
3671
+ tokenId: token.id,
3672
+ startBlock: Number(startBlock),
3673
+ depositAmount: amount.toString(),
3674
+ maxLockAmount: String(payload.amount),
3675
+ lockDuration,
3676
+ generation: payload.signature,
3677
+ payload
3678
+ };
3679
+ saveExternalDepositLockSession(next, null);
3680
+ installSession(next);
3681
+ } finally {
3682
+ signingRef.current = false;
3683
+ setIsSigning(false);
3684
+ }
3685
+ },
3686
+ [
3687
+ address,
3688
+ allowance,
3689
+ client,
3690
+ config,
3691
+ ensureCorrectChain,
3692
+ getTokenById,
3693
+ installSession,
3694
+ networkConfig,
3695
+ privateReadAddress,
3696
+ serviceAddress
3697
+ ]
3698
+ );
3699
+ const settleAfterCredit = react.useCallback(
3700
+ async (txHash, creditedAmount) => {
3701
+ const active = sessionRef.current;
3702
+ if (!active || settlingRef.current) return;
3703
+ if (!isCurrentExternalDepositVerification(active, txHash)) {
3704
+ return;
3705
+ }
3706
+ if (creditedAmount <= 0n) throw new Error("Credited amount must be positive");
3707
+ const credited = {
3708
+ ...active,
3709
+ verification: void 0,
3710
+ creditedAmount: creditedAmount.toString()
3711
+ };
3712
+ try {
3713
+ saveExternalDepositLockSession(credited, active);
3714
+ pendingCreditedTransitionRef.current = null;
3715
+ } catch (err) {
3716
+ const stored = loadExternalDepositLockSession(active.owner);
3717
+ if (err instanceof ExternalDepositLockSessionChangedError || !stored || !isSameExternalDepositLockSession(stored, active)) {
3718
+ pendingCreditedTransitionRef.current = null;
3719
+ installSession(stored ?? null);
3720
+ return;
3721
+ }
3722
+ pendingCreditedTransitionRef.current = { predecessor: active, credited };
3723
+ installSession(credited);
3724
+ notifyFailure(
3725
+ new chunk7KEQHWZB_cjs.PostDepositLockError(
3726
+ err instanceof Error ? err.message : "Unable to persist credited deposit state",
3727
+ "submission-failed",
3728
+ BigInt(active.maxLockAmount),
3729
+ creditedAmount,
3730
+ { cause: err }
3731
+ )
3732
+ );
3733
+ return;
3734
+ }
3735
+ installSession(credited);
3736
+ await submitSession(credited);
3737
+ },
3738
+ [installSession, notifyFailure, submitSession]
3739
+ );
3740
+ const recordVerification = react.useCallback(
3741
+ (context) => {
3742
+ const active = sessionRef.current;
3743
+ if (!active || active.creditedAmount) {
3744
+ throw new Error("No external deposit session is awaiting verification");
3745
+ }
3746
+ if (active.verification) {
3747
+ const sameTransfer = active.verification.hash.toLowerCase() === context.hash.toLowerCase() && active.verification.chainId === context.chainId && active.verification.amount === context.amount.toString() && (active.verification.logIndex ?? 0) === (context.logIndex ?? 0);
3748
+ if (sameTransfer) return;
3749
+ throw new Error("Another transfer is already being verified for this deposit session");
3750
+ }
3751
+ if (context.chainId !== active.chainId || context.amount <= 0n) {
3752
+ throw new Error("Discovered transfer does not match the signed deposit session");
3753
+ }
3754
+ const current = loadExternalDepositLockSession(active.owner);
3755
+ if (!current || current.generation !== active.generation) {
3756
+ throw new Error("The signed deposit session changed before verification");
3757
+ }
3758
+ const next = {
3759
+ ...active,
3760
+ verification: {
3761
+ hash: context.hash,
3762
+ chainId: context.chainId,
3763
+ amount: context.amount.toString(),
3764
+ logIndex: context.logIndex
3765
+ }
3766
+ };
3767
+ saveExternalDepositLockSession(next, active);
3768
+ installSession(next);
3769
+ },
3770
+ [installSession]
3771
+ );
3772
+ const retryAfterCredit = react.useCallback(async () => {
3773
+ const active = sessionRef.current;
3774
+ if (!active?.creditedAmount) throw new Error("No credited external deposit to recover");
3775
+ if (signingRef.current || settlingRef.current) {
3776
+ throw new Error("A policy operation is already in progress");
3777
+ }
3778
+ if (privateReadAddress?.toLowerCase() !== active.owner.toLowerCase()) {
3779
+ throw new Error("Authenticated deposit account does not match the credited deposit");
3780
+ }
3781
+ const token = getTokenById(active.tokenId);
3782
+ if (!token || token.chainId !== active.chainId || token.contract === viem.zeroAddress) {
3783
+ throw new Error("The credited token is no longer available");
3784
+ }
3785
+ const targetService = chunk7KEQHWZB_cjs.requireServiceAddress(serviceAddress);
3786
+ if (targetService.toLowerCase() !== active.serviceAddress.toLowerCase()) {
3787
+ throw new Error("The service for this credited deposit has changed");
3788
+ }
3789
+ if (active.payload) {
3790
+ await submitSession(active);
3791
+ return;
3792
+ }
3793
+ if (active.submissionAmbiguous) {
3794
+ throw new Error(
3795
+ "The previous lock submission may have succeeded; a fresh signature is unsafe"
3796
+ );
3797
+ }
3798
+ const owner = chunk7KEQHWZB_cjs.requireDepositLockOwner(address, privateReadAddress);
3799
+ const amount = externalDepositRetryAmount(active);
3800
+ let retrySession;
3801
+ signingRef.current = true;
3802
+ setIsSigning(true);
3803
+ try {
3804
+ await ensureCorrectChain(networkConfig.chainId);
3805
+ const signingWalletClient = await chunk7KEQHWZB_cjs.getWalletClient(config, {
3806
+ chainId: networkConfig.chainId
3807
+ });
3808
+ const payload = await chunk7KEQHWZB_cjs.createSignedLockRequest({
3809
+ client,
3810
+ walletClient: signingWalletClient,
3811
+ userAddress: owner,
3812
+ networkConfig,
3813
+ serviceAddress: targetService,
3814
+ tokenId: active.tokenId,
3815
+ amount,
3816
+ lockDuration: active.lockDuration
3817
+ });
3818
+ if (beneficiaryRef.current?.toLowerCase() !== owner.toLowerCase()) {
3819
+ throw new Error("Authenticated deposit account changed while signing");
3820
+ }
3821
+ retrySession = {
3822
+ ...active,
3823
+ depositAmount: amount.toString(),
3824
+ generation: payload.signature,
3825
+ verification: void 0,
3826
+ submissionAmbiguous: void 0,
3827
+ payload
3828
+ };
3829
+ saveExternalDepositLockSession(retrySession, active);
3830
+ installSession(retrySession);
3831
+ } finally {
3832
+ signingRef.current = false;
3833
+ setIsSigning(false);
3834
+ }
3835
+ await submitSession(retrySession);
3836
+ }, [
3837
+ address,
3838
+ client,
3839
+ config,
3840
+ ensureCorrectChain,
3841
+ getTokenById,
3842
+ installSession,
3843
+ networkConfig,
3844
+ privateReadAddress,
3845
+ serviceAddress,
3846
+ submitSession
3847
+ ]);
3848
+ const clearVerification = react.useCallback(() => {
3849
+ const active = sessionRef.current;
3850
+ if (!active?.verification || active.creditedAmount) return false;
3851
+ const next = clearExternalDepositVerification(active);
3852
+ if (!next) {
3853
+ installSession(loadExternalDepositLockSession(active.owner) ?? null);
3854
+ return false;
3855
+ }
3856
+ installSession(next);
3857
+ return true;
3858
+ }, [installSession]);
3859
+ const discardSession = react.useCallback(() => {
3860
+ const active = sessionRef.current;
3861
+ if (!active) return true;
3862
+ if (signingRef.current || settlingRef.current) return false;
3863
+ const pending = pendingCreditedTransitionRef.current;
3864
+ const discardTarget = pending && isSameExternalDepositLockSession(active, pending.credited) ? pending.predecessor : active;
3865
+ const discarded = discardExternalDepositLockSession(discardTarget);
3866
+ const restored = loadExternalDepositLockSession(active.owner) ?? null;
3867
+ if (discarded) pendingCreditedTransitionRef.current = null;
3868
+ installSession(restored);
3869
+ return discarded && !restored;
3870
+ }, [installSession]);
3871
+ return {
3872
+ isSigning,
3873
+ isSubmittingLock,
3874
+ session,
3875
+ signAndPersist,
3876
+ recordVerification,
3877
+ settleAfterCredit,
3878
+ retryAfterCredit,
3879
+ clearVerification,
3880
+ discardSession
3881
+ };
3882
+ }
3113
3883
  var DEFAULT_MOONPAY_API_URL = "https://api.moonpay.com/v3";
3114
3884
  function useMoonpayLimits({
3115
3885
  currencyCode,
@@ -3153,7 +3923,7 @@ function useMoonpayLimits({
3153
3923
  };
3154
3924
  }
3155
3925
  function TokenSelectorView2({ selectedTokenId, onSelect }) {
3156
- const { enabledTokens } = chunk4IW4V7YJ_cjs.usePrivanaContext();
3926
+ const { enabledTokens } = chunk7KEQHWZB_cjs.usePrivanaContext();
3157
3927
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col rounded-[10px] p-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-h-72 flex-col gap-1 overflow-y-auto", children: [
3158
3928
  enabledTokens.map((token) => {
3159
3929
  const isSelected = selectedTokenId === token.id;
@@ -3162,7 +3932,7 @@ function TokenSelectorView2({ selectedTokenId, onSelect }) {
3162
3932
  {
3163
3933
  type: "button",
3164
3934
  onClick: () => onSelect(token.id),
3165
- className: chunk4IW4V7YJ_cjs.cn(
3935
+ className: chunk7KEQHWZB_cjs.cn(
3166
3936
  "hover:bg-secondary flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-left transition-colors",
3167
3937
  isSelected && "bg-secondary"
3168
3938
  ),
@@ -3217,7 +3987,7 @@ function CreditCardWidgetView({
3217
3987
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
3218
3988
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Complete your purchase" }),
3219
3989
  token && moonpayCurrencyCode ? /* @__PURE__ */ jsxRuntime.jsx(
3220
- chunk4IW4V7YJ_cjs.FiatOnRampForm,
3990
+ chunk7KEQHWZB_cjs.FiatOnRampForm,
3221
3991
  {
3222
3992
  tokenId: token.id,
3223
3993
  currencyCode: moonpayCurrencyCode,
@@ -3277,7 +4047,7 @@ function PolicyTermRow({
3277
4047
  /* @__PURE__ */ jsxRuntime.jsx(
3278
4048
  "div",
3279
4049
  {
3280
- className: chunk4IW4V7YJ_cjs.cn(
4050
+ className: chunk7KEQHWZB_cjs.cn(
3281
4051
  "mt-0.5 shrink-0",
3282
4052
  kind === "permission" ? "text-emerald-500" : "text-orange-500"
3283
4053
  ),
@@ -3339,11 +4109,19 @@ function AllowancePolicySection({
3339
4109
  ] });
3340
4110
  }
3341
4111
  function MoonPayGate({ enabled, children }) {
3342
- const { networkConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
4112
+ const { networkConfig } = chunk7KEQHWZB_cjs.usePrivanaContext();
3343
4113
  const apiKey = networkConfig.moonpayApiKey;
3344
4114
  if (!enabled || !apiKey) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
3345
4115
  return /* @__PURE__ */ jsxRuntime.jsx(moonpayReact.MoonPayProvider, { apiKey, children });
3346
4116
  }
4117
+ function formatPostDepositLockFailure(error, token) {
4118
+ if (error?.reason === "credited-below-signed" && error.creditedAmount !== void 0 && error.signedAmount !== void 0 && token) {
4119
+ const creditedAmount = `${viem.formatUnits(error.creditedAmount, token.decimals)} ${token.symbol}`;
4120
+ const signedAmount = `${viem.formatUnits(error.signedAmount, token.decimals)} ${token.symbol}`;
4121
+ return `Credited amount (${creditedAmount}) is below the signed lock amount (${signedAmount})`;
4122
+ }
4123
+ return error?.message ?? "Lock submission failed";
4124
+ }
3347
4125
  function MethodTabs({
3348
4126
  activeTab,
3349
4127
  onTabChange
@@ -3352,7 +4130,7 @@ function MethodTabs({
3352
4130
  /* @__PURE__ */ jsxRuntime.jsx(
3353
4131
  "div",
3354
4132
  {
3355
- className: chunk4IW4V7YJ_cjs.cn(
4133
+ className: chunk7KEQHWZB_cjs.cn(
3356
4134
  "bg-input absolute top-1 bottom-1 left-1 w-[calc(50%-8px)] rounded-md transition-transform duration-200",
3357
4135
  activeTab === "credit-card" && "translate-x-[calc(100%+8px)]"
3358
4136
  )
@@ -3363,7 +4141,7 @@ function MethodTabs({
3363
4141
  {
3364
4142
  type: "button",
3365
4143
  onClick: () => onTabChange("crypto"),
3366
- className: chunk4IW4V7YJ_cjs.cn(
4144
+ className: chunk7KEQHWZB_cjs.cn(
3367
4145
  "relative z-10 flex-1 cursor-pointer rounded-md px-3 py-[9px] text-sm font-medium transition-colors",
3368
4146
  activeTab === "crypto" ? "text-foreground" : "text-muted-foreground"
3369
4147
  ),
@@ -3375,7 +4153,7 @@ function MethodTabs({
3375
4153
  {
3376
4154
  type: "button",
3377
4155
  onClick: () => onTabChange("credit-card"),
3378
- className: chunk4IW4V7YJ_cjs.cn(
4156
+ className: chunk7KEQHWZB_cjs.cn(
3379
4157
  "relative z-10 flex-1 cursor-pointer rounded-md px-3 py-[9px] text-sm font-medium transition-colors",
3380
4158
  activeTab === "credit-card" ? "text-foreground" : "text-muted-foreground"
3381
4159
  ),
@@ -3410,19 +4188,21 @@ function DepositView({
3410
4188
  selectedToken,
3411
4189
  amount,
3412
4190
  allowance,
4191
+ externalMinimum,
3413
4192
  onAmountChange,
3414
4193
  onSelectToken,
3415
4194
  onConnectWallet,
3416
4195
  onSubmit,
3417
4196
  isSubmitting = false
3418
4197
  }) {
3419
- const { getChainById: getChainById2, chains, serviceName, serviceIcon, networkConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
4198
+ const { getChainById: getChainById2, chains, serviceName, serviceIcon, networkConfig, hostedAuthConfig } = chunk7KEQHWZB_cjs.usePrivanaContext();
3420
4199
  const { address, isConnected } = wagmi.useAccount();
3421
4200
  const appName = serviceName ?? "Privana";
3422
4201
  const chain = selectedToken ? getChainById2(selectedToken.chainId) : void 0;
3423
4202
  const targetChain = chain ?? chains[0];
3424
4203
  const sourceLabel = source === "connected" ? "Connected Wallet" : "External Wallet";
3425
4204
  const isConnectedSource = source === "connected";
4205
+ const isExternal = source === "external";
3426
4206
  const isCreditCard = source === "credit-card";
3427
4207
  const isNative = selectedToken?.contract === viem.zeroAddress;
3428
4208
  const { data: nativeBalanceData } = wagmi.useBalance({
@@ -3439,7 +4219,7 @@ function DepositView({
3439
4219
  query: { enabled: isConnectedSource && !!address && !!selectedToken && !isNative }
3440
4220
  });
3441
4221
  const walletBalance = isNative ? nativeBalanceData?.value : erc20Balance;
3442
- const formattedWalletBalance = walletBalance != null && selectedToken ? chunk4IW4V7YJ_cjs.formatTokenAmount(walletBalance.toString(), selectedToken.decimals) : "0.00";
4222
+ const formattedWalletBalance = walletBalance != null && selectedToken ? chunk7KEQHWZB_cjs.formatTokenAmount(walletBalance.toString(), selectedToken.decimals) : "0.00";
3443
4223
  const {
3444
4224
  minBuyAmount: moonpayMinBuy,
3445
4225
  isLoading: moonpayLimitsLoading,
@@ -3452,12 +4232,18 @@ function DepositView({
3452
4232
  const hasValidAmount = !!amount && parseFloat(amount) > 0;
3453
4233
  const maxAmountDecimals = isCreditCard ? 2 : selectedToken?.decimals;
3454
4234
  const tooManyDecimals = hasValidAmount && maxAmountDecimals != null && amount.includes(".") && amount.split(".")[1].length > maxAmountDecimals;
3455
- const exceedsBalance = isConnectedSource && hasValidAmount && !tooManyDecimals && !!selectedToken && walletBalance != null && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals) > walletBalance;
4235
+ const exceedsBalance = isConnectedSource && hasValidAmount && !tooManyDecimals && !!selectedToken && walletBalance != null && chunk7KEQHWZB_cjs.parseTokenAmount(amount, selectedToken.decimals) > walletBalance;
3456
4236
  const belowMoonpayMin = isCreditCard && hasValidAmount && moonpayMinBuy != null && parseFloat(amount) < moonpayMinBuy;
3457
4237
  const moonpayLimitsUnready = isCreditCard && !!selectedToken?.moonpayCurrencyCode && moonpayMinBuy == null;
3458
4238
  const creditCardUnavailable = isCreditCard && !!selectedToken && !selectedToken.moonpayCurrencyCode;
3459
- const needsConnect = isConnectedSource && !isConnected;
3460
- const canDeposit = hasValidAmount && !!selectedToken && !tooManyDecimals && !exceedsBalance && !belowMoonpayMin && !moonpayLimitsUnready && !creditCardUnavailable && !needsConnect;
4239
+ const externalTokenUnavailable = isExternal && !!selectedToken && isNative;
4240
+ const externalMinimumRequired = isExternal && !!allowance && !!selectedToken;
4241
+ const externalMinimumLoading = externalMinimumRequired && externalMinimum === void 0;
4242
+ const externalMinimumUnavailable = externalMinimumRequired && externalMinimum === null;
4243
+ const belowExternalMinimum = externalMinimumRequired && hasValidAmount && !tooManyDecimals && !!selectedToken && typeof externalMinimum === "bigint" && chunk7KEQHWZB_cjs.parseTokenAmount(amount, selectedToken.decimals) < externalMinimum;
4244
+ const externalNeedsWallet = isExternal && (!!allowance || !hostedAuthConfig);
4245
+ const needsConnect = (isConnectedSource || externalNeedsWallet) && !isConnected;
4246
+ const canDeposit = hasValidAmount && !!selectedToken && !tooManyDecimals && !exceedsBalance && !belowMoonpayMin && !moonpayLimitsUnready && !creditCardUnavailable && !externalTokenUnavailable && !externalMinimumLoading && !externalMinimumUnavailable && !belowExternalMinimum && !needsConnect;
3461
4247
  const handleMax = () => {
3462
4248
  const max = formattedWalletBalance.replace(/\s/g, "");
3463
4249
  if (parseFloat(max) > 0) onAmountChange(max);
@@ -3466,9 +4252,12 @@ function DepositView({
3466
4252
  isCreditCard ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
3467
4253
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: "Buy with credit card and deposit" }),
3468
4254
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Enter your deposit amount and proceed to sign a policy." })
3469
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: [
3470
- "Deposit from ",
3471
- sourceLabel
4255
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
4256
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-foreground text-[28px] leading-8 font-medium", children: [
4257
+ "Deposit from ",
4258
+ sourceLabel
4259
+ ] }),
4260
+ allowance && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Enter your deposit amount and proceed to sign a policy." })
3472
4261
  ] }),
3473
4262
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
3474
4263
  /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-muted-foreground text-sm", children: "Token" }),
@@ -3477,7 +4266,8 @@ function DepositView({
3477
4266
  {
3478
4267
  type: "button",
3479
4268
  onClick: onSelectToken,
3480
- className: "border-border bg-input flex w-full cursor-pointer items-center gap-3 rounded-lg border p-3 text-left",
4269
+ disabled: isSubmitting,
4270
+ className: "border-border bg-input flex w-full cursor-pointer items-center gap-3 rounded-lg border p-3 text-left disabled:cursor-not-allowed disabled:opacity-50",
3481
4271
  children: [
3482
4272
  selectedToken ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3483
4273
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 w-8 shrink-0 overflow-hidden rounded-full", children: getTokenIcon(selectedToken.symbol, 32) }),
@@ -3507,7 +4297,7 @@ function DepositView({
3507
4297
  /* @__PURE__ */ jsxRuntime.jsxs(
3508
4298
  "div",
3509
4299
  {
3510
- className: chunk4IW4V7YJ_cjs.cn(
4300
+ className: chunk7KEQHWZB_cjs.cn(
3511
4301
  "border-border bg-input flex items-center gap-2 rounded-[10px] border",
3512
4302
  isConnectedSource ? "py-1 pr-1 pl-3" : "px-3 py-3"
3513
4303
  ),
@@ -3518,6 +4308,7 @@ function DepositView({
3518
4308
  type: "text",
3519
4309
  inputMode: "decimal",
3520
4310
  placeholder: "Enter Amount",
4311
+ disabled: isSubmitting,
3521
4312
  value: amount,
3522
4313
  onChange: (e) => {
3523
4314
  const value = e.target.value.replace(/[^0-9.,]/g, "").replace(/,/g, ".");
@@ -3549,11 +4340,24 @@ function DepositView({
3549
4340
  moonpayMinBuy,
3550
4341
  " USD."
3551
4342
  ] }),
4343
+ belowExternalMinimum && selectedToken && typeof externalMinimum === "bigint" && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-destructive text-sm", children: [
4344
+ "Minimum deposit is ",
4345
+ viem.formatUnits(externalMinimum, selectedToken.decimals),
4346
+ " ",
4347
+ selectedToken.symbol,
4348
+ "."
4349
+ ] }),
4350
+ externalMinimumLoading && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Checking minimum deposit\u2026" }),
4351
+ externalMinimumUnavailable && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive text-sm", children: "Couldn\u2019t load the minimum deposit. Please try again." }),
3552
4352
  isCreditCard && moonpayLimitsError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive text-sm", children: "Couldn\u2019t load purchase limits. Please try again." }),
3553
4353
  isCreditCard && moonpayLimitsLoading && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Checking purchase limits\u2026" }),
3554
4354
  creditCardUnavailable && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-destructive text-sm", children: [
3555
4355
  selectedToken?.symbol ?? "This token",
3556
4356
  " isn\u2019t available for card purchases yet."
4357
+ ] }),
4358
+ externalTokenUnavailable && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-destructive text-sm", children: [
4359
+ selectedToken?.symbol ?? "This token",
4360
+ " can\u2019t be used for external deposits. Choose an ERC20 token."
3557
4361
  ] })
3558
4362
  ] }),
3559
4363
  allowance && /* @__PURE__ */ jsxRuntime.jsx(
@@ -3628,19 +4432,33 @@ function AwaitingDepositStatus({
3628
4432
  function ExternalDepositView({
3629
4433
  token,
3630
4434
  amount,
3631
- onCredited
4435
+ depositAddressState,
4436
+ onCredited,
4437
+ onDiscardLock,
4438
+ lock
3632
4439
  }) {
3633
- const { getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
3634
- const { depositAddress, isReady, isLoading } = useDepositAddress();
4440
+ const { getChainById: getChainById2, getTokenById, serviceName } = chunk7KEQHWZB_cjs.usePrivanaContext();
4441
+ const appName = serviceName ?? "Privana";
4442
+ const { depositAddress, isReady, isLoading } = depositAddressState;
3635
4443
  const chain = token ? getChainById2(token.chainId) : void 0;
4444
+ const lockSession = lock?.session;
4445
+ const recordVerification = lock?.recordVerification;
4446
+ const settleAfterCredit = lock?.settleAfterCredit;
4447
+ const retryAfterCredit = lock?.retryAfterCredit;
4448
+ const discoveryToken = lockSession ? getTokenById(lockSession.tokenId) : token;
3636
4449
  const [copied, setCopied] = react.useState(false);
3637
4450
  const [deadline] = react.useState(() => Date.now() + LISTENING_WINDOW_MS);
3638
4451
  const secondsLeft = useCountdown(deadline);
3639
4452
  const listening = secondsLeft > 0;
3640
4453
  const [nothingFound, setNothingFound] = react.useState(false);
3641
4454
  const [credited, setCredited] = react.useState(null);
3642
- const verification = chunk4IW4V7YJ_cjs.useDepositVerification({
3643
- onCredited: (txHash) => {
4455
+ const [showCancelWarning, setShowCancelWarning] = react.useState(false);
4456
+ const verification = chunk7KEQHWZB_cjs.useDepositVerification({
4457
+ onCredited: (txHash, _response, creditedAmount) => {
4458
+ if (settleAfterCredit) {
4459
+ void settleAfterCredit(txHash, creditedAmount);
4460
+ return;
4461
+ }
3644
4462
  if (onCredited) {
3645
4463
  onCredited();
3646
4464
  return;
@@ -3648,8 +4466,9 @@ function ExternalDepositView({
3648
4466
  setCredited({ txHash });
3649
4467
  }
3650
4468
  });
3651
- const { isVerifying, verificationFailed, didTimeout, verify } = verification;
3652
- const scanPaused = isVerifying || verificationFailed || didTimeout || !!credited;
4469
+ const { isVerifying, verificationFailed, canCheckAnotherTransfer, didTimeout, verify } = verification;
4470
+ const scanPaused = isVerifying || verificationFailed || didTimeout || !!credited || !!lock?.isSigning || !!lock?.isSubmittingLock || !!lockSession?.verification || !!lockSession?.creditedAmount;
4471
+ const showDepositInstructions = !credited && !lockSession?.creditedAmount;
3653
4472
  const {
3654
4473
  pending,
3655
4474
  isFetching: isScanning,
@@ -3658,23 +4477,58 @@ function ExternalDepositView({
3658
4477
  isUnavailable,
3659
4478
  refetch: refetchPendingDeposits
3660
4479
  } = usePendingDeposits({
3661
- chainId: token?.chainId,
3662
- enabled: isReady && !!depositAddress && !!token,
4480
+ chainId: discoveryToken?.chainId,
4481
+ tokenAddress: discoveryToken?.contract === viem.zeroAddress ? void 0 : discoveryToken?.contract,
4482
+ enabled: isReady && !!depositAddress && !!discoveryToken && discoveryToken.contract !== viem.zeroAddress,
3663
4483
  refetchInterval: listening && !scanPaused ? 3e4 : false
3664
4484
  });
3665
4485
  const processedRef = react.useRef(/* @__PURE__ */ new Set());
4486
+ const verificationRunRef = react.useRef(null);
4487
+ react.useEffect(
4488
+ () => () => {
4489
+ verificationRunRef.current = null;
4490
+ },
4491
+ []
4492
+ );
4493
+ react.useEffect(() => {
4494
+ const stored = lockSession?.verification;
4495
+ if (!stored || lockSession.creditedAmount || isVerifying || verificationFailed || didTimeout) {
4496
+ return;
4497
+ }
4498
+ const key = `${lockSession.generation}:${stored.chainId}:${stored.hash}:${stored.logIndex ?? 0}`;
4499
+ if (verificationRunRef.current === key) return;
4500
+ verificationRunRef.current = key;
4501
+ processedRef.current.add(`${stored.hash}:${stored.logIndex ?? 0}`);
4502
+ void verify({
4503
+ hash: stored.hash,
4504
+ chainId: stored.chainId,
4505
+ amount: BigInt(stored.amount),
4506
+ logIndex: stored.logIndex
4507
+ });
4508
+ }, [didTimeout, isVerifying, lockSession, verificationFailed, verify]);
3666
4509
  react.useEffect(() => {
3667
4510
  if (scanPaused) return;
3668
- const next = [...pending].sort((a, b) => a.block_number - b.block_number).find((d) => !processedRef.current.has(`${d.tx_hash}:${d.log_index}`));
4511
+ const next = [...pending].sort((a, b) => a.block_number - b.block_number).find(
4512
+ (deposit) => (!lockSession || isExternalDepositBlockInSession(lockSession, deposit.block_number)) && !processedRef.current.has(`${deposit.tx_hash}:${deposit.log_index}`)
4513
+ );
3669
4514
  if (!next) return;
3670
- processedRef.current.add(`${next.tx_hash}:${next.log_index}`);
3671
- void verify({
4515
+ const context = {
3672
4516
  hash: next.tx_hash,
3673
4517
  chainId: next.chain_id,
3674
4518
  amount: BigInt(next.amount),
3675
4519
  logIndex: next.log_index
3676
- });
3677
- }, [pending, scanPaused, verify]);
4520
+ };
4521
+ if (recordVerification) {
4522
+ try {
4523
+ recordVerification(context);
4524
+ } catch (err) {
4525
+ sonner.toast.error(err instanceof Error ? err.message : "Unable to save deposit recovery state");
4526
+ return;
4527
+ }
4528
+ }
4529
+ processedRef.current.add(`${next.tx_hash}:${next.log_index}`);
4530
+ if (!recordVerification) void verify(context);
4531
+ }, [lockSession, pending, recordVerification, scanPaused, verify]);
3678
4532
  const nothingFoundTimerRef = react.useRef(void 0);
3679
4533
  react.useEffect(() => () => clearTimeout(nothingFoundTimerRef.current), []);
3680
4534
  const handleRefresh = () => {
@@ -3687,11 +4541,27 @@ function ExternalDepositView({
3687
4541
  }
3688
4542
  });
3689
4543
  };
3690
- const handleCopy = () => {
4544
+ const handleCopy = async () => {
3691
4545
  if (!depositAddress) return;
3692
- void navigator.clipboard.writeText(depositAddress);
3693
- setCopied(true);
3694
- setTimeout(() => setCopied(false), 2e3);
4546
+ try {
4547
+ await navigator.clipboard.writeText(depositAddress);
4548
+ setCopied(true);
4549
+ setTimeout(() => setCopied(false), 2e3);
4550
+ } catch {
4551
+ sonner.toast.error("Unable to copy the deposit address");
4552
+ }
4553
+ };
4554
+ const handleCheckAnotherTransfer = () => {
4555
+ try {
4556
+ if (!lock?.clearVerification()) {
4557
+ sonner.toast.error("Deposit recovery changed in another tab. Please review the current state.");
4558
+ return;
4559
+ }
4560
+ verificationRunRef.current = null;
4561
+ verification.reset();
4562
+ } catch (err) {
4563
+ sonner.toast.error(err instanceof Error ? err.message : "Unable to continue deposit discovery");
4564
+ }
3695
4565
  };
3696
4566
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
3697
4567
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
@@ -3705,31 +4575,68 @@ function ExternalDepositView({
3705
4575
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-border h-px w-full" }),
3706
4576
  /* @__PURE__ */ jsxRuntime.jsx(SummaryRow, { value: amount || "\u2014", label: "Value" })
3707
4577
  ] }),
3708
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-secondary flex h-50 items-center justify-center rounded-[10px]", children: !isReady ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground px-6 text-center text-sm", children: "Connect your wallet to generate a deposit address." }) : depositAddress ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-[10px] bg-white p-3", children: /* @__PURE__ */ jsxRuntime.jsx(qrcode_react.QRCodeSVG, { value: depositAddress, size: 160 }) }) : isLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunk4IW4V7YJ_cjs.Skeleton, { className: "h-full w-full rounded-[10px]" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: "Deposit address unavailable" }) }),
3709
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
3710
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Deposit Address" }),
3711
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
3712
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-border flex h-10 min-w-0 flex-1 items-center rounded-[10px] border px-3", children: depositAddress ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground min-w-0 flex-1 truncate text-sm", children: depositAddress }) : isReady && isLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunk4IW4V7YJ_cjs.Skeleton, { className: "h-4 w-3/4" }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "\u2014" }) }),
3713
- /* @__PURE__ */ jsxRuntime.jsxs(
3714
- "button",
3715
- {
3716
- type: "button",
3717
- onClick: handleCopy,
3718
- disabled: !depositAddress,
3719
- className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 shrink-0 cursor-pointer items-center gap-2 rounded-[10px] px-3 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
3720
- children: [
3721
- /* @__PURE__ */ jsxRuntime.jsx(CopyIcon, {}),
3722
- copied ? "Copied" : "Copy"
3723
- ]
3724
- }
3725
- )
4578
+ showDepositInstructions && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4579
+ !scanPaused && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Send the displayed amount in one transfer. Transfers below the minimum are not combined or automatically returned." }),
4580
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-secondary flex h-50 items-center justify-center rounded-[10px]", children: !isReady ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground px-6 text-center text-sm", children: "Connect your wallet to generate a deposit address." }) : depositAddress ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-[10px] bg-white p-3", children: /* @__PURE__ */ jsxRuntime.jsx(qrcode_react.QRCodeSVG, { value: depositAddress, size: 160 }) }) : isLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunk7KEQHWZB_cjs.Skeleton, { className: "h-full w-full rounded-[10px]" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: "Deposit address unavailable" }) }),
4581
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
4582
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "Deposit Address" }),
4583
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
4584
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-border flex h-10 min-w-0 flex-1 items-center rounded-[10px] border px-3", children: depositAddress ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground min-w-0 flex-1 truncate text-sm", children: depositAddress }) : isReady && isLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunk7KEQHWZB_cjs.Skeleton, { className: "h-4 w-3/4" }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "\u2014" }) }),
4585
+ /* @__PURE__ */ jsxRuntime.jsxs(
4586
+ "button",
4587
+ {
4588
+ type: "button",
4589
+ onClick: handleCopy,
4590
+ disabled: !depositAddress,
4591
+ className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 shrink-0 cursor-pointer items-center gap-2 rounded-[10px] px-3 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
4592
+ children: [
4593
+ /* @__PURE__ */ jsxRuntime.jsx(CopyIcon, {}),
4594
+ copied ? "Copied" : "Copy"
4595
+ ]
4596
+ }
4597
+ )
4598
+ ] })
3726
4599
  ] })
3727
4600
  ] }),
3728
- credited ? /* @__PURE__ */ jsxRuntime.jsx(
4601
+ showCancelWarning && lockSession && !lockSession.verification && !lockSession.creditedAmount ? /* @__PURE__ */ jsxRuntime.jsx(
4602
+ TransactionWarningView,
4603
+ {
4604
+ title: "Cancel this deposit?",
4605
+ message: "Only cancel if you have not sent funds. Canceling after a transfer was sent stops recovery and can leave the transfer uncredited or unlocked.",
4606
+ onDone: () => onDiscardLock?.(),
4607
+ actionLabel: "I haven\u2019t sent funds",
4608
+ onDismiss: () => setShowCancelWarning(false),
4609
+ dismissLabel: "Keep waiting"
4610
+ }
4611
+ ) : lock?.isSigning ? /* @__PURE__ */ jsxRuntime.jsx(
4612
+ AwaitingDepositStatus,
4613
+ {
4614
+ title: "Confirm policy in your wallet",
4615
+ subtitle: "Sign a fresh policy for the funds already credited."
4616
+ }
4617
+ ) : lock?.isSubmittingLock ? /* @__PURE__ */ jsxRuntime.jsx(
4618
+ AwaitingDepositStatus,
4619
+ {
4620
+ title: `Locking funds for ${appName}`,
4621
+ subtitle: "Deposit credited. Applying your signed policy\u2026"
4622
+ }
4623
+ ) : lock?.session?.creditedAmount ? /* @__PURE__ */ jsxRuntime.jsx(
4624
+ TransactionWarningView,
4625
+ {
4626
+ title: lock.session.submissionAmbiguous ? "Lock status unknown" : "Deposit credited",
4627
+ message: lock.session.submissionAmbiguous ? "The lock may already have succeeded. Retry only the saved signature, or check locked funds before stopping recovery." : "The deposit is credited, but its signed lock still needs to be submitted.",
4628
+ onDone: () => {
4629
+ void retryAfterCredit?.().catch((err) => {
4630
+ sonner.toast.error(err instanceof Error ? err.message : "Policy recovery failed");
4631
+ });
4632
+ },
4633
+ actionLabel: lock.session.payload ? "Retry lock submission" : "Sign policy and lock funds"
4634
+ }
4635
+ ) : credited ? /* @__PURE__ */ jsxRuntime.jsx(
3729
4636
  TransactionSuccessView,
3730
4637
  {
3731
4638
  title: "Deposit Credited",
3732
- message: `Transfer ${chunk4IW4V7YJ_cjs.shortenAddress(credited.txHash)} has been credited to your Privana balance.`,
4639
+ message: `Transfer ${chunk7KEQHWZB_cjs.shortenAddress(credited.txHash)} has been credited to your Privana balance.`,
3733
4640
  onDone: () => {
3734
4641
  setCredited(null);
3735
4642
  verification.reset();
@@ -3742,14 +4649,15 @@ function ExternalDepositView({
3742
4649
  title: "Could not verify deposit",
3743
4650
  message: didTimeout ? "Verification timed out \u2014 your deposit may still be credited in the background." : verification.error?.message ?? "Your transfer was found but could not be verified.",
3744
4651
  onRetry: () => void verification.retryVerification(),
3745
- onDismiss: () => verification.reset(),
4652
+ onDismiss: lock ? canCheckAnotherTransfer ? handleCheckAnotherTransfer : void 0 : () => verification.reset(),
4653
+ dismissLabel: lock && canCheckAnotherTransfer ? "Check another transfer" : void 0,
3746
4654
  isRetrying: isVerifying
3747
4655
  }
3748
4656
  ) : isVerifying ? /* @__PURE__ */ jsxRuntime.jsx(
3749
4657
  AwaitingDepositStatus,
3750
4658
  {
3751
4659
  title: "Deposit detected",
3752
- subtitle: "Crediting the incoming transaction to your Privana balance..."
4660
+ subtitle: "Crediting the incoming transaction to your Privana balance\u2026"
3753
4661
  }
3754
4662
  ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3755
4663
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -3757,7 +4665,7 @@ function ExternalDepositView({
3757
4665
  {
3758
4666
  title: "Awaiting Deposit",
3759
4667
  subtitle: listening ? "We are listening for your incoming transaction for the next hour." : "We've stopped listening automatically. Use the button below to check for your deposit.",
3760
- remaining: listening ? chunk4IW4V7YJ_cjs.formatCountdown(secondsLeft) : void 0
4668
+ remaining: listening ? chunk7KEQHWZB_cjs.formatCountdown(secondsLeft) : void 0
3761
4669
  }
3762
4670
  ),
3763
4671
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
@@ -3771,7 +4679,16 @@ function ExternalDepositView({
3771
4679
  children: "Refresh deposit status"
3772
4680
  }
3773
4681
  ),
3774
- isRateLimited ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "Checked too recently \u2014 try again in a moment." }) : isUnavailable ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "Deposit discovery is unavailable for this chain." }) : isScanError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "Chain temporarily unreachable \u2014 retrying automatically." }) : nothingFound ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "No incoming transaction found yet." }) : null
4682
+ lockSession && !lockSession.verification && !lockSession.creditedAmount && /* @__PURE__ */ jsxRuntime.jsx(
4683
+ "button",
4684
+ {
4685
+ type: "button",
4686
+ onClick: () => setShowCancelWarning(true),
4687
+ className: "border-border text-foreground hover:bg-secondary flex h-10 w-full cursor-pointer items-center justify-center rounded-[10px] border px-3 py-2 text-sm font-medium transition-colors",
4688
+ children: "Cancel deposit"
4689
+ }
4690
+ ),
4691
+ isRateLimited ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "Checked too recently. Try again in a moment." }) : isUnavailable ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "Deposit discovery is unavailable for this chain." }) : isScanError ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "Chain temporarily unreachable. Retrying automatically." }) : nothingFound ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-center text-sm", children: "No incoming transaction found yet." }) : null
3775
4692
  ] })
3776
4693
  ] })
3777
4694
  ] });
@@ -3790,7 +4707,7 @@ function DepositModalContent({
3790
4707
  onCloseBlockedChange,
3791
4708
  onExit
3792
4709
  }) {
3793
- const { serviceName, enabledTokens, defaultToken, hostedAuthConfig, getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
4710
+ const { serviceName, enabledTokens, defaultToken, hostedAuthConfig, getChainById: getChainById2, getTokenById } = chunk7KEQHWZB_cjs.usePrivanaContext();
3794
4711
  const { address } = wagmi.useAccount();
3795
4712
  const appName = serviceName ?? "Privana";
3796
4713
  const [activeTab, setActiveTab] = react.useState(defaultTab);
@@ -3799,6 +4716,10 @@ function DepositModalContent({
3799
4716
  const [selectedTokenId, setSelectedTokenId] = react.useState(defaultToken?.id ?? "");
3800
4717
  const [amount, setAmount] = react.useState("");
3801
4718
  const selectedToken = enabledTokens.find((t) => t.id === selectedTokenId) ?? defaultToken;
4719
+ const externalDepositAddress = useDepositAddress({
4720
+ enabled: source === "external" && (view === "deposit" || view === "external-deposit")
4721
+ });
4722
+ const externalMinimum = source !== "external" || !selectedToken ? void 0 : externalDepositAddress.isError ? null : externalDepositAddress.response ? getExternalDepositMinimum(externalDepositAddress.response, selectedToken.chainId) ?? null : void 0;
3802
4723
  const prevAddressRef = react.useRef(address);
3803
4724
  react.useEffect(() => {
3804
4725
  const prev = prevAddressRef.current;
@@ -3818,9 +4739,10 @@ function DepositModalContent({
3818
4739
  const [showTimeout, setShowTimeout] = react.useState(false);
3819
4740
  const [cancelled, setCancelled] = react.useState(false);
3820
4741
  const [isSubmittingLock, setIsSubmittingLock] = react.useState(false);
3821
- const [lockFailedMessage, setLockFailedMessage] = react.useState(null);
4742
+ const [lockFailure, setLockFailure] = react.useState(null);
3822
4743
  const finishDeposit = () => {
3823
4744
  setAmount("");
4745
+ if (view === "external-deposit") setView("deposit");
3824
4746
  if (onDepositSuccess) {
3825
4747
  resetDeposit();
3826
4748
  onDepositSuccess();
@@ -3855,6 +4777,7 @@ function DepositModalContent({
3855
4777
  },
3856
4778
  onLockSubmitted: () => {
3857
4779
  setIsSubmittingLock(false);
4780
+ setLockFailure(null);
3858
4781
  finishDeposit();
3859
4782
  },
3860
4783
  // The deposit credited; only the policy lock failed. Success must not
@@ -3862,7 +4785,7 @@ function DepositModalContent({
3862
4785
  // error view and let the host re-prompt for a fresh lock.
3863
4786
  onLockFailed: (err) => {
3864
4787
  setIsSubmittingLock(false);
3865
- setLockFailedMessage(err.message);
4788
+ setLockFailure(err);
3866
4789
  onLockFailed?.(err);
3867
4790
  },
3868
4791
  onCheckTimeout: () => {
@@ -3870,7 +4793,37 @@ function DepositModalContent({
3870
4793
  setShowTimeout(true);
3871
4794
  }
3872
4795
  });
3873
- const isUnsafeToClose = (isGettingAddress || isSendingTransaction) && !cancelled;
4796
+ const externalLock = useExternalDepositLock({
4797
+ allowance,
4798
+ onLockSubmitted: () => {
4799
+ setLockFailure(null);
4800
+ finishDeposit();
4801
+ },
4802
+ // Same contract as the connected flow: the deposit credited, only the
4803
+ // lock failed — never report success, show the lock-error view instead.
4804
+ onLockFailed: (err) => {
4805
+ setLockFailure(err);
4806
+ onLockFailed?.(err);
4807
+ }
4808
+ });
4809
+ react.useEffect(() => {
4810
+ const restored = externalLock.session;
4811
+ if (!restored) return;
4812
+ const canRestore = view === "method" || source === "external" && (view === "deposit" || view === "external-deposit");
4813
+ if (!canRestore) return;
4814
+ const token = getTokenById(restored.tokenId);
4815
+ if (!token) return;
4816
+ setSource("external");
4817
+ setSelectedTokenId(token.id);
4818
+ setAmount(viem.formatUnits(BigInt(restored.depositAmount), token.decimals));
4819
+ setView("external-deposit");
4820
+ }, [externalLock.session, getTokenById, source, view]);
4821
+ react.useEffect(() => {
4822
+ if (view === "external-deposit" && allowance && !externalLock.session) {
4823
+ setView("deposit");
4824
+ }
4825
+ }, [allowance, externalLock.session, view]);
4826
+ const isUnsafeToClose = (isGettingAddress || isSendingTransaction) && !cancelled || externalLock.isSigning || externalLock.isSubmittingLock;
3874
4827
  react.useEffect(() => {
3875
4828
  onCloseBlockedChange?.(isUnsafeToClose);
3876
4829
  }, [isUnsafeToClose, onCloseBlockedChange]);
@@ -3883,7 +4836,33 @@ function DepositModalContent({
3883
4836
  }, [depositError, verificationFailed]);
3884
4837
  const handleSubmit = (args) => {
3885
4838
  if (args.source === "external") {
3886
- setView("external-deposit");
4839
+ const token2 = enabledTokens.find((candidate) => candidate.id === args.tokenId);
4840
+ if (!token2) return;
4841
+ if (token2.contract === viem.zeroAddress) {
4842
+ sonner.toast.error("External deposits support ERC20 tokens only");
4843
+ return;
4844
+ }
4845
+ const depositAmount = chunk7KEQHWZB_cjs.parseTokenAmount(args.amount, token2.decimals);
4846
+ if (!allowance) {
4847
+ setView("external-deposit");
4848
+ return;
4849
+ }
4850
+ if (typeof externalMinimum !== "bigint") {
4851
+ sonner.toast.error("Minimum deposit is unavailable. Please try again.");
4852
+ return;
4853
+ }
4854
+ if (depositAmount < externalMinimum) {
4855
+ sonner.toast.error(
4856
+ `Minimum deposit is ${viem.formatUnits(externalMinimum, token2.decimals)} ${token2.symbol}`
4857
+ );
4858
+ return;
4859
+ }
4860
+ externalLock.signAndPersist({
4861
+ tokenId: token2.id,
4862
+ amount: depositAmount
4863
+ }).then(() => setView("external-deposit")).catch((err) => {
4864
+ sonner.toast.error(err instanceof Error ? err.message : "Policy signing failed");
4865
+ });
3887
4866
  return;
3888
4867
  }
3889
4868
  if (args.source === "credit-card") {
@@ -3896,7 +4875,7 @@ function DepositModalContent({
3896
4875
  setCancelled(false);
3897
4876
  deposit({
3898
4877
  tokenId: token.id,
3899
- amount: chunk4IW4V7YJ_cjs.parseTokenAmount(args.amount, token.decimals),
4878
+ amount: chunk7KEQHWZB_cjs.parseTokenAmount(args.amount, token.decimals),
3900
4879
  postDepositLock: allowance ? {
3901
4880
  maxAmount: BigInt(allowance.value),
3902
4881
  lockDuration: allowance.lockDuration
@@ -3935,7 +4914,14 @@ function DepositModalContent({
3935
4914
  }
3936
4915
  ] : []
3937
4916
  ];
3938
- const flowView = showSuccess ? "deposit-success" : lockFailedMessage ? "lock-error" : showTimeout ? "deposit-timeout" : verificationFailed ? "deposit-error" : isPending && !cancelled || isSubmittingLock ? "depositing" : null;
4917
+ const hasExternalLockRecovery = view === "external-deposit" && !!externalLock.session?.creditedAmount;
4918
+ const externalSubmissionAmbiguous = hasExternalLockRecovery && !!lockFailure?.submissionMayHaveSucceeded;
4919
+ const savedExternalPayloadUsable = !!externalLock.session?.payload && chunk7KEQHWZB_cjs.isSignedLockUsable(externalLock.session.payload);
4920
+ const ambiguousRecoveryMustBeAbandoned = externalSubmissionAmbiguous && !savedExternalPayloadUsable;
4921
+ const externalRecoveryExitLabel = externalSubmissionAmbiguous ? "Stop recovery" : "Keep funds unlocked";
4922
+ const lockFailureToken = hasExternalLockRecovery && externalLock.session ? getTokenById(externalLock.session.tokenId) ?? selectedToken : selectedToken;
4923
+ const lockFailureMessage = formatPostDepositLockFailure(lockFailure, lockFailureToken);
4924
+ const flowView = showSuccess ? "deposit-success" : lockFailure ? "lock-error" : showTimeout ? "deposit-timeout" : verificationFailed ? "deposit-error" : isPending && !cancelled || isSubmittingLock ? "depositing" : null;
3939
4925
  const activeView = flowView ?? view;
3940
4926
  const handleDepositDone = () => {
3941
4927
  setShowSuccess(false);
@@ -3948,10 +4934,28 @@ function DepositModalContent({
3948
4934
  resetDeposit();
3949
4935
  };
3950
4936
  const handleLockFailedDone = () => {
3951
- setLockFailedMessage(null);
4937
+ if (hasExternalLockRecovery && !externalLock.discardSession()) {
4938
+ sonner.toast.error("Deposit recovery changed in another tab. Please review the current state.");
4939
+ return;
4940
+ }
4941
+ setLockFailure(null);
3952
4942
  setAmount("");
3953
4943
  setCancelled(false);
3954
4944
  resetDeposit();
4945
+ if (view === "external-deposit") setView("deposit");
4946
+ };
4947
+ const handleExternalLockRetry = () => {
4948
+ externalLock.retryAfterCredit().catch((err) => {
4949
+ sonner.toast.error(err instanceof Error ? err.message : "Policy signing failed");
4950
+ });
4951
+ };
4952
+ const handleExternalVerificationDiscard = () => {
4953
+ if (!externalLock.discardSession()) {
4954
+ sonner.toast.error("Deposit recovery changed in another tab. Please review the current state.");
4955
+ return;
4956
+ }
4957
+ setAmount("");
4958
+ setView("deposit");
3955
4959
  };
3956
4960
  const handleDismissVerificationError = () => {
3957
4961
  setAmount("");
@@ -3964,6 +4968,10 @@ function DepositModalContent({
3964
4968
  };
3965
4969
  const back = view === "external-deposit" ? { to: "deposit", label: "Deposit from External Wallet" } : view === "credit-card-widget" ? { to: "deposit", label: "Buy with credit card and deposit" } : view === "select-token" ? { to: "deposit", label: "Deposit" } : { to: "method", label: "Deposit Method" };
3966
4970
  const goBack = () => {
4971
+ if (view === "external-deposit" && externalLock.session) {
4972
+ sonner.toast.error("Cancel the active deposit from the address screen before going back");
4973
+ return;
4974
+ }
3967
4975
  if (back.to === "method") {
3968
4976
  setAmount("");
3969
4977
  setSelectedTokenId("");
@@ -3978,7 +4986,7 @@ function DepositModalContent({
3978
4986
  onClick: onClose,
3979
4987
  disabled: isUnsafeToClose,
3980
4988
  "aria-label": "Close",
3981
- className: chunk4IW4V7YJ_cjs.cn(
4989
+ className: chunk7KEQHWZB_cjs.cn(
3982
4990
  "absolute top-6 right-5 z-20 flex h-5 w-5 items-center justify-center transition-colors",
3983
4991
  isUnsafeToClose ? "text-muted-foreground/40 cursor-not-allowed" : "text-muted-foreground hover:text-foreground cursor-pointer"
3984
4992
  ),
@@ -4009,9 +5017,14 @@ function DepositModalContent({
4009
5017
  activeView === "lock-error" && /* @__PURE__ */ jsxRuntime.jsx(
4010
5018
  TransactionWarningView,
4011
5019
  {
4012
- title: "Deposit credited, lock failed",
4013
- message: `Your deposit was credited but locking the funds for ${appName} failed: ${lockFailedMessage}`,
4014
- onDone: handleLockFailedDone
5020
+ title: externalSubmissionAmbiguous ? "Deposit credited, lock status unknown" : "Deposit credited, lock failed",
5021
+ message: externalSubmissionAmbiguous ? `Your deposit was credited, but the lock for ${appName} may already have succeeded. Retry only the saved signature; if it has expired, check locked funds before stopping recovery.` : `Your deposit was credited but locking the funds for ${appName} failed: ${lockFailureMessage}`,
5022
+ onDone: hasExternalLockRecovery && !ambiguousRecoveryMustBeAbandoned ? handleExternalLockRetry : handleLockFailedDone,
5023
+ actionLabel: hasExternalLockRecovery ? ambiguousRecoveryMustBeAbandoned ? externalRecoveryExitLabel : externalLock.session?.payload ? "Retry lock submission" : "Sign policy and lock funds" : void 0,
5024
+ pendingLabel: externalLock.isSigning ? "Confirm policy in wallet\u2026" : "Locking funds\u2026",
5025
+ isPending: externalLock.isSigning || externalLock.isSubmittingLock,
5026
+ onDismiss: hasExternalLockRecovery && !ambiguousRecoveryMustBeAbandoned ? handleLockFailedDone : void 0,
5027
+ dismissLabel: externalRecoveryExitLabel
4015
5028
  }
4016
5029
  ),
4017
5030
  activeView === "deposit-timeout" && /* @__PURE__ */ jsxRuntime.jsx(
@@ -4026,7 +5039,7 @@ function DepositModalContent({
4026
5039
  TransactionErrorView,
4027
5040
  {
4028
5041
  title: "Verification failed",
4029
- message: depositError?.message ? `Your transfer was sent on-chain but we could not verify the deposit. The funds are already at the deposit address \u2014 retry verification instead of starting a new deposit. (${depositError.message})` : "Your transfer was sent on-chain but we could not verify the deposit. The funds are already at the deposit address \u2014 retry verification instead of starting a new deposit.",
5042
+ message: depositError?.message ? `Your transfer was sent on-chain but we could not verify the deposit. The funds are already at the deposit address. Retry verification instead of starting a new deposit. (${depositError.message})` : "Your transfer was sent on-chain but we could not verify the deposit. The funds are already at the deposit address. Retry verification instead of starting a new deposit.",
4030
5043
  explorerUrl: explorerTxUrl,
4031
5044
  explorerLabel: "View transaction",
4032
5045
  onRetry: handleRetryVerification,
@@ -4036,7 +5049,7 @@ function DepositModalContent({
4036
5049
  activeView === "depositing" && /* @__PURE__ */ jsxRuntime.jsx(
4037
5050
  TransactionProgressView,
4038
5051
  {
4039
- title: "Depositing...",
5052
+ title: "Depositing\u2026",
4040
5053
  steps: depositSteps,
4041
5054
  onCancel: isGettingAddress || isSendingTransaction ? handleDepositCancel : void 0
4042
5055
  }
@@ -4090,11 +5103,12 @@ function DepositModalContent({
4090
5103
  selectedToken,
4091
5104
  amount,
4092
5105
  allowance,
5106
+ externalMinimum,
4093
5107
  onAmountChange: setAmount,
4094
5108
  onSelectToken: () => setView("select-token"),
4095
5109
  onConnectWallet,
4096
5110
  onSubmit: handleSubmit,
4097
- isSubmitting: isPending
5111
+ isSubmitting: isPending || externalLock.isSigning || externalLock.isSubmittingLock
4098
5112
  }
4099
5113
  ) }),
4100
5114
  activeView === "select-token" && /* @__PURE__ */ jsxRuntime.jsx(
@@ -4107,12 +5121,15 @@ function DepositModalContent({
4107
5121
  }
4108
5122
  }
4109
5123
  ),
4110
- activeView === "external-deposit" && /* @__PURE__ */ jsxRuntime.jsx(
5124
+ activeView === "external-deposit" && (!allowance || externalLock.session) && /* @__PURE__ */ jsxRuntime.jsx(
4111
5125
  ExternalDepositView,
4112
5126
  {
4113
5127
  token: selectedToken,
4114
5128
  amount,
4115
- onCredited: allowance ? void 0 : onDepositSuccess
5129
+ depositAddressState: externalDepositAddress,
5130
+ onCredited: allowance ? void 0 : onDepositSuccess,
5131
+ onDiscardLock: handleExternalVerificationDiscard,
5132
+ lock: externalLock.session ? externalLock : void 0
4116
5133
  }
4117
5134
  ),
4118
5135
  activeView === "credit-card-widget" && /* @__PURE__ */ jsxRuntime.jsx(MoonPayGate, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -4124,7 +5141,7 @@ function DepositModalContent({
4124
5141
  onCredited: allowance ? void 0 : finishCardPurchase,
4125
5142
  onLockSubmitted: finishCardPurchase,
4126
5143
  onLockFailed: (err) => {
4127
- setLockFailedMessage(err.message);
5144
+ setLockFailure(err);
4128
5145
  onLockFailed?.(err);
4129
5146
  }
4130
5147
  }
@@ -4177,7 +5194,7 @@ function DepositInlineModal({ className, ...handlers }) {
4177
5194
  "div",
4178
5195
  {
4179
5196
  "data-privana": true,
4180
- className: chunk4IW4V7YJ_cjs.cn(
5197
+ className: chunk7KEQHWZB_cjs.cn(
4181
5198
  "bg-card relative flex w-[560px] max-w-full flex-col gap-2 overflow-hidden rounded-2xl p-2 shadow-lg",
4182
5199
  className
4183
5200
  ),
@@ -4192,7 +5209,7 @@ function WithdrawView({
4192
5209
  onSelectToken,
4193
5210
  onPendingChange
4194
5211
  }) {
4195
- const { chains, getChainById: getChainById2 } = chunk4IW4V7YJ_cjs.usePrivanaContext();
5212
+ const { chains, getChainById: getChainById2 } = chunk7KEQHWZB_cjs.usePrivanaContext();
4196
5213
  const { isConnected, address } = wagmi.useAccount();
4197
5214
  const [showSuccess, setShowSuccess] = react.useState(false);
4198
5215
  const [showTimeout, setShowTimeout] = react.useState(false);
@@ -4206,7 +5223,7 @@ function WithdrawView({
4206
5223
  tokenId: selectedToken?.id,
4207
5224
  enabled: !!selectedToken
4208
5225
  });
4209
- const formattedBalance = selectedToken ? chunk4IW4V7YJ_cjs.formatTokenAmount(balanceWei, selectedToken.decimals) : "0.00";
5226
+ const formattedBalance = selectedToken ? chunk7KEQHWZB_cjs.formatTokenAmount(balanceWei, selectedToken.decimals) : "0.00";
4210
5227
  const { withdraw, isPending, currentStep, error, reset } = useWithdraw({
4211
5228
  onProcessingSuccess: () => {
4212
5229
  onAmountChange("");
@@ -4217,7 +5234,7 @@ function WithdrawView({
4217
5234
  setShowTimeout(true);
4218
5235
  }
4219
5236
  });
4220
- const explorerUrl = address && targetChain ? chunk4IW4V7YJ_cjs.getExplorerAddressUrl(targetChain.id, address) : void 0;
5237
+ const explorerUrl = address && targetChain ? chunk7KEQHWZB_cjs.getExplorerAddressUrl(targetChain.id, address) : void 0;
4221
5238
  const getStepStatus = (step, after) => {
4222
5239
  if (currentStep === step) return "active";
4223
5240
  if (after.includes(currentStep)) return "completed";
@@ -4242,7 +5259,7 @@ function WithdrawView({
4242
5259
  }, [isPending, cancelled, onPendingChange]);
4243
5260
  const hasValidAmount = !!amount && parseFloat(amount) > 0;
4244
5261
  const tooManyDecimals = !!hasValidAmount && !!selectedToken && amount.includes(".") && amount.split(".")[1].length > selectedToken.decimals;
4245
- const exceedsBalance = !!hasValidAmount && !tooManyDecimals && !!selectedToken && !isBalanceLoading && !isBalanceError && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals) > BigInt(balanceWei);
5262
+ const exceedsBalance = !!hasValidAmount && !tooManyDecimals && !!selectedToken && !isBalanceLoading && !isBalanceError && chunk7KEQHWZB_cjs.parseTokenAmount(amount, selectedToken.decimals) > BigInt(balanceWei);
4246
5263
  const canWithdraw = isConnected && hasValidAmount && !!selectedToken && !tooManyDecimals && !exceedsBalance;
4247
5264
  const handleMax = () => {
4248
5265
  if (!selectedToken) return;
@@ -4254,7 +5271,7 @@ function WithdrawView({
4254
5271
  setCancelled(false);
4255
5272
  await withdraw({
4256
5273
  tokenId: selectedToken.id,
4257
- amount: chunk4IW4V7YJ_cjs.parseTokenAmount(amount, selectedToken.decimals)
5274
+ amount: chunk7KEQHWZB_cjs.parseTokenAmount(amount, selectedToken.decimals)
4258
5275
  });
4259
5276
  };
4260
5277
  const handleCancel = () => {
@@ -4274,7 +5291,7 @@ function WithdrawView({
4274
5291
  title: "Withdrawal Complete",
4275
5292
  message: `Your ${selectedToken.symbol} withdrawal has been processed. Funds should appear in your wallet shortly.`,
4276
5293
  explorerUrl,
4277
- explorerLabel: targetChain ? chunk4IW4V7YJ_cjs.getExplorerLabel(targetChain.id) : void 0,
5294
+ explorerLabel: targetChain ? chunk7KEQHWZB_cjs.getExplorerLabel(targetChain.id) : void 0,
4278
5295
  onDone: handleDone
4279
5296
  }
4280
5297
  ) });
@@ -4385,7 +5402,7 @@ function WithdrawModalContent({
4385
5402
  onPendingChange,
4386
5403
  onBack
4387
5404
  }) {
4388
- const { serviceName, enabledTokens, defaultToken, hostedAuthConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
5405
+ const { serviceName, enabledTokens, defaultToken, hostedAuthConfig } = chunk7KEQHWZB_cjs.usePrivanaContext();
4389
5406
  const { address } = wagmi.useAccount();
4390
5407
  const appName = serviceName ?? "Privana";
4391
5408
  const [view, setView] = react.useState("form");
@@ -4503,7 +5520,7 @@ function WithdrawInlineModal({ className }) {
4503
5520
  "div",
4504
5521
  {
4505
5522
  "data-privana": true,
4506
- className: chunk4IW4V7YJ_cjs.cn(
5523
+ className: chunk7KEQHWZB_cjs.cn(
4507
5524
  "bg-card relative flex w-[560px] max-w-full flex-col gap-2 overflow-hidden rounded-2xl p-2 shadow-lg",
4508
5525
  className
4509
5526
  ),
@@ -4547,14 +5564,14 @@ function SegmentedBalanceBar({
4547
5564
  showAvailable && /* @__PURE__ */ jsxRuntime.jsx(
4548
5565
  "div",
4549
5566
  {
4550
- className: chunk4IW4V7YJ_cjs.cn(AVAILABLE_COLOR, "rounded-l-full", !showInUse && "rounded-r-full"),
5567
+ className: chunk7KEQHWZB_cjs.cn(AVAILABLE_COLOR, "rounded-l-full", !showInUse && "rounded-r-full"),
4551
5568
  style: { flexGrow: grow(availableWei) }
4552
5569
  }
4553
5570
  ),
4554
5571
  showInUse && /* @__PURE__ */ jsxRuntime.jsx(
4555
5572
  "div",
4556
5573
  {
4557
- className: chunk4IW4V7YJ_cjs.cn(IN_USE_COLOR, "rounded-r-full", !showAvailable && "rounded-l-full"),
5574
+ className: chunk7KEQHWZB_cjs.cn(IN_USE_COLOR, "rounded-r-full", !showAvailable && "rounded-l-full"),
4558
5575
  style: { flexGrow: grow(inUseWei) }
4559
5576
  }
4560
5577
  )
@@ -4562,7 +5579,7 @@ function SegmentedBalanceBar({
4562
5579
  }
4563
5580
  function BalanceLegendItem({ color, label }) {
4564
5581
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
4565
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: chunk4IW4V7YJ_cjs.cn("h-2.5 w-2.5 rounded-full", color) }),
5582
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: chunk7KEQHWZB_cjs.cn("h-2.5 w-2.5 rounded-full", color) }),
4566
5583
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-sm leading-5", children: label })
4567
5584
  ] });
4568
5585
  }
@@ -4571,11 +5588,11 @@ function WalletBalanceView({
4571
5588
  allowance,
4572
5589
  amount,
4573
5590
  onAmountChange,
4574
- onPlay,
5591
+ onFundSession,
4575
5592
  onAddFunds,
4576
5593
  onWithdraw
4577
5594
  }) {
4578
- const { serviceName, serviceIcon, defaultToken } = chunk4IW4V7YJ_cjs.usePrivanaContext();
5595
+ const { serviceName, serviceIcon, defaultToken } = chunk7KEQHWZB_cjs.usePrivanaContext();
4579
5596
  const appName = serviceName ?? "Privana";
4580
5597
  const token = defaultToken;
4581
5598
  const {
@@ -4588,33 +5605,32 @@ function WalletBalanceView({
4588
5605
  const variant = !session ? "idle" : inUseWei === 0n ? "session-zero" : availableWei === 0n ? "fully-in-use" : "mixed";
4589
5606
  const expiry = session?.expiry;
4590
5607
  useNow(3e4, expiry != null);
4591
- const countdown = expiry != null ? chunk4IW4V7YJ_cjs.formatTimeRemaining(expiry) : null;
5608
+ const countdown = expiry != null ? chunk7KEQHWZB_cjs.formatTimeRemaining(expiry) : null;
4592
5609
  const decimals = token?.decimals ?? 18;
4593
- const totalFormatted = chunk4IW4V7YJ_cjs.formatTokenAmount((availableWei + inUseWei).toString(), decimals);
4594
- const availableFormatted = chunk4IW4V7YJ_cjs.formatTokenAmount(availableWei.toString(), decimals);
4595
- const inUseFormatted = chunk4IW4V7YJ_cjs.formatTokenAmount(inUseWei.toString(), decimals);
5610
+ const totalFormatted = chunk7KEQHWZB_cjs.formatTokenAmount((availableWei + inUseWei).toString(), decimals);
5611
+ const availableFormatted = chunk7KEQHWZB_cjs.formatTokenAmount(availableWei.toString(), decimals);
5612
+ const inUseFormatted = chunk7KEQHWZB_cjs.formatTokenAmount(inUseWei.toString(), decimals);
4596
5613
  const hasValidAmount = !!amount && parseFloat(amount) > 0;
4597
5614
  const tooManyDecimals = hasValidAmount && !!token && amount.includes(".") && amount.split(".")[1].length > token.decimals;
4598
- const exceedsBalance = hasValidAmount && !tooManyDecimals && !!token && !isBalanceLoading && !isBalanceError && chunk4IW4V7YJ_cjs.parseTokenAmount(amount, token.decimals) > availableWei;
4599
- const canPlay = hasValidAmount && !!token && !tooManyDecimals && !exceedsBalance && !isBalanceLoading && !isBalanceError;
5615
+ const exceedsBalance = hasValidAmount && !tooManyDecimals && !!token && !isBalanceLoading && !isBalanceError && chunk7KEQHWZB_cjs.parseTokenAmount(amount, token.decimals) > availableWei;
5616
+ const canFundSession = hasValidAmount && !!token && !tooManyDecimals && !exceedsBalance && !isBalanceLoading && !isBalanceError;
4600
5617
  const handleMax = () => {
4601
5618
  const max = availableFormatted.replace(/\s/g, "");
4602
5619
  if (parseFloat(max) > 0) onAmountChange(max);
4603
5620
  };
4604
- const handlePlay = () => {
4605
- if (!token || !canPlay || !onPlay) return;
4606
- onPlay({ tokenId: token.id, amount });
4607
- onAmountChange("");
5621
+ const handleFundSession = () => {
5622
+ if (!token || !canFundSession || !onFundSession) return;
5623
+ onFundSession({ tokenId: token.id, amount });
4608
5624
  };
4609
5625
  const showInput = variant !== "fully-in-use";
4610
- const showInlinePlay = variant === "session-zero" || variant === "mixed";
5626
+ const showInlineFund = variant === "session-zero" || variant === "mixed";
4611
5627
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: [
4612
5628
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
4613
5629
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
4614
5630
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm leading-[14px]", children: "Total" }),
4615
5631
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-secondary text-muted-foreground rounded-full px-2 py-[5px] text-[10px] leading-[10px] font-bold", children: token?.symbol ?? "\u2014" })
4616
5632
  ] }),
4617
- isBalanceLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunk4IW4V7YJ_cjs.Skeleton, { className: "h-9 w-40" }) : isBalanceError ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-[32px] leading-9 font-medium", children: "\u2014" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-[32px] leading-9 font-medium", children: totalFormatted })
5633
+ isBalanceLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunk7KEQHWZB_cjs.Skeleton, { className: "h-9 w-40" }) : isBalanceError ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-[32px] leading-9 font-medium", children: "\u2014" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-[32px] leading-9 font-medium", children: totalFormatted })
4618
5634
  ] }),
4619
5635
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
4620
5636
  /* @__PURE__ */ jsxRuntime.jsx(SegmentedBalanceBar, { availableWei, inUseWei }),
@@ -4659,14 +5675,14 @@ function WalletBalanceView({
4659
5675
  }
4660
5676
  )
4661
5677
  ] }),
4662
- showInlinePlay && /* @__PURE__ */ jsxRuntime.jsx(
5678
+ showInlineFund && /* @__PURE__ */ jsxRuntime.jsx(
4663
5679
  "button",
4664
5680
  {
4665
5681
  type: "button",
4666
- disabled: !onPlay || !canPlay,
4667
- onClick: handlePlay,
5682
+ disabled: !onFundSession || !canFundSession,
5683
+ onClick: handleFundSession,
4668
5684
  className: "border-border flex h-10 min-w-20 cursor-pointer items-center justify-center rounded-[10px] border px-3 text-sm font-medium text-[#4fc77f] transition-opacity hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50",
4669
- children: "Play"
5685
+ children: "Fund session"
4670
5686
  }
4671
5687
  )
4672
5688
  ] }),
@@ -4690,10 +5706,10 @@ function WalletBalanceView({
4690
5706
  "button",
4691
5707
  {
4692
5708
  type: "button",
4693
- disabled: !onPlay || !canPlay,
4694
- onClick: handlePlay,
5709
+ disabled: !onFundSession || !canFundSession,
5710
+ onClick: handleFundSession,
4695
5711
  className: "bg-primary text-primary-foreground hover:bg-primary/90 flex h-10 flex-1 cursor-pointer items-center justify-center rounded-[10px] px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
4696
- children: "Play"
5712
+ children: "Fund session"
4697
5713
  }
4698
5714
  ),
4699
5715
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4730,17 +5746,41 @@ function WalletBalanceView({
4730
5746
  ] }) })
4731
5747
  ] });
4732
5748
  }
5749
+ function invokeGuarded(runRef, invoke, handlers) {
5750
+ const run = ++runRef.current;
5751
+ const isCurrent = () => runRef.current === run;
5752
+ let result;
5753
+ try {
5754
+ result = invoke();
5755
+ } catch (err) {
5756
+ if (isCurrent()) handlers.onError(err);
5757
+ return;
5758
+ }
5759
+ if (result == null || typeof result.then !== "function") {
5760
+ handlers.onSyncResult();
5761
+ return;
5762
+ }
5763
+ handlers.onAsyncStart();
5764
+ result.then(
5765
+ () => {
5766
+ if (isCurrent()) handlers.onSuccess();
5767
+ },
5768
+ (err) => {
5769
+ if (isCurrent()) handlers.onError(err);
5770
+ }
5771
+ );
5772
+ }
4733
5773
  function WalletModalContent({
4734
5774
  session,
4735
5775
  allowance,
4736
- onPlay,
5776
+ onFundSession,
4737
5777
  onEndSession,
4738
5778
  onDepositSuccess,
4739
5779
  onClose,
4740
5780
  onCloseBlockedChange,
4741
5781
  ...depositHandlers
4742
5782
  }) {
4743
- const { serviceName, hostedAuthConfig } = chunk4IW4V7YJ_cjs.usePrivanaContext();
5783
+ const { serviceName, hostedAuthConfig } = chunk7KEQHWZB_cjs.usePrivanaContext();
4744
5784
  const { address } = wagmi.useAccount();
4745
5785
  const appName = serviceName ?? "Privana";
4746
5786
  const [view, setView] = react.useState("balance");
@@ -4748,7 +5788,10 @@ function WalletModalContent({
4748
5788
  const [depositBlocked, setDepositBlocked] = react.useState(false);
4749
5789
  const [withdrawPending, setWithdrawPending] = react.useState(false);
4750
5790
  const [endSessionError, setEndSessionError] = react.useState(null);
5791
+ const [fundSessionError, setFundSessionError] = react.useState(null);
4751
5792
  const endSessionRunRef = react.useRef(0);
5793
+ const fundSessionRunRef = react.useRef(0);
5794
+ const [pendingFundSession, setPendingFundSession] = react.useState(null);
4752
5795
  const prevAddressRef = react.useRef(address);
4753
5796
  react.useEffect(() => {
4754
5797
  const prev = prevAddressRef.current;
@@ -4760,10 +5803,13 @@ function WalletModalContent({
4760
5803
  setDepositBlocked(false);
4761
5804
  setWithdrawPending(false);
4762
5805
  setEndSessionError(null);
5806
+ setFundSessionError(null);
5807
+ setPendingFundSession(null);
4763
5808
  endSessionRunRef.current++;
5809
+ fundSessionRunRef.current++;
4764
5810
  }
4765
5811
  }, [address, hostedAuthConfig]);
4766
- const closeBlocked = depositBlocked || withdrawPending || view === "ending-session";
5812
+ const closeBlocked = depositBlocked || withdrawPending || view === "funding-session" || view === "ending-session";
4767
5813
  react.useEffect(() => {
4768
5814
  onCloseBlockedChange?.(closeBlocked);
4769
5815
  }, [closeBlocked, onCloseBlockedChange]);
@@ -4777,20 +5823,16 @@ function WalletModalContent({
4777
5823
  };
4778
5824
  const startEndSession = () => {
4779
5825
  if (!onEndSession) return;
4780
- const run = ++endSessionRunRef.current;
4781
5826
  setEndSessionError(null);
4782
- setView("ending-session");
4783
- Promise.resolve().then(() => onEndSession()).then(
4784
- () => {
4785
- if (endSessionRunRef.current !== run) return;
4786
- setView("withdraw");
4787
- },
4788
- (err) => {
4789
- if (endSessionRunRef.current !== run) return;
5827
+ invokeGuarded(endSessionRunRef, () => onEndSession(), {
5828
+ onSyncResult: () => setView("withdraw"),
5829
+ onAsyncStart: () => setView("ending-session"),
5830
+ onSuccess: () => setView("withdraw"),
5831
+ onError: (err) => {
4790
5832
  setEndSessionError(err instanceof Error ? err.message : null);
4791
5833
  setView("end-session-error");
4792
5834
  }
4793
- );
5835
+ });
4794
5836
  };
4795
5837
  const handleWithdraw = () => {
4796
5838
  if (session && onEndSession) {
@@ -4804,6 +5846,36 @@ function WalletModalContent({
4804
5846
  setEndSessionError(null);
4805
5847
  setView("balance");
4806
5848
  };
5849
+ const fundSession = (args) => {
5850
+ if (!onFundSession) return;
5851
+ setFundSessionError(null);
5852
+ setPendingFundSession(args);
5853
+ setAmount("");
5854
+ invokeGuarded(fundSessionRunRef, () => onFundSession(args), {
5855
+ onSyncResult: () => {
5856
+ setPendingFundSession(null);
5857
+ setView("balance");
5858
+ },
5859
+ onAsyncStart: () => setView("funding-session"),
5860
+ onSuccess: () => {
5861
+ setPendingFundSession(null);
5862
+ setView("balance");
5863
+ },
5864
+ onError: (err) => {
5865
+ setFundSessionError(err instanceof Error ? err.message : null);
5866
+ setView("fund-session-error");
5867
+ }
5868
+ });
5869
+ };
5870
+ const dismissFundSessionError = () => {
5871
+ fundSessionRunRef.current++;
5872
+ setFundSessionError(null);
5873
+ if (pendingFundSession) {
5874
+ setAmount(pendingFundSession.amount);
5875
+ setPendingFundSession(null);
5876
+ }
5877
+ setView("balance");
5878
+ };
4807
5879
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4808
5880
  onClose && /* @__PURE__ */ jsxRuntime.jsx(
4809
5881
  "button",
@@ -4812,14 +5884,14 @@ function WalletModalContent({
4812
5884
  onClick: onClose,
4813
5885
  disabled: closeBlocked,
4814
5886
  "aria-label": "Close",
4815
- className: chunk4IW4V7YJ_cjs.cn(
5887
+ className: chunk7KEQHWZB_cjs.cn(
4816
5888
  "absolute top-6 right-5 z-20 flex h-5 w-5 items-center justify-center transition-colors",
4817
5889
  closeBlocked ? "text-muted-foreground/40 cursor-not-allowed" : "text-muted-foreground hover:text-foreground cursor-pointer"
4818
5890
  ),
4819
5891
  children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
4820
5892
  }
4821
5893
  ),
4822
- (view === "balance" || view === "ending-session" || view === "end-session-error") && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-5 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-xl leading-5 font-medium", children: appName }) }),
5894
+ (view === "balance" || view === "funding-session" || view === "fund-session-error" || view === "ending-session" || view === "end-session-error") && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-5 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground text-xl leading-5 font-medium", children: appName }) }),
4823
5895
  view === "balance" && /* @__PURE__ */ jsxRuntime.jsx(
4824
5896
  WalletBalanceView,
4825
5897
  {
@@ -4827,11 +5899,30 @@ function WalletModalContent({
4827
5899
  allowance,
4828
5900
  amount,
4829
5901
  onAmountChange: setAmount,
4830
- onPlay,
5902
+ onFundSession: onFundSession ? fundSession : void 0,
4831
5903
  onAddFunds: () => setView("deposit"),
4832
- onWithdraw: handleWithdraw
5904
+ onWithdraw: session && !onEndSession ? void 0 : handleWithdraw
4833
5905
  }
4834
5906
  ),
5907
+ view === "funding-session" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: /* @__PURE__ */ jsxRuntime.jsx(
5908
+ TransactionProgressView,
5909
+ {
5910
+ title: "Funding session...",
5911
+ steps: [{ label: "Waiting for the session to be funded", status: "active" }]
5912
+ }
5913
+ ) }),
5914
+ view === "fund-session-error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: /* @__PURE__ */ jsxRuntime.jsx(
5915
+ TransactionErrorView,
5916
+ {
5917
+ title: "Could not fund session",
5918
+ message: fundSessionError ? `Your session could not be funded. (${fundSessionError})` : "Your session could not be funded.",
5919
+ onRetry: () => {
5920
+ if (pendingFundSession) fundSession(pendingFundSession);
5921
+ },
5922
+ onDismiss: dismissFundSessionError,
5923
+ retryLabel: "Try again"
5924
+ }
5925
+ ) }),
4835
5926
  view === "ending-session" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted flex flex-col gap-6 rounded-[10px] p-5", children: /* @__PURE__ */ jsxRuntime.jsx(
4836
5927
  TransactionProgressView,
4837
5928
  {
@@ -4845,7 +5936,8 @@ function WalletModalContent({
4845
5936
  title: "Could not end session",
4846
5937
  message: endSessionError ? `Your game session could not be ended, so the funds committed to it are not available to withdraw yet. (${endSessionError})` : "Your game session could not be ended, so the funds committed to it are not available to withdraw yet.",
4847
5938
  onRetry: startEndSession,
4848
- onDismiss: dismissEndSessionError
5939
+ onDismiss: dismissEndSessionError,
5940
+ retryLabel: "Try again"
4849
5941
  }
4850
5942
  ) }),
4851
5943
  view === "withdraw" && /* @__PURE__ */ jsxRuntime.jsx(WithdrawModalContent, { onBack: exitWithdraw, onPendingChange: setWithdrawPending }),
@@ -4910,7 +6002,7 @@ function WalletInlineModal({ className, ...handlers }) {
4910
6002
  "div",
4911
6003
  {
4912
6004
  "data-privana": true,
4913
- className: chunk4IW4V7YJ_cjs.cn(
6005
+ className: chunk7KEQHWZB_cjs.cn(
4914
6006
  "bg-card relative flex w-[560px] max-w-full flex-col gap-2 overflow-hidden rounded-2xl p-2 shadow-lg",
4915
6007
  className
4916
6008
  ),
@@ -4921,287 +6013,295 @@ function WalletInlineModal({ className, ...handlers }) {
4921
6013
 
4922
6014
  Object.defineProperty(exports, "AccountingApiError", {
4923
6015
  enumerable: true,
4924
- get: function () { return chunk4IW4V7YJ_cjs.AccountingApiError; }
6016
+ get: function () { return chunk7KEQHWZB_cjs.AccountingApiError; }
4925
6017
  });
4926
6018
  Object.defineProperty(exports, "Button", {
4927
6019
  enumerable: true,
4928
- get: function () { return chunk4IW4V7YJ_cjs.Button; }
6020
+ get: function () { return chunk7KEQHWZB_cjs.Button; }
4929
6021
  });
4930
6022
  Object.defineProperty(exports, "DEFAULT_LOCK_DURATION_SECONDS", {
4931
6023
  enumerable: true,
4932
- get: function () { return chunk4IW4V7YJ_cjs.DEFAULT_LOCK_DURATION_SECONDS; }
6024
+ get: function () { return chunk7KEQHWZB_cjs.DEFAULT_LOCK_DURATION_SECONDS; }
4933
6025
  });
4934
6026
  Object.defineProperty(exports, "DEFAULT_ONRAMP_LOCK_BUFFER", {
4935
6027
  enumerable: true,
4936
- get: function () { return chunk4IW4V7YJ_cjs.DEFAULT_ONRAMP_LOCK_BUFFER; }
6028
+ get: function () { return chunk7KEQHWZB_cjs.DEFAULT_ONRAMP_LOCK_BUFFER; }
4937
6029
  });
4938
6030
  Object.defineProperty(exports, "HOSTED_AUTH_CLOCK_SKEW_MS", {
4939
6031
  enumerable: true,
4940
- get: function () { return chunk4IW4V7YJ_cjs.HOSTED_AUTH_CLOCK_SKEW_MS; }
6032
+ get: function () { return chunk7KEQHWZB_cjs.HOSTED_AUTH_CLOCK_SKEW_MS; }
4941
6033
  });
4942
6034
  Object.defineProperty(exports, "HostedAuthError", {
4943
6035
  enumerable: true,
4944
- get: function () { return chunk4IW4V7YJ_cjs.HostedAuthError; }
6036
+ get: function () { return chunk7KEQHWZB_cjs.HostedAuthError; }
4945
6037
  });
4946
6038
  Object.defineProperty(exports, "HostedAuthRequiredError", {
4947
6039
  enumerable: true,
4948
- get: function () { return chunk4IW4V7YJ_cjs.HostedAuthRequiredError; }
6040
+ get: function () { return chunk7KEQHWZB_cjs.HostedAuthRequiredError; }
4949
6041
  });
4950
6042
  Object.defineProperty(exports, "HostedAuthStateMismatchError", {
4951
6043
  enumerable: true,
4952
- get: function () { return chunk4IW4V7YJ_cjs.HostedAuthStateMismatchError; }
6044
+ get: function () { return chunk7KEQHWZB_cjs.HostedAuthStateMismatchError; }
4953
6045
  });
4954
6046
  Object.defineProperty(exports, "HttpClient", {
4955
6047
  enumerable: true,
4956
- get: function () { return chunk4IW4V7YJ_cjs.HttpClient; }
6048
+ get: function () { return chunk7KEQHWZB_cjs.HttpClient; }
4957
6049
  });
4958
6050
  Object.defineProperty(exports, "LOCK_TYPES", {
4959
6051
  enumerable: true,
4960
- get: function () { return chunk4IW4V7YJ_cjs.LOCK_TYPES; }
6052
+ get: function () { return chunk7KEQHWZB_cjs.LOCK_TYPES; }
4961
6053
  });
4962
6054
  Object.defineProperty(exports, "MODIFY_LOCK_TYPES", {
4963
6055
  enumerable: true,
4964
- get: function () { return chunk4IW4V7YJ_cjs.MODIFY_LOCK_TYPES; }
6056
+ get: function () { return chunk7KEQHWZB_cjs.MODIFY_LOCK_TYPES; }
4965
6057
  });
4966
6058
  Object.defineProperty(exports, "NETWORK_CONFIG", {
4967
6059
  enumerable: true,
4968
- get: function () { return chunk4IW4V7YJ_cjs.NETWORK_CONFIG; }
6060
+ get: function () { return chunk7KEQHWZB_cjs.NETWORK_CONFIG; }
4969
6061
  });
4970
6062
  Object.defineProperty(exports, "NetworkError", {
4971
6063
  enumerable: true,
4972
- get: function () { return chunk4IW4V7YJ_cjs.NetworkError; }
6064
+ get: function () { return chunk7KEQHWZB_cjs.NetworkError; }
4973
6065
  });
4974
6066
  Object.defineProperty(exports, "PostDepositLockError", {
4975
6067
  enumerable: true,
4976
- get: function () { return chunk4IW4V7YJ_cjs.PostDepositLockError; }
6068
+ get: function () { return chunk7KEQHWZB_cjs.PostDepositLockError; }
4977
6069
  });
4978
6070
  Object.defineProperty(exports, "PrivanaClient", {
4979
6071
  enumerable: true,
4980
- get: function () { return chunk4IW4V7YJ_cjs.PrivanaClient; }
6072
+ get: function () { return chunk7KEQHWZB_cjs.PrivanaClient; }
4981
6073
  });
4982
6074
  Object.defineProperty(exports, "PrivanaProvider", {
4983
6075
  enumerable: true,
4984
- get: function () { return chunk4IW4V7YJ_cjs.PrivanaProvider; }
6076
+ get: function () { return chunk7KEQHWZB_cjs.PrivanaProvider; }
4985
6077
  });
4986
6078
  Object.defineProperty(exports, "SUPPORTED_CHAINS", {
4987
6079
  enumerable: true,
4988
- get: function () { return chunk4IW4V7YJ_cjs.SUPPORTED_CHAINS; }
6080
+ get: function () { return chunk7KEQHWZB_cjs.SUPPORTED_CHAINS; }
4989
6081
  });
4990
6082
  Object.defineProperty(exports, "SiweAuthProvider", {
4991
6083
  enumerable: true,
4992
- get: function () { return chunk4IW4V7YJ_cjs.SiweAuthProvider; }
6084
+ get: function () { return chunk7KEQHWZB_cjs.SiweAuthProvider; }
4993
6085
  });
4994
6086
  Object.defineProperty(exports, "Skeleton", {
4995
6087
  enumerable: true,
4996
- get: function () { return chunk4IW4V7YJ_cjs.Skeleton; }
6088
+ get: function () { return chunk7KEQHWZB_cjs.Skeleton; }
4997
6089
  });
4998
6090
  Object.defineProperty(exports, "TRANSFER_LOCKED_TYPES", {
4999
6091
  enumerable: true,
5000
- get: function () { return chunk4IW4V7YJ_cjs.TRANSFER_LOCKED_TYPES; }
6092
+ get: function () { return chunk7KEQHWZB_cjs.TRANSFER_LOCKED_TYPES; }
5001
6093
  });
5002
6094
  Object.defineProperty(exports, "TRANSFER_TYPES", {
5003
6095
  enumerable: true,
5004
- get: function () { return chunk4IW4V7YJ_cjs.TRANSFER_TYPES; }
6096
+ get: function () { return chunk7KEQHWZB_cjs.TRANSFER_TYPES; }
5005
6097
  });
5006
6098
  Object.defineProperty(exports, "ValidationError", {
5007
6099
  enumerable: true,
5008
- get: function () { return chunk4IW4V7YJ_cjs.ValidationError; }
6100
+ get: function () { return chunk7KEQHWZB_cjs.ValidationError; }
5009
6101
  });
5010
6102
  Object.defineProperty(exports, "WITHDRAW_FROM_LOCK_TYPES", {
5011
6103
  enumerable: true,
5012
- get: function () { return chunk4IW4V7YJ_cjs.WITHDRAW_FROM_LOCK_TYPES; }
6104
+ get: function () { return chunk7KEQHWZB_cjs.WITHDRAW_FROM_LOCK_TYPES; }
5013
6105
  });
5014
6106
  Object.defineProperty(exports, "WITHDRAW_TYPES", {
5015
6107
  enumerable: true,
5016
- get: function () { return chunk4IW4V7YJ_cjs.WITHDRAW_TYPES; }
6108
+ get: function () { return chunk7KEQHWZB_cjs.WITHDRAW_TYPES; }
5017
6109
  });
5018
6110
  Object.defineProperty(exports, "applyLockBuffer", {
5019
6111
  enumerable: true,
5020
- get: function () { return chunk4IW4V7YJ_cjs.applyLockBuffer; }
6112
+ get: function () { return chunk7KEQHWZB_cjs.applyLockBuffer; }
5021
6113
  });
5022
6114
  Object.defineProperty(exports, "applyRefreshResponse", {
5023
6115
  enumerable: true,
5024
- get: function () { return chunk4IW4V7YJ_cjs.applyRefreshResponse; }
6116
+ get: function () { return chunk7KEQHWZB_cjs.applyRefreshResponse; }
5025
6117
  });
5026
6118
  Object.defineProperty(exports, "buildHostedAuthSession", {
5027
6119
  enumerable: true,
5028
- get: function () { return chunk4IW4V7YJ_cjs.buildHostedAuthSession; }
6120
+ get: function () { return chunk7KEQHWZB_cjs.buildHostedAuthSession; }
5029
6121
  });
5030
6122
  Object.defineProperty(exports, "buildSiweStatement", {
5031
6123
  enumerable: true,
5032
- get: function () { return chunk4IW4V7YJ_cjs.buildSiweStatement; }
6124
+ get: function () { return chunk7KEQHWZB_cjs.buildSiweStatement; }
5033
6125
  });
5034
6126
  Object.defineProperty(exports, "buttonVariants", {
5035
6127
  enumerable: true,
5036
- get: function () { return chunk4IW4V7YJ_cjs.buttonVariants; }
6128
+ get: function () { return chunk7KEQHWZB_cjs.buttonVariants; }
5037
6129
  });
5038
6130
  Object.defineProperty(exports, "clampLockAmount", {
5039
6131
  enumerable: true,
5040
- get: function () { return chunk4IW4V7YJ_cjs.clampLockAmount; }
6132
+ get: function () { return chunk7KEQHWZB_cjs.clampLockAmount; }
5041
6133
  });
5042
6134
  Object.defineProperty(exports, "clearHostedAuthPendingTransaction", {
5043
6135
  enumerable: true,
5044
- get: function () { return chunk4IW4V7YJ_cjs.clearHostedAuthPendingTransaction; }
6136
+ get: function () { return chunk7KEQHWZB_cjs.clearHostedAuthPendingTransaction; }
5045
6137
  });
5046
6138
  Object.defineProperty(exports, "clearPendingLock", {
5047
6139
  enumerable: true,
5048
- get: function () { return chunk4IW4V7YJ_cjs.clearPendingLock; }
6140
+ get: function () { return chunk7KEQHWZB_cjs.clearPendingLock; }
5049
6141
  });
5050
6142
  Object.defineProperty(exports, "createDomain", {
5051
6143
  enumerable: true,
5052
- get: function () { return chunk4IW4V7YJ_cjs.createDomain; }
6144
+ get: function () { return chunk7KEQHWZB_cjs.createDomain; }
5053
6145
  });
5054
6146
  Object.defineProperty(exports, "createHostedAuthPendingStorageKey", {
5055
6147
  enumerable: true,
5056
- get: function () { return chunk4IW4V7YJ_cjs.createHostedAuthPendingStorageKey; }
6148
+ get: function () { return chunk7KEQHWZB_cjs.createHostedAuthPendingStorageKey; }
5057
6149
  });
5058
6150
  Object.defineProperty(exports, "createHostedAuthState", {
5059
6151
  enumerable: true,
5060
- get: function () { return chunk4IW4V7YJ_cjs.createHostedAuthState; }
6152
+ get: function () { return chunk7KEQHWZB_cjs.createHostedAuthState; }
5061
6153
  });
5062
6154
  Object.defineProperty(exports, "createHostedAuthStorageKey", {
5063
6155
  enumerable: true,
5064
- get: function () { return chunk4IW4V7YJ_cjs.createHostedAuthStorageKey; }
6156
+ get: function () { return chunk7KEQHWZB_cjs.createHostedAuthStorageKey; }
5065
6157
  });
5066
6158
  Object.defineProperty(exports, "createLockExpiry", {
5067
6159
  enumerable: true,
5068
- get: function () { return chunk4IW4V7YJ_cjs.createLockExpiry; }
6160
+ get: function () { return chunk7KEQHWZB_cjs.createLockExpiry; }
5069
6161
  });
5070
6162
  Object.defineProperty(exports, "createPkceChallenge", {
5071
6163
  enumerable: true,
5072
- get: function () { return chunk4IW4V7YJ_cjs.createPkceChallenge; }
6164
+ get: function () { return chunk7KEQHWZB_cjs.createPkceChallenge; }
5073
6165
  });
5074
6166
  Object.defineProperty(exports, "createPkceVerifier", {
5075
6167
  enumerable: true,
5076
- get: function () { return chunk4IW4V7YJ_cjs.createPkceVerifier; }
6168
+ get: function () { return chunk7KEQHWZB_cjs.createPkceVerifier; }
5077
6169
  });
5078
6170
  Object.defineProperty(exports, "createSignedLockRequest", {
5079
6171
  enumerable: true,
5080
- get: function () { return chunk4IW4V7YJ_cjs.createSignedLockRequest; }
6172
+ get: function () { return chunk7KEQHWZB_cjs.createSignedLockRequest; }
5081
6173
  });
5082
6174
  Object.defineProperty(exports, "getAccountingContract", {
5083
6175
  enumerable: true,
5084
- get: function () { return chunk4IW4V7YJ_cjs.getAccountingContract; }
6176
+ get: function () { return chunk7KEQHWZB_cjs.getAccountingContract; }
5085
6177
  });
5086
6178
  Object.defineProperty(exports, "getApiUrl", {
5087
6179
  enumerable: true,
5088
- get: function () { return chunk4IW4V7YJ_cjs.getApiUrl; }
6180
+ get: function () { return chunk7KEQHWZB_cjs.getApiUrl; }
5089
6181
  });
5090
6182
  Object.defineProperty(exports, "getChainById", {
5091
6183
  enumerable: true,
5092
- get: function () { return chunk4IW4V7YJ_cjs.getChainById; }
6184
+ get: function () { return chunk7KEQHWZB_cjs.getChainById; }
5093
6185
  });
5094
6186
  Object.defineProperty(exports, "getChainId", {
5095
6187
  enumerable: true,
5096
- get: function () { return chunk4IW4V7YJ_cjs.getChainId; }
6188
+ get: function () { return chunk7KEQHWZB_cjs.getChainId; }
5097
6189
  });
5098
6190
  Object.defineProperty(exports, "getExplorerAddressUrl", {
5099
6191
  enumerable: true,
5100
- get: function () { return chunk4IW4V7YJ_cjs.getExplorerAddressUrl; }
6192
+ get: function () { return chunk7KEQHWZB_cjs.getExplorerAddressUrl; }
5101
6193
  });
5102
6194
  Object.defineProperty(exports, "getExplorerLabel", {
5103
6195
  enumerable: true,
5104
- get: function () { return chunk4IW4V7YJ_cjs.getExplorerLabel; }
6196
+ get: function () { return chunk7KEQHWZB_cjs.getExplorerLabel; }
5105
6197
  });
5106
6198
  Object.defineProperty(exports, "isHostedAuthRefreshActive", {
5107
6199
  enumerable: true,
5108
- get: function () { return chunk4IW4V7YJ_cjs.isHostedAuthRefreshActive; }
6200
+ get: function () { return chunk7KEQHWZB_cjs.isHostedAuthRefreshActive; }
5109
6201
  });
5110
6202
  Object.defineProperty(exports, "isHostedAuthSessionActive", {
5111
6203
  enumerable: true,
5112
- get: function () { return chunk4IW4V7YJ_cjs.isHostedAuthSessionActive; }
6204
+ get: function () { return chunk7KEQHWZB_cjs.isHostedAuthSessionActive; }
5113
6205
  });
5114
6206
  Object.defineProperty(exports, "isSignedLockUsable", {
5115
6207
  enumerable: true,
5116
- get: function () { return chunk4IW4V7YJ_cjs.isSignedLockUsable; }
6208
+ get: function () { return chunk7KEQHWZB_cjs.isSignedLockUsable; }
5117
6209
  });
5118
6210
  Object.defineProperty(exports, "loadPendingLock", {
5119
6211
  enumerable: true,
5120
- get: function () { return chunk4IW4V7YJ_cjs.loadPendingLock; }
6212
+ get: function () { return chunk7KEQHWZB_cjs.loadPendingLock; }
5121
6213
  });
5122
6214
  Object.defineProperty(exports, "normalizeAddress", {
5123
6215
  enumerable: true,
5124
- get: function () { return chunk4IW4V7YJ_cjs.normalizeAddress; }
6216
+ get: function () { return chunk7KEQHWZB_cjs.normalizeAddress; }
5125
6217
  });
5126
6218
  Object.defineProperty(exports, "normalizeHex", {
5127
6219
  enumerable: true,
5128
- get: function () { return chunk4IW4V7YJ_cjs.normalizeHex; }
6220
+ get: function () { return chunk7KEQHWZB_cjs.normalizeHex; }
5129
6221
  });
5130
6222
  Object.defineProperty(exports, "parseHostedAuthCallback", {
5131
6223
  enumerable: true,
5132
- get: function () { return chunk4IW4V7YJ_cjs.parseHostedAuthCallback; }
6224
+ get: function () { return chunk7KEQHWZB_cjs.parseHostedAuthCallback; }
5133
6225
  });
5134
6226
  Object.defineProperty(exports, "persistHostedAuthPendingTransaction", {
5135
6227
  enumerable: true,
5136
- get: function () { return chunk4IW4V7YJ_cjs.persistHostedAuthPendingTransaction; }
6228
+ get: function () { return chunk7KEQHWZB_cjs.persistHostedAuthPendingTransaction; }
5137
6229
  });
5138
6230
  Object.defineProperty(exports, "readHostedAuthPendingTransaction", {
5139
6231
  enumerable: true,
5140
- get: function () { return chunk4IW4V7YJ_cjs.readHostedAuthPendingTransaction; }
6232
+ get: function () { return chunk7KEQHWZB_cjs.readHostedAuthPendingTransaction; }
5141
6233
  });
5142
6234
  Object.defineProperty(exports, "readStoredHostedAuthSession", {
5143
6235
  enumerable: true,
5144
- get: function () { return chunk4IW4V7YJ_cjs.readStoredHostedAuthSession; }
6236
+ get: function () { return chunk7KEQHWZB_cjs.readStoredHostedAuthSession; }
6237
+ });
6238
+ Object.defineProperty(exports, "requireDepositLockOwner", {
6239
+ enumerable: true,
6240
+ get: function () { return chunk7KEQHWZB_cjs.requireDepositLockOwner; }
6241
+ });
6242
+ Object.defineProperty(exports, "requireServiceAddress", {
6243
+ enumerable: true,
6244
+ get: function () { return chunk7KEQHWZB_cjs.requireServiceAddress; }
5145
6245
  });
5146
6246
  Object.defineProperty(exports, "savePendingLock", {
5147
6247
  enumerable: true,
5148
- get: function () { return chunk4IW4V7YJ_cjs.savePendingLock; }
6248
+ get: function () { return chunk7KEQHWZB_cjs.savePendingLock; }
5149
6249
  });
5150
6250
  Object.defineProperty(exports, "signLockMessage", {
5151
6251
  enumerable: true,
5152
- get: function () { return chunk4IW4V7YJ_cjs.signLockMessage; }
6252
+ get: function () { return chunk7KEQHWZB_cjs.signLockMessage; }
5153
6253
  });
5154
6254
  Object.defineProperty(exports, "signModifyLockMessage", {
5155
6255
  enumerable: true,
5156
- get: function () { return chunk4IW4V7YJ_cjs.signModifyLockMessage; }
6256
+ get: function () { return chunk7KEQHWZB_cjs.signModifyLockMessage; }
5157
6257
  });
5158
6258
  Object.defineProperty(exports, "signTransferLockedMessage", {
5159
6259
  enumerable: true,
5160
- get: function () { return chunk4IW4V7YJ_cjs.signTransferLockedMessage; }
6260
+ get: function () { return chunk7KEQHWZB_cjs.signTransferLockedMessage; }
5161
6261
  });
5162
6262
  Object.defineProperty(exports, "signTransferMessage", {
5163
6263
  enumerable: true,
5164
- get: function () { return chunk4IW4V7YJ_cjs.signTransferMessage; }
6264
+ get: function () { return chunk7KEQHWZB_cjs.signTransferMessage; }
5165
6265
  });
5166
6266
  Object.defineProperty(exports, "signWithdrawFromLockMessage", {
5167
6267
  enumerable: true,
5168
- get: function () { return chunk4IW4V7YJ_cjs.signWithdrawFromLockMessage; }
6268
+ get: function () { return chunk7KEQHWZB_cjs.signWithdrawFromLockMessage; }
5169
6269
  });
5170
6270
  Object.defineProperty(exports, "signWithdrawMessage", {
5171
6271
  enumerable: true,
5172
- get: function () { return chunk4IW4V7YJ_cjs.signWithdrawMessage; }
6272
+ get: function () { return chunk7KEQHWZB_cjs.signWithdrawMessage; }
5173
6273
  });
5174
6274
  Object.defineProperty(exports, "stripHostedAuthCallbackParams", {
5175
6275
  enumerable: true,
5176
- get: function () { return chunk4IW4V7YJ_cjs.stripHostedAuthCallbackParams; }
6276
+ get: function () { return chunk7KEQHWZB_cjs.stripHostedAuthCallbackParams; }
5177
6277
  });
5178
6278
  Object.defineProperty(exports, "submitPendingLock", {
5179
6279
  enumerable: true,
5180
- get: function () { return chunk4IW4V7YJ_cjs.submitPendingLock; }
6280
+ get: function () { return chunk7KEQHWZB_cjs.submitPendingLock; }
5181
6281
  });
5182
6282
  Object.defineProperty(exports, "syncHostedAuthSessionToClient", {
5183
6283
  enumerable: true,
5184
- get: function () { return chunk4IW4V7YJ_cjs.syncHostedAuthSessionToClient; }
6284
+ get: function () { return chunk7KEQHWZB_cjs.syncHostedAuthSessionToClient; }
5185
6285
  });
5186
6286
  Object.defineProperty(exports, "useDepositVerification", {
5187
6287
  enumerable: true,
5188
- get: function () { return chunk4IW4V7YJ_cjs.useDepositVerification; }
6288
+ get: function () { return chunk7KEQHWZB_cjs.useDepositVerification; }
5189
6289
  });
5190
6290
  Object.defineProperty(exports, "usePrivanaContext", {
5191
6291
  enumerable: true,
5192
- get: function () { return chunk4IW4V7YJ_cjs.usePrivanaContext; }
6292
+ get: function () { return chunk7KEQHWZB_cjs.usePrivanaContext; }
5193
6293
  });
5194
6294
  Object.defineProperty(exports, "useSafeAccount", {
5195
6295
  enumerable: true,
5196
- get: function () { return chunk4IW4V7YJ_cjs.useSafeAccount; }
6296
+ get: function () { return chunk7KEQHWZB_cjs.useSafeAccount; }
5197
6297
  });
5198
6298
  Object.defineProperty(exports, "useSafePrivanaContext", {
5199
6299
  enumerable: true,
5200
- get: function () { return chunk4IW4V7YJ_cjs.useSafePrivanaContext; }
6300
+ get: function () { return chunk7KEQHWZB_cjs.useSafePrivanaContext; }
5201
6301
  });
5202
6302
  Object.defineProperty(exports, "useSiweAuth", {
5203
6303
  enumerable: true,
5204
- get: function () { return chunk4IW4V7YJ_cjs.useSiweAuth; }
6304
+ get: function () { return chunk7KEQHWZB_cjs.useSiweAuth; }
5205
6305
  });
5206
6306
  exports.DepositInlineModal = DepositInlineModal;
5207
6307
  exports.DepositModal = DepositModal;