@unifold/ui-react 0.1.61 → 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";
@@ -5252,7 +5252,7 @@ function CashAppButton({
5252
5252
  }
5253
5253
 
5254
5254
  // src/components/deposits/buttons/BrowserWalletButton.tsx
5255
- import * as React24 from "react";
5255
+ import * as React25 from "react";
5256
5256
  import { Wallet, ChevronRight as ChevronRight10, Loader2 as Loader23 } from "lucide-react";
5257
5257
  import { getAddressBalances } from "@unifold/core";
5258
5258
 
@@ -5306,6 +5306,197 @@ function collectAllEip6963EthProviders() {
5306
5306
  return store.getProviders().map((d) => d.provider);
5307
5307
  }
5308
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
+
5309
5500
  // src/components/deposits/browser-wallets/disconnectInjectedBrowserWallet.ts
5310
5501
  var SOLANA_DISCONNECT_TYPES = [
5311
5502
  "phantom-solana",
@@ -5391,14 +5582,14 @@ async function disconnectInjectedBrowserWallet(wallet) {
5391
5582
  }
5392
5583
 
5393
5584
  // src/resources/icons/MetamaskIcon.tsx
5394
- import * as React12 from "react";
5585
+ import * as React13 from "react";
5395
5586
  import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
5396
5587
  function MetamaskIcon({
5397
5588
  size = 24,
5398
5589
  className,
5399
5590
  variant = "color"
5400
5591
  }) {
5401
- const id = React12.useId();
5592
+ const id = React13.useId();
5402
5593
  if (variant === "light" || variant === "dark") {
5403
5594
  return /* @__PURE__ */ jsxs20(
5404
5595
  "svg",
@@ -5520,14 +5711,14 @@ function MetamaskIcon({
5520
5711
  }
5521
5712
 
5522
5713
  // src/resources/icons/PhantomIcon.tsx
5523
- import * as React13 from "react";
5714
+ import * as React14 from "react";
5524
5715
  import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
5525
5716
  function PhantomIcon({
5526
5717
  size = 24,
5527
5718
  className,
5528
5719
  variant = "color"
5529
5720
  }) {
5530
- const id = React13.useId();
5721
+ const id = React14.useId();
5531
5722
  if (variant === "light") {
5532
5723
  return /* @__PURE__ */ jsx24(
5533
5724
  "svg",
@@ -5595,14 +5786,14 @@ function PhantomIcon({
5595
5786
  }
5596
5787
 
5597
5788
  // src/resources/icons/CoinbaseIcon.tsx
5598
- import * as React14 from "react";
5789
+ import * as React15 from "react";
5599
5790
  import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
5600
5791
  function CoinbaseIcon({
5601
5792
  size = 24,
5602
5793
  className,
5603
5794
  variant = "color"
5604
5795
  }) {
5605
- const id = React14.useId();
5796
+ const id = React15.useId();
5606
5797
  if (variant === "light") {
5607
5798
  return /* @__PURE__ */ jsxs22(
5608
5799
  "svg",
@@ -5683,14 +5874,14 @@ function CoinbaseIcon({
5683
5874
  }
5684
5875
 
5685
5876
  // src/resources/icons/RabbyIcon.tsx
5686
- import * as React15 from "react";
5877
+ import * as React16 from "react";
5687
5878
  import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
5688
5879
  function RabbyIcon({
5689
5880
  size = 24,
5690
5881
  className,
5691
5882
  variant = "color"
5692
5883
  }) {
5693
- const id = React15.useId();
5884
+ const id = React16.useId();
5694
5885
  if (variant === "light") {
5695
5886
  return /* @__PURE__ */ jsxs23(
5696
5887
  "svg",
@@ -6038,14 +6229,14 @@ function RabbyIcon({
6038
6229
  }
6039
6230
 
6040
6231
  // src/resources/icons/RainbowIcon.tsx
6041
- import * as React16 from "react";
6232
+ import * as React17 from "react";
6042
6233
  import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
6043
6234
  function RainbowIcon({
6044
6235
  size = 24,
6045
6236
  className,
6046
6237
  variant = "color"
6047
6238
  }) {
6048
- const id = React16.useId();
6239
+ const id = React17.useId();
6049
6240
  if (variant === "light") {
6050
6241
  return /* @__PURE__ */ jsxs24(
6051
6242
  "svg",
@@ -6508,14 +6699,14 @@ function RainbowIcon({
6508
6699
  }
6509
6700
 
6510
6701
  // src/resources/icons/TrustIcon.tsx
6511
- import * as React17 from "react";
6702
+ import * as React18 from "react";
6512
6703
  import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
6513
6704
  function TrustIcon({
6514
6705
  size = 24,
6515
6706
  className,
6516
6707
  variant = "color"
6517
6708
  }) {
6518
- const id = React17.useId();
6709
+ const id = React18.useId();
6519
6710
  if (variant === "light") {
6520
6711
  return /* @__PURE__ */ jsx28(
6521
6712
  "svg",
@@ -6605,14 +6796,14 @@ function TrustIcon({
6605
6796
  }
6606
6797
 
6607
6798
  // src/resources/icons/OkxIcon.tsx
6608
- import * as React18 from "react";
6799
+ import * as React19 from "react";
6609
6800
  import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
6610
6801
  function OkxIcon({
6611
6802
  size = 24,
6612
6803
  className,
6613
6804
  variant = "color"
6614
6805
  }) {
6615
- const id = React18.useId();
6806
+ const id = React19.useId();
6616
6807
  if (variant === "light") {
6617
6808
  return /* @__PURE__ */ jsx29(
6618
6809
  "svg",
@@ -6680,14 +6871,14 @@ function OkxIcon({
6680
6871
  }
6681
6872
 
6682
6873
  // src/resources/icons/GlowIcon.tsx
6683
- import * as React19 from "react";
6874
+ import * as React20 from "react";
6684
6875
  import { jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
6685
6876
  function GlowIcon({
6686
6877
  size = 24,
6687
6878
  className,
6688
6879
  variant = "color"
6689
6880
  }) {
6690
- const id = React19.useId();
6881
+ const id = React20.useId();
6691
6882
  if (variant === "light") {
6692
6883
  return /* @__PURE__ */ jsx30(
6693
6884
  "svg",
@@ -6789,14 +6980,14 @@ function GlowIcon({
6789
6980
  }
6790
6981
 
6791
6982
  // src/resources/icons/BackpackIcon.tsx
6792
- import * as React20 from "react";
6983
+ import * as React21 from "react";
6793
6984
  import { jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
6794
6985
  function BackpackIcon({
6795
6986
  size = 24,
6796
6987
  className,
6797
6988
  variant = "color"
6798
6989
  }) {
6799
- const id = React20.useId();
6990
+ const id = React21.useId();
6800
6991
  if (variant === "light") {
6801
6992
  return /* @__PURE__ */ jsx31(
6802
6993
  "svg",
@@ -6870,14 +7061,14 @@ function BackpackIcon({
6870
7061
  }
6871
7062
 
6872
7063
  // src/resources/icons/SolflareIcon.tsx
6873
- import * as React21 from "react";
7064
+ import * as React22 from "react";
6874
7065
  import { jsx as jsx32, jsxs as jsxs29 } from "react/jsx-runtime";
6875
7066
  function SolflareIcon({
6876
7067
  size = 24,
6877
7068
  className,
6878
7069
  variant = "color"
6879
7070
  }) {
6880
- const id = React21.useId();
7071
+ const id = React22.useId();
6881
7072
  if (variant === "light") {
6882
7073
  return /* @__PURE__ */ jsx32(
6883
7074
  "svg",
@@ -6945,14 +7136,14 @@ function SolflareIcon({
6945
7136
  }
6946
7137
 
6947
7138
  // src/resources/icons/EthereumIcon.tsx
6948
- import * as React22 from "react";
7139
+ import * as React23 from "react";
6949
7140
  import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
6950
7141
  function EthereumIcon({
6951
7142
  size = 24,
6952
7143
  className,
6953
7144
  variant = "color"
6954
7145
  }) {
6955
- const id = React22.useId();
7146
+ const id = React23.useId();
6956
7147
  if (variant === "light") {
6957
7148
  return /* @__PURE__ */ jsxs30(
6958
7149
  "svg",
@@ -7083,14 +7274,14 @@ function EthereumIcon({
7083
7274
  }
7084
7275
 
7085
7276
  // src/resources/icons/SolanaIcon.tsx
7086
- import * as React23 from "react";
7277
+ import * as React24 from "react";
7087
7278
  import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
7088
7279
  function SolanaIcon({
7089
7280
  size = 24,
7090
7281
  className,
7091
7282
  variant = "color"
7092
7283
  }) {
7093
- const id = React23.useId();
7284
+ const id = React24.useId();
7094
7285
  if (variant === "light") {
7095
7286
  return /* @__PURE__ */ jsx34(
7096
7287
  "svg",
@@ -7345,44 +7536,6 @@ function truncateAddress3(address) {
7345
7536
  if (address.length <= 10) return address;
7346
7537
  return `${address.slice(0, 4)}...${address.slice(-4)}`;
7347
7538
  }
7348
- function identifyEthWallet(provider, _win, hint) {
7349
- switch (hint) {
7350
- case "metamask":
7351
- return { type: "metamask", name: "MetaMask", icon: "metamask" };
7352
- case "phantom":
7353
- return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
7354
- case "coinbase":
7355
- return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
7356
- case "okx":
7357
- return { type: "okx", name: "OKX Wallet", icon: "okx" };
7358
- case "rabby":
7359
- return { type: "rabby", name: "Rabby", icon: "rabby" };
7360
- case "trust":
7361
- return { type: "trust", name: "Trust Wallet", icon: "trust" };
7362
- case "rainbow":
7363
- return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
7364
- }
7365
- const anyProvider = provider;
7366
- if (provider.isPhantom) {
7367
- return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
7368
- }
7369
- if (anyProvider.isCoinbaseWallet) {
7370
- return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
7371
- }
7372
- if (anyProvider.isRabby) {
7373
- return { type: "rabby", name: "Rabby", icon: "rabby" };
7374
- }
7375
- if (anyProvider.isTrust) {
7376
- return { type: "trust", name: "Trust Wallet", icon: "trust" };
7377
- }
7378
- if (anyProvider.isRainbow) {
7379
- return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
7380
- }
7381
- if (provider.isMetaMask && !provider.isPhantom) {
7382
- return { type: "metamask", name: "MetaMask", icon: "metamask" };
7383
- }
7384
- return { type: "metamask", name: "Wallet", icon: "metamask" };
7385
- }
7386
7539
  function BrowserWalletButton({
7387
7540
  onClick,
7388
7541
  onConnectClick,
@@ -7393,30 +7546,19 @@ function BrowserWalletButton({
7393
7546
  subtitle = i18n.depositModal.browserWallet.subtitle
7394
7547
  }) {
7395
7548
  const { colors: colors2, fonts, components } = useTheme();
7396
- const [isHovered, setIsHovered] = React24.useState(false);
7397
- const [isTouchDevice, setIsTouchDevice] = React24.useState(false);
7398
- const [wallet, setWallet] = React24.useState(null);
7399
- const [isLoading, setIsLoading] = React24.useState(true);
7400
- const [isConnecting, setIsConnecting] = React24.useState(false);
7401
- const [balanceText, setBalanceText] = React24.useState(null);
7402
- const [isLoadingBalance, setIsLoadingBalance] = React24.useState(false);
7403
- const [isDisconnecting, setIsDisconnecting] = React24.useState(false);
7404
- 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);
7405
7557
  onDisconnectRef.current = onDisconnect;
7406
- React24.useEffect(() => {
7558
+ React25.useEffect(() => {
7407
7559
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7408
7560
  }, []);
7409
- const [eip6963ProviderCount, setEip6963ProviderCount] = React24.useState(0);
7410
- React24.useEffect(() => {
7411
- const store = getEip6963Store();
7412
- if (!store) return;
7413
- setEip6963ProviderCount(store.getProviders().length);
7414
- const unsubscribe = store.subscribe((providers) => {
7415
- setEip6963ProviderCount(providers.length);
7416
- });
7417
- return unsubscribe;
7418
- }, []);
7419
- React24.useEffect(() => {
7561
+ React25.useEffect(() => {
7420
7562
  if (!wallet || !publishableKey) {
7421
7563
  setBalanceText(null);
7422
7564
  return;
@@ -7457,206 +7599,6 @@ function BrowserWalletButton({
7457
7599
  cancelled = true;
7458
7600
  };
7459
7601
  }, [wallet, publishableKey]);
7460
- React24.useEffect(() => {
7461
- let mounted = true;
7462
- const detectWallet = async () => {
7463
- if (!mounted) return;
7464
- setIsLoading(true);
7465
- try {
7466
- const win = typeof window !== "undefined" ? window : null;
7467
- if (!win) return;
7468
- if (getUserDisconnectedWallet()) {
7469
- if (mounted) {
7470
- setWallet(null);
7471
- setIsLoading(false);
7472
- }
7473
- return;
7474
- }
7475
- if (!chainType || chainType === "solana") {
7476
- const anyWin = win;
7477
- const trySilentSolana = async (provider, type, name, icon) => {
7478
- if (!provider) return false;
7479
- if (provider.isConnected && provider.publicKey) {
7480
- if (mounted) {
7481
- setWallet({
7482
- type,
7483
- name,
7484
- address: provider.publicKey.toString(),
7485
- icon
7486
- });
7487
- setIsLoading(false);
7488
- }
7489
- return true;
7490
- }
7491
- try {
7492
- const resp = await provider.connect({ onlyIfTrusted: true });
7493
- if (mounted && resp.publicKey) {
7494
- setWallet({
7495
- type,
7496
- name,
7497
- address: resp.publicKey.toString(),
7498
- icon
7499
- });
7500
- setIsLoading(false);
7501
- return true;
7502
- }
7503
- } catch {
7504
- }
7505
- return false;
7506
- };
7507
- if (await trySilentSolana(
7508
- win.phantom?.solana,
7509
- "phantom-solana",
7510
- "Phantom",
7511
- "phantom"
7512
- ))
7513
- return;
7514
- if (await trySilentSolana(
7515
- anyWin.solflare,
7516
- "solflare",
7517
- "Solflare",
7518
- "solflare"
7519
- ))
7520
- return;
7521
- if (await trySilentSolana(
7522
- anyWin.backpack,
7523
- "backpack",
7524
- "Backpack",
7525
- "backpack"
7526
- ))
7527
- return;
7528
- if (await trySilentSolana(
7529
- anyWin.glow,
7530
- "glow",
7531
- "Glow",
7532
- "glow"
7533
- ))
7534
- return;
7535
- }
7536
- if (!chainType || chainType === "ethereum") {
7537
- const anyWin = win;
7538
- const allProviders = [];
7539
- const eip6963 = getEip6963Providers();
7540
- for (const { provider, walletId } of eip6963) {
7541
- allProviders.push({
7542
- provider,
7543
- walletId: walletId === "unknown" ? "default" : walletId
7544
- });
7545
- }
7546
- if (allProviders.length === 0) {
7547
- if (win.phantom?.ethereum) {
7548
- allProviders.push({
7549
- provider: win.phantom.ethereum,
7550
- walletId: "phantom"
7551
- });
7552
- }
7553
- if (anyWin.okxwallet) {
7554
- allProviders.push({
7555
- provider: anyWin.okxwallet,
7556
- walletId: "okx"
7557
- });
7558
- }
7559
- if (anyWin.coinbaseWalletExtension) {
7560
- allProviders.push({
7561
- provider: anyWin.coinbaseWalletExtension,
7562
- walletId: "coinbase"
7563
- });
7564
- }
7565
- if (win.ethereum) {
7566
- const isDuplicate = allProviders.some(
7567
- (p) => p.provider === win.ethereum
7568
- );
7569
- if (!isDuplicate) {
7570
- allProviders.push({
7571
- provider: win.ethereum,
7572
- walletId: "default"
7573
- });
7574
- }
7575
- }
7576
- }
7577
- for (const { provider, walletId } of allProviders) {
7578
- if (!provider) continue;
7579
- try {
7580
- const accounts = await provider.request({
7581
- method: "eth_accounts"
7582
- });
7583
- if (!accounts || accounts.length === 0) continue;
7584
- const address = accounts[0];
7585
- const resolved = identifyEthWallet(provider, anyWin, walletId);
7586
- if (mounted) {
7587
- setWallet({ ...resolved, address });
7588
- setIsLoading(false);
7589
- }
7590
- return;
7591
- } catch {
7592
- }
7593
- }
7594
- }
7595
- if (mounted) {
7596
- setWallet(null);
7597
- setIsLoading(false);
7598
- }
7599
- } catch (error) {
7600
- console.error("[BrowserWalletButton] Error detecting wallet:", error);
7601
- if (mounted) {
7602
- setWallet(null);
7603
- setIsLoading(false);
7604
- }
7605
- }
7606
- };
7607
- detectWallet();
7608
- const handleAccountsChanged = () => {
7609
- detectWallet();
7610
- };
7611
- const handleDisconnect = () => {
7612
- onDisconnectRef.current?.();
7613
- detectWallet();
7614
- };
7615
- const handleEthAccountsChanged = (accounts) => {
7616
- if (Array.isArray(accounts) && accounts.length === 0) {
7617
- onDisconnectRef.current?.();
7618
- }
7619
- detectWallet();
7620
- };
7621
- const solanaProvider = window.phantom?.solana || window.solana;
7622
- if (solanaProvider) {
7623
- solanaProvider.on("connect", handleAccountsChanged);
7624
- solanaProvider.on("disconnect", handleDisconnect);
7625
- solanaProvider.on("accountChanged", handleAccountsChanged);
7626
- }
7627
- const ethProviders = [];
7628
- for (const { provider } of getEip6963Providers()) {
7629
- const p = provider;
7630
- if (p && !ethProviders.includes(p)) {
7631
- ethProviders.push(p);
7632
- }
7633
- }
7634
- if (window.ethereum && !ethProviders.includes(window.ethereum)) {
7635
- ethProviders.push(window.ethereum);
7636
- }
7637
- if (window.phantom?.ethereum && !ethProviders.includes(window.phantom.ethereum)) {
7638
- ethProviders.push(window.phantom.ethereum);
7639
- }
7640
- for (const provider of ethProviders) {
7641
- provider.on("accountsChanged", handleEthAccountsChanged);
7642
- provider.on("chainChanged", handleAccountsChanged);
7643
- }
7644
- return () => {
7645
- mounted = false;
7646
- if (solanaProvider) {
7647
- solanaProvider.off("connect", handleAccountsChanged);
7648
- solanaProvider.off("disconnect", handleDisconnect);
7649
- solanaProvider.off("accountChanged", handleAccountsChanged);
7650
- }
7651
- for (const provider of ethProviders) {
7652
- const off = provider.off?.bind(provider) ?? provider.removeListener?.bind(provider);
7653
- if (off) {
7654
- off("accountsChanged", handleEthAccountsChanged);
7655
- off("chainChanged", handleAccountsChanged);
7656
- }
7657
- }
7658
- };
7659
- }, [chainType, eip6963ProviderCount]);
7660
7602
  const handleConnect = async () => {
7661
7603
  if (wallet) {
7662
7604
  onClick(wallet);
@@ -7740,7 +7682,7 @@ function BrowserWalletButton({
7740
7682
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
7741
7683
  };
7742
7684
  const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
7743
- 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], {
7744
7686
  size: 36,
7745
7687
  className: "uf-rounded-lg",
7746
7688
  variant: "color"
@@ -7891,7 +7833,7 @@ function BrowserWalletButton({
7891
7833
  }
7892
7834
 
7893
7835
  // src/components/deposits/CoinbaseConnect.tsx
7894
- 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";
7895
7837
  import {
7896
7838
  ChevronRight as ChevronRight11,
7897
7839
  ChevronDown as ChevronDown3,
@@ -8046,6 +7988,7 @@ function CoinbaseConnect({
8046
7988
  onBack: parentOnBack,
8047
7989
  onDisconnect,
8048
7990
  skipToHoldings,
7991
+ canGoBack = true,
8049
7992
  onExecutionsChange
8050
7993
  }) {
8051
7994
  const { colors: colors2, fonts, components } = useTheme();
@@ -8071,25 +8014,25 @@ function CoinbaseConnect({
8071
8014
  const appName = projectConfig?.project_name ?? "Unifold";
8072
8015
  const t12 = i18n.connectExchange;
8073
8016
  const initialView = skipToHoldings && getStoredIntegrationToken(IntegrationProvider.COINBASE) ? "holdings" : "select_exchange";
8074
- const [view, setView] = useState21(initialView);
8075
- const [prevView, setPrevView] = useState21(initialView);
8076
- const [isTransitioning, setIsTransitioning] = useState21(false);
8077
- const [exchanges, setExchanges] = useState21([]);
8078
- const [exchangesLoading, setExchangesLoading] = useState21(true);
8079
- const [selectedExchange, setSelectedExchange] = useState21(null);
8080
- const [accessToken, setAccessToken] = useState21(null);
8081
- const [holdings, setHoldings] = useState21([]);
8082
- const [selectedHolding, setSelectedHolding] = useState21(null);
8083
- const [selectedAsset, setSelectedAsset] = useState21(null);
8084
- const [sendAmount, setSendAmount] = useState21("");
8085
- const [transferIntent, setTransferIntent] = useState21(null);
8086
- const [mfaCode, setMfaCode] = useState21("");
8087
- const [mfaError, setMfaError] = useState21(false);
8088
- const [errorMessage, setErrorMessage] = useState21("");
8089
- const [isLoading, setIsLoading] = useState21(initialView === "holdings");
8090
- const [confirmResult, setConfirmResult] = useState21(null);
8091
- const [showTransferDetails, setShowTransferDetails] = useState21(false);
8092
- 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);
8093
8036
  const exchangeSupportedCurrencies = useMemo4(() => {
8094
8037
  const set = /* @__PURE__ */ new Set();
8095
8038
  selectedExchange?.supported_currencies.forEach((c) => set.add(c.toLowerCase()));
@@ -8144,12 +8087,12 @@ function CoinbaseConnect({
8144
8087
  } : void 0,
8145
8088
  onDepositError: onTransferError
8146
8089
  });
8147
- useEffect16(() => {
8090
+ useEffect17(() => {
8148
8091
  onExecutionsChange?.(depositExecutions);
8149
8092
  }, [depositExecutions, onExecutionsChange]);
8150
- const pollRef = useRef5(null);
8151
- const popupRef = useRef5(null);
8152
- const viewRef = useRef5(initialView);
8093
+ const pollRef = useRef6(null);
8094
+ const popupRef = useRef6(null);
8095
+ const viewRef = useRef6(initialView);
8153
8096
  const transitionTo = useCallback2((nextView) => {
8154
8097
  if (nextView === viewRef.current) return;
8155
8098
  setIsTransitioning(true);
@@ -8179,7 +8122,7 @@ function CoinbaseConnect({
8179
8122
  },
8180
8123
  [publishableKey]
8181
8124
  );
8182
- useEffect16(() => {
8125
+ useEffect17(() => {
8183
8126
  getIntegrationExchanges(publishableKey).then((res) => {
8184
8127
  setExchanges(res.data);
8185
8128
  if (!selectedExchange) {
@@ -8237,7 +8180,7 @@ function CoinbaseConnect({
8237
8180
  },
8238
8181
  [publishableKey, transitionTo, tryRefreshToken]
8239
8182
  );
8240
- useEffect16(() => {
8183
+ useEffect17(() => {
8241
8184
  return () => {
8242
8185
  if (pollRef.current) clearInterval(pollRef.current);
8243
8186
  };
@@ -8433,6 +8376,16 @@ function CoinbaseConnect({
8433
8376
  setIsLoading(false);
8434
8377
  }
8435
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
+ };
8436
8389
  const handleBack = () => {
8437
8390
  switch (view) {
8438
8391
  case "select_exchange":
@@ -8493,7 +8446,7 @@ function CoinbaseConnect({
8493
8446
  DepositHeader,
8494
8447
  {
8495
8448
  title: t12.title,
8496
- showBack: true,
8449
+ showBack: canGoBack,
8497
8450
  onBack: handleBack,
8498
8451
  onClose
8499
8452
  }
@@ -8506,7 +8459,7 @@ function CoinbaseConnect({
8506
8459
  DepositHeader,
8507
8460
  {
8508
8461
  title: t12.title,
8509
- showBack: true,
8462
+ showBack: canGoBack,
8510
8463
  onBack: handleBack,
8511
8464
  onClose
8512
8465
  }
@@ -9218,7 +9171,7 @@ function CoinbaseConnect({
9218
9171
  borderRadius: components.button.borderRadius,
9219
9172
  fontFamily: fonts.medium
9220
9173
  },
9221
- onClick: onDisconnect,
9174
+ onClick: handleDisconnect,
9222
9175
  children: t12.disconnect
9223
9176
  }
9224
9177
  )
@@ -10036,7 +9989,7 @@ function useAddressValidation({
10036
9989
  }
10037
9990
 
10038
9991
  // src/components/deposits/TransferCryptoSingleInput.tsx
10039
- 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";
10040
9993
  import {
10041
9994
  ChevronDown as ChevronDown4,
10042
9995
  ChevronUp as ChevronUp3,
@@ -10051,17 +10004,17 @@ import {
10051
10004
  } from "lucide-react";
10052
10005
 
10053
10006
  // src/components/deposits/DepositsModal.tsx
10054
- import { useEffect as useEffect18, useState as useState22 } from "react";
10007
+ import { useEffect as useEffect19, useState as useState23 } from "react";
10055
10008
 
10056
10009
  // src/components/shared/ThemeStyleInjector.tsx
10057
- import * as React26 from "react";
10010
+ import * as React27 from "react";
10058
10011
  import { jsx as jsx38 } from "react/jsx-runtime";
10059
10012
  function ThemeStyleInjector({
10060
10013
  children,
10061
10014
  className
10062
10015
  }) {
10063
10016
  const { colors: colors2, fonts, mode } = useTheme();
10064
- const cssVars = React26.useMemo(() => {
10017
+ const cssVars = React27.useMemo(() => {
10065
10018
  const hexToHSL = (hex) => {
10066
10019
  hex = hex.replace("#", "");
10067
10020
  const r = parseInt(hex.slice(0, 2), 16) / 255;
@@ -10121,7 +10074,7 @@ function ThemeStyleInjector({
10121
10074
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
10122
10075
  };
10123
10076
  }, [colors2, fonts.regular]);
10124
- React26.useEffect(() => {
10077
+ React27.useEffect(() => {
10125
10078
  if (typeof document === "undefined") return;
10126
10079
  if (fonts.regular) {
10127
10080
  document.documentElement.style.setProperty(
@@ -10210,9 +10163,9 @@ function DepositsModal({
10210
10163
  themeClass = ""
10211
10164
  }) {
10212
10165
  const { colors: colors2, fonts, components } = useTheme();
10213
- const [allExecutions, setAllExecutions] = useState22(sessionExecutions);
10214
- const [selectedExecution, setSelectedExecution] = useState22(null);
10215
- useEffect18(() => {
10166
+ const [allExecutions, setAllExecutions] = useState23(sessionExecutions);
10167
+ const [selectedExecution, setSelectedExecution] = useState23(null);
10168
+ useEffect19(() => {
10216
10169
  if (!open || !userId) return;
10217
10170
  const fetchExecutions = async () => {
10218
10171
  try {
@@ -10234,7 +10187,7 @@ function DepositsModal({
10234
10187
  clearInterval(pollInterval);
10235
10188
  };
10236
10189
  }, [open, userId, publishableKey, sessionExecutions]);
10237
- useEffect18(() => {
10190
+ useEffect19(() => {
10238
10191
  if (!open) {
10239
10192
  setSelectedExecution(null);
10240
10193
  }
@@ -10310,7 +10263,7 @@ function DepositsModal({
10310
10263
  }
10311
10264
 
10312
10265
  // src/components/deposits/TokenSelectorSheet.tsx
10313
- 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";
10314
10267
  import { ArrowLeft as ArrowLeft2, X as X4 } from "lucide-react";
10315
10268
  import Fuse from "fuse.js";
10316
10269
  import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
@@ -10371,10 +10324,10 @@ function TokenSelectorSheet({
10371
10324
  }) {
10372
10325
  const { themeClass, colors: colors2, fonts, components } = useTheme();
10373
10326
  const isDarkMode = themeClass.includes("uf-dark");
10374
- const [searchQuery, setSearchQuery] = useState23("");
10375
- const [recentTokens, setRecentTokens] = useState23([]);
10376
- const [hoveredTokenKey, setHoveredTokenKey] = useState23(null);
10377
- useEffect19(() => {
10327
+ const [searchQuery, setSearchQuery] = useState24("");
10328
+ const [recentTokens, setRecentTokens] = useState24([]);
10329
+ const [hoveredTokenKey, setHoveredTokenKey] = useState24(null);
10330
+ useEffect20(() => {
10378
10331
  setRecentTokens(getRecentTokens());
10379
10332
  }, []);
10380
10333
  const allOptions = useMemo6(() => {
@@ -10806,7 +10759,7 @@ function TokenSelectorSheet({
10806
10759
  }
10807
10760
 
10808
10761
  // src/hooks/use-default-token.ts
10809
- 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";
10810
10763
  var getChainKey = (chainId, chainType) => {
10811
10764
  return `${chainType}:${chainId}`;
10812
10765
  };
@@ -10861,11 +10814,11 @@ function useDefaultToken({
10861
10814
  defaultTokenAddress,
10862
10815
  defaultSymbol
10863
10816
  }) {
10864
- const [token, setToken] = useState24(null);
10865
- const [chain, setChain] = useState24(null);
10866
- const [initialSelectionDone, setInitialSelectionDone] = useState24(false);
10867
- const appliedDefaultsRef = useRef6("");
10868
- 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(() => {
10869
10822
  if (!tokens.length) return;
10870
10823
  const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
10871
10824
  const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
@@ -10891,7 +10844,7 @@ function useDefaultToken({
10891
10844
  defaultChainId,
10892
10845
  initialSelectionDone
10893
10846
  ]);
10894
- useEffect20(() => {
10847
+ useEffect21(() => {
10895
10848
  if (!tokens.length || !token) return;
10896
10849
  const currentToken = tokens.find((t12) => t12.symbol === token);
10897
10850
  if (!currentToken || currentToken.chains.length === 0) return;
@@ -11096,9 +11049,9 @@ function GlossaryModal({
11096
11049
  }
11097
11050
 
11098
11051
  // src/components/deposits/shared/useCopyAddress.ts
11099
- import { useState as useState25 } from "react";
11052
+ import { useState as useState26 } from "react";
11100
11053
  function useCopyAddress() {
11101
- const [copied, setCopied] = useState25(false);
11054
+ const [copied, setCopied] = useState26(false);
11102
11055
  const handleCopy = (address) => {
11103
11056
  if (!address) return;
11104
11057
  navigator.clipboard.writeText(address);
@@ -11109,7 +11062,7 @@ function useCopyAddress() {
11109
11062
  }
11110
11063
 
11111
11064
  // src/components/shared/tooltip.tsx
11112
- import * as React27 from "react";
11065
+ import * as React28 from "react";
11113
11066
  import * as TooltipPrimitive from "@radix-ui/react-tooltip";
11114
11067
  import { jsx as jsx44 } from "react/jsx-runtime";
11115
11068
  var TooltipProvider = TooltipPrimitive.Provider;
@@ -11117,7 +11070,7 @@ function Tooltip({
11117
11070
  children,
11118
11071
  ...props
11119
11072
  }) {
11120
- const [open, setOpen] = React27.useState(props.defaultOpen ?? false);
11073
+ const [open, setOpen] = React28.useState(props.defaultOpen ?? false);
11121
11074
  const isControlled = props.open !== void 0;
11122
11075
  const isOpen = isControlled ? props.open : open;
11123
11076
  const onOpenChange = isControlled ? props.onOpenChange : (nextOpen) => setOpen(nextOpen);
@@ -11137,14 +11090,14 @@ function Tooltip({
11137
11090
  }
11138
11091
  );
11139
11092
  }
11140
- var TooltipContext = React27.createContext({
11093
+ var TooltipContext = React28.createContext({
11141
11094
  open: false,
11142
11095
  onOpenChange: () => {
11143
11096
  }
11144
11097
  });
11145
- var TooltipTrigger = React27.forwardRef(({ onClick, ...props }, ref) => {
11146
- const { open, onOpenChange } = React27.useContext(TooltipContext);
11147
- const handleClick = React27.useCallback(
11098
+ var TooltipTrigger = React28.forwardRef(({ onClick, ...props }, ref) => {
11099
+ const { open, onOpenChange } = React28.useContext(TooltipContext);
11100
+ const handleClick = React28.useCallback(
11148
11101
  (e) => {
11149
11102
  onOpenChange(!open);
11150
11103
  onClick?.(e);
@@ -11154,7 +11107,7 @@ var TooltipTrigger = React27.forwardRef(({ onClick, ...props }, ref) => {
11154
11107
  return /* @__PURE__ */ jsx44(TooltipPrimitive.Trigger, { ref, onClick: handleClick, ...props });
11155
11108
  });
11156
11109
  TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
11157
- var TooltipContent = React27.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
11110
+ var TooltipContent = React28.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
11158
11111
  const { themeClass, colors: colors2 } = useTheme();
11159
11112
  return /* @__PURE__ */ jsx44(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx44(
11160
11113
  TooltipPrimitive.Content,
@@ -11300,12 +11253,12 @@ function TransferCryptoSingleInput({
11300
11253
  }) {
11301
11254
  const { themeClass, colors: colors2, fonts, components } = useTheme();
11302
11255
  const isDarkMode = themeClass.includes("uf-dark");
11303
- const [copied, setCopied] = useState27(false);
11256
+ const [copied, setCopied] = useState28(false);
11304
11257
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
11305
- const [glossaryOpen, setGlossaryOpen] = useState27(false);
11306
- const [detailsExpanded, setDetailsExpanded] = useState27(false);
11307
- const [depositsModalOpen, setDepositsModalOpen] = useState27(false);
11308
- 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);
11309
11262
  const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(publishableKey, {
11310
11263
  destination_token_address: destinationTokenAddress,
11311
11264
  destination_chain_id: destinationChainId,
@@ -11378,7 +11331,7 @@ function TransferCryptoSingleInput({
11378
11331
  publishableKey,
11379
11332
  enabled: !!depositAddress && !!recipientAddress
11380
11333
  });
11381
- useEffect21(() => {
11334
+ useEffect22(() => {
11382
11335
  if (!onSourceTokenChange || !token || !chain || !initialSelectionDone) return;
11383
11336
  const { chainType, chainId } = parseChainKey(chain);
11384
11337
  const matchedToken = supportedTokens.find((t12) => t12.symbol === token);
@@ -11395,7 +11348,7 @@ function TransferCryptoSingleInput({
11395
11348
  isStablecoin: matchedToken?.is_stablecoin ?? false
11396
11349
  });
11397
11350
  }, [token, chain, initialSelectionDone, onSourceTokenChange, supportedTokens]);
11398
- useEffect21(() => {
11351
+ useEffect22(() => {
11399
11352
  if (onExecutionsChange) {
11400
11353
  onExecutionsChange(depositExecutions);
11401
11354
  }
@@ -11782,7 +11735,7 @@ function TransferCryptoSingleInput({
11782
11735
  }
11783
11736
 
11784
11737
  // src/components/deposits/TransferCryptoDoubleInput.tsx
11785
- 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";
11786
11739
  import {
11787
11740
  ChevronDown as ChevronDown6,
11788
11741
  ChevronUp as ChevronUp5,
@@ -11797,14 +11750,14 @@ import {
11797
11750
  } from "lucide-react";
11798
11751
 
11799
11752
  // src/components/shared/select.tsx
11800
- import * as React28 from "react";
11753
+ import * as React29 from "react";
11801
11754
  import * as SelectPrimitive from "@radix-ui/react-select";
11802
11755
  import { Check as Check5, ChevronDown as ChevronDown5, ChevronUp as ChevronUp4 } from "lucide-react";
11803
11756
  import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
11804
11757
  var Select = SelectPrimitive.Root;
11805
11758
  var SelectGroup = SelectPrimitive.Group;
11806
11759
  var SelectValue = SelectPrimitive.Value;
11807
- var SelectTrigger = React28.forwardRef(({ className, style, children, ...props }, ref) => {
11760
+ var SelectTrigger = React29.forwardRef(({ className, style, children, ...props }, ref) => {
11808
11761
  const { components } = useTheme();
11809
11762
  return /* @__PURE__ */ jsxs42(
11810
11763
  SelectPrimitive.Trigger,
@@ -11828,7 +11781,7 @@ var SelectTrigger = React28.forwardRef(({ className, style, children, ...props }
11828
11781
  );
11829
11782
  });
11830
11783
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
11831
- var SelectScrollUpButton = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11784
+ var SelectScrollUpButton = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11832
11785
  SelectPrimitive.ScrollUpButton,
11833
11786
  {
11834
11787
  ref,
@@ -11841,7 +11794,7 @@ var SelectScrollUpButton = React28.forwardRef(({ className, ...props }, ref) =>
11841
11794
  }
11842
11795
  ));
11843
11796
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
11844
- var SelectScrollDownButton = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11797
+ var SelectScrollDownButton = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11845
11798
  SelectPrimitive.ScrollDownButton,
11846
11799
  {
11847
11800
  ref,
@@ -11854,7 +11807,7 @@ var SelectScrollDownButton = React28.forwardRef(({ className, ...props }, ref) =
11854
11807
  }
11855
11808
  ));
11856
11809
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
11857
- var SelectContent = React28.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
11810
+ var SelectContent = React29.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
11858
11811
  const { themeClass, colors: colors2, components } = useTheme();
11859
11812
  return /* @__PURE__ */ jsx47(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs42(
11860
11813
  SelectPrimitive.Content,
@@ -11892,7 +11845,7 @@ var SelectContent = React28.forwardRef(({ className, style, children, position =
11892
11845
  ) });
11893
11846
  });
11894
11847
  SelectContent.displayName = SelectPrimitive.Content.displayName;
11895
- var SelectLabel = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11848
+ var SelectLabel = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11896
11849
  SelectPrimitive.Label,
11897
11850
  {
11898
11851
  ref,
@@ -11904,7 +11857,7 @@ var SelectLabel = React28.forwardRef(({ className, ...props }, ref) => /* @__PUR
11904
11857
  }
11905
11858
  ));
11906
11859
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
11907
- var SelectItem = React28.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs42(
11860
+ var SelectItem = React29.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs42(
11908
11861
  SelectPrimitive.Item,
11909
11862
  {
11910
11863
  ref,
@@ -11920,7 +11873,7 @@ var SelectItem = React28.forwardRef(({ className, children, ...props }, ref) =>
11920
11873
  }
11921
11874
  ));
11922
11875
  SelectItem.displayName = SelectPrimitive.Item.displayName;
11923
- var SelectSeparator = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11876
+ var SelectSeparator = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
11924
11877
  SelectPrimitive.Separator,
11925
11878
  {
11926
11879
  ref,
@@ -11962,11 +11915,11 @@ function TransferCryptoDoubleInput({
11962
11915
  }) {
11963
11916
  const { themeClass, colors: colors2, fonts, components } = useTheme();
11964
11917
  const isDarkMode = themeClass.includes("uf-dark");
11965
- const [copied, setCopied] = useState28(false);
11918
+ const [copied, setCopied] = useState29(false);
11966
11919
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
11967
- const [glossaryOpen, setGlossaryOpen] = useState28(false);
11968
- const [detailsExpanded, setDetailsExpanded] = useState28(false);
11969
- const [depositsModalOpen, setDepositsModalOpen] = useState28(false);
11920
+ const [glossaryOpen, setGlossaryOpen] = useState29(false);
11921
+ const [detailsExpanded, setDetailsExpanded] = useState29(false);
11922
+ const [depositsModalOpen, setDepositsModalOpen] = useState29(false);
11970
11923
  const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(publishableKey, {
11971
11924
  destination_token_address: destinationTokenAddress,
11972
11925
  destination_chain_id: destinationChainId,
@@ -12037,7 +11990,7 @@ function TransferCryptoDoubleInput({
12037
11990
  publishableKey,
12038
11991
  enabled: !!depositAddress && !!recipientAddress
12039
11992
  });
12040
- useEffect22(() => {
11993
+ useEffect23(() => {
12041
11994
  if (onExecutionsChange) {
12042
11995
  onExecutionsChange(depositExecutions);
12043
11996
  }
@@ -12380,7 +12333,7 @@ function TransferCryptoDoubleInput({
12380
12333
  }
12381
12334
 
12382
12335
  // src/components/deposits/WalletConnect.tsx
12383
- import * as React29 from "react";
12336
+ import * as React30 from "react";
12384
12337
  import { ExternalLink as ExternalLink3, Loader2 as Loader28 } from "lucide-react";
12385
12338
  import {
12386
12339
  getAddressBalances as getAddressBalances2,
@@ -13332,7 +13285,7 @@ function ReviewView({
13332
13285
  }
13333
13286
 
13334
13287
  // src/components/deposits/browser-wallets/ConfirmingView.tsx
13335
- import { useEffect as useEffect23, useState as useState29 } from "react";
13288
+ import { useEffect as useEffect24, useState as useState30 } from "react";
13336
13289
  import { Loader2 as Loader27, CheckCircle2 as CheckCircle23 } from "lucide-react";
13337
13290
  import { Fragment as Fragment10, jsx as jsx53, jsxs as jsxs47 } from "react/jsx-runtime";
13338
13291
  var SETTLE_FALLBACK_MS = 15e3;
@@ -13348,13 +13301,13 @@ function ConfirmingView({
13348
13301
  amountReceivedUsdAtSubmission
13349
13302
  }) {
13350
13303
  const { colors: colors2, fonts, components } = useTheme();
13351
- const [fallbackSettled, setFallbackSettled] = useState29(false);
13304
+ const [fallbackSettled, setFallbackSettled] = useState30(false);
13352
13305
  const hasExecution = executions.length > 0;
13353
13306
  const isCheckoutMode = paymentIntentStatus != null;
13354
13307
  const isPaymentComplete = paymentIntentStatus === "succeeded";
13355
13308
  const amountChanged = amountReceivedUsdAtSubmission != null && amountReceivedUsd != null && amountReceivedUsd !== amountReceivedUsdAtSubmission;
13356
13309
  const piSettled = !isCheckoutMode || isPaymentComplete || amountChanged || fallbackSettled;
13357
- useEffect23(() => {
13310
+ useEffect24(() => {
13358
13311
  if (!hasExecution || piSettled) return;
13359
13312
  const timeout = setTimeout(() => setFallbackSettled(true), SETTLE_FALLBACK_MS);
13360
13313
  return () => clearTimeout(timeout);
@@ -13630,22 +13583,27 @@ function WalletConnect({
13630
13583
  productType,
13631
13584
  onBack: parentOnBack,
13632
13585
  onClose,
13586
+ canGoBack = true,
13587
+ depositWalletsLoading = false,
13633
13588
  onExecutionsChange
13634
13589
  }) {
13635
13590
  const { colors: colors2, fonts, components } = useTheme();
13636
- const walletProvidedAtMount = React29.useRef(!!initialWalletInfo && !!initialDepositWallet);
13637
- const [activeWalletInfo, setActiveWalletInfo] = React29.useState(initialWalletInfo ?? null);
13638
- 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);
13639
13594
  const initialView = initialWalletInfo && initialDepositWallet ? "select_token" : "select_wallet";
13640
- const [view, setView] = React29.useState(initialView);
13641
- const [isTransitioning, setIsTransitioning] = React29.useState(false);
13642
- const viewRef = React29.useRef(initialView);
13643
- const [selectedWalletDef, setSelectedWalletDef] = React29.useState(null);
13644
- const [connectingNetwork, setConnectingNetwork] = React29.useState(null);
13645
- const [walletError, setWalletError] = React29.useState(null);
13646
- const [isWalletConnecting, setIsWalletConnecting] = React29.useState(false);
13647
- const [eip6963ProviderCount, setEip6963ProviderCount] = React29.useState(0);
13648
- 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(() => {
13649
13607
  const store = getEip6963Store();
13650
13608
  if (!store) return;
13651
13609
  setEip6963ProviderCount(store.getProviders().length);
@@ -13653,20 +13611,44 @@ function WalletConnect({
13653
13611
  setEip6963ProviderCount(providers.length);
13654
13612
  });
13655
13613
  }, []);
13656
- const availableWallets = React29.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13657
- const [balances, setBalances] = React29.useState([]);
13658
- const [isLoading, setIsLoading] = React29.useState(false);
13659
- const [selectedBalance, setSelectedBalance] = React29.useState(null);
13660
- const [totalBalanceUsd, setTotalBalanceUsd] = React29.useState(null);
13661
- const [error, setError] = React29.useState(null);
13662
- const [isDisconnectingWallet, setIsDisconnectingWallet] = React29.useState(false);
13663
- const [amountUsd, setAmountUsd] = React29.useState(prefillAmountUsd ?? "");
13664
- const [isConfirming, setIsConfirming] = React29.useState(false);
13665
- const [hasSignedTransaction, setHasSignedTransaction] = React29.useState(false);
13666
- const [tokenChainDetails, setTokenChainDetails] = React29.useState(null);
13667
- const [loadingTokenDetails, setLoadingTokenDetails] = React29.useState(false);
13668
- const [showTransactionDetails, setShowTransactionDetails] = React29.useState(false);
13669
- 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);
13670
13652
  const walletInfo = activeWalletInfo;
13671
13653
  const depositWallet = activeDepositWallet;
13672
13654
  const hasWallet = !!activeWalletInfo && !!activeDepositWallet;
@@ -13674,7 +13656,7 @@ function WalletConnect({
13674
13656
  const recipientAddress = activeDepositWallet?.address ?? "";
13675
13657
  const isCheckoutMode = !!checkoutAmountUsd;
13676
13658
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
13677
- const transitionTo = React29.useCallback((nextView) => {
13659
+ const transitionTo = React30.useCallback((nextView) => {
13678
13660
  if (nextView === viewRef.current) return;
13679
13661
  setIsTransitioning(true);
13680
13662
  setTimeout(() => {
@@ -13811,7 +13793,7 @@ function WalletConnect({
13811
13793
  }
13812
13794
  };
13813
13795
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
13814
- const effectiveDestinationAmount = React29.useMemo(() => {
13796
+ const effectiveDestinationAmount = React30.useMemo(() => {
13815
13797
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
13816
13798
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
13817
13799
  const remaining = BigInt(checkoutRemainingBaseUnits);
@@ -13839,7 +13821,7 @@ function WalletConnect({
13839
13821
  stablecoinParity,
13840
13822
  enabled: isCheckoutMode && !!selectedToken && !!checkoutDestination && effectiveDestinationAmount !== "0"
13841
13823
  });
13842
- const activeCheckoutQuote = React29.useMemo(() => {
13824
+ const activeCheckoutQuote = React30.useMemo(() => {
13843
13825
  if (!isCheckoutMode) return null;
13844
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 };
13845
13827
  return checkoutQuote ?? null;
@@ -13853,19 +13835,19 @@ function WalletConnect({
13853
13835
  onDepositSuccess,
13854
13836
  onDepositError
13855
13837
  });
13856
- React29.useEffect(() => {
13838
+ React30.useEffect(() => {
13857
13839
  onExecutionsChange?.(depositExecutions);
13858
13840
  }, [depositExecutions, onExecutionsChange]);
13859
- React29.useEffect(() => {
13841
+ React30.useEffect(() => {
13860
13842
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
13861
13843
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
13862
13844
  const currentAmount = parseFloat(amountUsd) || 0;
13863
13845
  if (currentAmount > 0 && currentAmount < minDeposit) setAmountUsd(minDeposit.toFixed(2));
13864
13846
  }, [tokenChainDetails, view, prefillAmountUsd]);
13865
- React29.useEffect(() => {
13847
+ React30.useEffect(() => {
13866
13848
  if (view === "review") setShowTransactionDetails(false);
13867
13849
  }, [view]);
13868
- React29.useEffect(() => {
13850
+ React30.useEffect(() => {
13869
13851
  if (view !== "enter_amount" && view !== "review" || !selectedBalance || !activeDepositWallet) return;
13870
13852
  let cancelled = false;
13871
13853
  const fetchTokenDetails = async () => {
@@ -13892,7 +13874,7 @@ function WalletConnect({
13892
13874
  cancelled = true;
13893
13875
  };
13894
13876
  }, [view, selectedBalance, publishableKey, activeDepositWallet]);
13895
- React29.useEffect(() => {
13877
+ React30.useEffect(() => {
13896
13878
  if (!activeWalletInfo || !activeDepositWallet) return;
13897
13879
  let cancelled = false;
13898
13880
  setIsLoading(true);
@@ -13925,20 +13907,20 @@ function WalletConnect({
13925
13907
  cancelled = true;
13926
13908
  };
13927
13909
  }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
13928
- const usdToTokenRate = React29.useMemo(() => {
13910
+ const usdToTokenRate = React30.useMemo(() => {
13929
13911
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
13930
13912
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
13931
13913
  const balanceUsd = parseFloat(selectedBalance.amount_usd);
13932
13914
  if (balanceAmount === 0 || balanceUsd === 0) return 0;
13933
13915
  return balanceAmount / balanceUsd;
13934
13916
  }, [selectedBalance, selectedToken]);
13935
- const tokenAmount = React29.useMemo(() => {
13917
+ const tokenAmount = React30.useMemo(() => {
13936
13918
  if (isCheckoutMode && activeCheckoutQuote && selectedToken) return Number(activeCheckoutQuote.sourceAmount) / 10 ** activeCheckoutQuote.sourceTokenDecimals;
13937
13919
  const usdNum = parseFloat(amountUsd) || 0;
13938
13920
  if (usdNum === 0 || usdToTokenRate === 0) return 0;
13939
13921
  return usdNum * usdToTokenRate;
13940
13922
  }, [amountUsd, usdToTokenRate, isCheckoutMode, activeCheckoutQuote, selectedToken]);
13941
- React29.useEffect(() => {
13923
+ React30.useEffect(() => {
13942
13924
  if (isCheckoutMode && activeCheckoutQuote?.sourceAmountUsd && view === "enter_amount") setAmountUsd(activeCheckoutQuote.sourceAmountUsd);
13943
13925
  }, [isCheckoutMode, activeCheckoutQuote, view]);
13944
13926
  const maxTokenAmount = selectedBalance && selectedToken ? Number(selectedBalance.amount) / 10 ** selectedToken.decimals : 0;
@@ -13946,7 +13928,7 @@ function WalletConnect({
13946
13928
  const inputUsdNum = parseFloat(amountUsd) || 0;
13947
13929
  const minDepositUsd = tokenChainDetails?.minimum_deposit_amount_usd || 0;
13948
13930
  const isValidAmount = isCheckoutMode && activeCheckoutQuote ? tokenAmount > 0 && tokenAmount <= maxTokenAmount : inputUsdNum > 0 && inputUsdNum <= maxUsdAmount && inputUsdNum >= minDepositUsd;
13949
- const formattedTokenAmount = React29.useMemo(() => {
13931
+ const formattedTokenAmount = React30.useMemo(() => {
13950
13932
  if (tokenAmount === 0 || !selectedToken) return null;
13951
13933
  return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
13952
13934
  }, [tokenAmount, selectedToken]);
@@ -13994,16 +13976,25 @@ function WalletConnect({
13994
13976
  } catch (err) {
13995
13977
  console.warn("[WalletConnect] disconnect error:", err);
13996
13978
  } finally {
13997
- setActiveWalletInfo(null);
13998
- setActiveDepositWallet(null);
13999
- setSelectedBalance(null);
14000
- setBalances([]);
14001
- setTotalBalanceUsd(null);
14002
- setAmountUsd(prefillAmountUsd ?? "");
14003
- setError(null);
14004
13979
  setIsDisconnectingWallet(false);
14005
- if (onWalletDisconnect) onWalletDisconnect();
14006
- 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
+ }
14007
13998
  }
14008
13999
  };
14009
14000
  const handleReview = () => {
@@ -14129,9 +14120,15 @@ function WalletConnect({
14129
14120
  setIsConfirming(false);
14130
14121
  }
14131
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
+ }
14132
14129
  if (view === "select_wallet") {
14133
14130
  return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14134
- /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: true, onBack: handleBack, onClose }),
14131
+ /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14135
14132
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
14136
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" }),
14137
14134
  /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ jsxs48(
@@ -14297,45 +14294,56 @@ function DepositModal({
14297
14294
  if (s === "tracker" && hideDepositTracker) return "main";
14298
14295
  if (s === "cashapp" && !enableCashApp) return "main";
14299
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";
14300
14300
  return s;
14301
- }, [initialScreen, hideDepositTracker, enableCashApp, enableFiatOnramp]);
14302
- 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);
14303
14311
  const containerCallbackRef = useCallback5((el) => {
14304
14312
  setContainerEl(el);
14305
14313
  }, []);
14306
- const [view, setView] = useState31(
14314
+ const [view, setView] = useState32(
14307
14315
  effectiveInitialScreen
14308
14316
  );
14309
- const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = useState31(false);
14310
- const resetViewTimeoutRef = useRef8(null);
14311
- const [cardView, setCardView] = useState31(
14317
+ const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = useState32(false);
14318
+ const resetViewTimeoutRef = useRef9(null);
14319
+ const [cardView, setCardView] = useState32(
14312
14320
  "amount"
14313
14321
  );
14314
- const [exchangeView, setExchangeView] = useState31(
14322
+ const [exchangeView, setExchangeView] = useState32(
14315
14323
  "providers"
14316
14324
  );
14317
- const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState31(false);
14318
- const [browserWalletInfo, setBrowserWalletInfo] = useState31(null);
14319
- const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState31(false);
14320
- const [browserWalletChainType, setBrowserWalletChainType] = useState31(() => getStoredWalletChainType());
14321
- const [quotesCount, setQuotesCount] = useState31(0);
14322
- const [allExecutions, setAllExecutions] = useState31([]);
14323
- const [selectedExecution, setSelectedExecution] = useState31(null);
14324
- 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([]);
14325
14333
  const isMobileView = useIsMobileViewport();
14326
- const [integrationExchanges, setIntegrationExchanges] = useState31([]);
14327
- useEffect25(() => {
14334
+ const [integrationExchanges, setIntegrationExchanges] = useState32([]);
14335
+ useEffect26(() => {
14328
14336
  if (!enableConnectExchange || !open) return;
14329
14337
  getIntegrationExchanges2(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
14330
14338
  });
14331
14339
  }, [enableConnectExchange, open, publishableKey]);
14332
- const [connectedExchange, setConnectedExchange] = useState31(() => {
14340
+ const [connectedExchange, setConnectedExchange] = useState32(() => {
14333
14341
  if (!enableConnectExchange) return null;
14334
14342
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
14335
14343
  if (!stored) return null;
14336
14344
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
14337
14345
  });
14338
- useEffect25(() => {
14346
+ useEffect26(() => {
14339
14347
  if (!enableConnectExchange || !open || view !== "main") return;
14340
14348
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
14341
14349
  if (!stored) {
@@ -14372,7 +14380,7 @@ function DepositModal({
14372
14380
  }
14373
14381
  });
14374
14382
  }, [enableConnectExchange, open, view, publishableKey]);
14375
- useEffect25(() => {
14383
+ useEffect26(() => {
14376
14384
  if (!connectedExchange || integrationExchanges.length === 0) return;
14377
14385
  const cbExchange = integrationExchanges.find(
14378
14386
  (e) => e.service_provider === IntegrationProvider2.COINBASE
@@ -14394,10 +14402,10 @@ function DepositModal({
14394
14402
  // Only fetch when modal is open
14395
14403
  });
14396
14404
  const wallets = depositAddressResponse?.data ?? [];
14397
- const [resolvedTheme, setResolvedTheme] = useState31(
14405
+ const [resolvedTheme, setResolvedTheme] = useState32(
14398
14406
  theme === "auto" ? "dark" : theme
14399
14407
  );
14400
- useEffect25(() => {
14408
+ useEffect26(() => {
14401
14409
  if (theme === "auto") {
14402
14410
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
14403
14411
  setResolvedTheme(mediaQuery.matches ? "dark" : "light");
@@ -14416,12 +14424,18 @@ function DepositModal({
14416
14424
  });
14417
14425
  const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14418
14426
  const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14419
- useEffect25(() => {
14427
+ useEffect26(() => {
14420
14428
  if (view === "card" && !showFiatOnramp) {
14421
14429
  setView("main");
14422
14430
  setCardView("amount");
14423
14431
  }
14424
14432
  }, [view, showFiatOnramp]);
14433
+ useEffect26(() => {
14434
+ if (view === "exchange" && !showPayWithExchange) {
14435
+ setView("main");
14436
+ setExchangeView("providers");
14437
+ }
14438
+ }, [view, showPayWithExchange]);
14425
14439
  const { exchanges, isLoading: exchangesLoading } = useExchanges({
14426
14440
  publishableKey,
14427
14441
  enabled: open && showPayWithExchange
@@ -14436,7 +14450,7 @@ function DepositModal({
14436
14450
  subdivisionCode: userIpInfo?.subdivisionCode ?? void 0,
14437
14451
  enabled: open && !isLoadingIp
14438
14452
  });
14439
- useEffect25(() => {
14453
+ useEffect26(() => {
14440
14454
  if (view !== "tracker" || !userId) return;
14441
14455
  const fetchExecutions = async () => {
14442
14456
  try {
@@ -14457,7 +14471,7 @@ function DepositModal({
14457
14471
  clearInterval(pollInterval);
14458
14472
  };
14459
14473
  }, [view, userId, publishableKey]);
14460
- useEffect25(() => {
14474
+ useEffect26(() => {
14461
14475
  if (view !== "tracker") {
14462
14476
  setSelectedExecution(null);
14463
14477
  }
@@ -14541,7 +14555,7 @@ function DepositModal({
14541
14555
  setBrowserWalletChainType(void 0);
14542
14556
  setBrowserWalletInfo(null);
14543
14557
  setBrowserWalletModalOpen(false);
14544
- if (view === "wallet_connect") setView("main");
14558
+ if (view === "wallet_connect" && sessionOpenedFromMenu) setView("main");
14545
14559
  };
14546
14560
  const handleExchangeDisconnect = () => {
14547
14561
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
@@ -14550,7 +14564,7 @@ function DepositModal({
14550
14564
  }
14551
14565
  clearStoredIntegrationToken(IntegrationProvider2.COINBASE);
14552
14566
  setConnectedExchange(null);
14553
- if (view === "coinbase_connect") setView("main");
14567
+ if (view === "coinbase_connect" && sessionOpenedFromMenu) setView("main");
14554
14568
  };
14555
14569
  const handleClose = () => {
14556
14570
  onOpenChange(false);
@@ -14562,6 +14576,7 @@ function DepositModal({
14562
14576
  setCardView("amount");
14563
14577
  setExchangeView("providers");
14564
14578
  setBrowserWalletInfo(null);
14579
+ setCoinbaseSkipToHoldings(false);
14565
14580
  resetViewTimeoutRef.current = null;
14566
14581
  }, 200);
14567
14582
  };
@@ -14576,8 +14591,9 @@ function DepositModal({
14576
14591
  setExchangeView("providers");
14577
14592
  setBrowserWalletInfo(null);
14578
14593
  setSelectedExecution(null);
14594
+ setCoinbaseSkipToHoldings(false);
14579
14595
  }, [open, effectiveInitialScreen]);
14580
- useEffect25(
14596
+ useEffect26(
14581
14597
  () => () => {
14582
14598
  if (resetViewTimeoutRef.current) {
14583
14599
  clearTimeout(resetViewTimeoutRef.current);
@@ -14585,8 +14601,8 @@ function DepositModal({
14585
14601
  },
14586
14602
  []
14587
14603
  );
14588
- const [cashAppView, setCashAppView] = useState31("amount");
14589
- const [cashAppAmount, setCashAppAmount] = useState31("");
14604
+ const [cashAppView, setCashAppView] = useState32("amount");
14605
+ const [cashAppAmount, setCashAppAmount] = useState32("");
14590
14606
  const handleBack = () => {
14591
14607
  if (view === "card" && cardView === "quotes") {
14592
14608
  setCardView("amount");
@@ -14935,7 +14951,7 @@ function DepositModal({
14935
14951
  DepositHeader,
14936
14952
  {
14937
14953
  title: payWithExchangeTitle,
14938
- showBack: true,
14954
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
14939
14955
  onBack: handleBack,
14940
14956
  onClose: handleClose
14941
14957
  }
@@ -14989,6 +15005,7 @@ function DepositModal({
14989
15005
  onClose: handleClose,
14990
15006
  onDisconnect: handleExchangeDisconnect,
14991
15007
  skipToHoldings: coinbaseSkipToHoldings,
15008
+ canGoBack: sessionOpenedFromMenu,
14992
15009
  onExecutionsChange: setDepositExecutions
14993
15010
  }
14994
15011
  ),
@@ -15026,7 +15043,9 @@ function DepositModal({
15026
15043
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15027
15044
  },
15028
15045
  onBack: handleBack,
15029
- onClose: handleClose
15046
+ onClose: handleClose,
15047
+ canGoBack: sessionOpenedFromMenu,
15048
+ depositWalletsLoading: walletsLoading
15030
15049
  }
15031
15050
  ),
15032
15051
  depositPoweredByFooter
@@ -15035,7 +15054,7 @@ function DepositModal({
15035
15054
  DepositHeader,
15036
15055
  {
15037
15056
  title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15038
- showBack: true,
15057
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15039
15058
  onBack: handleBack,
15040
15059
  onClose: handleClose
15041
15060
  }
@@ -15070,11 +15089,11 @@ function DepositModal({
15070
15089
 
15071
15090
  // src/components/checkout/CheckoutModal.tsx
15072
15091
  import {
15073
- useState as useState32,
15074
- useEffect as useEffect26,
15092
+ useState as useState33,
15093
+ useEffect as useEffect27,
15075
15094
  useLayoutEffect as useLayoutEffect3,
15076
15095
  useCallback as useCallback6,
15077
- useRef as useRef9,
15096
+ useRef as useRef10,
15078
15097
  useMemo as useMemo11
15079
15098
  } from "react";
15080
15099
  import { AlertTriangle as AlertTriangle3, ChevronRight as ChevronRight15 } from "lucide-react";
@@ -15155,19 +15174,19 @@ function CheckoutModal({
15155
15174
  onCheckoutError
15156
15175
  }) {
15157
15176
  const { colors: colors2, fonts, components } = useTheme();
15158
- const [view, setView] = useState32("main");
15159
- const resetViewTimeoutRef = useRef9(
15177
+ const [view, setView] = useState33("main");
15178
+ const resetViewTimeoutRef = useRef10(
15160
15179
  null
15161
15180
  );
15162
- const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState32(false);
15163
- const [browserWalletInfo, setBrowserWalletInfo] = useState32(null);
15164
- const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState32(false);
15165
- 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());
15166
15185
  const isMobileView = useIsMobileViewport();
15167
- const [resolvedTheme, setResolvedTheme] = useState32(
15186
+ const [resolvedTheme, setResolvedTheme] = useState33(
15168
15187
  theme === "auto" ? "dark" : theme
15169
15188
  );
15170
- useEffect26(() => {
15189
+ useEffect27(() => {
15171
15190
  if (theme === "auto") {
15172
15191
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
15173
15192
  setResolvedTheme(mediaQuery.matches ? "dark" : "light");
@@ -15195,8 +15214,8 @@ function CheckoutModal({
15195
15214
  publishableKey,
15196
15215
  enabled: open
15197
15216
  });
15198
- const prevStatusRef = useRef9(null);
15199
- useEffect26(() => {
15217
+ const prevStatusRef = useRef10(null);
15218
+ useEffect27(() => {
15200
15219
  if (!paymentIntent) return;
15201
15220
  const prev = prevStatusRef.current;
15202
15221
  prevStatusRef.current = paymentIntent.status;
@@ -15242,7 +15261,7 @@ function CheckoutModal({
15242
15261
  const remaining = total - received;
15243
15262
  return remaining > 0n ? remaining.toString() : "0";
15244
15263
  }, [paymentIntent]);
15245
- const [selectedSource, setSelectedSource] = useState32(null);
15264
+ const [selectedSource, setSelectedSource] = useState33(null);
15246
15265
  const remainingDestinationAmount = useMemo11(() => {
15247
15266
  if (!paymentIntent) return "0";
15248
15267
  const remaining = BigInt(paymentIntent.destination_amount) - BigInt(paymentIntent.destination_amount_received);
@@ -15362,7 +15381,7 @@ function CheckoutModal({
15362
15381
  setView("main");
15363
15382
  setBrowserWalletInfo(null);
15364
15383
  }, [open]);
15365
- useEffect26(
15384
+ useEffect27(
15366
15385
  () => () => {
15367
15386
  if (resetViewTimeoutRef.current) {
15368
15387
  clearTimeout(resetViewTimeoutRef.current);
@@ -15739,11 +15758,11 @@ function CheckoutModal({
15739
15758
 
15740
15759
  // src/components/withdrawals/WithdrawModal.tsx
15741
15760
  import {
15742
- useState as useState36,
15743
- useEffect as useEffect30,
15761
+ useState as useState37,
15762
+ useEffect as useEffect31,
15744
15763
  useLayoutEffect as useLayoutEffect4,
15745
15764
  useCallback as useCallback8,
15746
- useRef as useRef11
15765
+ useRef as useRef12
15747
15766
  } from "react";
15748
15767
  import { AlertTriangle as AlertTriangle5, ChevronRight as ChevronRight17, Clock as Clock6 } from "lucide-react";
15749
15768
 
@@ -15919,7 +15938,7 @@ function useExecutions(userId, publishableKey, options) {
15919
15938
  }
15920
15939
 
15921
15940
  // src/hooks/use-withdraw-polling.ts
15922
- 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";
15923
15942
  import {
15924
15943
  queryExecutions as queryExecutions5,
15925
15944
  pollDirectExecutions as pollDirectExecutions2,
@@ -15937,20 +15956,20 @@ function useWithdrawPolling({
15937
15956
  onWithdrawSuccess,
15938
15957
  onWithdrawError
15939
15958
  }) {
15940
- const [executions, setExecutions] = useState33([]);
15941
- const [isPolling, setIsPolling] = useState33(false);
15942
- const enabledAtRef = useRef10(/* @__PURE__ */ new Date());
15943
- const trackedRef = useRef10(/* @__PURE__ */ new Map());
15944
- const prevEnabledRef = useRef10(false);
15945
- const onSuccessRef = useRef10(onWithdrawSuccess);
15946
- const onErrorRef = useRef10(onWithdrawError);
15947
- 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(() => {
15948
15967
  onSuccessRef.current = onWithdrawSuccess;
15949
15968
  }, [onWithdrawSuccess]);
15950
- useEffect27(() => {
15969
+ useEffect28(() => {
15951
15970
  onErrorRef.current = onWithdrawError;
15952
15971
  }, [onWithdrawError]);
15953
- useEffect27(() => {
15972
+ useEffect28(() => {
15954
15973
  if (enabled && !prevEnabledRef.current) {
15955
15974
  enabledAtRef.current = /* @__PURE__ */ new Date();
15956
15975
  trackedRef.current.clear();
@@ -15960,7 +15979,7 @@ function useWithdrawPolling({
15960
15979
  }
15961
15980
  prevEnabledRef.current = enabled;
15962
15981
  }, [enabled]);
15963
- useEffect27(() => {
15982
+ useEffect28(() => {
15964
15983
  if (!userId || !enabled) return;
15965
15984
  const enabledAt = enabledAtRef.current;
15966
15985
  const poll = async () => {
@@ -16022,7 +16041,7 @@ function useWithdrawPolling({
16022
16041
  setIsPolling(false);
16023
16042
  };
16024
16043
  }, [userId, publishableKey, enabled]);
16025
- useEffect27(() => {
16044
+ useEffect28(() => {
16026
16045
  if (!enabled || !depositWalletId) return;
16027
16046
  const trigger = async () => {
16028
16047
  try {
@@ -16193,7 +16212,7 @@ function WithdrawDoubleInput({
16193
16212
  }
16194
16213
 
16195
16214
  // src/components/withdrawals/WithdrawForm.tsx
16196
- 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";
16197
16216
  import {
16198
16217
  AlertTriangle as AlertTriangle4,
16199
16218
  ArrowUpDown,
@@ -16670,27 +16689,27 @@ function WithdrawForm({
16670
16689
  footerLeft
16671
16690
  }) {
16672
16691
  const { colors: colors2, fonts, components } = useTheme();
16673
- const [recipientAddress, setRecipientAddress] = useState34(recipientAddressProp || "");
16674
- const [amount, setAmount] = useState34("");
16675
- const [inputUnit, setInputUnit] = useState34("fiat");
16676
- const [isSubmitting, setIsSubmitting] = useState34(false);
16677
- const [submitError, setSubmitError] = useState34(null);
16678
- const [detailsExpanded, setDetailsExpanded] = useState34(false);
16679
- const [glossaryOpen, setGlossaryOpen] = useState34(false);
16680
- const [isMaxed, setIsMaxed] = useState34(false);
16681
- 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(() => {
16682
16701
  setRecipientAddress(recipientAddressProp || "");
16683
16702
  setAmount("");
16684
16703
  setInputUnit("fiat");
16685
16704
  setSubmitError(null);
16686
16705
  setIsMaxed(false);
16687
16706
  }, [recipientAddressProp]);
16688
- useEffect28(() => {
16707
+ useEffect29(() => {
16689
16708
  setIsMaxed(false);
16690
16709
  }, [balanceData?.balanceBaseUnit]);
16691
16710
  const trimmedAddress = recipientAddress.trim();
16692
- const [debouncedAddress, setDebouncedAddress] = useState34(trimmedAddress);
16693
- useEffect28(() => {
16711
+ const [debouncedAddress, setDebouncedAddress] = useState35(trimmedAddress);
16712
+ useEffect29(() => {
16694
16713
  const id = setTimeout(() => setDebouncedAddress(trimmedAddress), 500);
16695
16714
  return () => clearTimeout(id);
16696
16715
  }, [trimmedAddress]);
@@ -17330,7 +17349,7 @@ function WithdrawExecutionItem({
17330
17349
  }
17331
17350
 
17332
17351
  // src/components/withdrawals/WithdrawConfirmingView.tsx
17333
- import { useState as useState35, useEffect as useEffect29 } from "react";
17352
+ import { useState as useState36, useEffect as useEffect30 } from "react";
17334
17353
  import { Fragment as Fragment14, jsx as jsx60, jsxs as jsxs54 } from "react/jsx-runtime";
17335
17354
  function truncateAddress4(addr) {
17336
17355
  if (addr.length <= 12) return addr;
@@ -17344,9 +17363,9 @@ function WithdrawConfirmingView({
17344
17363
  onViewTracker
17345
17364
  }) {
17346
17365
  const { colors: colors2, fonts, components } = useTheme();
17347
- const [showButton, setShowButton] = useState35(false);
17366
+ const [showButton, setShowButton] = useState36(false);
17348
17367
  const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
17349
- useEffect29(() => {
17368
+ useEffect30(() => {
17350
17369
  if (latestExecution) return;
17351
17370
  const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
17352
17371
  return () => clearTimeout(timer);
@@ -17511,14 +17530,14 @@ function WithdrawModal({
17511
17530
  hideOverlay = false
17512
17531
  }) {
17513
17532
  const { colors: colors2, fonts, components } = useTheme();
17514
- const [containerEl, setContainerEl] = useState36(null);
17533
+ const [containerEl, setContainerEl] = useState37(null);
17515
17534
  const containerCallbackRef = useCallback8((el) => {
17516
17535
  setContainerEl(el);
17517
17536
  }, []);
17518
- const [resolvedTheme, setResolvedTheme] = useState36(
17537
+ const [resolvedTheme, setResolvedTheme] = useState37(
17519
17538
  theme === "auto" ? "dark" : theme
17520
17539
  );
17521
- useEffect30(() => {
17540
+ useEffect31(() => {
17522
17541
  if (theme === "auto") {
17523
17542
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
17524
17543
  setResolvedTheme(mq.matches ? "dark" : "light");
@@ -17562,10 +17581,10 @@ function WithdrawModal({
17562
17581
  });
17563
17582
  const selectedToken = selectedTokenSymbol ? destinationTokens.find((t12) => t12.symbol === selectedTokenSymbol) ?? null : null;
17564
17583
  const selectedChain = selectedToken && selectedChainKey ? selectedToken.chains.find((c) => getChainKey5(c.chain_id, c.chain_type) === selectedChainKey) ?? null : null;
17565
- const [view, setView] = useState36("form");
17566
- const [withdrawDepositWalletId, setWithdrawDepositWalletId] = useState36();
17567
- const [selectedExecution, setSelectedExecution] = useState36(null);
17568
- 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);
17569
17588
  const { executions: realtimeExecutions } = useWithdrawPolling({
17570
17589
  userId: externalUserId,
17571
17590
  publishableKey,
@@ -17604,7 +17623,7 @@ function WithdrawModal({
17604
17623
  setSubmittedTxInfo(txInfo);
17605
17624
  setView("confirming");
17606
17625
  }, []);
17607
- const resetViewTimeoutRef = useRef11(null);
17626
+ const resetViewTimeoutRef = useRef12(null);
17608
17627
  const handleClose = useCallback8(() => {
17609
17628
  onOpenChange(false);
17610
17629
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
@@ -17627,7 +17646,7 @@ function WithdrawModal({
17627
17646
  setSubmittedTxInfo(null);
17628
17647
  setWithdrawDepositWalletId(void 0);
17629
17648
  }, [open]);
17630
- useEffect30(() => () => {
17649
+ useEffect31(() => () => {
17631
17650
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
17632
17651
  }, []);
17633
17652
  const handleTokenSymbolChange = useCallback8((symbol) => {
@@ -17750,7 +17769,7 @@ function WithdrawModal({
17750
17769
  }
17751
17770
 
17752
17771
  // src/components/withdrawals/WithdrawTokenSelector.tsx
17753
- import { useState as useState37, useMemo as useMemo14 } from "react";
17772
+ import { useState as useState38, useMemo as useMemo14 } from "react";
17754
17773
  import { Search } from "lucide-react";
17755
17774
  import Fuse2 from "fuse.js";
17756
17775
  import { jsx as jsx62, jsxs as jsxs56 } from "react/jsx-runtime";
@@ -17761,8 +17780,8 @@ function WithdrawTokenSelector({
17761
17780
  onBack
17762
17781
  }) {
17763
17782
  const { themeClass, colors: colors2, fonts, components } = useTheme();
17764
- const [searchQuery, setSearchQuery] = useState37("");
17765
- const [hoveredKey, setHoveredKey] = useState37(null);
17783
+ const [searchQuery, setSearchQuery] = useState38("");
17784
+ const [hoveredKey, setHoveredKey] = useState38(null);
17766
17785
  const allOptions = useMemo14(() => {
17767
17786
  const options = [];
17768
17787
  tokens.forEach((token) => {