@unifold/ui-react 0.1.60 → 0.1.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  // src/components/deposits/DepositModal.tsx
2
2
  import {
3
- useState as useState31,
4
- useEffect as useEffect25,
3
+ useState as useState32,
4
+ useEffect as useEffect26,
5
5
  useLayoutEffect as useLayoutEffect2,
6
6
  useCallback as useCallback5,
7
- useRef as useRef8,
7
+ useRef as useRef9,
8
8
  useMemo as useMemo10
9
9
  } from "react";
10
10
  import { ChevronRight as ChevronRight14, MapPinOff, AlertTriangle as AlertTriangle2 } from "lucide-react";
@@ -624,6 +624,7 @@ function useDepositAddress(params) {
624
624
  destinationChainId,
625
625
  destinationTokenAddress,
626
626
  actionType,
627
+ contractCalls,
627
628
  enabled = true
628
629
  } = params;
629
630
  return useQuery({
@@ -636,6 +637,7 @@ function useDepositAddress(params) {
636
637
  destinationChainId ?? null,
637
638
  destinationTokenAddress ?? null,
638
639
  actionType ?? null,
640
+ contractCalls ?? null,
639
641
  publishableKey
640
642
  ],
641
643
  queryFn: () => createDepositAddress(
@@ -645,7 +647,8 @@ function useDepositAddress(params) {
645
647
  destination_chain_type: destinationChainType,
646
648
  destination_chain_id: destinationChainId,
647
649
  destination_token_address: destinationTokenAddress,
648
- action_type: actionType
650
+ action_type: actionType,
651
+ contract_calls: contractCalls
649
652
  },
650
653
  publishableKey
651
654
  ),
@@ -5249,7 +5252,7 @@ function CashAppButton({
5249
5252
  }
5250
5253
 
5251
5254
  // src/components/deposits/buttons/BrowserWalletButton.tsx
5252
- import * as React24 from "react";
5255
+ import * as React25 from "react";
5253
5256
  import { Wallet, ChevronRight as ChevronRight10, Loader2 as Loader23 } from "lucide-react";
5254
5257
  import { getAddressBalances } from "@unifold/core";
5255
5258
 
@@ -5303,6 +5306,197 @@ function collectAllEip6963EthProviders() {
5303
5306
  return store.getProviders().map((d) => d.provider);
5304
5307
  }
5305
5308
 
5309
+ // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
5310
+ import * as React12 from "react";
5311
+
5312
+ // src/components/deposits/browser-wallets/detectConnectedWallet.ts
5313
+ function identifyEthWallet(provider, hint) {
5314
+ switch (hint) {
5315
+ case "metamask":
5316
+ return { type: "metamask", name: "MetaMask", icon: "metamask" };
5317
+ case "phantom":
5318
+ return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
5319
+ case "coinbase":
5320
+ return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
5321
+ case "okx":
5322
+ return { type: "okx", name: "OKX Wallet", icon: "okx" };
5323
+ case "rabby":
5324
+ return { type: "rabby", name: "Rabby", icon: "rabby" };
5325
+ case "trust":
5326
+ return { type: "trust", name: "Trust Wallet", icon: "trust" };
5327
+ case "rainbow":
5328
+ return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
5329
+ }
5330
+ const anyProvider = provider;
5331
+ if (provider.isPhantom) {
5332
+ return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
5333
+ }
5334
+ if (anyProvider.isCoinbaseWallet) {
5335
+ return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
5336
+ }
5337
+ if (anyProvider.isRabby) {
5338
+ return { type: "rabby", name: "Rabby", icon: "rabby" };
5339
+ }
5340
+ if (anyProvider.isTrust) {
5341
+ return { type: "trust", name: "Trust Wallet", icon: "trust" };
5342
+ }
5343
+ if (anyProvider.isRainbow) {
5344
+ return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
5345
+ }
5346
+ if (provider.isMetaMask && !provider.isPhantom) {
5347
+ return { type: "metamask", name: "MetaMask", icon: "metamask" };
5348
+ }
5349
+ return { type: "metamask", name: "Wallet", icon: "metamask" };
5350
+ }
5351
+ async function detectConnectedBrowserWallet(chainType) {
5352
+ if (typeof window === "undefined") return null;
5353
+ if (getUserDisconnectedWallet()) return null;
5354
+ try {
5355
+ const win = window;
5356
+ if (!chainType || chainType === "solana") {
5357
+ const trySilentSolana = async (provider, type, name, icon) => {
5358
+ if (!provider) return null;
5359
+ if (provider.isConnected && provider.publicKey) {
5360
+ return { type, name, address: provider.publicKey.toString(), icon };
5361
+ }
5362
+ try {
5363
+ const resp = await provider.connect({ onlyIfTrusted: true });
5364
+ if (resp.publicKey) {
5365
+ return { type, name, address: resp.publicKey.toString(), icon };
5366
+ }
5367
+ } catch {
5368
+ }
5369
+ return null;
5370
+ };
5371
+ const solanaCandidates = [
5372
+ [win.phantom?.solana, "phantom-solana", "Phantom", "phantom"],
5373
+ [win.solflare, "solflare", "Solflare", "solflare"],
5374
+ [win.backpack, "backpack", "Backpack", "backpack"],
5375
+ [win.glow, "glow", "Glow", "glow"]
5376
+ ];
5377
+ for (const [provider, type, name, icon] of solanaCandidates) {
5378
+ const found = await trySilentSolana(provider, type, name, icon);
5379
+ if (found) return found;
5380
+ }
5381
+ }
5382
+ if (!chainType || chainType === "ethereum") {
5383
+ const allProviders = [];
5384
+ const eip6963 = getEip6963Providers();
5385
+ for (const { provider, walletId } of eip6963) {
5386
+ allProviders.push({
5387
+ provider,
5388
+ walletId: walletId === "unknown" ? "default" : walletId
5389
+ });
5390
+ }
5391
+ if (allProviders.length === 0) {
5392
+ if (win.phantom?.ethereum) {
5393
+ allProviders.push({ provider: win.phantom.ethereum, walletId: "phantom" });
5394
+ }
5395
+ if (win.okxwallet) {
5396
+ allProviders.push({ provider: win.okxwallet, walletId: "okx" });
5397
+ }
5398
+ if (win.coinbaseWalletExtension) {
5399
+ allProviders.push({ provider: win.coinbaseWalletExtension, walletId: "coinbase" });
5400
+ }
5401
+ if (win.ethereum && !allProviders.some((p) => p.provider === win.ethereum)) {
5402
+ allProviders.push({ provider: win.ethereum, walletId: "default" });
5403
+ }
5404
+ }
5405
+ for (const { provider, walletId } of allProviders) {
5406
+ if (!provider) continue;
5407
+ try {
5408
+ const accounts = await provider.request({ method: "eth_accounts" });
5409
+ if (!accounts || accounts.length === 0) continue;
5410
+ const resolved = identifyEthWallet(provider, walletId);
5411
+ return { ...resolved, address: accounts[0] };
5412
+ } catch {
5413
+ }
5414
+ }
5415
+ }
5416
+ } catch (error) {
5417
+ console.error("[detectConnectedBrowserWallet] detection error:", error);
5418
+ }
5419
+ return null;
5420
+ }
5421
+
5422
+ // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
5423
+ function useDetectedBrowserWallet(opts = {}) {
5424
+ const { chainType, enabled = true, onDisconnect } = opts;
5425
+ const [wallet, setWallet] = React12.useState(null);
5426
+ const [isLoading, setIsLoading] = React12.useState(enabled);
5427
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React12.useState(0);
5428
+ const onDisconnectRef = React12.useRef(onDisconnect);
5429
+ onDisconnectRef.current = onDisconnect;
5430
+ React12.useEffect(() => {
5431
+ const store = getEip6963Store();
5432
+ if (!store) return;
5433
+ setEip6963ProviderCount(store.getProviders().length);
5434
+ return store.subscribe((providers) => setEip6963ProviderCount(providers.length));
5435
+ }, []);
5436
+ React12.useEffect(() => {
5437
+ if (!enabled) {
5438
+ setWallet(null);
5439
+ setIsLoading(false);
5440
+ return;
5441
+ }
5442
+ let mounted = true;
5443
+ const detect = async () => {
5444
+ if (!mounted) return;
5445
+ setIsLoading(true);
5446
+ const detected = await detectConnectedBrowserWallet(chainType);
5447
+ if (!mounted) return;
5448
+ setWallet(detected);
5449
+ setIsLoading(false);
5450
+ };
5451
+ detect();
5452
+ const onChange = () => detect();
5453
+ const onDisc = () => {
5454
+ onDisconnectRef.current?.();
5455
+ detect();
5456
+ };
5457
+ const onEthAccounts = (accounts) => {
5458
+ if (Array.isArray(accounts) && accounts.length === 0) onDisconnectRef.current?.();
5459
+ detect();
5460
+ };
5461
+ const win = typeof window !== "undefined" ? window : void 0;
5462
+ const solanaProvider = win?.phantom?.solana || win?.solana;
5463
+ if (solanaProvider) {
5464
+ solanaProvider.on("connect", onChange);
5465
+ solanaProvider.on("disconnect", onDisc);
5466
+ solanaProvider.on("accountChanged", onChange);
5467
+ }
5468
+ const ethProviders = [];
5469
+ for (const { provider } of getEip6963Providers()) {
5470
+ const p = provider;
5471
+ if (p && !ethProviders.includes(p)) ethProviders.push(p);
5472
+ }
5473
+ if (win?.ethereum && !ethProviders.includes(win.ethereum)) ethProviders.push(win.ethereum);
5474
+ if (win?.phantom?.ethereum && !ethProviders.includes(win.phantom.ethereum)) {
5475
+ ethProviders.push(win.phantom.ethereum);
5476
+ }
5477
+ for (const p of ethProviders) {
5478
+ p.on("accountsChanged", onEthAccounts);
5479
+ p.on("chainChanged", onChange);
5480
+ }
5481
+ return () => {
5482
+ mounted = false;
5483
+ if (solanaProvider) {
5484
+ solanaProvider.off?.("connect", onChange);
5485
+ solanaProvider.off?.("disconnect", onDisc);
5486
+ solanaProvider.off?.("accountChanged", onChange);
5487
+ }
5488
+ for (const p of ethProviders) {
5489
+ const off = p.off?.bind(p) ?? p.removeListener?.bind(p);
5490
+ if (off) {
5491
+ off("accountsChanged", onEthAccounts);
5492
+ off("chainChanged", onChange);
5493
+ }
5494
+ }
5495
+ };
5496
+ }, [chainType, eip6963ProviderCount, enabled]);
5497
+ return { wallet, isLoading, setWallet };
5498
+ }
5499
+
5306
5500
  // src/components/deposits/browser-wallets/disconnectInjectedBrowserWallet.ts
5307
5501
  var SOLANA_DISCONNECT_TYPES = [
5308
5502
  "phantom-solana",
@@ -5388,14 +5582,14 @@ async function disconnectInjectedBrowserWallet(wallet) {
5388
5582
  }
5389
5583
 
5390
5584
  // src/resources/icons/MetamaskIcon.tsx
5391
- import * as React12 from "react";
5585
+ import * as React13 from "react";
5392
5586
  import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
5393
5587
  function MetamaskIcon({
5394
5588
  size = 24,
5395
5589
  className,
5396
5590
  variant = "color"
5397
5591
  }) {
5398
- const id = React12.useId();
5592
+ const id = React13.useId();
5399
5593
  if (variant === "light" || variant === "dark") {
5400
5594
  return /* @__PURE__ */ jsxs20(
5401
5595
  "svg",
@@ -5517,14 +5711,14 @@ function MetamaskIcon({
5517
5711
  }
5518
5712
 
5519
5713
  // src/resources/icons/PhantomIcon.tsx
5520
- import * as React13 from "react";
5714
+ import * as React14 from "react";
5521
5715
  import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
5522
5716
  function PhantomIcon({
5523
5717
  size = 24,
5524
5718
  className,
5525
5719
  variant = "color"
5526
5720
  }) {
5527
- const id = React13.useId();
5721
+ const id = React14.useId();
5528
5722
  if (variant === "light") {
5529
5723
  return /* @__PURE__ */ jsx24(
5530
5724
  "svg",
@@ -5592,14 +5786,14 @@ function PhantomIcon({
5592
5786
  }
5593
5787
 
5594
5788
  // src/resources/icons/CoinbaseIcon.tsx
5595
- import * as React14 from "react";
5789
+ import * as React15 from "react";
5596
5790
  import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
5597
5791
  function CoinbaseIcon({
5598
5792
  size = 24,
5599
5793
  className,
5600
5794
  variant = "color"
5601
5795
  }) {
5602
- const id = React14.useId();
5796
+ const id = React15.useId();
5603
5797
  if (variant === "light") {
5604
5798
  return /* @__PURE__ */ jsxs22(
5605
5799
  "svg",
@@ -5680,14 +5874,14 @@ function CoinbaseIcon({
5680
5874
  }
5681
5875
 
5682
5876
  // src/resources/icons/RabbyIcon.tsx
5683
- import * as React15 from "react";
5877
+ import * as React16 from "react";
5684
5878
  import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
5685
5879
  function RabbyIcon({
5686
5880
  size = 24,
5687
5881
  className,
5688
5882
  variant = "color"
5689
5883
  }) {
5690
- const id = React15.useId();
5884
+ const id = React16.useId();
5691
5885
  if (variant === "light") {
5692
5886
  return /* @__PURE__ */ jsxs23(
5693
5887
  "svg",
@@ -6035,14 +6229,14 @@ function RabbyIcon({
6035
6229
  }
6036
6230
 
6037
6231
  // src/resources/icons/RainbowIcon.tsx
6038
- import * as React16 from "react";
6232
+ import * as React17 from "react";
6039
6233
  import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
6040
6234
  function RainbowIcon({
6041
6235
  size = 24,
6042
6236
  className,
6043
6237
  variant = "color"
6044
6238
  }) {
6045
- const id = React16.useId();
6239
+ const id = React17.useId();
6046
6240
  if (variant === "light") {
6047
6241
  return /* @__PURE__ */ jsxs24(
6048
6242
  "svg",
@@ -6505,14 +6699,14 @@ function RainbowIcon({
6505
6699
  }
6506
6700
 
6507
6701
  // src/resources/icons/TrustIcon.tsx
6508
- import * as React17 from "react";
6702
+ import * as React18 from "react";
6509
6703
  import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
6510
6704
  function TrustIcon({
6511
6705
  size = 24,
6512
6706
  className,
6513
6707
  variant = "color"
6514
6708
  }) {
6515
- const id = React17.useId();
6709
+ const id = React18.useId();
6516
6710
  if (variant === "light") {
6517
6711
  return /* @__PURE__ */ jsx28(
6518
6712
  "svg",
@@ -6602,14 +6796,14 @@ function TrustIcon({
6602
6796
  }
6603
6797
 
6604
6798
  // src/resources/icons/OkxIcon.tsx
6605
- import * as React18 from "react";
6799
+ import * as React19 from "react";
6606
6800
  import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
6607
6801
  function OkxIcon({
6608
6802
  size = 24,
6609
6803
  className,
6610
6804
  variant = "color"
6611
6805
  }) {
6612
- const id = React18.useId();
6806
+ const id = React19.useId();
6613
6807
  if (variant === "light") {
6614
6808
  return /* @__PURE__ */ jsx29(
6615
6809
  "svg",
@@ -6677,14 +6871,14 @@ function OkxIcon({
6677
6871
  }
6678
6872
 
6679
6873
  // src/resources/icons/GlowIcon.tsx
6680
- import * as React19 from "react";
6874
+ import * as React20 from "react";
6681
6875
  import { jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
6682
6876
  function GlowIcon({
6683
6877
  size = 24,
6684
6878
  className,
6685
6879
  variant = "color"
6686
6880
  }) {
6687
- const id = React19.useId();
6881
+ const id = React20.useId();
6688
6882
  if (variant === "light") {
6689
6883
  return /* @__PURE__ */ jsx30(
6690
6884
  "svg",
@@ -6786,14 +6980,14 @@ function GlowIcon({
6786
6980
  }
6787
6981
 
6788
6982
  // src/resources/icons/BackpackIcon.tsx
6789
- import * as React20 from "react";
6983
+ import * as React21 from "react";
6790
6984
  import { jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
6791
6985
  function BackpackIcon({
6792
6986
  size = 24,
6793
6987
  className,
6794
6988
  variant = "color"
6795
6989
  }) {
6796
- const id = React20.useId();
6990
+ const id = React21.useId();
6797
6991
  if (variant === "light") {
6798
6992
  return /* @__PURE__ */ jsx31(
6799
6993
  "svg",
@@ -6867,14 +7061,14 @@ function BackpackIcon({
6867
7061
  }
6868
7062
 
6869
7063
  // src/resources/icons/SolflareIcon.tsx
6870
- import * as React21 from "react";
7064
+ import * as React22 from "react";
6871
7065
  import { jsx as jsx32, jsxs as jsxs29 } from "react/jsx-runtime";
6872
7066
  function SolflareIcon({
6873
7067
  size = 24,
6874
7068
  className,
6875
7069
  variant = "color"
6876
7070
  }) {
6877
- const id = React21.useId();
7071
+ const id = React22.useId();
6878
7072
  if (variant === "light") {
6879
7073
  return /* @__PURE__ */ jsx32(
6880
7074
  "svg",
@@ -6942,14 +7136,14 @@ function SolflareIcon({
6942
7136
  }
6943
7137
 
6944
7138
  // src/resources/icons/EthereumIcon.tsx
6945
- import * as React22 from "react";
7139
+ import * as React23 from "react";
6946
7140
  import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
6947
7141
  function EthereumIcon({
6948
7142
  size = 24,
6949
7143
  className,
6950
7144
  variant = "color"
6951
7145
  }) {
6952
- const id = React22.useId();
7146
+ const id = React23.useId();
6953
7147
  if (variant === "light") {
6954
7148
  return /* @__PURE__ */ jsxs30(
6955
7149
  "svg",
@@ -7080,14 +7274,14 @@ function EthereumIcon({
7080
7274
  }
7081
7275
 
7082
7276
  // src/resources/icons/SolanaIcon.tsx
7083
- import * as React23 from "react";
7277
+ import * as React24 from "react";
7084
7278
  import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
7085
7279
  function SolanaIcon({
7086
7280
  size = 24,
7087
7281
  className,
7088
7282
  variant = "color"
7089
7283
  }) {
7090
- const id = React23.useId();
7284
+ const id = React24.useId();
7091
7285
  if (variant === "light") {
7092
7286
  return /* @__PURE__ */ jsx34(
7093
7287
  "svg",
@@ -7342,44 +7536,6 @@ function truncateAddress3(address) {
7342
7536
  if (address.length <= 10) return address;
7343
7537
  return `${address.slice(0, 4)}...${address.slice(-4)}`;
7344
7538
  }
7345
- function identifyEthWallet(provider, _win, hint) {
7346
- switch (hint) {
7347
- case "metamask":
7348
- return { type: "metamask", name: "MetaMask", icon: "metamask" };
7349
- case "phantom":
7350
- return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
7351
- case "coinbase":
7352
- return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
7353
- case "okx":
7354
- return { type: "okx", name: "OKX Wallet", icon: "okx" };
7355
- case "rabby":
7356
- return { type: "rabby", name: "Rabby", icon: "rabby" };
7357
- case "trust":
7358
- return { type: "trust", name: "Trust Wallet", icon: "trust" };
7359
- case "rainbow":
7360
- return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
7361
- }
7362
- const anyProvider = provider;
7363
- if (provider.isPhantom) {
7364
- return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
7365
- }
7366
- if (anyProvider.isCoinbaseWallet) {
7367
- return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
7368
- }
7369
- if (anyProvider.isRabby) {
7370
- return { type: "rabby", name: "Rabby", icon: "rabby" };
7371
- }
7372
- if (anyProvider.isTrust) {
7373
- return { type: "trust", name: "Trust Wallet", icon: "trust" };
7374
- }
7375
- if (anyProvider.isRainbow) {
7376
- return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
7377
- }
7378
- if (provider.isMetaMask && !provider.isPhantom) {
7379
- return { type: "metamask", name: "MetaMask", icon: "metamask" };
7380
- }
7381
- return { type: "metamask", name: "Wallet", icon: "metamask" };
7382
- }
7383
7539
  function BrowserWalletButton({
7384
7540
  onClick,
7385
7541
  onConnectClick,
@@ -7390,30 +7546,19 @@ function BrowserWalletButton({
7390
7546
  subtitle = i18n.depositModal.browserWallet.subtitle
7391
7547
  }) {
7392
7548
  const { colors: colors2, fonts, components } = useTheme();
7393
- const [isHovered, setIsHovered] = React24.useState(false);
7394
- const [isTouchDevice, setIsTouchDevice] = React24.useState(false);
7395
- const [wallet, setWallet] = React24.useState(null);
7396
- const [isLoading, setIsLoading] = React24.useState(true);
7397
- const [isConnecting, setIsConnecting] = React24.useState(false);
7398
- const [balanceText, setBalanceText] = React24.useState(null);
7399
- const [isLoadingBalance, setIsLoadingBalance] = React24.useState(false);
7400
- const [isDisconnecting, setIsDisconnecting] = React24.useState(false);
7401
- const onDisconnectRef = React24.useRef(onDisconnect);
7549
+ const [isHovered, setIsHovered] = React25.useState(false);
7550
+ const [isTouchDevice, setIsTouchDevice] = React25.useState(false);
7551
+ const { wallet, isLoading, setWallet } = useDetectedBrowserWallet({ chainType, onDisconnect });
7552
+ const [isConnecting, setIsConnecting] = React25.useState(false);
7553
+ const [balanceText, setBalanceText] = React25.useState(null);
7554
+ const [isLoadingBalance, setIsLoadingBalance] = React25.useState(false);
7555
+ const [isDisconnecting, setIsDisconnecting] = React25.useState(false);
7556
+ const onDisconnectRef = React25.useRef(onDisconnect);
7402
7557
  onDisconnectRef.current = onDisconnect;
7403
- React24.useEffect(() => {
7558
+ React25.useEffect(() => {
7404
7559
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7405
7560
  }, []);
7406
- const [eip6963ProviderCount, setEip6963ProviderCount] = React24.useState(0);
7407
- React24.useEffect(() => {
7408
- const store = getEip6963Store();
7409
- if (!store) return;
7410
- setEip6963ProviderCount(store.getProviders().length);
7411
- const unsubscribe = store.subscribe((providers) => {
7412
- setEip6963ProviderCount(providers.length);
7413
- });
7414
- return unsubscribe;
7415
- }, []);
7416
- React24.useEffect(() => {
7561
+ React25.useEffect(() => {
7417
7562
  if (!wallet || !publishableKey) {
7418
7563
  setBalanceText(null);
7419
7564
  return;
@@ -7454,206 +7599,6 @@ function BrowserWalletButton({
7454
7599
  cancelled = true;
7455
7600
  };
7456
7601
  }, [wallet, publishableKey]);
7457
- React24.useEffect(() => {
7458
- let mounted = true;
7459
- const detectWallet = async () => {
7460
- if (!mounted) return;
7461
- setIsLoading(true);
7462
- try {
7463
- const win = typeof window !== "undefined" ? window : null;
7464
- if (!win) return;
7465
- if (getUserDisconnectedWallet()) {
7466
- if (mounted) {
7467
- setWallet(null);
7468
- setIsLoading(false);
7469
- }
7470
- return;
7471
- }
7472
- if (!chainType || chainType === "solana") {
7473
- const anyWin = win;
7474
- const trySilentSolana = async (provider, type, name, icon) => {
7475
- if (!provider) return false;
7476
- if (provider.isConnected && provider.publicKey) {
7477
- if (mounted) {
7478
- setWallet({
7479
- type,
7480
- name,
7481
- address: provider.publicKey.toString(),
7482
- icon
7483
- });
7484
- setIsLoading(false);
7485
- }
7486
- return true;
7487
- }
7488
- try {
7489
- const resp = await provider.connect({ onlyIfTrusted: true });
7490
- if (mounted && resp.publicKey) {
7491
- setWallet({
7492
- type,
7493
- name,
7494
- address: resp.publicKey.toString(),
7495
- icon
7496
- });
7497
- setIsLoading(false);
7498
- return true;
7499
- }
7500
- } catch {
7501
- }
7502
- return false;
7503
- };
7504
- if (await trySilentSolana(
7505
- win.phantom?.solana,
7506
- "phantom-solana",
7507
- "Phantom",
7508
- "phantom"
7509
- ))
7510
- return;
7511
- if (await trySilentSolana(
7512
- anyWin.solflare,
7513
- "solflare",
7514
- "Solflare",
7515
- "solflare"
7516
- ))
7517
- return;
7518
- if (await trySilentSolana(
7519
- anyWin.backpack,
7520
- "backpack",
7521
- "Backpack",
7522
- "backpack"
7523
- ))
7524
- return;
7525
- if (await trySilentSolana(
7526
- anyWin.glow,
7527
- "glow",
7528
- "Glow",
7529
- "glow"
7530
- ))
7531
- return;
7532
- }
7533
- if (!chainType || chainType === "ethereum") {
7534
- const anyWin = win;
7535
- const allProviders = [];
7536
- const eip6963 = getEip6963Providers();
7537
- for (const { provider, walletId } of eip6963) {
7538
- allProviders.push({
7539
- provider,
7540
- walletId: walletId === "unknown" ? "default" : walletId
7541
- });
7542
- }
7543
- if (allProviders.length === 0) {
7544
- if (win.phantom?.ethereum) {
7545
- allProviders.push({
7546
- provider: win.phantom.ethereum,
7547
- walletId: "phantom"
7548
- });
7549
- }
7550
- if (anyWin.okxwallet) {
7551
- allProviders.push({
7552
- provider: anyWin.okxwallet,
7553
- walletId: "okx"
7554
- });
7555
- }
7556
- if (anyWin.coinbaseWalletExtension) {
7557
- allProviders.push({
7558
- provider: anyWin.coinbaseWalletExtension,
7559
- walletId: "coinbase"
7560
- });
7561
- }
7562
- if (win.ethereum) {
7563
- const isDuplicate = allProviders.some(
7564
- (p) => p.provider === win.ethereum
7565
- );
7566
- if (!isDuplicate) {
7567
- allProviders.push({
7568
- provider: win.ethereum,
7569
- walletId: "default"
7570
- });
7571
- }
7572
- }
7573
- }
7574
- for (const { provider, walletId } of allProviders) {
7575
- if (!provider) continue;
7576
- try {
7577
- const accounts = await provider.request({
7578
- method: "eth_accounts"
7579
- });
7580
- if (!accounts || accounts.length === 0) continue;
7581
- const address = accounts[0];
7582
- const resolved = identifyEthWallet(provider, anyWin, walletId);
7583
- if (mounted) {
7584
- setWallet({ ...resolved, address });
7585
- setIsLoading(false);
7586
- }
7587
- return;
7588
- } catch {
7589
- }
7590
- }
7591
- }
7592
- if (mounted) {
7593
- setWallet(null);
7594
- setIsLoading(false);
7595
- }
7596
- } catch (error) {
7597
- console.error("[BrowserWalletButton] Error detecting wallet:", error);
7598
- if (mounted) {
7599
- setWallet(null);
7600
- setIsLoading(false);
7601
- }
7602
- }
7603
- };
7604
- detectWallet();
7605
- const handleAccountsChanged = () => {
7606
- detectWallet();
7607
- };
7608
- const handleDisconnect = () => {
7609
- onDisconnectRef.current?.();
7610
- detectWallet();
7611
- };
7612
- const handleEthAccountsChanged = (accounts) => {
7613
- if (Array.isArray(accounts) && accounts.length === 0) {
7614
- onDisconnectRef.current?.();
7615
- }
7616
- detectWallet();
7617
- };
7618
- const solanaProvider = window.phantom?.solana || window.solana;
7619
- if (solanaProvider) {
7620
- solanaProvider.on("connect", handleAccountsChanged);
7621
- solanaProvider.on("disconnect", handleDisconnect);
7622
- solanaProvider.on("accountChanged", handleAccountsChanged);
7623
- }
7624
- const ethProviders = [];
7625
- for (const { provider } of getEip6963Providers()) {
7626
- const p = provider;
7627
- if (p && !ethProviders.includes(p)) {
7628
- ethProviders.push(p);
7629
- }
7630
- }
7631
- if (window.ethereum && !ethProviders.includes(window.ethereum)) {
7632
- ethProviders.push(window.ethereum);
7633
- }
7634
- if (window.phantom?.ethereum && !ethProviders.includes(window.phantom.ethereum)) {
7635
- ethProviders.push(window.phantom.ethereum);
7636
- }
7637
- for (const provider of ethProviders) {
7638
- provider.on("accountsChanged", handleEthAccountsChanged);
7639
- provider.on("chainChanged", handleAccountsChanged);
7640
- }
7641
- return () => {
7642
- mounted = false;
7643
- if (solanaProvider) {
7644
- solanaProvider.off("connect", handleAccountsChanged);
7645
- solanaProvider.off("disconnect", handleDisconnect);
7646
- solanaProvider.off("accountChanged", handleAccountsChanged);
7647
- }
7648
- for (const provider of ethProviders) {
7649
- const off = provider.off?.bind(provider) ?? provider.removeListener?.bind(provider);
7650
- if (off) {
7651
- off("accountsChanged", handleEthAccountsChanged);
7652
- off("chainChanged", handleAccountsChanged);
7653
- }
7654
- }
7655
- };
7656
- }, [chainType, eip6963ProviderCount]);
7657
7602
  const handleConnect = async () => {
7658
7603
  if (wallet) {
7659
7604
  onClick(wallet);
@@ -7737,7 +7682,7 @@ function BrowserWalletButton({
7737
7682
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
7738
7683
  };
7739
7684
  const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
7740
- const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React24.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
7685
+ const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React25.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
7741
7686
  size: 36,
7742
7687
  className: "uf-rounded-lg",
7743
7688
  variant: "color"
@@ -7888,7 +7833,7 @@ function BrowserWalletButton({
7888
7833
  }
7889
7834
 
7890
7835
  // src/components/deposits/CoinbaseConnect.tsx
7891
- import { useState as useState21, useEffect as useEffect16, useCallback as useCallback2, useMemo as useMemo4, useRef as useRef5 } from "react";
7836
+ import { useState as useState22, useEffect as useEffect17, useCallback as useCallback2, useMemo as useMemo4, useRef as useRef6 } from "react";
7892
7837
  import {
7893
7838
  ChevronRight as ChevronRight11,
7894
7839
  ChevronDown as ChevronDown3,
@@ -8043,6 +7988,7 @@ function CoinbaseConnect({
8043
7988
  onBack: parentOnBack,
8044
7989
  onDisconnect,
8045
7990
  skipToHoldings,
7991
+ canGoBack = true,
8046
7992
  onExecutionsChange
8047
7993
  }) {
8048
7994
  const { colors: colors2, fonts, components } = useTheme();
@@ -8068,25 +8014,25 @@ function CoinbaseConnect({
8068
8014
  const appName = projectConfig?.project_name ?? "Unifold";
8069
8015
  const t12 = i18n.connectExchange;
8070
8016
  const initialView = skipToHoldings && getStoredIntegrationToken(IntegrationProvider.COINBASE) ? "holdings" : "select_exchange";
8071
- const [view, setView] = useState21(initialView);
8072
- const [prevView, setPrevView] = useState21(initialView);
8073
- const [isTransitioning, setIsTransitioning] = useState21(false);
8074
- const [exchanges, setExchanges] = useState21([]);
8075
- const [exchangesLoading, setExchangesLoading] = useState21(true);
8076
- const [selectedExchange, setSelectedExchange] = useState21(null);
8077
- const [accessToken, setAccessToken] = useState21(null);
8078
- const [holdings, setHoldings] = useState21([]);
8079
- const [selectedHolding, setSelectedHolding] = useState21(null);
8080
- const [selectedAsset, setSelectedAsset] = useState21(null);
8081
- const [sendAmount, setSendAmount] = useState21("");
8082
- const [transferIntent, setTransferIntent] = useState21(null);
8083
- const [mfaCode, setMfaCode] = useState21("");
8084
- const [mfaError, setMfaError] = useState21(false);
8085
- const [errorMessage, setErrorMessage] = useState21("");
8086
- const [isLoading, setIsLoading] = useState21(initialView === "holdings");
8087
- const [confirmResult, setConfirmResult] = useState21(null);
8088
- const [showTransferDetails, setShowTransferDetails] = useState21(false);
8089
- const [transferDepositWalletId, setTransferDepositWalletId] = useState21(void 0);
8017
+ const [view, setView] = useState22(initialView);
8018
+ const [prevView, setPrevView] = useState22(initialView);
8019
+ const [isTransitioning, setIsTransitioning] = useState22(false);
8020
+ const [exchanges, setExchanges] = useState22([]);
8021
+ const [exchangesLoading, setExchangesLoading] = useState22(true);
8022
+ const [selectedExchange, setSelectedExchange] = useState22(null);
8023
+ const [accessToken, setAccessToken] = useState22(null);
8024
+ const [holdings, setHoldings] = useState22([]);
8025
+ const [selectedHolding, setSelectedHolding] = useState22(null);
8026
+ const [selectedAsset, setSelectedAsset] = useState22(null);
8027
+ const [sendAmount, setSendAmount] = useState22("");
8028
+ const [transferIntent, setTransferIntent] = useState22(null);
8029
+ const [mfaCode, setMfaCode] = useState22("");
8030
+ const [mfaError, setMfaError] = useState22(false);
8031
+ const [errorMessage, setErrorMessage] = useState22("");
8032
+ const [isLoading, setIsLoading] = useState22(initialView === "holdings");
8033
+ const [confirmResult, setConfirmResult] = useState22(null);
8034
+ const [showTransferDetails, setShowTransferDetails] = useState22(false);
8035
+ const [transferDepositWalletId, setTransferDepositWalletId] = useState22(void 0);
8090
8036
  const exchangeSupportedCurrencies = useMemo4(() => {
8091
8037
  const set = /* @__PURE__ */ new Set();
8092
8038
  selectedExchange?.supported_currencies.forEach((c) => set.add(c.toLowerCase()));
@@ -8141,12 +8087,12 @@ function CoinbaseConnect({
8141
8087
  } : void 0,
8142
8088
  onDepositError: onTransferError
8143
8089
  });
8144
- useEffect16(() => {
8090
+ useEffect17(() => {
8145
8091
  onExecutionsChange?.(depositExecutions);
8146
8092
  }, [depositExecutions, onExecutionsChange]);
8147
- const pollRef = useRef5(null);
8148
- const popupRef = useRef5(null);
8149
- const viewRef = useRef5(initialView);
8093
+ const pollRef = useRef6(null);
8094
+ const popupRef = useRef6(null);
8095
+ const viewRef = useRef6(initialView);
8150
8096
  const transitionTo = useCallback2((nextView) => {
8151
8097
  if (nextView === viewRef.current) return;
8152
8098
  setIsTransitioning(true);
@@ -8176,7 +8122,7 @@ function CoinbaseConnect({
8176
8122
  },
8177
8123
  [publishableKey]
8178
8124
  );
8179
- useEffect16(() => {
8125
+ useEffect17(() => {
8180
8126
  getIntegrationExchanges(publishableKey).then((res) => {
8181
8127
  setExchanges(res.data);
8182
8128
  if (!selectedExchange) {
@@ -8234,7 +8180,7 @@ function CoinbaseConnect({
8234
8180
  },
8235
8181
  [publishableKey, transitionTo, tryRefreshToken]
8236
8182
  );
8237
- useEffect16(() => {
8183
+ useEffect17(() => {
8238
8184
  return () => {
8239
8185
  if (pollRef.current) clearInterval(pollRef.current);
8240
8186
  };
@@ -8430,6 +8376,16 @@ function CoinbaseConnect({
8430
8376
  setIsLoading(false);
8431
8377
  }
8432
8378
  };
8379
+ const handleDisconnect = () => {
8380
+ onDisconnect?.();
8381
+ if (!canGoBack) {
8382
+ setAccessToken(null);
8383
+ setHoldings([]);
8384
+ setSelectedHolding(null);
8385
+ setSelectedAsset(null);
8386
+ transitionTo("select_exchange");
8387
+ }
8388
+ };
8433
8389
  const handleBack = () => {
8434
8390
  switch (view) {
8435
8391
  case "select_exchange":
@@ -8490,7 +8446,7 @@ function CoinbaseConnect({
8490
8446
  DepositHeader,
8491
8447
  {
8492
8448
  title: t12.title,
8493
- showBack: true,
8449
+ showBack: canGoBack,
8494
8450
  onBack: handleBack,
8495
8451
  onClose
8496
8452
  }
@@ -8503,7 +8459,7 @@ function CoinbaseConnect({
8503
8459
  DepositHeader,
8504
8460
  {
8505
8461
  title: t12.title,
8506
- showBack: true,
8462
+ showBack: canGoBack,
8507
8463
  onBack: handleBack,
8508
8464
  onClose
8509
8465
  }
@@ -9215,7 +9171,7 @@ function CoinbaseConnect({
9215
9171
  borderRadius: components.button.borderRadius,
9216
9172
  fontFamily: fonts.medium
9217
9173
  },
9218
- onClick: onDisconnect,
9174
+ onClick: handleDisconnect,
9219
9175
  children: t12.disconnect
9220
9176
  }
9221
9177
  )
@@ -10033,7 +9989,7 @@ function useAddressValidation({
10033
9989
  }
10034
9990
 
10035
9991
  // src/components/deposits/TransferCryptoSingleInput.tsx
10036
- import { useState as useState27, useEffect as useEffect21, useMemo as useMemo7 } from "react";
9992
+ import { useState as useState28, useEffect as useEffect22, useMemo as useMemo7 } from "react";
10037
9993
  import {
10038
9994
  ChevronDown as ChevronDown4,
10039
9995
  ChevronUp as ChevronUp3,
@@ -10048,17 +10004,17 @@ import {
10048
10004
  } from "lucide-react";
10049
10005
 
10050
10006
  // src/components/deposits/DepositsModal.tsx
10051
- import { useEffect as useEffect18, useState as useState22 } from "react";
10007
+ import { useEffect as useEffect19, useState as useState23 } from "react";
10052
10008
 
10053
10009
  // src/components/shared/ThemeStyleInjector.tsx
10054
- import * as React26 from "react";
10010
+ import * as React27 from "react";
10055
10011
  import { jsx as jsx38 } from "react/jsx-runtime";
10056
10012
  function ThemeStyleInjector({
10057
10013
  children,
10058
10014
  className
10059
10015
  }) {
10060
10016
  const { colors: colors2, fonts, mode } = useTheme();
10061
- const cssVars = React26.useMemo(() => {
10017
+ const cssVars = React27.useMemo(() => {
10062
10018
  const hexToHSL = (hex) => {
10063
10019
  hex = hex.replace("#", "");
10064
10020
  const r = parseInt(hex.slice(0, 2), 16) / 255;
@@ -10118,7 +10074,7 @@ function ThemeStyleInjector({
10118
10074
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
10119
10075
  };
10120
10076
  }, [colors2, fonts.regular]);
10121
- React26.useEffect(() => {
10077
+ React27.useEffect(() => {
10122
10078
  if (typeof document === "undefined") return;
10123
10079
  if (fonts.regular) {
10124
10080
  document.documentElement.style.setProperty(
@@ -10207,9 +10163,9 @@ function DepositsModal({
10207
10163
  themeClass = ""
10208
10164
  }) {
10209
10165
  const { colors: colors2, fonts, components } = useTheme();
10210
- const [allExecutions, setAllExecutions] = useState22(sessionExecutions);
10211
- const [selectedExecution, setSelectedExecution] = useState22(null);
10212
- useEffect18(() => {
10166
+ const [allExecutions, setAllExecutions] = useState23(sessionExecutions);
10167
+ const [selectedExecution, setSelectedExecution] = useState23(null);
10168
+ useEffect19(() => {
10213
10169
  if (!open || !userId) return;
10214
10170
  const fetchExecutions = async () => {
10215
10171
  try {
@@ -10231,7 +10187,7 @@ function DepositsModal({
10231
10187
  clearInterval(pollInterval);
10232
10188
  };
10233
10189
  }, [open, userId, publishableKey, sessionExecutions]);
10234
- useEffect18(() => {
10190
+ useEffect19(() => {
10235
10191
  if (!open) {
10236
10192
  setSelectedExecution(null);
10237
10193
  }
@@ -10307,7 +10263,7 @@ function DepositsModal({
10307
10263
  }
10308
10264
 
10309
10265
  // src/components/deposits/TokenSelectorSheet.tsx
10310
- import { useState as useState23, useMemo as useMemo6, useEffect as useEffect19 } from "react";
10266
+ import { useState as useState24, useMemo as useMemo6, useEffect as useEffect20 } from "react";
10311
10267
  import { ArrowLeft as ArrowLeft2, X as X4 } from "lucide-react";
10312
10268
  import Fuse from "fuse.js";
10313
10269
  import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
@@ -10368,10 +10324,10 @@ function TokenSelectorSheet({
10368
10324
  }) {
10369
10325
  const { themeClass, colors: colors2, fonts, components } = useTheme();
10370
10326
  const isDarkMode = themeClass.includes("uf-dark");
10371
- const [searchQuery, setSearchQuery] = useState23("");
10372
- const [recentTokens, setRecentTokens] = useState23([]);
10373
- const [hoveredTokenKey, setHoveredTokenKey] = useState23(null);
10374
- useEffect19(() => {
10327
+ const [searchQuery, setSearchQuery] = useState24("");
10328
+ const [recentTokens, setRecentTokens] = useState24([]);
10329
+ const [hoveredTokenKey, setHoveredTokenKey] = useState24(null);
10330
+ useEffect20(() => {
10375
10331
  setRecentTokens(getRecentTokens());
10376
10332
  }, []);
10377
10333
  const allOptions = useMemo6(() => {
@@ -10803,7 +10759,7 @@ function TokenSelectorSheet({
10803
10759
  }
10804
10760
 
10805
10761
  // src/hooks/use-default-token.ts
10806
- import { useState as useState24, useEffect as useEffect20, useRef as useRef6 } from "react";
10762
+ import { useState as useState25, useEffect as useEffect21, useRef as useRef7 } from "react";
10807
10763
  var getChainKey = (chainId, chainType) => {
10808
10764
  return `${chainType}:${chainId}`;
10809
10765
  };
@@ -10858,11 +10814,11 @@ function useDefaultToken({
10858
10814
  defaultTokenAddress,
10859
10815
  defaultSymbol
10860
10816
  }) {
10861
- const [token, setToken] = useState24(null);
10862
- const [chain, setChain] = useState24(null);
10863
- const [initialSelectionDone, setInitialSelectionDone] = useState24(false);
10864
- const appliedDefaultsRef = useRef6("");
10865
- useEffect20(() => {
10817
+ const [token, setToken] = useState25(null);
10818
+ const [chain, setChain] = useState25(null);
10819
+ const [initialSelectionDone, setInitialSelectionDone] = useState25(false);
10820
+ const appliedDefaultsRef = useRef7("");
10821
+ useEffect21(() => {
10866
10822
  if (!tokens.length) return;
10867
10823
  const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
10868
10824
  const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
@@ -10888,7 +10844,7 @@ function useDefaultToken({
10888
10844
  defaultChainId,
10889
10845
  initialSelectionDone
10890
10846
  ]);
10891
- useEffect20(() => {
10847
+ useEffect21(() => {
10892
10848
  if (!tokens.length || !token) return;
10893
10849
  const currentToken = tokens.find((t12) => t12.symbol === token);
10894
10850
  if (!currentToken || currentToken.chains.length === 0) return;
@@ -11093,9 +11049,9 @@ function GlossaryModal({
11093
11049
  }
11094
11050
 
11095
11051
  // src/components/deposits/shared/useCopyAddress.ts
11096
- import { useState as useState25 } from "react";
11052
+ import { useState as useState26 } from "react";
11097
11053
  function useCopyAddress() {
11098
- const [copied, setCopied] = useState25(false);
11054
+ const [copied, setCopied] = useState26(false);
11099
11055
  const handleCopy = (address) => {
11100
11056
  if (!address) return;
11101
11057
  navigator.clipboard.writeText(address);
@@ -11106,7 +11062,7 @@ function useCopyAddress() {
11106
11062
  }
11107
11063
 
11108
11064
  // src/components/shared/tooltip.tsx
11109
- import * as React27 from "react";
11065
+ import * as React28 from "react";
11110
11066
  import * as TooltipPrimitive from "@radix-ui/react-tooltip";
11111
11067
  import { jsx as jsx44 } from "react/jsx-runtime";
11112
11068
  var TooltipProvider = TooltipPrimitive.Provider;
@@ -11114,7 +11070,7 @@ function Tooltip({
11114
11070
  children,
11115
11071
  ...props
11116
11072
  }) {
11117
- const [open, setOpen] = React27.useState(props.defaultOpen ?? false);
11073
+ const [open, setOpen] = React28.useState(props.defaultOpen ?? false);
11118
11074
  const isControlled = props.open !== void 0;
11119
11075
  const isOpen = isControlled ? props.open : open;
11120
11076
  const onOpenChange = isControlled ? props.onOpenChange : (nextOpen) => setOpen(nextOpen);
@@ -11134,14 +11090,14 @@ function Tooltip({
11134
11090
  }
11135
11091
  );
11136
11092
  }
11137
- var TooltipContext = React27.createContext({
11093
+ var TooltipContext = React28.createContext({
11138
11094
  open: false,
11139
11095
  onOpenChange: () => {
11140
11096
  }
11141
11097
  });
11142
- var TooltipTrigger = React27.forwardRef(({ onClick, ...props }, ref) => {
11143
- const { open, onOpenChange } = React27.useContext(TooltipContext);
11144
- const handleClick = React27.useCallback(
11098
+ var TooltipTrigger = React28.forwardRef(({ onClick, ...props }, ref) => {
11099
+ const { open, onOpenChange } = React28.useContext(TooltipContext);
11100
+ const handleClick = React28.useCallback(
11145
11101
  (e) => {
11146
11102
  onOpenChange(!open);
11147
11103
  onClick?.(e);
@@ -11151,7 +11107,7 @@ var TooltipTrigger = React27.forwardRef(({ onClick, ...props }, ref) => {
11151
11107
  return /* @__PURE__ */ jsx44(TooltipPrimitive.Trigger, { ref, onClick: handleClick, ...props });
11152
11108
  });
11153
11109
  TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
11154
- var TooltipContent = React27.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
11110
+ var TooltipContent = React28.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
11155
11111
  const { themeClass, colors: colors2 } = useTheme();
11156
11112
  return /* @__PURE__ */ jsx44(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx44(
11157
11113
  TooltipPrimitive.Content,
@@ -11297,12 +11253,12 @@ function TransferCryptoSingleInput({
11297
11253
  }) {
11298
11254
  const { themeClass, colors: colors2, fonts, components } = useTheme();
11299
11255
  const isDarkMode = themeClass.includes("uf-dark");
11300
- const [copied, setCopied] = useState27(false);
11256
+ const [copied, setCopied] = useState28(false);
11301
11257
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
11302
- const [glossaryOpen, setGlossaryOpen] = useState27(false);
11303
- const [detailsExpanded, setDetailsExpanded] = useState27(false);
11304
- const [depositsModalOpen, setDepositsModalOpen] = useState27(false);
11305
- const [tokenSelectorOpen, setTokenSelectorOpen] = useState27(false);
11258
+ const [glossaryOpen, setGlossaryOpen] = useState28(false);
11259
+ const [detailsExpanded, setDetailsExpanded] = useState28(false);
11260
+ const [depositsModalOpen, setDepositsModalOpen] = useState28(false);
11261
+ const [tokenSelectorOpen, setTokenSelectorOpen] = useState28(false);
11306
11262
  const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(publishableKey, {
11307
11263
  destination_token_address: destinationTokenAddress,
11308
11264
  destination_chain_id: destinationChainId,
@@ -11375,7 +11331,7 @@ function TransferCryptoSingleInput({
11375
11331
  publishableKey,
11376
11332
  enabled: !!depositAddress && !!recipientAddress
11377
11333
  });
11378
- useEffect21(() => {
11334
+ useEffect22(() => {
11379
11335
  if (!onSourceTokenChange || !token || !chain || !initialSelectionDone) return;
11380
11336
  const { chainType, chainId } = parseChainKey(chain);
11381
11337
  const matchedToken = supportedTokens.find((t12) => t12.symbol === token);
@@ -11392,7 +11348,7 @@ function TransferCryptoSingleInput({
11392
11348
  isStablecoin: matchedToken?.is_stablecoin ?? false
11393
11349
  });
11394
11350
  }, [token, chain, initialSelectionDone, onSourceTokenChange, supportedTokens]);
11395
- useEffect21(() => {
11351
+ useEffect22(() => {
11396
11352
  if (onExecutionsChange) {
11397
11353
  onExecutionsChange(depositExecutions);
11398
11354
  }
@@ -11779,7 +11735,7 @@ function TransferCryptoSingleInput({
11779
11735
  }
11780
11736
 
11781
11737
  // src/components/deposits/TransferCryptoDoubleInput.tsx
11782
- import { useState as useState28, useEffect as useEffect22, useMemo as useMemo8 } from "react";
11738
+ import { useState as useState29, useEffect as useEffect23, useMemo as useMemo8 } from "react";
11783
11739
  import {
11784
11740
  ChevronDown as ChevronDown6,
11785
11741
  ChevronUp as ChevronUp5,
@@ -11794,14 +11750,14 @@ import {
11794
11750
  } from "lucide-react";
11795
11751
 
11796
11752
  // src/components/shared/select.tsx
11797
- import * as React28 from "react";
11753
+ import * as React29 from "react";
11798
11754
  import * as SelectPrimitive from "@radix-ui/react-select";
11799
11755
  import { Check as Check5, ChevronDown as ChevronDown5, ChevronUp as ChevronUp4 } from "lucide-react";
11800
11756
  import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
11801
11757
  var Select = SelectPrimitive.Root;
11802
11758
  var SelectGroup = SelectPrimitive.Group;
11803
11759
  var SelectValue = SelectPrimitive.Value;
11804
- var SelectTrigger = React28.forwardRef(({ className, style, children, ...props }, ref) => {
11760
+ var SelectTrigger = React29.forwardRef(({ className, style, children, ...props }, ref) => {
11805
11761
  const { components } = useTheme();
11806
11762
  return /* @__PURE__ */ jsxs42(
11807
11763
  SelectPrimitive.Trigger,
@@ -11825,7 +11781,7 @@ var SelectTrigger = React28.forwardRef(({ className, style, children, ...props }
11825
11781
  );
11826
11782
  });
11827
11783
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
11828
- var SelectScrollUpButton = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11784
+ var SelectScrollUpButton = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11829
11785
  SelectPrimitive.ScrollUpButton,
11830
11786
  {
11831
11787
  ref,
@@ -11838,7 +11794,7 @@ var SelectScrollUpButton = React28.forwardRef(({ className, ...props }, ref) =>
11838
11794
  }
11839
11795
  ));
11840
11796
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
11841
- var SelectScrollDownButton = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11797
+ var SelectScrollDownButton = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11842
11798
  SelectPrimitive.ScrollDownButton,
11843
11799
  {
11844
11800
  ref,
@@ -11851,7 +11807,7 @@ var SelectScrollDownButton = React28.forwardRef(({ className, ...props }, ref) =
11851
11807
  }
11852
11808
  ));
11853
11809
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
11854
- var SelectContent = React28.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
11810
+ var SelectContent = React29.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
11855
11811
  const { themeClass, colors: colors2, components } = useTheme();
11856
11812
  return /* @__PURE__ */ jsx47(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs42(
11857
11813
  SelectPrimitive.Content,
@@ -11889,7 +11845,7 @@ var SelectContent = React28.forwardRef(({ className, style, children, position =
11889
11845
  ) });
11890
11846
  });
11891
11847
  SelectContent.displayName = SelectPrimitive.Content.displayName;
11892
- var SelectLabel = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11848
+ var SelectLabel = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11893
11849
  SelectPrimitive.Label,
11894
11850
  {
11895
11851
  ref,
@@ -11901,7 +11857,7 @@ var SelectLabel = React28.forwardRef(({ className, ...props }, ref) => /* @__PUR
11901
11857
  }
11902
11858
  ));
11903
11859
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
11904
- var SelectItem = React28.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs42(
11860
+ var SelectItem = React29.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs42(
11905
11861
  SelectPrimitive.Item,
11906
11862
  {
11907
11863
  ref,
@@ -11917,7 +11873,7 @@ var SelectItem = React28.forwardRef(({ className, children, ...props }, ref) =>
11917
11873
  }
11918
11874
  ));
11919
11875
  SelectItem.displayName = SelectPrimitive.Item.displayName;
11920
- var SelectSeparator = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11876
+ var SelectSeparator = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11921
11877
  SelectPrimitive.Separator,
11922
11878
  {
11923
11879
  ref,
@@ -11959,11 +11915,11 @@ function TransferCryptoDoubleInput({
11959
11915
  }) {
11960
11916
  const { themeClass, colors: colors2, fonts, components } = useTheme();
11961
11917
  const isDarkMode = themeClass.includes("uf-dark");
11962
- const [copied, setCopied] = useState28(false);
11918
+ const [copied, setCopied] = useState29(false);
11963
11919
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
11964
- const [glossaryOpen, setGlossaryOpen] = useState28(false);
11965
- const [detailsExpanded, setDetailsExpanded] = useState28(false);
11966
- const [depositsModalOpen, setDepositsModalOpen] = useState28(false);
11920
+ const [glossaryOpen, setGlossaryOpen] = useState29(false);
11921
+ const [detailsExpanded, setDetailsExpanded] = useState29(false);
11922
+ const [depositsModalOpen, setDepositsModalOpen] = useState29(false);
11967
11923
  const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(publishableKey, {
11968
11924
  destination_token_address: destinationTokenAddress,
11969
11925
  destination_chain_id: destinationChainId,
@@ -12034,7 +11990,7 @@ function TransferCryptoDoubleInput({
12034
11990
  publishableKey,
12035
11991
  enabled: !!depositAddress && !!recipientAddress
12036
11992
  });
12037
- useEffect22(() => {
11993
+ useEffect23(() => {
12038
11994
  if (onExecutionsChange) {
12039
11995
  onExecutionsChange(depositExecutions);
12040
11996
  }
@@ -12377,7 +12333,7 @@ function TransferCryptoDoubleInput({
12377
12333
  }
12378
12334
 
12379
12335
  // src/components/deposits/WalletConnect.tsx
12380
- import * as React29 from "react";
12336
+ import * as React30 from "react";
12381
12337
  import { ExternalLink as ExternalLink3, Loader2 as Loader28 } from "lucide-react";
12382
12338
  import {
12383
12339
  getAddressBalances as getAddressBalances2,
@@ -13329,7 +13285,7 @@ function ReviewView({
13329
13285
  }
13330
13286
 
13331
13287
  // src/components/deposits/browser-wallets/ConfirmingView.tsx
13332
- import { useEffect as useEffect23, useState as useState29 } from "react";
13288
+ import { useEffect as useEffect24, useState as useState30 } from "react";
13333
13289
  import { Loader2 as Loader27, CheckCircle2 as CheckCircle23 } from "lucide-react";
13334
13290
  import { Fragment as Fragment10, jsx as jsx53, jsxs as jsxs47 } from "react/jsx-runtime";
13335
13291
  var SETTLE_FALLBACK_MS = 15e3;
@@ -13345,13 +13301,13 @@ function ConfirmingView({
13345
13301
  amountReceivedUsdAtSubmission
13346
13302
  }) {
13347
13303
  const { colors: colors2, fonts, components } = useTheme();
13348
- const [fallbackSettled, setFallbackSettled] = useState29(false);
13304
+ const [fallbackSettled, setFallbackSettled] = useState30(false);
13349
13305
  const hasExecution = executions.length > 0;
13350
13306
  const isCheckoutMode = paymentIntentStatus != null;
13351
13307
  const isPaymentComplete = paymentIntentStatus === "succeeded";
13352
13308
  const amountChanged = amountReceivedUsdAtSubmission != null && amountReceivedUsd != null && amountReceivedUsd !== amountReceivedUsdAtSubmission;
13353
13309
  const piSettled = !isCheckoutMode || isPaymentComplete || amountChanged || fallbackSettled;
13354
- useEffect23(() => {
13310
+ useEffect24(() => {
13355
13311
  if (!hasExecution || piSettled) return;
13356
13312
  const timeout = setTimeout(() => setFallbackSettled(true), SETTLE_FALLBACK_MS);
13357
13313
  return () => clearTimeout(timeout);
@@ -13627,22 +13583,27 @@ function WalletConnect({
13627
13583
  productType,
13628
13584
  onBack: parentOnBack,
13629
13585
  onClose,
13586
+ canGoBack = true,
13587
+ depositWalletsLoading = false,
13630
13588
  onExecutionsChange
13631
13589
  }) {
13632
13590
  const { colors: colors2, fonts, components } = useTheme();
13633
- const walletProvidedAtMount = React29.useRef(!!initialWalletInfo && !!initialDepositWallet);
13634
- const [activeWalletInfo, setActiveWalletInfo] = React29.useState(initialWalletInfo ?? null);
13635
- const [activeDepositWallet, setActiveDepositWallet] = React29.useState(initialDepositWallet ?? null);
13591
+ const walletProvidedAtMount = React30.useRef(!!initialWalletInfo && !!initialDepositWallet);
13592
+ const [activeWalletInfo, setActiveWalletInfo] = React30.useState(initialWalletInfo ?? null);
13593
+ const [activeDepositWallet, setActiveDepositWallet] = React30.useState(initialDepositWallet ?? null);
13636
13594
  const initialView = initialWalletInfo && initialDepositWallet ? "select_token" : "select_wallet";
13637
- const [view, setView] = React29.useState(initialView);
13638
- const [isTransitioning, setIsTransitioning] = React29.useState(false);
13639
- const viewRef = React29.useRef(initialView);
13640
- const [selectedWalletDef, setSelectedWalletDef] = React29.useState(null);
13641
- const [connectingNetwork, setConnectingNetwork] = React29.useState(null);
13642
- const [walletError, setWalletError] = React29.useState(null);
13643
- const [isWalletConnecting, setIsWalletConnecting] = React29.useState(false);
13644
- const [eip6963ProviderCount, setEip6963ProviderCount] = React29.useState(0);
13645
- React29.useEffect(() => {
13595
+ const [view, setView] = React30.useState(initialView);
13596
+ const [isTransitioning, setIsTransitioning] = React30.useState(false);
13597
+ const viewRef = React30.useRef(initialView);
13598
+ const standalone = !canGoBack && !walletProvidedAtMount.current;
13599
+ const { wallet: detectedWallet, isLoading: detectingWallet } = useDetectedBrowserWallet({ enabled: standalone });
13600
+ const [autoResolved, setAutoResolved] = React30.useState(false);
13601
+ const [selectedWalletDef, setSelectedWalletDef] = React30.useState(null);
13602
+ const [connectingNetwork, setConnectingNetwork] = React30.useState(null);
13603
+ const [walletError, setWalletError] = React30.useState(null);
13604
+ const [isWalletConnecting, setIsWalletConnecting] = React30.useState(false);
13605
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React30.useState(0);
13606
+ React30.useEffect(() => {
13646
13607
  const store = getEip6963Store();
13647
13608
  if (!store) return;
13648
13609
  setEip6963ProviderCount(store.getProviders().length);
@@ -13650,20 +13611,44 @@ function WalletConnect({
13650
13611
  setEip6963ProviderCount(providers.length);
13651
13612
  });
13652
13613
  }, []);
13653
- const availableWallets = React29.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13654
- const [balances, setBalances] = React29.useState([]);
13655
- const [isLoading, setIsLoading] = React29.useState(false);
13656
- const [selectedBalance, setSelectedBalance] = React29.useState(null);
13657
- const [totalBalanceUsd, setTotalBalanceUsd] = React29.useState(null);
13658
- const [error, setError] = React29.useState(null);
13659
- const [isDisconnectingWallet, setIsDisconnectingWallet] = React29.useState(false);
13660
- const [amountUsd, setAmountUsd] = React29.useState(prefillAmountUsd ?? "");
13661
- const [isConfirming, setIsConfirming] = React29.useState(false);
13662
- const [hasSignedTransaction, setHasSignedTransaction] = React29.useState(false);
13663
- const [tokenChainDetails, setTokenChainDetails] = React29.useState(null);
13664
- const [loadingTokenDetails, setLoadingTokenDetails] = React29.useState(false);
13665
- const [showTransactionDetails, setShowTransactionDetails] = React29.useState(false);
13666
- const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React29.useState(null);
13614
+ const availableWallets = React30.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13615
+ React30.useEffect(() => {
13616
+ if (!standalone || autoResolved || detectingWallet) return;
13617
+ if (!detectedWallet) {
13618
+ setAutoResolved(true);
13619
+ return;
13620
+ }
13621
+ const wct = detectedWallet.type === "phantom-solana" || detectedWallet.type === "solflare" || detectedWallet.type === "backpack" || detectedWallet.type === "glow" ? "solana" : "ethereum";
13622
+ const matching = depositWallets?.find((w) => w.chain_type === wct);
13623
+ if (!matching) {
13624
+ if (!depositWalletsLoading) setAutoResolved(true);
13625
+ return;
13626
+ }
13627
+ setActiveWalletInfo(detectedWallet);
13628
+ setActiveDepositWallet(matching);
13629
+ onWalletConnected?.(detectedWallet, matching);
13630
+ setView("select_token");
13631
+ viewRef.current = "select_token";
13632
+ setAutoResolved(true);
13633
+ }, [standalone, autoResolved, detectingWallet, detectedWallet, depositWallets, depositWalletsLoading]);
13634
+ React30.useEffect(() => {
13635
+ if (!standalone || autoResolved) return;
13636
+ const t12 = setTimeout(() => setAutoResolved(true), 5e3);
13637
+ return () => clearTimeout(t12);
13638
+ }, [standalone, autoResolved]);
13639
+ const [balances, setBalances] = React30.useState([]);
13640
+ const [isLoading, setIsLoading] = React30.useState(false);
13641
+ const [selectedBalance, setSelectedBalance] = React30.useState(null);
13642
+ const [totalBalanceUsd, setTotalBalanceUsd] = React30.useState(null);
13643
+ const [error, setError] = React30.useState(null);
13644
+ const [isDisconnectingWallet, setIsDisconnectingWallet] = React30.useState(false);
13645
+ const [amountUsd, setAmountUsd] = React30.useState(prefillAmountUsd ?? "");
13646
+ const [isConfirming, setIsConfirming] = React30.useState(false);
13647
+ const [hasSignedTransaction, setHasSignedTransaction] = React30.useState(false);
13648
+ const [tokenChainDetails, setTokenChainDetails] = React30.useState(null);
13649
+ const [loadingTokenDetails, setLoadingTokenDetails] = React30.useState(false);
13650
+ const [showTransactionDetails, setShowTransactionDetails] = React30.useState(false);
13651
+ const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React30.useState(null);
13667
13652
  const walletInfo = activeWalletInfo;
13668
13653
  const depositWallet = activeDepositWallet;
13669
13654
  const hasWallet = !!activeWalletInfo && !!activeDepositWallet;
@@ -13671,7 +13656,7 @@ function WalletConnect({
13671
13656
  const recipientAddress = activeDepositWallet?.address ?? "";
13672
13657
  const isCheckoutMode = !!checkoutAmountUsd;
13673
13658
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
13674
- const transitionTo = React29.useCallback((nextView) => {
13659
+ const transitionTo = React30.useCallback((nextView) => {
13675
13660
  if (nextView === viewRef.current) return;
13676
13661
  setIsTransitioning(true);
13677
13662
  setTimeout(() => {
@@ -13808,7 +13793,7 @@ function WalletConnect({
13808
13793
  }
13809
13794
  };
13810
13795
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
13811
- const effectiveDestinationAmount = React29.useMemo(() => {
13796
+ const effectiveDestinationAmount = React30.useMemo(() => {
13812
13797
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
13813
13798
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
13814
13799
  const remaining = BigInt(checkoutRemainingBaseUnits);
@@ -13836,7 +13821,7 @@ function WalletConnect({
13836
13821
  stablecoinParity,
13837
13822
  enabled: isCheckoutMode && !!selectedToken && !!checkoutDestination && effectiveDestinationAmount !== "0"
13838
13823
  });
13839
- const activeCheckoutQuote = React29.useMemo(() => {
13824
+ const activeCheckoutQuote = React30.useMemo(() => {
13840
13825
  if (!isCheckoutMode) return null;
13841
13826
  if (walletCheckoutQuote) return { sourceAmount: walletCheckoutQuote.source_amount, sourceTokenDecimals: walletCheckoutQuote.source_token_decimals, sourceTokenSymbol: walletCheckoutQuote.source_token_symbol, sourceAmountUsd: walletCheckoutQuote.source_amount_usd, slippageBufferPercent: walletCheckoutQuote.slippage_buffer_percent ?? null };
13842
13827
  return checkoutQuote ?? null;
@@ -13850,19 +13835,19 @@ function WalletConnect({
13850
13835
  onDepositSuccess,
13851
13836
  onDepositError
13852
13837
  });
13853
- React29.useEffect(() => {
13838
+ React30.useEffect(() => {
13854
13839
  onExecutionsChange?.(depositExecutions);
13855
13840
  }, [depositExecutions, onExecutionsChange]);
13856
- React29.useEffect(() => {
13841
+ React30.useEffect(() => {
13857
13842
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
13858
13843
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
13859
13844
  const currentAmount = parseFloat(amountUsd) || 0;
13860
13845
  if (currentAmount > 0 && currentAmount < minDeposit) setAmountUsd(minDeposit.toFixed(2));
13861
13846
  }, [tokenChainDetails, view, prefillAmountUsd]);
13862
- React29.useEffect(() => {
13847
+ React30.useEffect(() => {
13863
13848
  if (view === "review") setShowTransactionDetails(false);
13864
13849
  }, [view]);
13865
- React29.useEffect(() => {
13850
+ React30.useEffect(() => {
13866
13851
  if (view !== "enter_amount" && view !== "review" || !selectedBalance || !activeDepositWallet) return;
13867
13852
  let cancelled = false;
13868
13853
  const fetchTokenDetails = async () => {
@@ -13889,7 +13874,7 @@ function WalletConnect({
13889
13874
  cancelled = true;
13890
13875
  };
13891
13876
  }, [view, selectedBalance, publishableKey, activeDepositWallet]);
13892
- React29.useEffect(() => {
13877
+ React30.useEffect(() => {
13893
13878
  if (!activeWalletInfo || !activeDepositWallet) return;
13894
13879
  let cancelled = false;
13895
13880
  setIsLoading(true);
@@ -13922,20 +13907,20 @@ function WalletConnect({
13922
13907
  cancelled = true;
13923
13908
  };
13924
13909
  }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
13925
- const usdToTokenRate = React29.useMemo(() => {
13910
+ const usdToTokenRate = React30.useMemo(() => {
13926
13911
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
13927
13912
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
13928
13913
  const balanceUsd = parseFloat(selectedBalance.amount_usd);
13929
13914
  if (balanceAmount === 0 || balanceUsd === 0) return 0;
13930
13915
  return balanceAmount / balanceUsd;
13931
13916
  }, [selectedBalance, selectedToken]);
13932
- const tokenAmount = React29.useMemo(() => {
13917
+ const tokenAmount = React30.useMemo(() => {
13933
13918
  if (isCheckoutMode && activeCheckoutQuote && selectedToken) return Number(activeCheckoutQuote.sourceAmount) / 10 ** activeCheckoutQuote.sourceTokenDecimals;
13934
13919
  const usdNum = parseFloat(amountUsd) || 0;
13935
13920
  if (usdNum === 0 || usdToTokenRate === 0) return 0;
13936
13921
  return usdNum * usdToTokenRate;
13937
13922
  }, [amountUsd, usdToTokenRate, isCheckoutMode, activeCheckoutQuote, selectedToken]);
13938
- React29.useEffect(() => {
13923
+ React30.useEffect(() => {
13939
13924
  if (isCheckoutMode && activeCheckoutQuote?.sourceAmountUsd && view === "enter_amount") setAmountUsd(activeCheckoutQuote.sourceAmountUsd);
13940
13925
  }, [isCheckoutMode, activeCheckoutQuote, view]);
13941
13926
  const maxTokenAmount = selectedBalance && selectedToken ? Number(selectedBalance.amount) / 10 ** selectedToken.decimals : 0;
@@ -13943,7 +13928,7 @@ function WalletConnect({
13943
13928
  const inputUsdNum = parseFloat(amountUsd) || 0;
13944
13929
  const minDepositUsd = tokenChainDetails?.minimum_deposit_amount_usd || 0;
13945
13930
  const isValidAmount = isCheckoutMode && activeCheckoutQuote ? tokenAmount > 0 && tokenAmount <= maxTokenAmount : inputUsdNum > 0 && inputUsdNum <= maxUsdAmount && inputUsdNum >= minDepositUsd;
13946
- const formattedTokenAmount = React29.useMemo(() => {
13931
+ const formattedTokenAmount = React30.useMemo(() => {
13947
13932
  if (tokenAmount === 0 || !selectedToken) return null;
13948
13933
  return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
13949
13934
  }, [tokenAmount, selectedToken]);
@@ -13991,16 +13976,25 @@ function WalletConnect({
13991
13976
  } catch (err) {
13992
13977
  console.warn("[WalletConnect] disconnect error:", err);
13993
13978
  } finally {
13994
- setActiveWalletInfo(null);
13995
- setActiveDepositWallet(null);
13996
- setSelectedBalance(null);
13997
- setBalances([]);
13998
- setTotalBalanceUsd(null);
13999
- setAmountUsd(prefillAmountUsd ?? "");
14000
- setError(null);
14001
13979
  setIsDisconnectingWallet(false);
14002
- if (onWalletDisconnect) onWalletDisconnect();
14003
- else parentOnBack?.();
13980
+ const clearWalletState = () => {
13981
+ setActiveWalletInfo(null);
13982
+ setActiveDepositWallet(null);
13983
+ setSelectedBalance(null);
13984
+ setBalances([]);
13985
+ setTotalBalanceUsd(null);
13986
+ setAmountUsd(prefillAmountUsd ?? "");
13987
+ setError(null);
13988
+ };
13989
+ if (standalone) {
13990
+ onWalletDisconnect?.();
13991
+ transitionTo("select_wallet");
13992
+ setTimeout(clearWalletState, 160);
13993
+ } else {
13994
+ clearWalletState();
13995
+ if (onWalletDisconnect) onWalletDisconnect();
13996
+ else parentOnBack?.();
13997
+ }
14004
13998
  }
14005
13999
  };
14006
14000
  const handleReview = () => {
@@ -14126,9 +14120,15 @@ function WalletConnect({
14126
14120
  setIsConfirming(false);
14127
14121
  }
14128
14122
  };
14123
+ if (standalone && !autoResolved) {
14124
+ return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14125
+ /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14126
+ /* @__PURE__ */ jsx54("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: /* @__PURE__ */ jsx54(Loader28, { className: "uf-w-8 uf-h-8 uf-animate-spin", style: { color: colors2.primary } }) })
14127
+ ] });
14128
+ }
14129
14129
  if (view === "select_wallet") {
14130
14130
  return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14131
- /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: true, onBack: handleBack, onClose }),
14131
+ /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14132
14132
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
14133
14133
  /* @__PURE__ */ jsx54("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Select a wallet to connect" }),
14134
14134
  /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ jsxs48(
@@ -14259,6 +14259,7 @@ function DepositModal({
14259
14259
  destinationChainType,
14260
14260
  destinationChainId,
14261
14261
  destinationTokenAddress,
14262
+ contractCalls,
14262
14263
  defaultSourceChainType,
14263
14264
  defaultSourceChainId,
14264
14265
  defaultSourceTokenAddress,
@@ -14293,45 +14294,56 @@ function DepositModal({
14293
14294
  if (s === "tracker" && hideDepositTracker) return "main";
14294
14295
  if (s === "cashapp" && !enableCashApp) return "main";
14295
14296
  if (s === "card" && enableFiatOnramp === false) return "main";
14297
+ if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
14298
+ if (s === "exchange_connect") return enableConnectExchange ? "coinbase_connect" : "main";
14299
+ if (s === "wallet_connect") return enableConnectWallet ? "wallet_connect" : "main";
14296
14300
  return s;
14297
- }, [initialScreen, hideDepositTracker, enableCashApp, enableFiatOnramp]);
14298
- const [containerEl, setContainerEl] = useState31(null);
14301
+ }, [
14302
+ initialScreen,
14303
+ hideDepositTracker,
14304
+ enableCashApp,
14305
+ enableFiatOnramp,
14306
+ enablePayWithExchange,
14307
+ enableConnectExchange,
14308
+ enableConnectWallet
14309
+ ]);
14310
+ const [containerEl, setContainerEl] = useState32(null);
14299
14311
  const containerCallbackRef = useCallback5((el) => {
14300
14312
  setContainerEl(el);
14301
14313
  }, []);
14302
- const [view, setView] = useState31(
14314
+ const [view, setView] = useState32(
14303
14315
  effectiveInitialScreen
14304
14316
  );
14305
- const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = useState31(false);
14306
- const resetViewTimeoutRef = useRef8(null);
14307
- const [cardView, setCardView] = useState31(
14317
+ const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = useState32(false);
14318
+ const resetViewTimeoutRef = useRef9(null);
14319
+ const [cardView, setCardView] = useState32(
14308
14320
  "amount"
14309
14321
  );
14310
- const [exchangeView, setExchangeView] = useState31(
14322
+ const [exchangeView, setExchangeView] = useState32(
14311
14323
  "providers"
14312
14324
  );
14313
- const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState31(false);
14314
- const [browserWalletInfo, setBrowserWalletInfo] = useState31(null);
14315
- const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState31(false);
14316
- const [browserWalletChainType, setBrowserWalletChainType] = useState31(() => getStoredWalletChainType());
14317
- const [quotesCount, setQuotesCount] = useState31(0);
14318
- const [allExecutions, setAllExecutions] = useState31([]);
14319
- const [selectedExecution, setSelectedExecution] = useState31(null);
14320
- const [depositExecutions, setDepositExecutions] = useState31([]);
14325
+ const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState32(false);
14326
+ const [browserWalletInfo, setBrowserWalletInfo] = useState32(null);
14327
+ const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState32(false);
14328
+ const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletChainType());
14329
+ const [quotesCount, setQuotesCount] = useState32(0);
14330
+ const [allExecutions, setAllExecutions] = useState32([]);
14331
+ const [selectedExecution, setSelectedExecution] = useState32(null);
14332
+ const [depositExecutions, setDepositExecutions] = useState32([]);
14321
14333
  const isMobileView = useIsMobileViewport();
14322
- const [integrationExchanges, setIntegrationExchanges] = useState31([]);
14323
- useEffect25(() => {
14334
+ const [integrationExchanges, setIntegrationExchanges] = useState32([]);
14335
+ useEffect26(() => {
14324
14336
  if (!enableConnectExchange || !open) return;
14325
14337
  getIntegrationExchanges2(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
14326
14338
  });
14327
14339
  }, [enableConnectExchange, open, publishableKey]);
14328
- const [connectedExchange, setConnectedExchange] = useState31(() => {
14340
+ const [connectedExchange, setConnectedExchange] = useState32(() => {
14329
14341
  if (!enableConnectExchange) return null;
14330
14342
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
14331
14343
  if (!stored) return null;
14332
14344
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
14333
14345
  });
14334
- useEffect25(() => {
14346
+ useEffect26(() => {
14335
14347
  if (!enableConnectExchange || !open || view !== "main") return;
14336
14348
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
14337
14349
  if (!stored) {
@@ -14368,7 +14380,7 @@ function DepositModal({
14368
14380
  }
14369
14381
  });
14370
14382
  }, [enableConnectExchange, open, view, publishableKey]);
14371
- useEffect25(() => {
14383
+ useEffect26(() => {
14372
14384
  if (!connectedExchange || integrationExchanges.length === 0) return;
14373
14385
  const cbExchange = integrationExchanges.find(
14374
14386
  (e) => e.service_provider === IntegrationProvider2.COINBASE
@@ -14385,14 +14397,15 @@ function DepositModal({
14385
14397
  destinationChainType,
14386
14398
  destinationChainId,
14387
14399
  destinationTokenAddress,
14400
+ contractCalls,
14388
14401
  enabled: open
14389
14402
  // Only fetch when modal is open
14390
14403
  });
14391
14404
  const wallets = depositAddressResponse?.data ?? [];
14392
- const [resolvedTheme, setResolvedTheme] = useState31(
14405
+ const [resolvedTheme, setResolvedTheme] = useState32(
14393
14406
  theme === "auto" ? "dark" : theme
14394
14407
  );
14395
- useEffect25(() => {
14408
+ useEffect26(() => {
14396
14409
  if (theme === "auto") {
14397
14410
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
14398
14411
  setResolvedTheme(mediaQuery.matches ? "dark" : "light");
@@ -14411,12 +14424,18 @@ function DepositModal({
14411
14424
  });
14412
14425
  const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14413
14426
  const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14414
- useEffect25(() => {
14427
+ useEffect26(() => {
14415
14428
  if (view === "card" && !showFiatOnramp) {
14416
14429
  setView("main");
14417
14430
  setCardView("amount");
14418
14431
  }
14419
14432
  }, [view, showFiatOnramp]);
14433
+ useEffect26(() => {
14434
+ if (view === "exchange" && !showPayWithExchange) {
14435
+ setView("main");
14436
+ setExchangeView("providers");
14437
+ }
14438
+ }, [view, showPayWithExchange]);
14420
14439
  const { exchanges, isLoading: exchangesLoading } = useExchanges({
14421
14440
  publishableKey,
14422
14441
  enabled: open && showPayWithExchange
@@ -14431,7 +14450,7 @@ function DepositModal({
14431
14450
  subdivisionCode: userIpInfo?.subdivisionCode ?? void 0,
14432
14451
  enabled: open && !isLoadingIp
14433
14452
  });
14434
- useEffect25(() => {
14453
+ useEffect26(() => {
14435
14454
  if (view !== "tracker" || !userId) return;
14436
14455
  const fetchExecutions = async () => {
14437
14456
  try {
@@ -14452,7 +14471,7 @@ function DepositModal({
14452
14471
  clearInterval(pollInterval);
14453
14472
  };
14454
14473
  }, [view, userId, publishableKey]);
14455
- useEffect25(() => {
14474
+ useEffect26(() => {
14456
14475
  if (view !== "tracker") {
14457
14476
  setSelectedExecution(null);
14458
14477
  }
@@ -14536,7 +14555,7 @@ function DepositModal({
14536
14555
  setBrowserWalletChainType(void 0);
14537
14556
  setBrowserWalletInfo(null);
14538
14557
  setBrowserWalletModalOpen(false);
14539
- if (view === "wallet_connect") setView("main");
14558
+ if (view === "wallet_connect" && sessionOpenedFromMenu) setView("main");
14540
14559
  };
14541
14560
  const handleExchangeDisconnect = () => {
14542
14561
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
@@ -14545,7 +14564,7 @@ function DepositModal({
14545
14564
  }
14546
14565
  clearStoredIntegrationToken(IntegrationProvider2.COINBASE);
14547
14566
  setConnectedExchange(null);
14548
- if (view === "coinbase_connect") setView("main");
14567
+ if (view === "coinbase_connect" && sessionOpenedFromMenu) setView("main");
14549
14568
  };
14550
14569
  const handleClose = () => {
14551
14570
  onOpenChange(false);
@@ -14557,6 +14576,7 @@ function DepositModal({
14557
14576
  setCardView("amount");
14558
14577
  setExchangeView("providers");
14559
14578
  setBrowserWalletInfo(null);
14579
+ setCoinbaseSkipToHoldings(false);
14560
14580
  resetViewTimeoutRef.current = null;
14561
14581
  }, 200);
14562
14582
  };
@@ -14571,8 +14591,9 @@ function DepositModal({
14571
14591
  setExchangeView("providers");
14572
14592
  setBrowserWalletInfo(null);
14573
14593
  setSelectedExecution(null);
14594
+ setCoinbaseSkipToHoldings(false);
14574
14595
  }, [open, effectiveInitialScreen]);
14575
- useEffect25(
14596
+ useEffect26(
14576
14597
  () => () => {
14577
14598
  if (resetViewTimeoutRef.current) {
14578
14599
  clearTimeout(resetViewTimeoutRef.current);
@@ -14580,8 +14601,8 @@ function DepositModal({
14580
14601
  },
14581
14602
  []
14582
14603
  );
14583
- const [cashAppView, setCashAppView] = useState31("amount");
14584
- const [cashAppAmount, setCashAppAmount] = useState31("");
14604
+ const [cashAppView, setCashAppView] = useState32("amount");
14605
+ const [cashAppAmount, setCashAppAmount] = useState32("");
14585
14606
  const handleBack = () => {
14586
14607
  if (view === "card" && cardView === "quotes") {
14587
14608
  setCardView("amount");
@@ -14930,7 +14951,7 @@ function DepositModal({
14930
14951
  DepositHeader,
14931
14952
  {
14932
14953
  title: payWithExchangeTitle,
14933
- showBack: true,
14954
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
14934
14955
  onBack: handleBack,
14935
14956
  onClose: handleClose
14936
14957
  }
@@ -14984,6 +15005,7 @@ function DepositModal({
14984
15005
  onClose: handleClose,
14985
15006
  onDisconnect: handleExchangeDisconnect,
14986
15007
  skipToHoldings: coinbaseSkipToHoldings,
15008
+ canGoBack: sessionOpenedFromMenu,
14987
15009
  onExecutionsChange: setDepositExecutions
14988
15010
  }
14989
15011
  ),
@@ -15021,7 +15043,9 @@ function DepositModal({
15021
15043
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15022
15044
  },
15023
15045
  onBack: handleBack,
15024
- onClose: handleClose
15046
+ onClose: handleClose,
15047
+ canGoBack: sessionOpenedFromMenu,
15048
+ depositWalletsLoading: walletsLoading
15025
15049
  }
15026
15050
  ),
15027
15051
  depositPoweredByFooter
@@ -15030,7 +15054,7 @@ function DepositModal({
15030
15054
  DepositHeader,
15031
15055
  {
15032
15056
  title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15033
- showBack: true,
15057
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15034
15058
  onBack: handleBack,
15035
15059
  onClose: handleClose
15036
15060
  }
@@ -15065,11 +15089,11 @@ function DepositModal({
15065
15089
 
15066
15090
  // src/components/checkout/CheckoutModal.tsx
15067
15091
  import {
15068
- useState as useState32,
15069
- useEffect as useEffect26,
15092
+ useState as useState33,
15093
+ useEffect as useEffect27,
15070
15094
  useLayoutEffect as useLayoutEffect3,
15071
15095
  useCallback as useCallback6,
15072
- useRef as useRef9,
15096
+ useRef as useRef10,
15073
15097
  useMemo as useMemo11
15074
15098
  } from "react";
15075
15099
  import { AlertTriangle as AlertTriangle3, ChevronRight as ChevronRight15 } from "lucide-react";
@@ -15150,19 +15174,19 @@ function CheckoutModal({
15150
15174
  onCheckoutError
15151
15175
  }) {
15152
15176
  const { colors: colors2, fonts, components } = useTheme();
15153
- const [view, setView] = useState32("main");
15154
- const resetViewTimeoutRef = useRef9(
15177
+ const [view, setView] = useState33("main");
15178
+ const resetViewTimeoutRef = useRef10(
15155
15179
  null
15156
15180
  );
15157
- const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState32(false);
15158
- const [browserWalletInfo, setBrowserWalletInfo] = useState32(null);
15159
- const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState32(false);
15160
- const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletChainType());
15181
+ const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState33(false);
15182
+ const [browserWalletInfo, setBrowserWalletInfo] = useState33(null);
15183
+ const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState33(false);
15184
+ const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletChainType());
15161
15185
  const isMobileView = useIsMobileViewport();
15162
- const [resolvedTheme, setResolvedTheme] = useState32(
15186
+ const [resolvedTheme, setResolvedTheme] = useState33(
15163
15187
  theme === "auto" ? "dark" : theme
15164
15188
  );
15165
- useEffect26(() => {
15189
+ useEffect27(() => {
15166
15190
  if (theme === "auto") {
15167
15191
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
15168
15192
  setResolvedTheme(mediaQuery.matches ? "dark" : "light");
@@ -15190,8 +15214,8 @@ function CheckoutModal({
15190
15214
  publishableKey,
15191
15215
  enabled: open
15192
15216
  });
15193
- const prevStatusRef = useRef9(null);
15194
- useEffect26(() => {
15217
+ const prevStatusRef = useRef10(null);
15218
+ useEffect27(() => {
15195
15219
  if (!paymentIntent) return;
15196
15220
  const prev = prevStatusRef.current;
15197
15221
  prevStatusRef.current = paymentIntent.status;
@@ -15237,7 +15261,7 @@ function CheckoutModal({
15237
15261
  const remaining = total - received;
15238
15262
  return remaining > 0n ? remaining.toString() : "0";
15239
15263
  }, [paymentIntent]);
15240
- const [selectedSource, setSelectedSource] = useState32(null);
15264
+ const [selectedSource, setSelectedSource] = useState33(null);
15241
15265
  const remainingDestinationAmount = useMemo11(() => {
15242
15266
  if (!paymentIntent) return "0";
15243
15267
  const remaining = BigInt(paymentIntent.destination_amount) - BigInt(paymentIntent.destination_amount_received);
@@ -15357,7 +15381,7 @@ function CheckoutModal({
15357
15381
  setView("main");
15358
15382
  setBrowserWalletInfo(null);
15359
15383
  }, [open]);
15360
- useEffect26(
15384
+ useEffect27(
15361
15385
  () => () => {
15362
15386
  if (resetViewTimeoutRef.current) {
15363
15387
  clearTimeout(resetViewTimeoutRef.current);
@@ -15734,11 +15758,11 @@ function CheckoutModal({
15734
15758
 
15735
15759
  // src/components/withdrawals/WithdrawModal.tsx
15736
15760
  import {
15737
- useState as useState36,
15738
- useEffect as useEffect30,
15761
+ useState as useState37,
15762
+ useEffect as useEffect31,
15739
15763
  useLayoutEffect as useLayoutEffect4,
15740
15764
  useCallback as useCallback8,
15741
- useRef as useRef11
15765
+ useRef as useRef12
15742
15766
  } from "react";
15743
15767
  import { AlertTriangle as AlertTriangle5, ChevronRight as ChevronRight17, Clock as Clock6 } from "lucide-react";
15744
15768
 
@@ -15914,7 +15938,7 @@ function useExecutions(userId, publishableKey, options) {
15914
15938
  }
15915
15939
 
15916
15940
  // src/hooks/use-withdraw-polling.ts
15917
- import { useState as useState33, useEffect as useEffect27, useRef as useRef10 } from "react";
15941
+ import { useState as useState34, useEffect as useEffect28, useRef as useRef11 } from "react";
15918
15942
  import {
15919
15943
  queryExecutions as queryExecutions5,
15920
15944
  pollDirectExecutions as pollDirectExecutions2,
@@ -15932,20 +15956,20 @@ function useWithdrawPolling({
15932
15956
  onWithdrawSuccess,
15933
15957
  onWithdrawError
15934
15958
  }) {
15935
- const [executions, setExecutions] = useState33([]);
15936
- const [isPolling, setIsPolling] = useState33(false);
15937
- const enabledAtRef = useRef10(/* @__PURE__ */ new Date());
15938
- const trackedRef = useRef10(/* @__PURE__ */ new Map());
15939
- const prevEnabledRef = useRef10(false);
15940
- const onSuccessRef = useRef10(onWithdrawSuccess);
15941
- const onErrorRef = useRef10(onWithdrawError);
15942
- useEffect27(() => {
15959
+ const [executions, setExecutions] = useState34([]);
15960
+ const [isPolling, setIsPolling] = useState34(false);
15961
+ const enabledAtRef = useRef11(/* @__PURE__ */ new Date());
15962
+ const trackedRef = useRef11(/* @__PURE__ */ new Map());
15963
+ const prevEnabledRef = useRef11(false);
15964
+ const onSuccessRef = useRef11(onWithdrawSuccess);
15965
+ const onErrorRef = useRef11(onWithdrawError);
15966
+ useEffect28(() => {
15943
15967
  onSuccessRef.current = onWithdrawSuccess;
15944
15968
  }, [onWithdrawSuccess]);
15945
- useEffect27(() => {
15969
+ useEffect28(() => {
15946
15970
  onErrorRef.current = onWithdrawError;
15947
15971
  }, [onWithdrawError]);
15948
- useEffect27(() => {
15972
+ useEffect28(() => {
15949
15973
  if (enabled && !prevEnabledRef.current) {
15950
15974
  enabledAtRef.current = /* @__PURE__ */ new Date();
15951
15975
  trackedRef.current.clear();
@@ -15955,7 +15979,7 @@ function useWithdrawPolling({
15955
15979
  }
15956
15980
  prevEnabledRef.current = enabled;
15957
15981
  }, [enabled]);
15958
- useEffect27(() => {
15982
+ useEffect28(() => {
15959
15983
  if (!userId || !enabled) return;
15960
15984
  const enabledAt = enabledAtRef.current;
15961
15985
  const poll = async () => {
@@ -16017,7 +16041,7 @@ function useWithdrawPolling({
16017
16041
  setIsPolling(false);
16018
16042
  };
16019
16043
  }, [userId, publishableKey, enabled]);
16020
- useEffect27(() => {
16044
+ useEffect28(() => {
16021
16045
  if (!enabled || !depositWalletId) return;
16022
16046
  const trigger = async () => {
16023
16047
  try {
@@ -16188,7 +16212,7 @@ function WithdrawDoubleInput({
16188
16212
  }
16189
16213
 
16190
16214
  // src/components/withdrawals/WithdrawForm.tsx
16191
- import { useState as useState34, useCallback as useCallback7, useMemo as useMemo13, useEffect as useEffect28 } from "react";
16215
+ import { useState as useState35, useCallback as useCallback7, useMemo as useMemo13, useEffect as useEffect29 } from "react";
16192
16216
  import {
16193
16217
  AlertTriangle as AlertTriangle4,
16194
16218
  ArrowUpDown,
@@ -16665,27 +16689,27 @@ function WithdrawForm({
16665
16689
  footerLeft
16666
16690
  }) {
16667
16691
  const { colors: colors2, fonts, components } = useTheme();
16668
- const [recipientAddress, setRecipientAddress] = useState34(recipientAddressProp || "");
16669
- const [amount, setAmount] = useState34("");
16670
- const [inputUnit, setInputUnit] = useState34("fiat");
16671
- const [isSubmitting, setIsSubmitting] = useState34(false);
16672
- const [submitError, setSubmitError] = useState34(null);
16673
- const [detailsExpanded, setDetailsExpanded] = useState34(false);
16674
- const [glossaryOpen, setGlossaryOpen] = useState34(false);
16675
- const [isMaxed, setIsMaxed] = useState34(false);
16676
- useEffect28(() => {
16692
+ const [recipientAddress, setRecipientAddress] = useState35(recipientAddressProp || "");
16693
+ const [amount, setAmount] = useState35("");
16694
+ const [inputUnit, setInputUnit] = useState35("fiat");
16695
+ const [isSubmitting, setIsSubmitting] = useState35(false);
16696
+ const [submitError, setSubmitError] = useState35(null);
16697
+ const [detailsExpanded, setDetailsExpanded] = useState35(false);
16698
+ const [glossaryOpen, setGlossaryOpen] = useState35(false);
16699
+ const [isMaxed, setIsMaxed] = useState35(false);
16700
+ useEffect29(() => {
16677
16701
  setRecipientAddress(recipientAddressProp || "");
16678
16702
  setAmount("");
16679
16703
  setInputUnit("fiat");
16680
16704
  setSubmitError(null);
16681
16705
  setIsMaxed(false);
16682
16706
  }, [recipientAddressProp]);
16683
- useEffect28(() => {
16707
+ useEffect29(() => {
16684
16708
  setIsMaxed(false);
16685
16709
  }, [balanceData?.balanceBaseUnit]);
16686
16710
  const trimmedAddress = recipientAddress.trim();
16687
- const [debouncedAddress, setDebouncedAddress] = useState34(trimmedAddress);
16688
- useEffect28(() => {
16711
+ const [debouncedAddress, setDebouncedAddress] = useState35(trimmedAddress);
16712
+ useEffect29(() => {
16689
16713
  const id = setTimeout(() => setDebouncedAddress(trimmedAddress), 500);
16690
16714
  return () => clearTimeout(id);
16691
16715
  }, [trimmedAddress]);
@@ -17325,7 +17349,7 @@ function WithdrawExecutionItem({
17325
17349
  }
17326
17350
 
17327
17351
  // src/components/withdrawals/WithdrawConfirmingView.tsx
17328
- import { useState as useState35, useEffect as useEffect29 } from "react";
17352
+ import { useState as useState36, useEffect as useEffect30 } from "react";
17329
17353
  import { Fragment as Fragment14, jsx as jsx60, jsxs as jsxs54 } from "react/jsx-runtime";
17330
17354
  function truncateAddress4(addr) {
17331
17355
  if (addr.length <= 12) return addr;
@@ -17339,9 +17363,9 @@ function WithdrawConfirmingView({
17339
17363
  onViewTracker
17340
17364
  }) {
17341
17365
  const { colors: colors2, fonts, components } = useTheme();
17342
- const [showButton, setShowButton] = useState35(false);
17366
+ const [showButton, setShowButton] = useState36(false);
17343
17367
  const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
17344
- useEffect29(() => {
17368
+ useEffect30(() => {
17345
17369
  if (latestExecution) return;
17346
17370
  const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
17347
17371
  return () => clearTimeout(timer);
@@ -17506,14 +17530,14 @@ function WithdrawModal({
17506
17530
  hideOverlay = false
17507
17531
  }) {
17508
17532
  const { colors: colors2, fonts, components } = useTheme();
17509
- const [containerEl, setContainerEl] = useState36(null);
17533
+ const [containerEl, setContainerEl] = useState37(null);
17510
17534
  const containerCallbackRef = useCallback8((el) => {
17511
17535
  setContainerEl(el);
17512
17536
  }, []);
17513
- const [resolvedTheme, setResolvedTheme] = useState36(
17537
+ const [resolvedTheme, setResolvedTheme] = useState37(
17514
17538
  theme === "auto" ? "dark" : theme
17515
17539
  );
17516
- useEffect30(() => {
17540
+ useEffect31(() => {
17517
17541
  if (theme === "auto") {
17518
17542
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
17519
17543
  setResolvedTheme(mq.matches ? "dark" : "light");
@@ -17557,10 +17581,10 @@ function WithdrawModal({
17557
17581
  });
17558
17582
  const selectedToken = selectedTokenSymbol ? destinationTokens.find((t12) => t12.symbol === selectedTokenSymbol) ?? null : null;
17559
17583
  const selectedChain = selectedToken && selectedChainKey ? selectedToken.chains.find((c) => getChainKey5(c.chain_id, c.chain_type) === selectedChainKey) ?? null : null;
17560
- const [view, setView] = useState36("form");
17561
- const [withdrawDepositWalletId, setWithdrawDepositWalletId] = useState36();
17562
- const [selectedExecution, setSelectedExecution] = useState36(null);
17563
- const [submittedTxInfo, setSubmittedTxInfo] = useState36(null);
17584
+ const [view, setView] = useState37("form");
17585
+ const [withdrawDepositWalletId, setWithdrawDepositWalletId] = useState37();
17586
+ const [selectedExecution, setSelectedExecution] = useState37(null);
17587
+ const [submittedTxInfo, setSubmittedTxInfo] = useState37(null);
17564
17588
  const { executions: realtimeExecutions } = useWithdrawPolling({
17565
17589
  userId: externalUserId,
17566
17590
  publishableKey,
@@ -17599,7 +17623,7 @@ function WithdrawModal({
17599
17623
  setSubmittedTxInfo(txInfo);
17600
17624
  setView("confirming");
17601
17625
  }, []);
17602
- const resetViewTimeoutRef = useRef11(null);
17626
+ const resetViewTimeoutRef = useRef12(null);
17603
17627
  const handleClose = useCallback8(() => {
17604
17628
  onOpenChange(false);
17605
17629
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
@@ -17622,7 +17646,7 @@ function WithdrawModal({
17622
17646
  setSubmittedTxInfo(null);
17623
17647
  setWithdrawDepositWalletId(void 0);
17624
17648
  }, [open]);
17625
- useEffect30(() => () => {
17649
+ useEffect31(() => () => {
17626
17650
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
17627
17651
  }, []);
17628
17652
  const handleTokenSymbolChange = useCallback8((symbol) => {
@@ -17745,7 +17769,7 @@ function WithdrawModal({
17745
17769
  }
17746
17770
 
17747
17771
  // src/components/withdrawals/WithdrawTokenSelector.tsx
17748
- import { useState as useState37, useMemo as useMemo14 } from "react";
17772
+ import { useState as useState38, useMemo as useMemo14 } from "react";
17749
17773
  import { Search } from "lucide-react";
17750
17774
  import Fuse2 from "fuse.js";
17751
17775
  import { jsx as jsx62, jsxs as jsxs56 } from "react/jsx-runtime";
@@ -17756,8 +17780,8 @@ function WithdrawTokenSelector({
17756
17780
  onBack
17757
17781
  }) {
17758
17782
  const { themeClass, colors: colors2, fonts, components } = useTheme();
17759
- const [searchQuery, setSearchQuery] = useState37("");
17760
- const [hoveredKey, setHoveredKey] = useState37(null);
17783
+ const [searchQuery, setSearchQuery] = useState38("");
17784
+ const [hoveredKey, setHoveredKey] = useState38(null);
17761
17785
  const allOptions = useMemo14(() => {
17762
17786
  const options = [];
17763
17787
  tokens.forEach((token) => {