@unifold/ui-react 0.1.62 → 0.1.64

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
@@ -20,8 +20,32 @@ import { twMerge } from "tailwind-merge";
20
20
  function cn(...inputs) {
21
21
  return twMerge(clsx(inputs));
22
22
  }
23
- var WALLET_CHAIN_TYPE_STORAGE_KEY = "unifold_last_wallet_type";
23
+ var WALLET_STATE_STORAGE_KEY = "unifold_wallet_state";
24
+ var LEGACY_WALLET_KEYS = [
25
+ "unifold_last_wallet_type",
26
+ "unifold_last_connected_wallet"
27
+ ];
24
28
  var WALLET_USER_DISCONNECTED_KEY = "unifold_wallet_user_disconnected";
29
+ var SOLANA_WALLET_TYPES = /* @__PURE__ */ new Set([
30
+ "phantom-solana",
31
+ "solflare",
32
+ "backpack",
33
+ "glow"
34
+ ]);
35
+ var ETHEREUM_WALLET_TYPES = /* @__PURE__ */ new Set([
36
+ "metamask",
37
+ "phantom-ethereum",
38
+ "coinbase",
39
+ "trust",
40
+ "rainbow",
41
+ "rabby",
42
+ "okx"
43
+ ]);
44
+ function walletTypeToChain(t12) {
45
+ if (SOLANA_WALLET_TYPES.has(t12)) return "solana";
46
+ if (ETHEREUM_WALLET_TYPES.has(t12)) return "ethereum";
47
+ return void 0;
48
+ }
25
49
  function getUserDisconnectedWallet() {
26
50
  if (typeof window === "undefined") return false;
27
51
  try {
@@ -41,26 +65,35 @@ function setUserDisconnectedWallet(disconnected) {
41
65
  } catch {
42
66
  }
43
67
  }
44
- function getStoredWalletChainType() {
68
+ function getStoredWalletState() {
45
69
  if (typeof window === "undefined") return void 0;
46
70
  try {
47
- const stored = localStorage.getItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
48
- if (stored === "ethereum" || stored === "solana") return stored;
71
+ const raw = localStorage.getItem(WALLET_STATE_STORAGE_KEY);
72
+ if (!raw) return void 0;
73
+ const chainType = walletTypeToChain(raw);
74
+ if (!chainType) {
75
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
76
+ return void 0;
77
+ }
78
+ return { walletType: raw, chainType };
49
79
  } catch {
80
+ return void 0;
50
81
  }
51
- return void 0;
52
82
  }
53
- function setStoredWalletChainType(chainType) {
83
+ function setStoredWalletState(walletType) {
54
84
  if (typeof window === "undefined") return;
85
+ if (!walletTypeToChain(walletType)) return;
55
86
  try {
56
- localStorage.setItem(WALLET_CHAIN_TYPE_STORAGE_KEY, chainType);
87
+ localStorage.setItem(WALLET_STATE_STORAGE_KEY, walletType);
88
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
57
89
  } catch {
58
90
  }
59
91
  }
60
- function clearStoredWalletChainType() {
92
+ function clearStoredWalletState() {
61
93
  if (typeof window === "undefined") return;
62
94
  try {
63
- localStorage.removeItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
95
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
96
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
64
97
  } catch {
65
98
  }
66
99
  }
@@ -431,6 +464,36 @@ function ThemeProvider({
431
464
  );
432
465
  return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: contextValue, children });
433
466
  }
467
+ function AccentColorOverride({
468
+ accentColor,
469
+ accentForeground,
470
+ children
471
+ }) {
472
+ const parent = useTheme();
473
+ const value = React.useMemo(() => {
474
+ if (!accentColor) return parent;
475
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
476
+ const nextColors = {
477
+ ...parent.colors,
478
+ primary: accentColor,
479
+ primaryForeground: foreground
480
+ };
481
+ const nextComponents = {
482
+ ...parent.components,
483
+ button: {
484
+ ...parent.components.button,
485
+ primaryBackground: accentColor,
486
+ primaryText: foreground
487
+ },
488
+ card: {
489
+ ...parent.components.card,
490
+ iconBackgroundColor: `${accentColor}26`
491
+ }
492
+ };
493
+ return { ...parent, colors: nextColors, components: nextComponents };
494
+ }, [parent, accentColor, accentForeground]);
495
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
496
+ }
434
497
  function useTheme() {
435
498
  const context = React.useContext(ThemeContext);
436
499
  if (!context) {
@@ -674,7 +737,63 @@ import { useEffect as useEffect2, useLayoutEffect, useState as useState2 } from
674
737
  import { getAddressBalance } from "@unifold/core";
675
738
 
676
739
  // src/components/deposits/browser-wallets/utils.ts
677
- import { IneligibilityReason } from "@unifold/core";
740
+ import {
741
+ IneligibilityReason
742
+ } from "@unifold/core";
743
+ var normalize = (value) => value?.toLowerCase();
744
+ function sourceTokenMatchesDefaultSource(token, defaultSource) {
745
+ if (!token || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
746
+ return false;
747
+ }
748
+ if (token.chain_type !== defaultSource.defaultSourceChainType || token.chain_id !== defaultSource.defaultSourceChainId) {
749
+ return false;
750
+ }
751
+ if (defaultSource.defaultSourceTokenAddress && normalize(token.token_address) === normalize(defaultSource.defaultSourceTokenAddress)) {
752
+ return true;
753
+ }
754
+ if (defaultSource.defaultSourceTokenAddress) {
755
+ return false;
756
+ }
757
+ return !!defaultSource.defaultSourceSymbol && normalize(token.symbol) === normalize(defaultSource.defaultSourceSymbol);
758
+ }
759
+ function isDefaultSourceBalance(balance, defaultSource) {
760
+ return isBalanceEligible(balance) && sourceTokenMatchesDefaultSource(getTokenFromBalance(balance), defaultSource);
761
+ }
762
+ function compareBalancesWithDefaultSource(a, b, defaultSource) {
763
+ const aDefault = isDefaultSourceBalance(a, defaultSource);
764
+ const bDefault = isDefaultSourceBalance(b, defaultSource);
765
+ if (aDefault && !bDefault) return -1;
766
+ if (!aDefault && bDefault) return 1;
767
+ const aEligible = isBalanceEligible(a);
768
+ const bEligible = isBalanceEligible(b);
769
+ if (aEligible && !bEligible) return -1;
770
+ if (!aEligible && bEligible) return 1;
771
+ return 0;
772
+ }
773
+ function resolveDefaultSourceSymbol(supportedTokens, defaultSource) {
774
+ if (!supportedTokens?.length || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
775
+ return null;
776
+ }
777
+ if (defaultSource.defaultSourceTokenAddress) {
778
+ for (const token of supportedTokens) {
779
+ const matchingChain = token.chains.find(
780
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId && normalize(chain.token_address) === normalize(defaultSource.defaultSourceTokenAddress)
781
+ );
782
+ if (matchingChain) return token.symbol;
783
+ }
784
+ }
785
+ if (!defaultSource.defaultSourceSymbol) return null;
786
+ for (const token of supportedTokens) {
787
+ if (normalize(token.symbol) !== normalize(defaultSource.defaultSourceSymbol)) {
788
+ continue;
789
+ }
790
+ const matchingChain = token.chains.find(
791
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId
792
+ );
793
+ if (matchingChain) return token.symbol;
794
+ }
795
+ return null;
796
+ }
678
797
  function formatUsdFromBalancePercent(maxUsdAmount, percent) {
679
798
  if (maxUsdAmount <= 0 || percent < 0) return "";
680
799
  const raw = maxUsdAmount * percent / 100;
@@ -1502,6 +1621,7 @@ function useDepositPolling({
1502
1621
  clientSecret,
1503
1622
  depositConfirmationMode = "auto_ui",
1504
1623
  depositWalletId,
1624
+ depositWalletIds,
1505
1625
  enabled = true,
1506
1626
  immediateDirectPolling = false,
1507
1627
  onDepositSuccess,
@@ -1647,21 +1767,25 @@ function useDepositPolling({
1647
1767
  setIsPolling(false);
1648
1768
  };
1649
1769
  }, [userId, publishableKey, clientSecret, enabled]);
1770
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
1650
1771
  useEffect3(() => {
1651
- if (!pollingEnabled || !depositWalletId) return;
1772
+ if (!pollingEnabled || !pollWalletIdsKey) return;
1773
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
1652
1774
  const triggerPoll = async () => {
1653
- try {
1654
- await pollDirectExecutions(
1655
- { deposit_wallet_id: depositWalletId },
1656
- publishableKey
1657
- );
1658
- } catch {
1659
- }
1775
+ await Promise.all(
1776
+ ids.map(
1777
+ (id) => pollDirectExecutions(
1778
+ { deposit_wallet_id: id },
1779
+ publishableKey
1780
+ ).catch(() => {
1781
+ })
1782
+ )
1783
+ );
1660
1784
  };
1661
1785
  triggerPoll();
1662
1786
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
1663
1787
  return () => clearInterval(interval);
1664
- }, [pollingEnabled, depositWalletId, publishableKey]);
1788
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
1665
1789
  const handleIveDeposited = () => {
1666
1790
  setPollingEnabled(true);
1667
1791
  setShowWaitingUi(true);
@@ -2885,6 +3009,7 @@ function BuyWithCard({
2885
3009
  if (!selectedProvider) return "0.000000";
2886
3010
  return selectedProvider.destination_amount.toFixed(6);
2887
3011
  };
3012
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
2888
3013
  const selectedCurrencyData = fiatCurrencies.find(
2889
3014
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
2890
3015
  );
@@ -3070,9 +3195,12 @@ function BuyWithCard({
3070
3195
  /* @__PURE__ */ jsx11(
3071
3196
  "button",
3072
3197
  {
3073
- onClick: () => handleViewChange("quotes"),
3198
+ onClick: () => {
3199
+ if (canOpenProviderSelector) handleViewChange("quotes");
3200
+ },
3074
3201
  disabled: quotesLoading || quotes.length === 0,
3075
- className: "uf-w-full hover:uf-bg-accent uf-transition-colors uf-p-4 uf-group disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
3202
+ "aria-disabled": !canOpenProviderSelector,
3203
+ className: `uf-w-full uf-transition-colors uf-p-4 uf-group disabled:uf-opacity-50 disabled:uf-cursor-not-allowed ${canOpenProviderSelector ? "hover:uf-bg-accent uf-cursor-pointer" : "uf-cursor-default"}`,
3076
3204
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
3077
3205
  children: quotesLoading ? /* @__PURE__ */ jsxs9("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
3078
3206
  /* @__PURE__ */ jsx11(
@@ -3099,7 +3227,7 @@ function BuyWithCard({
3099
3227
  )
3100
3228
  ] })
3101
3229
  ] }) : /* @__PURE__ */ jsxs9("div", { className: "uf-w-full uf-text-left", children: [
3102
- isAutoSelected && /* @__PURE__ */ jsx11(
3230
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ jsx11(
3103
3231
  "div",
3104
3232
  {
3105
3233
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -3135,7 +3263,7 @@ function BuyWithCard({
3135
3263
  ),
3136
3264
  selectedProvider.low_kyc === false && /* @__PURE__ */ jsx11("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ jsx11("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
3137
3265
  ] }),
3138
- quotes.length > 0 && /* @__PURE__ */ jsx11(
3266
+ canOpenProviderSelector && /* @__PURE__ */ jsx11(
3139
3267
  ChevronRight,
3140
3268
  {
3141
3269
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -5348,70 +5476,106 @@ function identifyEthWallet(provider, hint) {
5348
5476
  }
5349
5477
  return { type: "metamask", name: "Wallet", icon: "metamask" };
5350
5478
  }
5479
+ var EIP6963_ID_TO_WALLET_TYPE = {
5480
+ metamask: "metamask",
5481
+ phantom: "phantom-ethereum",
5482
+ coinbase: "coinbase",
5483
+ trust: "trust",
5484
+ rainbow: "rainbow",
5485
+ rabby: "rabby",
5486
+ okx: "okx"
5487
+ };
5488
+ function inferEthWalletType(provider, walletId) {
5489
+ if (EIP6963_ID_TO_WALLET_TYPE[walletId]) return EIP6963_ID_TO_WALLET_TYPE[walletId];
5490
+ const any = provider;
5491
+ if (provider.isPhantom) return "phantom-ethereum";
5492
+ if (any.isCoinbaseWallet) return "coinbase";
5493
+ if (any.isRabby) return "rabby";
5494
+ if (any.isTrust) return "trust";
5495
+ if (any.isRainbow) return "rainbow";
5496
+ if (any.isOkxWallet) return "okx";
5497
+ if (provider.isMetaMask && !provider.isPhantom) return "metamask";
5498
+ return null;
5499
+ }
5500
+ function solanaCandidate(provider, type, name, icon) {
5501
+ return {
5502
+ walletType: type,
5503
+ detect: async () => {
5504
+ if (!provider) return null;
5505
+ if (provider.isConnected && provider.publicKey) {
5506
+ return { type, name, address: provider.publicKey.toString(), icon };
5507
+ }
5508
+ try {
5509
+ const resp = await provider.connect({ onlyIfTrusted: true });
5510
+ if (resp.publicKey) {
5511
+ return { type, name, address: resp.publicKey.toString(), icon };
5512
+ }
5513
+ } catch {
5514
+ }
5515
+ return null;
5516
+ }
5517
+ };
5518
+ }
5519
+ function ethereumCandidate(provider, walletId) {
5520
+ return {
5521
+ walletType: inferEthWalletType(provider, walletId),
5522
+ detect: async () => {
5523
+ try {
5524
+ const accounts = await provider.request({ method: "eth_accounts" });
5525
+ if (!accounts?.length) return null;
5526
+ const resolved = identifyEthWallet(provider, walletId);
5527
+ return { ...resolved, address: accounts[0] };
5528
+ } catch {
5529
+ return null;
5530
+ }
5531
+ }
5532
+ };
5533
+ }
5534
+ function buildCandidates(win, chainType) {
5535
+ const candidates = [];
5536
+ if (!chainType || chainType === "solana") {
5537
+ candidates.push(
5538
+ solanaCandidate(win.phantom?.solana, "phantom-solana", "Phantom", "phantom"),
5539
+ solanaCandidate(win.solflare, "solflare", "Solflare", "solflare"),
5540
+ solanaCandidate(win.backpack, "backpack", "Backpack", "backpack"),
5541
+ solanaCandidate(win.glow, "glow", "Glow", "glow")
5542
+ );
5543
+ }
5544
+ if (!chainType || chainType === "ethereum") {
5545
+ const seen = /* @__PURE__ */ new Set();
5546
+ const addEth = (provider, walletId) => {
5547
+ if (!provider || seen.has(provider)) return;
5548
+ seen.add(provider);
5549
+ candidates.push(ethereumCandidate(provider, walletId));
5550
+ };
5551
+ for (const { provider, walletId } of getEip6963Providers()) {
5552
+ addEth(
5553
+ provider,
5554
+ walletId === "unknown" ? "default" : walletId
5555
+ );
5556
+ }
5557
+ addEth(win.phantom?.ethereum, "phantom");
5558
+ addEth(win.coinbaseWalletExtension, "coinbase");
5559
+ addEth(win.okxwallet, "okx");
5560
+ addEth(win.trustwallet?.ethereum, "trust");
5561
+ addEth(win.ethereum, "default");
5562
+ }
5563
+ return candidates;
5564
+ }
5351
5565
  async function detectConnectedBrowserWallet(chainType) {
5352
5566
  if (typeof window === "undefined") return null;
5353
5567
  if (getUserDisconnectedWallet()) return null;
5354
5568
  try {
5355
5569
  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
- }
5570
+ const candidates = buildCandidates(win, chainType);
5571
+ const preferred = getStoredWalletState();
5572
+ if (preferred && (!chainType || preferred.chainType === chainType)) {
5573
+ const idx = candidates.findIndex((c) => c.walletType === preferred.walletType);
5574
+ if (idx > 0) candidates.unshift(...candidates.splice(idx, 1));
5381
5575
  }
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
- }
5576
+ for (const c of candidates) {
5577
+ const found = await c.detect();
5578
+ if (found) return found;
5415
5579
  }
5416
5580
  } catch (error) {
5417
5581
  console.error("[detectConnectedBrowserWallet] detection error:", error);
@@ -7615,6 +7779,7 @@ function BrowserWalletButton({
7615
7779
  if (solanaProvider?.isPhantom) {
7616
7780
  const { publicKey } = await solanaProvider.connect();
7617
7781
  setUserDisconnectedWallet(false);
7782
+ setStoredWalletState("phantom-solana");
7618
7783
  setWallet({
7619
7784
  type: "phantom-solana",
7620
7785
  name: "Phantom",
@@ -7634,8 +7799,10 @@ function BrowserWalletButton({
7634
7799
  if (accounts && accounts.length > 0) {
7635
7800
  setUserDisconnectedWallet(false);
7636
7801
  const isPhantom = ethProvider.isPhantom;
7802
+ const walletType = isPhantom ? "phantom-ethereum" : "metamask";
7803
+ setStoredWalletState(walletType);
7637
7804
  setWallet({
7638
- type: isPhantom ? "phantom-ethereum" : "metamask",
7805
+ type: walletType,
7639
7806
  name: isPhantom ? "Phantom" : "MetaMask",
7640
7807
  address: accounts[0],
7641
7808
  icon: isPhantom ? "phantom" : "metamask"
@@ -7989,7 +8156,11 @@ function CoinbaseConnect({
7989
8156
  onDisconnect,
7990
8157
  skipToHoldings,
7991
8158
  canGoBack = true,
7992
- onExecutionsChange
8159
+ onExecutionsChange,
8160
+ defaultSourceChainType,
8161
+ defaultSourceChainId,
8162
+ defaultSourceTokenAddress,
8163
+ defaultSourceSymbol
7993
8164
  }) {
7994
8165
  const { colors: colors2, fonts, components } = useTheme();
7995
8166
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -8054,6 +8225,21 @@ function CoinbaseConnect({
8054
8225
  params: defaultTokenParams,
8055
8226
  publishableKey
8056
8227
  });
8228
+ const defaultSourceCurrency = useMemo4(
8229
+ () => resolveDefaultSourceSymbol(supportedTokensData?.data, {
8230
+ defaultSourceChainType,
8231
+ defaultSourceChainId,
8232
+ defaultSourceTokenAddress,
8233
+ defaultSourceSymbol
8234
+ })?.toLowerCase() ?? null,
8235
+ [
8236
+ supportedTokensData,
8237
+ defaultSourceChainType,
8238
+ defaultSourceChainId,
8239
+ defaultSourceTokenAddress,
8240
+ defaultSourceSymbol
8241
+ ]
8242
+ );
8057
8243
  const sortedHoldings = useMemo4(() => {
8058
8244
  const supported = [];
8059
8245
  const unsupported = [];
@@ -8063,13 +8249,42 @@ function CoinbaseConnect({
8063
8249
  if (isSupported) supported.push(account);
8064
8250
  else unsupported.push(account);
8065
8251
  });
8252
+ if (defaultSourceCurrency) {
8253
+ const defaultIndex = supported.findIndex(
8254
+ (account) => account.currency.toLowerCase() === defaultSourceCurrency
8255
+ );
8256
+ if (defaultIndex > 0) {
8257
+ const [defaultHolding] = supported.splice(defaultIndex, 1);
8258
+ supported.unshift(defaultHolding);
8259
+ }
8260
+ }
8066
8261
  return [...supported, ...unsupported];
8067
- }, [holdings, supportedSymbols, exchangeSupportedCurrencies]);
8262
+ }, [
8263
+ holdings,
8264
+ supportedSymbols,
8265
+ exchangeSupportedCurrencies,
8266
+ defaultSourceCurrency
8267
+ ]);
8068
8268
  const selectedHoldingIsSupported = useMemo4(() => {
8069
8269
  if (!selectedHolding) return false;
8070
8270
  const currencyLower = selectedHolding.currency.toLowerCase();
8071
8271
  return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
8072
8272
  }, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
8273
+ useEffect17(() => {
8274
+ if (!defaultSourceCurrency || selectedHolding) return;
8275
+ const defaultHolding = sortedHoldings.find((account) => {
8276
+ const currencyLower = account.currency.toLowerCase();
8277
+ return currencyLower === defaultSourceCurrency && (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
8278
+ });
8279
+ if (!defaultHolding) return;
8280
+ setSelectedHolding(defaultHolding);
8281
+ }, [
8282
+ defaultSourceCurrency,
8283
+ selectedHolding,
8284
+ sortedHoldings,
8285
+ supportedSymbols,
8286
+ exchangeSupportedCurrencies
8287
+ ]);
8073
8288
  const exchangeName = selectedExchange?.service_provider_display_name || "Exchange";
8074
8289
  const {
8075
8290
  executions: depositExecutions,
@@ -12338,8 +12553,10 @@ import { ExternalLink as ExternalLink3, Loader2 as Loader28 } from "lucide-react
12338
12553
  import {
12339
12554
  getAddressBalances as getAddressBalances2,
12340
12555
  getSupportedDepositTokens as getSupportedDepositTokens2,
12556
+ ExecutionStatus as ExecutionStatus5,
12341
12557
  buildSolanaTransaction,
12342
- sendSolanaTransaction as sendSolanaTransactionToBackend
12558
+ sendSolanaTransaction as sendSolanaTransactionToBackend,
12559
+ getWalletMobileDeepLink
12343
12560
  } from "@unifold/core";
12344
12561
 
12345
12562
  // src/hooks/use-deposit-quote.ts
@@ -12399,6 +12616,68 @@ function useDepositQuote(params) {
12399
12616
  });
12400
12617
  }
12401
12618
 
12619
+ // src/hooks/use-external-wallets.ts
12620
+ import { useQuery as useQuery13 } from "@tanstack/react-query";
12621
+ import { getExternalWallets } from "@unifold/core";
12622
+ function useExternalWallets({
12623
+ publishableKey,
12624
+ enabled = true
12625
+ }) {
12626
+ const { data: wallets = [], isLoading } = useQuery13({
12627
+ queryKey: ["unifold", "external-wallets", publishableKey],
12628
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
12629
+ enabled: enabled && !!publishableKey,
12630
+ staleTime: 1e3 * 60 * 30,
12631
+ refetchOnMount: false,
12632
+ refetchOnWindowFocus: false
12633
+ });
12634
+ return { wallets, isLoading };
12635
+ }
12636
+
12637
+ // src/theme/walletBrandColors.ts
12638
+ var WALLET_BRAND_COLORS = {
12639
+ phantom: "#AB9FF2",
12640
+ metamask: "#F6851B",
12641
+ coinbase: "#0052FF",
12642
+ trust: "#3375BB",
12643
+ rainbow: "#5B6CFF",
12644
+ rabby: "#7084FF",
12645
+ okx: "#000000"
12646
+ };
12647
+ function normalizeWalletId(type) {
12648
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
12649
+ }
12650
+ function getWalletBrandColor(type, mode = "dark") {
12651
+ if (!type) return void 0;
12652
+ const id = normalizeWalletId(type);
12653
+ const color = WALLET_BRAND_COLORS[id];
12654
+ if (!color) return void 0;
12655
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
12656
+ return color;
12657
+ }
12658
+ function getContrastingTextColor(hex) {
12659
+ const c = hex.replace("#", "");
12660
+ if (c.length !== 6) return "#FFFFFF";
12661
+ const r = parseInt(c.slice(0, 2), 16);
12662
+ const g = parseInt(c.slice(2, 4), 16);
12663
+ const b = parseInt(c.slice(4, 6), 16);
12664
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
12665
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
12666
+ }
12667
+
12668
+ // src/components/deposits/browser-wallets/mobileDeepLinks.ts
12669
+ function isMobileDevice() {
12670
+ if (typeof navigator === "undefined") return false;
12671
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
12672
+ }
12673
+ function getMobilePlatform() {
12674
+ if (typeof navigator === "undefined") return null;
12675
+ const ua = navigator.userAgent;
12676
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
12677
+ if (/android/i.test(ua)) return "android";
12678
+ return null;
12679
+ }
12680
+
12402
12681
  // src/components/deposits/browser-wallets/SelectTokenView.tsx
12403
12682
  import { Loader2 as Loader25 } from "lucide-react";
12404
12683
 
@@ -13427,18 +13706,46 @@ var WALLET_ICONS3 = {
13427
13706
  backpack: BackpackIcon,
13428
13707
  glow: GlowIcon
13429
13708
  };
13430
- var WALLET_DEFINITIONS = [
13431
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
13432
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
13433
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
13434
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
13435
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
13436
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
13437
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
13438
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
13439
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
13440
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
13709
+ var FALLBACK_WALLET_DEFINITIONS = [
13710
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
13711
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
13712
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
13713
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
13714
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
13715
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
13716
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
13441
13717
  ];
13718
+ function getMobileInstallUrl(walletId, defaultUrl) {
13719
+ if (!isMobileDevice()) return defaultUrl;
13720
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
13721
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
13722
+ const stores = {
13723
+ rabby: {
13724
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
13725
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
13726
+ },
13727
+ glow: {
13728
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
13729
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
13730
+ }
13731
+ };
13732
+ const entry = stores[walletId];
13733
+ if (!entry) return defaultUrl;
13734
+ return isIOS ? entry.ios : entry.android;
13735
+ }
13736
+ function normalizeTokenAddress(address) {
13737
+ const normalized = (address ?? "").toLowerCase();
13738
+ if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
13739
+ return "native";
13740
+ }
13741
+ return normalized;
13742
+ }
13743
+ function balancesRepresentSameToken(a, b) {
13744
+ const tokenA = getTokenFromBalance(a);
13745
+ const tokenB = getTokenFromBalance(b);
13746
+ if (!tokenA || !tokenB) return false;
13747
+ return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
13748
+ }
13442
13749
  function getSolanaProviders() {
13443
13750
  if (typeof window === "undefined") return {};
13444
13751
  const win = window;
@@ -13461,7 +13768,7 @@ function getLegacyEvmProviders() {
13461
13768
  okxEthereum: win.okxwallet
13462
13769
  };
13463
13770
  }
13464
- function detectAvailableWallets(filterChainType) {
13771
+ function detectAvailableWallets(definitions, filterChainType) {
13465
13772
  const solProviders = getSolanaProviders();
13466
13773
  const legacyEvm = getLegacyEvmProviders();
13467
13774
  const eip6963List = getEip6963Providers();
@@ -13487,7 +13794,7 @@ function detectAvailableWallets(filterChainType) {
13487
13794
  return false;
13488
13795
  }
13489
13796
  });
13490
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13797
+ return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13491
13798
  let isInstalled = false;
13492
13799
  const detectedNetworks = [];
13493
13800
  switch (wallet.id) {
@@ -13581,13 +13888,17 @@ function WalletConnect({
13581
13888
  checkoutRemainingBaseUnits,
13582
13889
  stablecoinParity = false,
13583
13890
  productType,
13891
+ defaultSourceChainType,
13892
+ defaultSourceChainId,
13893
+ defaultSourceTokenAddress,
13894
+ defaultSourceSymbol,
13584
13895
  onBack: parentOnBack,
13585
13896
  onClose,
13586
13897
  canGoBack = true,
13587
13898
  depositWalletsLoading = false,
13588
13899
  onExecutionsChange
13589
13900
  }) {
13590
- const { colors: colors2, fonts, components } = useTheme();
13901
+ const { colors: colors2, fonts, components, mode } = useTheme();
13591
13902
  const walletProvidedAtMount = React30.useRef(!!initialWalletInfo && !!initialDepositWallet);
13592
13903
  const [activeWalletInfo, setActiveWalletInfo] = React30.useState(initialWalletInfo ?? null);
13593
13904
  const [activeDepositWallet, setActiveDepositWallet] = React30.useState(initialDepositWallet ?? null);
@@ -13611,7 +13922,37 @@ function WalletConnect({
13611
13922
  setEip6963ProviderCount(providers.length);
13612
13923
  });
13613
13924
  }, []);
13614
- const availableWallets = React30.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13925
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
13926
+ const walletDefinitions = React30.useMemo(
13927
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
13928
+ id: w.id,
13929
+ name: w.name,
13930
+ networks: w.chain_types,
13931
+ installUrl: w.install_url,
13932
+ supportsMobileBrowse: w.supports_mobile_browse,
13933
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
13934
+ })) : FALLBACK_WALLET_DEFINITIONS,
13935
+ [backendWallets]
13936
+ );
13937
+ const availableWallets = React30.useMemo(
13938
+ () => detectAvailableWallets(walletDefinitions),
13939
+ [walletDefinitions, eip6963ProviderCount]
13940
+ );
13941
+ const [isMobile, setIsMobile] = React30.useState(false);
13942
+ React30.useEffect(() => {
13943
+ setIsMobile(isMobileDevice());
13944
+ }, []);
13945
+ const mobileDepositAddresses = React30.useMemo(
13946
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
13947
+ [depositWallets]
13948
+ );
13949
+ const mobileDepositWalletIds = React30.useMemo(
13950
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
13951
+ [depositWallets]
13952
+ );
13953
+ const [mobileRedirect, setMobileRedirect] = React30.useState(null);
13954
+ const [pendingMobileWallet, setPendingMobileWallet] = React30.useState(null);
13955
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React30.useState(false);
13615
13956
  React30.useEffect(() => {
13616
13957
  if (!standalone || autoResolved || detectingWallet) return;
13617
13958
  if (!detectedWallet) {
@@ -13670,9 +14011,36 @@ function WalletConnect({
13670
14011
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
13671
14012
  transition: "opacity 150ms ease, transform 150ms ease"
13672
14013
  };
13673
- const handleWalletClick = (wallet) => {
14014
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
14015
+ try {
14016
+ const res = await getWalletMobileDeepLink(
14017
+ wallet.id,
14018
+ depositAddresses,
14019
+ publishableKey
14020
+ );
14021
+ if (res.deeplink) {
14022
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
14023
+ setAwaitingMobileDeposit(true);
14024
+ transitionTo("mobile_redirect");
14025
+ window.location.href = res.deeplink;
14026
+ return true;
14027
+ }
14028
+ } catch {
14029
+ }
14030
+ return false;
14031
+ };
14032
+ const handleWalletClick = async (wallet) => {
13674
14033
  if (!wallet.isInstalled) {
13675
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
14034
+ const platform = getMobilePlatform();
14035
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform ?? "");
14036
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
14037
+ if (mobileDepositAddresses.length === 0) {
14038
+ setPendingMobileWallet(wallet);
14039
+ return;
14040
+ }
14041
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
14042
+ }
14043
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
13676
14044
  return;
13677
14045
  }
13678
14046
  setSelectedWalletDef(wallet);
@@ -13688,6 +14056,27 @@ function WalletConnect({
13688
14056
  if (!selectedWalletDef) return;
13689
14057
  handleConnectWallet(selectedWalletDef, network);
13690
14058
  };
14059
+ React30.useEffect(() => {
14060
+ if (!pendingMobileWallet) return;
14061
+ if (mobileDepositAddresses.length > 0) {
14062
+ const wallet = pendingMobileWallet;
14063
+ setPendingMobileWallet(null);
14064
+ void (async () => {
14065
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
14066
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
14067
+ }
14068
+ })();
14069
+ return;
14070
+ }
14071
+ const timeout = setTimeout(() => {
14072
+ setPendingMobileWallet((current) => {
14073
+ if (!current) return null;
14074
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
14075
+ return null;
14076
+ });
14077
+ }, 8e3);
14078
+ return () => clearTimeout(timeout);
14079
+ }, [pendingMobileWallet, mobileDepositAddresses]);
13691
14080
  const handleConnectWallet = async (wallet, network) => {
13692
14081
  setConnectingNetwork(network);
13693
14082
  transitionTo("connecting");
@@ -13741,6 +14130,7 @@ function WalletConnect({
13741
14130
  metamask: "metamask"
13742
14131
  };
13743
14132
  const walletType = walletIdToType[wallet.id] || "metamask";
14133
+ setStoredWalletState(walletType);
13744
14134
  connectedInfo = { type: walletType, name: wallet.name, address: accounts[0], icon: wallet.id };
13745
14135
  } else {
13746
14136
  const solProviders = getSolanaProviders();
@@ -13769,6 +14159,7 @@ function WalletConnect({
13769
14159
  const response = await provider.connect();
13770
14160
  setUserDisconnectedWallet(false);
13771
14161
  const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
14162
+ setStoredWalletState(walletType);
13772
14163
  connectedInfo = { type: walletType, name: wallet.name, address: response.publicKey.toString(), icon: wallet.id };
13773
14164
  }
13774
14165
  const walletChainType = network === "solana" ? "solana" : "ethereum";
@@ -13830,14 +14221,32 @@ function WalletConnect({
13830
14221
  userId,
13831
14222
  publishableKey,
13832
14223
  clientSecret,
14224
+ // In-tab flow: poll the single connected deposit wallet.
13833
14225
  depositWalletId: activeDepositWallet?.id ?? "",
13834
- enabled: hasSignedTransaction && !!activeDepositWallet,
14226
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
14227
+ // chain's deposit wallet. Detection still happens via the single /query by
14228
+ // external_user_id, which already spans all chains.
14229
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
14230
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
13835
14231
  onDepositSuccess,
13836
14232
  onDepositError
13837
14233
  });
13838
14234
  React30.useEffect(() => {
13839
14235
  onExecutionsChange?.(depositExecutions);
13840
14236
  }, [depositExecutions, onExecutionsChange]);
14237
+ const latestDepositExecution = React30.useMemo(() => {
14238
+ if (depositExecutions.length === 0) return null;
14239
+ return [...depositExecutions].sort((a, b) => {
14240
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
14241
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
14242
+ return tb - ta;
14243
+ })[0];
14244
+ }, [depositExecutions]);
14245
+ React30.useEffect(() => {
14246
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
14247
+ transitionTo("mobile_deposit_status");
14248
+ }
14249
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
13841
14250
  React30.useEffect(() => {
13842
14251
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
13843
14252
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -13883,18 +14292,33 @@ function WalletConnect({
13883
14292
  getAddressBalances2(activeWalletInfo.address, sct, publishableKey).then((response) => {
13884
14293
  if (cancelled) return;
13885
14294
  const nonZero = response.balances.filter((b) => b.amount !== "0");
13886
- const sorted = [...nonZero].sort((a, b) => {
13887
- const ae = isBalanceEligible(a);
13888
- const be = isBalanceEligible(b);
13889
- if (ae && !be) return -1;
13890
- if (!ae && be) return 1;
13891
- return 0;
13892
- });
14295
+ const defaultSource = {
14296
+ defaultSourceChainType,
14297
+ defaultSourceChainId,
14298
+ defaultSourceTokenAddress,
14299
+ defaultSourceSymbol
14300
+ };
14301
+ const sorted = [...nonZero].sort(
14302
+ (a, b) => compareBalancesWithDefaultSource(a, b, defaultSource)
14303
+ );
13893
14304
  setBalances(sorted);
13894
14305
  const totalUsd = nonZero.reduce((sum, b) => b.amount_usd ? sum + parseFloat(b.amount_usd) : sum, 0);
13895
14306
  if (totalUsd > 0) setTotalBalanceUsd(totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }));
13896
14307
  const eligible = sorted.filter(isBalanceEligible);
13897
- if (eligible.length === 1) setSelectedBalance(eligible[0]);
14308
+ const defaultBalance = sorted.find(
14309
+ (balance) => isDefaultSourceBalance(balance, defaultSource)
14310
+ );
14311
+ setSelectedBalance((current) => {
14312
+ if (current) {
14313
+ const currentInNewBalances = sorted.find(
14314
+ (balance) => balancesRepresentSameToken(balance, current)
14315
+ );
14316
+ if (currentInNewBalances) return currentInNewBalances;
14317
+ }
14318
+ if (defaultBalance) return defaultBalance;
14319
+ if (eligible.length === 1) return eligible[0];
14320
+ return null;
14321
+ });
13898
14322
  }).catch((err) => {
13899
14323
  if (!cancelled) {
13900
14324
  console.error("[WalletConnect] Error fetching balances:", err);
@@ -13906,7 +14330,15 @@ function WalletConnect({
13906
14330
  return () => {
13907
14331
  cancelled = true;
13908
14332
  };
13909
- }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
14333
+ }, [
14334
+ activeWalletInfo?.address,
14335
+ activeDepositWallet?.chain_type,
14336
+ publishableKey,
14337
+ defaultSourceChainType,
14338
+ defaultSourceChainId,
14339
+ defaultSourceTokenAddress,
14340
+ defaultSourceSymbol
14341
+ ]);
13910
14342
  const usdToTokenRate = React30.useMemo(() => {
13911
14343
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
13912
14344
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
@@ -13945,6 +14377,16 @@ function WalletConnect({
13945
14377
  setSelectedWalletDef(null);
13946
14378
  setConnectingNetwork(null);
13947
14379
  break;
14380
+ case "mobile_redirect":
14381
+ transitionTo("select_wallet");
14382
+ setMobileRedirect(null);
14383
+ setAwaitingMobileDeposit(false);
14384
+ break;
14385
+ case "mobile_deposit_status":
14386
+ transitionTo("select_wallet");
14387
+ setMobileRedirect(null);
14388
+ setAwaitingMobileDeposit(false);
14389
+ break;
13948
14390
  case "select_token":
13949
14391
  if (walletProvidedAtMount.current) parentOnBack?.();
13950
14392
  else transitionTo("select_wallet");
@@ -14130,33 +14572,40 @@ function WalletConnect({
14130
14572
  return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14131
14573
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14132
14574
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
14133
- /* @__PURE__ */ jsx54("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Select a wallet to connect" }),
14134
- /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ jsxs48(
14135
- "button",
14136
- {
14137
- onClick: () => handleWalletClick(wallet),
14138
- disabled: isWalletConnecting,
14139
- className: "uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between hover:uf-opacity-90 disabled:uf-opacity-50",
14140
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
14141
- children: [
14142
- /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
14143
- WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ jsx54(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ jsx54("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
14144
- /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
14145
- ] }),
14146
- wallet.isInstalled ? /* @__PURE__ */ jsx54("span", { className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Detected" }) : /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
14147
- /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
14148
- /* @__PURE__ */ jsx54(ExternalLink3, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
14149
- ] })
14150
- ]
14151
- },
14152
- wallet.id
14153
- )) }),
14575
+ /* @__PURE__ */ jsx54("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: isMobile ? "Open this page in your wallet's app to connect" : "Select a wallet to connect" }),
14576
+ /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
14577
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
14578
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
14579
+ const isPending = pendingMobileWallet?.id === wallet.id;
14580
+ return /* @__PURE__ */ jsxs48(
14581
+ "button",
14582
+ {
14583
+ onClick: () => void handleWalletClick(wallet),
14584
+ disabled: isWalletConnecting || !!pendingMobileWallet,
14585
+ className: "uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between hover:uf-opacity-90 disabled:uf-opacity-50",
14586
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
14587
+ children: [
14588
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
14589
+ WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ jsx54(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ jsx54("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
14590
+ /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
14591
+ ] }),
14592
+ isPending ? /* @__PURE__ */ jsx54(Loader28, { className: "uf-w-4 uf-h-4 uf-animate-spin", style: { color: colors2.primary } }) : wallet.isInstalled ? /* @__PURE__ */ jsx54("span", { className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Detected" }) : /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
14593
+ /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
14594
+ /* @__PURE__ */ jsx54(ExternalLink3, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
14595
+ ] })
14596
+ ]
14597
+ },
14598
+ wallet.id
14599
+ );
14600
+ }) }),
14154
14601
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
14155
14602
  ] })
14156
14603
  ] });
14157
14604
  }
14605
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
14606
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
14158
14607
  if (view === "select_network" && selectedWalletDef) {
14159
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14608
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14160
14609
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
14161
14610
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
14162
14611
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -14186,10 +14635,10 @@ function WalletConnect({
14186
14635
  )) }),
14187
14636
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
14188
14637
  ] })
14189
- ] });
14638
+ ] }) });
14190
14639
  }
14191
14640
  if (view === "connecting") {
14192
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14641
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14193
14642
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
14194
14643
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
14195
14644
  /* @__PURE__ */ jsx54(Loader28, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -14200,49 +14649,157 @@ function WalletConnect({
14200
14649
  ] }),
14201
14650
  /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: "Please approve the connection in your wallet" })
14202
14651
  ] })
14203
- ] });
14204
- }
14205
- if (!hasWallet) return null;
14206
- if (view === "select_token") {
14207
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
14208
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
14209
- }
14210
- if (view === "enter_amount" && selectedToken && selectedBalance) {
14211
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
14212
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
14213
- }
14214
- if (view === "review" && selectedToken) {
14215
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
14216
- }) }) });
14217
- }
14218
- if (view === "confirming") {
14219
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
14220
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
14652
+ ] }) });
14221
14653
  }
14222
- return null;
14223
- }
14224
-
14225
- // src/components/deposits/DepositModal.tsx
14226
- import { Fragment as Fragment11, jsx as jsx55, jsxs as jsxs49 } from "react/jsx-runtime";
14227
- function SkeletonButton({
14228
- variant = "default"
14229
- }) {
14230
- return /* @__PURE__ */ jsxs49("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-animate-pulse", children: [
14231
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
14232
- /* @__PURE__ */ jsx55("div", { className: "uf-bg-muted uf-rounded-lg uf-w-9 uf-h-9" }),
14233
- /* @__PURE__ */ jsxs49("div", { className: "uf-space-y-1.5", children: [
14234
- /* @__PURE__ */ jsx55("div", { className: "uf-h-3.5 uf-w-24 uf-bg-muted uf-rounded" }),
14235
- /* @__PURE__ */ jsx55("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded" })
14236
- ] })
14237
- ] }),
14238
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
14239
- variant === "with-icons" && /* @__PURE__ */ jsx55("div", { className: "uf-flex uf--space-x-1", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx55(
14240
- "div",
14241
- {
14242
- className: "uf-w-5 uf-h-5 uf-rounded-full uf-bg-muted uf-border-2 uf-border-secondary"
14243
- },
14244
- i
14245
- )) }),
14654
+ if (view === "mobile_redirect" && mobileRedirect) {
14655
+ const Icon2 = WALLET_ICONS3[mobileRedirect.walletId];
14656
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14657
+ /* @__PURE__ */ jsx54(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
14658
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-px-6 uf-py-10", children: [
14659
+ Icon2 ? /* @__PURE__ */ jsx54(Icon2, { size: 64, className: "uf-rounded-2xl uf-mb-5" }) : /* @__PURE__ */ jsx54("div", { className: "uf-w-16 uf-h-16 uf-rounded-2xl uf-bg-gray-500 uf-mb-5" }),
14660
+ /* @__PURE__ */ jsxs48(
14661
+ "div",
14662
+ {
14663
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
14664
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
14665
+ children: [
14666
+ "Continue in ",
14667
+ mobileRedirect.walletName
14668
+ ]
14669
+ }
14670
+ ),
14671
+ /* @__PURE__ */ jsxs48(
14672
+ "div",
14673
+ {
14674
+ className: "uf-text-sm uf-text-center uf-mb-6",
14675
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
14676
+ children: [
14677
+ "Complete your deposit in the ",
14678
+ mobileRedirect.walletName,
14679
+ " app"
14680
+ ]
14681
+ }
14682
+ ),
14683
+ /* @__PURE__ */ jsxs48(
14684
+ "button",
14685
+ {
14686
+ type: "button",
14687
+ onClick: () => {
14688
+ window.location.href = mobileRedirect.deeplink;
14689
+ },
14690
+ className: "uf-w-full uf-transition-colors uf-p-3.5 uf-flex uf-items-center uf-justify-center uf-gap-2 hover:uf-opacity-90",
14691
+ style: {
14692
+ backgroundColor: components.card.backgroundColor,
14693
+ borderRadius: components.card.borderRadius,
14694
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
14695
+ color: components.card.titleColor,
14696
+ fontFamily: fonts.medium
14697
+ },
14698
+ children: [
14699
+ /* @__PURE__ */ jsx54(ExternalLink3, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
14700
+ /* @__PURE__ */ jsxs48("span", { className: "uf-text-sm uf-font-medium", children: [
14701
+ "Open in ",
14702
+ mobileRedirect.walletName
14703
+ ] })
14704
+ ]
14705
+ }
14706
+ ),
14707
+ awaitingMobileDeposit && /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
14708
+ /* @__PURE__ */ jsx54(
14709
+ Loader28,
14710
+ {
14711
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
14712
+ style: { color: colors2.foregroundMuted }
14713
+ }
14714
+ ),
14715
+ /* @__PURE__ */ jsx54(
14716
+ "span",
14717
+ {
14718
+ className: "uf-text-sm",
14719
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
14720
+ children: "Checking for deposit..."
14721
+ }
14722
+ )
14723
+ ] })
14724
+ ] })
14725
+ ] }) });
14726
+ }
14727
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
14728
+ const isComplete = latestDepositExecution.status === ExecutionStatus5.SUCCEEDED;
14729
+ const isFailed = latestDepositExecution.status === ExecutionStatus5.FAILED;
14730
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
14731
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14732
+ /* @__PURE__ */ jsx54(
14733
+ DepositHeader,
14734
+ {
14735
+ title,
14736
+ showBack: false,
14737
+ onClose: isComplete && onDone ? onDone : onClose
14738
+ }
14739
+ ),
14740
+ /* @__PURE__ */ jsx54(DepositDetailContent, { execution: latestDepositExecution }),
14741
+ isComplete && /* @__PURE__ */ jsx54("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-4 uf-pb-4", children: /* @__PURE__ */ jsx54(
14742
+ "button",
14743
+ {
14744
+ type: "button",
14745
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
14746
+ }),
14747
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
14748
+ style: {
14749
+ backgroundColor: colors2.primary,
14750
+ color: colors2.primaryForeground,
14751
+ fontFamily: fonts.medium,
14752
+ borderRadius: components.button.borderRadius,
14753
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
14754
+ },
14755
+ children: "Done"
14756
+ }
14757
+ ) })
14758
+ ] }) });
14759
+ }
14760
+ if (!hasWallet) return null;
14761
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
14762
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
14763
+ if (view === "select_token") {
14764
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
14765
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
14766
+ }
14767
+ if (view === "enter_amount" && selectedToken && selectedBalance) {
14768
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
14769
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
14770
+ }
14771
+ if (view === "review" && selectedToken) {
14772
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
14773
+ }) }) }) });
14774
+ }
14775
+ if (view === "confirming") {
14776
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
14777
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
14778
+ }
14779
+ return null;
14780
+ }
14781
+
14782
+ // src/components/deposits/DepositModal.tsx
14783
+ import { Fragment as Fragment11, jsx as jsx55, jsxs as jsxs49 } from "react/jsx-runtime";
14784
+ function SkeletonButton({
14785
+ variant = "default"
14786
+ }) {
14787
+ return /* @__PURE__ */ jsxs49("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-animate-pulse", children: [
14788
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
14789
+ /* @__PURE__ */ jsx55("div", { className: "uf-bg-muted uf-rounded-lg uf-w-9 uf-h-9" }),
14790
+ /* @__PURE__ */ jsxs49("div", { className: "uf-space-y-1.5", children: [
14791
+ /* @__PURE__ */ jsx55("div", { className: "uf-h-3.5 uf-w-24 uf-bg-muted uf-rounded" }),
14792
+ /* @__PURE__ */ jsx55("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded" })
14793
+ ] })
14794
+ ] }),
14795
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
14796
+ variant === "with-icons" && /* @__PURE__ */ jsx55("div", { className: "uf-flex uf--space-x-1", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx55(
14797
+ "div",
14798
+ {
14799
+ className: "uf-w-5 uf-h-5 uf-rounded-full uf-bg-muted uf-border-2 uf-border-secondary"
14800
+ },
14801
+ i
14802
+ )) }),
14246
14803
  /* @__PURE__ */ jsx55(ChevronRight14, { className: "uf-w-4 uf-h-4 uf-text-muted" })
14247
14804
  ] })
14248
14805
  ] });
@@ -14264,16 +14821,17 @@ function DepositModal({
14264
14821
  defaultSourceChainId,
14265
14822
  defaultSourceTokenAddress,
14266
14823
  defaultSourceSymbol,
14267
- hideDepositTracker = false,
14824
+ hideDepositTracker,
14268
14825
  showBalanceHeader = false,
14269
14826
  transferInputVariant = "double_input",
14270
14827
  depositConfirmationMode = "auto_ui",
14271
- enableConnectWallet = false,
14828
+ enableTransferCrypto,
14829
+ enableConnectWallet,
14272
14830
  browserWalletAmountQuickSelect = "percentage",
14273
14831
  enablePayWithExchange,
14274
14832
  enableFiatOnramp,
14275
- enableConnectExchange = false,
14276
- enableCashApp = false,
14833
+ enableConnectExchange,
14834
+ enableCashApp,
14277
14835
  hideDepositFlowInfo = false,
14278
14836
  hideDisplayDescription = false,
14279
14837
  onDepositSuccess,
@@ -14291,12 +14849,13 @@ function DepositModal({
14291
14849
  const { colors: colors2, fonts, components } = useTheme();
14292
14850
  const effectiveInitialScreen = useMemo10(() => {
14293
14851
  const s = initialScreen ?? "main";
14294
- if (s === "tracker" && hideDepositTracker) return "main";
14295
- if (s === "cashapp" && !enableCashApp) return "main";
14852
+ if (s === "tracker" && hideDepositTracker === true) return "main";
14853
+ if (s === "cashapp" && enableCashApp === false) return "main";
14296
14854
  if (s === "card" && enableFiatOnramp === false) return "main";
14297
14855
  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";
14856
+ if (s === "exchange_connect")
14857
+ return enableConnectExchange === false ? "main" : "coinbase_connect";
14858
+ if (s === "wallet_connect") return enableConnectWallet === false ? "main" : "wallet_connect";
14300
14859
  return s;
14301
14860
  }, [
14302
14861
  initialScreen,
@@ -14325,26 +14884,36 @@ function DepositModal({
14325
14884
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState32(false);
14326
14885
  const [browserWalletInfo, setBrowserWalletInfo] = useState32(null);
14327
14886
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState32(false);
14328
- const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletChainType());
14887
+ const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletState()?.chainType);
14329
14888
  const [quotesCount, setQuotesCount] = useState32(0);
14330
14889
  const [allExecutions, setAllExecutions] = useState32([]);
14331
14890
  const [selectedExecution, setSelectedExecution] = useState32(null);
14332
14891
  const [depositExecutions, setDepositExecutions] = useState32([]);
14333
- const isMobileView = useIsMobileViewport();
14892
+ const { projectConfig } = useProjectConfig({
14893
+ publishableKey,
14894
+ enabled: open
14895
+ });
14896
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
14897
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
14898
+ const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14899
+ const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14900
+ const showConnectExchange = enableConnectExchange ?? projectConfig?.connect_exchange?.enabled ?? true;
14901
+ const showCashApp = enableCashApp ?? projectConfig?.cash_app?.enabled ?? true;
14902
+ const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
14334
14903
  const [integrationExchanges, setIntegrationExchanges] = useState32([]);
14335
14904
  useEffect26(() => {
14336
- if (!enableConnectExchange || !open) return;
14905
+ if (!showConnectExchange || !open) return;
14337
14906
  getIntegrationExchanges2(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
14338
14907
  });
14339
- }, [enableConnectExchange, open, publishableKey]);
14908
+ }, [showConnectExchange, open, publishableKey]);
14340
14909
  const [connectedExchange, setConnectedExchange] = useState32(() => {
14341
- if (!enableConnectExchange) return null;
14910
+ if (!showConnectExchange) return null;
14342
14911
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
14343
14912
  if (!stored) return null;
14344
14913
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
14345
14914
  });
14346
14915
  useEffect26(() => {
14347
- if (!enableConnectExchange || !open || view !== "main") return;
14916
+ if (!showConnectExchange || !open || view !== "main") return;
14348
14917
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
14349
14918
  if (!stored) {
14350
14919
  setConnectedExchange(null);
@@ -14379,7 +14948,7 @@ function DepositModal({
14379
14948
  setConnectedExchange(null);
14380
14949
  }
14381
14950
  });
14382
- }, [enableConnectExchange, open, view, publishableKey]);
14951
+ }, [showConnectExchange, open, view, publishableKey]);
14383
14952
  useEffect26(() => {
14384
14953
  if (!connectedExchange || integrationExchanges.length === 0) return;
14385
14954
  const cbExchange = integrationExchanges.find(
@@ -14418,18 +14987,33 @@ function DepositModal({
14418
14987
  setResolvedTheme(theme);
14419
14988
  }
14420
14989
  }, [theme]);
14421
- const { projectConfig } = useProjectConfig({
14422
- publishableKey,
14423
- enabled: open
14424
- });
14425
- const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14426
- const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14427
14990
  useEffect26(() => {
14428
14991
  if (view === "card" && !showFiatOnramp) {
14429
14992
  setView("main");
14430
14993
  setCardView("amount");
14994
+ } else if (view === "transfer" && !showTransferCrypto) {
14995
+ setView("main");
14996
+ } else if (view === "exchange" && !showPayWithExchange) {
14997
+ setView("main");
14998
+ } else if (view === "cashapp" && !showCashApp) {
14999
+ setView("main");
15000
+ } else if (view === "tracker" && !showDepositTracker) {
15001
+ setView("main");
15002
+ } else if (view === "coinbase_connect" && !showConnectExchange) {
15003
+ setView("main");
15004
+ } else if (view === "wallet_connect" && !showConnectWallet) {
15005
+ setView("main");
14431
15006
  }
14432
- }, [view, showFiatOnramp]);
15007
+ }, [
15008
+ view,
15009
+ showFiatOnramp,
15010
+ showTransferCrypto,
15011
+ showPayWithExchange,
15012
+ showCashApp,
15013
+ showDepositTracker,
15014
+ showConnectExchange,
15015
+ showConnectWallet
15016
+ ]);
14433
15017
  useEffect26(() => {
14434
15018
  if (view === "exchange" && !showPayWithExchange) {
14435
15019
  setView("main");
@@ -14519,7 +15103,7 @@ function DepositModal({
14519
15103
  depositPrerequisiteBody = standaloneNeedsDepositPrereq ? /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }) : /* @__PURE__ */ jsxs49(Fragment11, { children: [
14520
15104
  /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }),
14521
15105
  /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }),
14522
- !hideDepositTracker && /* @__PURE__ */ jsx55(SkeletonButton, {})
15106
+ showDepositTracker && /* @__PURE__ */ jsx55(SkeletonButton, {})
14523
15107
  ] });
14524
15108
  } else if (countryError) {
14525
15109
  depositPrerequisiteBody = /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
@@ -14551,7 +15135,7 @@ function DepositModal({
14551
15135
  const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
14552
15136
  const handleWalletDisconnect = () => {
14553
15137
  setUserDisconnectedWallet(true);
14554
- clearStoredWalletChainType();
15138
+ clearStoredWalletState();
14555
15139
  setBrowserWalletChainType(void 0);
14556
15140
  setBrowserWalletInfo(null);
14557
15141
  setBrowserWalletModalOpen(false);
@@ -14629,7 +15213,7 @@ function DepositModal({
14629
15213
  };
14630
15214
  const handleBrowserWalletClick = (walletInfo) => {
14631
15215
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
14632
- setStoredWalletChainType(walletChainType);
15216
+ setStoredWalletState(walletInfo.type);
14633
15217
  setBrowserWalletChainType(walletChainType);
14634
15218
  const matchingDepositWallet = wallets.find(
14635
15219
  (w) => w.chain_type === walletChainType
@@ -14660,7 +15244,7 @@ function DepositModal({
14660
15244
  };
14661
15245
  const handleWalletConnected = (walletInfo) => {
14662
15246
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
14663
- setStoredWalletChainType(walletChainType);
15247
+ setStoredWalletState(walletInfo.type);
14664
15248
  setBrowserWalletChainType(walletChainType);
14665
15249
  const matchingDepositWallet = wallets.find(
14666
15250
  (w) => w.chain_type === walletChainType
@@ -14700,7 +15284,7 @@ function DepositModal({
14700
15284
  open: hideOverlay || open,
14701
15285
  onOpenChange: hideOverlay ? void 0 : handleClose,
14702
15286
  modal: !hideOverlay,
14703
- children: /* @__PURE__ */ jsx55(
15287
+ children: /* @__PURE__ */ jsxs49(
14704
15288
  DialogContent,
14705
15289
  {
14706
15290
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -14709,378 +15293,389 @@ function DepositModal({
14709
15293
  style: { backgroundColor: colors2.background },
14710
15294
  onPointerDownOutside: (e) => e.preventDefault(),
14711
15295
  onInteractOutside: (e) => e.preventDefault(),
14712
- children: /* @__PURE__ */ jsx55(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
14713
- /* @__PURE__ */ jsx55(
14714
- DepositHeader,
14715
- {
14716
- title: modalTitle || "Deposit",
14717
- showClose: !hideOverlay,
14718
- onClose: handleClose,
14719
- showBalance: showBalanceHeader,
14720
- balanceAddress: recipientAddress,
14721
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
14722
- balanceChainId: destinationChainId,
14723
- balanceTokenAddress: destinationTokenAddress,
14724
- projectName: projectConfig?.project_name,
14725
- publishableKey
14726
- }
14727
- ),
14728
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14729
- /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ jsxs49(Fragment11, { children: [
14730
- /* @__PURE__ */ jsx55(
14731
- TransferCryptoButton,
14732
- {
14733
- onClick: () => setView("transfer"),
14734
- title: transferCryptoTitle,
14735
- subtitle: t7.transferCrypto.subtitle,
14736
- featuredTokens: projectConfig?.transfer_crypto.networks
14737
- }
14738
- ),
14739
- enableConnectWallet && !isMobileView && /* @__PURE__ */ jsx55(
14740
- BrowserWalletButton,
15296
+ children: [
15297
+ /* @__PURE__ */ jsx55(DialogTitle, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
15298
+ /* @__PURE__ */ jsx55(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15299
+ /* @__PURE__ */ jsx55(
15300
+ DepositHeader,
15301
+ {
15302
+ title: modalTitle || "Deposit",
15303
+ showClose: !hideOverlay,
15304
+ onClose: handleClose,
15305
+ showBalance: showBalanceHeader,
15306
+ balanceAddress: recipientAddress,
15307
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15308
+ balanceChainId: destinationChainId,
15309
+ balanceTokenAddress: destinationTokenAddress,
15310
+ projectName: projectConfig?.project_name,
15311
+ publishableKey
15312
+ }
15313
+ ),
15314
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15315
+ /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15316
+ showTransferCrypto && /* @__PURE__ */ jsx55(
15317
+ TransferCryptoButton,
15318
+ {
15319
+ onClick: () => setView("transfer"),
15320
+ title: transferCryptoTitle,
15321
+ subtitle: t7.transferCrypto.subtitle,
15322
+ featuredTokens: projectConfig?.transfer_crypto.networks
15323
+ }
15324
+ ),
15325
+ showConnectWallet && /* @__PURE__ */ jsx55(
15326
+ BrowserWalletButton,
15327
+ {
15328
+ onClick: handleBrowserWalletClick,
15329
+ onConnectClick: handleWalletConnectClick,
15330
+ onDisconnect: handleWalletDisconnect,
15331
+ chainType: browserWalletChainType,
15332
+ publishableKey,
15333
+ featuredWallets: projectConfig?.connect_wallet?.wallets
15334
+ }
15335
+ ),
15336
+ showFiatOnramp && /* @__PURE__ */ jsx55(
15337
+ DepositWithCardButton,
15338
+ {
15339
+ onClick: () => setView("card"),
15340
+ title: depositWithCardTitle,
15341
+ subtitle: t7.depositWithCard.subtitle,
15342
+ paymentNetworks: projectConfig?.payment_networks.networks
15343
+ }
15344
+ ),
15345
+ showPayWithExchange && /* @__PURE__ */ jsx55(
15346
+ PayWithExchangeButton,
15347
+ {
15348
+ onClick: () => setView("exchange"),
15349
+ title: payWithExchangeTitle,
15350
+ subtitle: t7.payWithExchange.subtitle,
15351
+ exchanges,
15352
+ loading: exchangesLoading
15353
+ }
15354
+ ),
15355
+ showConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
15356
+ ConnectExchangeButton,
15357
+ {
15358
+ onClick: () => {
15359
+ setCoinbaseSkipToHoldings(true);
15360
+ setView("coinbase_connect");
15361
+ },
15362
+ onDisconnect: handleExchangeDisconnect,
15363
+ title: i18n.connectExchange.title,
15364
+ subtitle: i18n.connectExchange.subtitle,
15365
+ exchanges: integrationExchanges,
15366
+ connectedExchange
15367
+ }
15368
+ ),
15369
+ showConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
15370
+ ConnectExchangeButton,
15371
+ {
15372
+ onClick: () => {
15373
+ setCoinbaseSkipToHoldings(false);
15374
+ setView("coinbase_connect");
15375
+ },
15376
+ title: i18n.connectExchange.title,
15377
+ subtitle: i18n.connectExchange.subtitle,
15378
+ exchanges: integrationExchanges
15379
+ }
15380
+ ),
15381
+ showCashApp && /* @__PURE__ */ jsx55(
15382
+ CashAppButton,
15383
+ {
15384
+ onClick: () => setView("cashapp"),
15385
+ title: "Pay with Cash App",
15386
+ subtitle: "Deposit via Cash App",
15387
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
15388
+ }
15389
+ ),
15390
+ showDepositTracker && /* @__PURE__ */ jsx55(
15391
+ DepositTrackerButton,
15392
+ {
15393
+ onClick: () => {
15394
+ setAllExecutions(depositExecutions);
15395
+ setView("tracker");
15396
+ },
15397
+ title: depositTrackerTitle,
15398
+ subtitle: depositTrackerSubTitle,
15399
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
15400
+ }
15401
+ )
15402
+ ] }) }),
15403
+ depositPoweredByFooter
15404
+ ] })
15405
+ ] }) : view === "transfer" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15406
+ /* @__PURE__ */ jsx55(
15407
+ DepositHeader,
15408
+ {
15409
+ title: transferCryptoTitle,
15410
+ showBack: showBackTransfer,
15411
+ onBack: handleBack,
15412
+ onClose: handleClose,
15413
+ showBalance: showBalanceHeader,
15414
+ balanceAddress: recipientAddress,
15415
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15416
+ balanceChainId: destinationChainId,
15417
+ balanceTokenAddress: destinationTokenAddress,
15418
+ projectName: projectConfig?.project_name,
15419
+ publishableKey
15420
+ }
15421
+ ),
15422
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15423
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ jsx55(
15424
+ TransferCryptoSingleInput,
14741
15425
  {
14742
- onClick: handleBrowserWalletClick,
14743
- onConnectClick: handleWalletConnectClick,
14744
- onDisconnect: handleWalletDisconnect,
14745
- chainType: browserWalletChainType,
15426
+ userId,
14746
15427
  publishableKey,
14747
- featuredWallets: projectConfig?.connect_wallet?.wallets
15428
+ recipientAddress,
15429
+ destinationChainType,
15430
+ destinationChainId,
15431
+ destinationTokenAddress,
15432
+ defaultSourceChainType,
15433
+ defaultSourceChainId,
15434
+ defaultSourceTokenAddress,
15435
+ defaultSourceSymbol,
15436
+ depositConfirmationMode,
15437
+ onExecutionsChange: setDepositExecutions,
15438
+ onDepositSuccess,
15439
+ onDepositError,
15440
+ wallets
14748
15441
  }
14749
- ),
14750
- showFiatOnramp && /* @__PURE__ */ jsx55(
14751
- DepositWithCardButton,
15442
+ ) : /* @__PURE__ */ jsx55(
15443
+ TransferCryptoDoubleInput,
14752
15444
  {
14753
- onClick: () => setView("card"),
14754
- title: depositWithCardTitle,
14755
- subtitle: t7.depositWithCard.subtitle,
14756
- paymentNetworks: projectConfig?.payment_networks.networks
15445
+ userId,
15446
+ publishableKey,
15447
+ recipientAddress,
15448
+ destinationChainType,
15449
+ destinationChainId,
15450
+ destinationTokenAddress,
15451
+ defaultSourceChainType,
15452
+ defaultSourceChainId,
15453
+ defaultSourceTokenAddress,
15454
+ defaultSourceSymbol,
15455
+ depositConfirmationMode,
15456
+ onExecutionsChange: setDepositExecutions,
15457
+ onDepositSuccess,
15458
+ onDepositError,
15459
+ wallets
14757
15460
  }
14758
15461
  ),
14759
- showPayWithExchange && /* @__PURE__ */ jsx55(
14760
- PayWithExchangeButton,
15462
+ depositPoweredByFooter
15463
+ ] })
15464
+ ] }) : view === "tracker" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15465
+ /* @__PURE__ */ jsx55(
15466
+ DepositHeader,
15467
+ {
15468
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
15469
+ showBack: showBackTracker,
15470
+ onBack: handleBack,
15471
+ onClose: handleClose
15472
+ }
15473
+ ),
15474
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15475
+ /* @__PURE__ */ jsx55("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ jsx55(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ jsx55("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ jsx55("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ jsx55(
15476
+ "div",
14761
15477
  {
14762
- onClick: () => setView("exchange"),
14763
- title: payWithExchangeTitle,
14764
- subtitle: t7.payWithExchange.subtitle,
14765
- exchanges,
14766
- loading: exchangesLoading
15478
+ className: "uf-text-sm",
15479
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
15480
+ children: "No deposits yet"
14767
15481
  }
14768
- ),
14769
- enableConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
14770
- ConnectExchangeButton,
15482
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ jsx55(
15483
+ DepositExecutionItem,
14771
15484
  {
14772
- onClick: () => {
14773
- setCoinbaseSkipToHoldings(true);
14774
- setView("coinbase_connect");
14775
- },
14776
- onDisconnect: handleExchangeDisconnect,
14777
- title: i18n.connectExchange.title,
14778
- subtitle: i18n.connectExchange.subtitle,
14779
- exchanges: integrationExchanges,
14780
- connectedExchange
14781
- }
14782
- ),
14783
- enableConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
14784
- ConnectExchangeButton,
15485
+ execution,
15486
+ onClick: () => setSelectedExecution(execution)
15487
+ },
15488
+ execution.id
15489
+ )) }) }),
15490
+ depositPoweredByFooter
15491
+ ] })
15492
+ ] }) : view === "card" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15493
+ /* @__PURE__ */ jsx55(
15494
+ DepositHeader,
15495
+ {
15496
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
15497
+ showBack: showBackCard,
15498
+ onBack: handleBack,
15499
+ onClose: handleClose,
15500
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
15501
+ showBalance: showBalanceHeader,
15502
+ balanceAddress: recipientAddress,
15503
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15504
+ balanceChainId: destinationChainId,
15505
+ balanceTokenAddress: destinationTokenAddress,
15506
+ projectName: projectConfig?.project_name,
15507
+ publishableKey
15508
+ }
15509
+ ),
15510
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15511
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ jsx55(
15512
+ BuyWithCard,
14785
15513
  {
14786
- onClick: () => {
14787
- setCoinbaseSkipToHoldings(false);
14788
- setView("coinbase_connect");
14789
- },
14790
- title: i18n.connectExchange.title,
14791
- subtitle: i18n.connectExchange.subtitle,
14792
- exchanges: integrationExchanges
15514
+ userId,
15515
+ publishableKey,
15516
+ view: cardView,
15517
+ onViewChange: handleCardViewChange,
15518
+ destinationTokenSymbol,
15519
+ recipientAddress,
15520
+ destinationChainType,
15521
+ destinationChainId,
15522
+ destinationTokenAddress,
15523
+ onDepositSuccess,
15524
+ onDepositError,
15525
+ onEvent,
15526
+ themeClass,
15527
+ wallets,
15528
+ assetCdnUrl: projectConfig?.asset_cdn_url,
15529
+ hideDepositFlowInfo,
15530
+ hideDisplayDescription
14793
15531
  }
14794
15532
  ),
14795
- enableCashApp && /* @__PURE__ */ jsx55(
14796
- CashAppButton,
15533
+ depositPoweredByFooter
15534
+ ] })
15535
+ ] }) : view === "exchange" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15536
+ /* @__PURE__ */ jsx55(
15537
+ DepositHeader,
15538
+ {
15539
+ title: payWithExchangeTitle,
15540
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
15541
+ onBack: handleBack,
15542
+ onClose: handleClose
15543
+ }
15544
+ ),
15545
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15546
+ /* @__PURE__ */ jsx55(
15547
+ PayWithExchange,
14797
15548
  {
14798
- onClick: () => setView("cashapp"),
14799
- title: "Pay with Cash App",
14800
- subtitle: "Deposit via Cash App",
14801
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
15549
+ userId,
15550
+ publishableKey,
15551
+ exchanges,
15552
+ view: exchangeView,
15553
+ onViewChange: setExchangeView,
15554
+ destinationTokenSymbol,
15555
+ recipientAddress,
15556
+ destinationChainType,
15557
+ destinationChainId,
15558
+ destinationTokenAddress,
15559
+ onDepositSuccess,
15560
+ onDepositError,
15561
+ wallets,
15562
+ defaultToken: defaultToken ?? null
14802
15563
  }
14803
15564
  ),
14804
- !hideDepositTracker && /* @__PURE__ */ jsx55(
14805
- DepositTrackerButton,
14806
- {
14807
- onClick: () => {
14808
- setAllExecutions(depositExecutions);
14809
- setView("tracker");
14810
- },
14811
- title: depositTrackerTitle,
14812
- subtitle: depositTrackerSubTitle,
14813
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
14814
- }
14815
- )
14816
- ] }) }),
14817
- depositPoweredByFooter
14818
- ] })
14819
- ] }) : view === "transfer" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
14820
- /* @__PURE__ */ jsx55(
14821
- DepositHeader,
14822
- {
14823
- title: transferCryptoTitle,
14824
- showBack: showBackTransfer,
14825
- onBack: handleBack,
14826
- onClose: handleClose,
14827
- showBalance: showBalanceHeader,
14828
- balanceAddress: recipientAddress,
14829
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
14830
- balanceChainId: destinationChainId,
14831
- balanceTokenAddress: destinationTokenAddress,
14832
- projectName: projectConfig?.project_name,
14833
- publishableKey
14834
- }
14835
- ),
14836
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14837
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ jsx55(
14838
- TransferCryptoSingleInput,
15565
+ depositPoweredByFooter
15566
+ ] })
15567
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15568
+ /* @__PURE__ */ jsx55(
15569
+ CoinbaseConnect,
14839
15570
  {
14840
- userId,
14841
15571
  publishableKey,
14842
- recipientAddress,
14843
- destinationChainType,
14844
- destinationChainId,
14845
- destinationTokenAddress,
14846
- defaultSourceChainType,
14847
- defaultSourceChainId,
14848
- defaultSourceTokenAddress,
14849
- defaultSourceSymbol,
14850
- depositConfirmationMode,
14851
- onExecutionsChange: setDepositExecutions,
14852
- onDepositSuccess,
14853
- onDepositError,
14854
- wallets
14855
- }
14856
- ) : /* @__PURE__ */ jsx55(
14857
- TransferCryptoDoubleInput,
14858
- {
14859
15572
  userId,
14860
- publishableKey,
15573
+ wallets,
14861
15574
  recipientAddress,
14862
- destinationChainType,
14863
- destinationChainId,
14864
- destinationTokenAddress,
15575
+ destinationTokenAddress: destinationTokenAddress ?? "",
15576
+ destinationChainId: destinationChainId ?? "",
15577
+ destinationChainType: destinationChainType ?? "",
15578
+ onTransferSuccess: (result) => {
15579
+ onDepositSuccess?.({
15580
+ message: "Transfer completed via Coinbase Connect",
15581
+ transaction: result
15582
+ });
15583
+ },
15584
+ onTransferError: (error) => {
15585
+ onDepositError?.({
15586
+ message: error.message,
15587
+ error
15588
+ });
15589
+ },
15590
+ onBack: handleBack,
15591
+ onClose: handleClose,
15592
+ onDisconnect: handleExchangeDisconnect,
15593
+ skipToHoldings: coinbaseSkipToHoldings,
15594
+ canGoBack: sessionOpenedFromMenu,
15595
+ onExecutionsChange: setDepositExecutions,
14865
15596
  defaultSourceChainType,
14866
15597
  defaultSourceChainId,
14867
15598
  defaultSourceTokenAddress,
14868
- defaultSourceSymbol,
14869
- depositConfirmationMode,
14870
- onExecutionsChange: setDepositExecutions,
14871
- onDepositSuccess,
14872
- onDepositError,
14873
- wallets
14874
- }
14875
- ),
14876
- depositPoweredByFooter
14877
- ] })
14878
- ] }) : view === "tracker" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
14879
- /* @__PURE__ */ jsx55(
14880
- DepositHeader,
14881
- {
14882
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
14883
- showBack: showBackTracker,
14884
- onBack: handleBack,
14885
- onClose: handleClose
14886
- }
14887
- ),
14888
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14889
- /* @__PURE__ */ jsx55("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ jsx55(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ jsx55("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ jsx55("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ jsx55(
14890
- "div",
14891
- {
14892
- className: "uf-text-sm",
14893
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
14894
- children: "No deposits yet"
14895
- }
14896
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ jsx55(
14897
- DepositExecutionItem,
14898
- {
14899
- execution,
14900
- onClick: () => setSelectedExecution(execution)
14901
- },
14902
- execution.id
14903
- )) }) }),
14904
- depositPoweredByFooter
14905
- ] })
14906
- ] }) : view === "card" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
14907
- /* @__PURE__ */ jsx55(
14908
- DepositHeader,
14909
- {
14910
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
14911
- showBack: showBackCard,
14912
- onBack: handleBack,
14913
- onClose: handleClose,
14914
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
14915
- showBalance: showBalanceHeader,
14916
- balanceAddress: recipientAddress,
14917
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
14918
- balanceChainId: destinationChainId,
14919
- balanceTokenAddress: destinationTokenAddress,
14920
- projectName: projectConfig?.project_name,
14921
- publishableKey
14922
- }
14923
- ),
14924
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14925
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ jsx55(
14926
- BuyWithCard,
14927
- {
14928
- userId,
14929
- publishableKey,
14930
- view: cardView,
14931
- onViewChange: handleCardViewChange,
14932
- destinationTokenSymbol,
14933
- recipientAddress,
14934
- destinationChainType,
14935
- destinationChainId,
14936
- destinationTokenAddress,
14937
- onDepositSuccess,
14938
- onDepositError,
14939
- onEvent,
14940
- themeClass,
14941
- wallets,
14942
- assetCdnUrl: projectConfig?.asset_cdn_url,
14943
- hideDepositFlowInfo,
14944
- hideDisplayDescription
15599
+ defaultSourceSymbol
14945
15600
  }
14946
15601
  ),
14947
15602
  depositPoweredByFooter
14948
- ] })
14949
- ] }) : view === "exchange" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
14950
- /* @__PURE__ */ jsx55(
14951
- DepositHeader,
14952
- {
14953
- title: payWithExchangeTitle,
14954
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
14955
- onBack: handleBack,
14956
- onClose: handleClose
14957
- }
14958
- ),
14959
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15603
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14960
15604
  /* @__PURE__ */ jsx55(
14961
- PayWithExchange,
15605
+ WalletConnect,
14962
15606
  {
15607
+ walletInfo: browserWalletInfo ?? void 0,
15608
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
15609
+ wallets,
14963
15610
  userId,
14964
15611
  publishableKey,
14965
- exchanges,
14966
- view: exchangeView,
14967
- onViewChange: setExchangeView,
14968
- destinationTokenSymbol,
14969
- recipientAddress,
14970
- destinationChainType,
14971
- destinationChainId,
14972
- destinationTokenAddress,
15612
+ assetCdnUrl: projectConfig?.asset_cdn_url,
15613
+ projectName: projectConfig?.project_name,
15614
+ onSuccess: (txHash) => {
15615
+ onDepositSuccess?.({
15616
+ message: "Transaction sent successfully",
15617
+ transaction: { txHash }
15618
+ });
15619
+ },
15620
+ onError: (error) => {
15621
+ onDepositError?.({
15622
+ message: error.message,
15623
+ error
15624
+ });
15625
+ },
14973
15626
  onDepositSuccess,
14974
15627
  onDepositError,
14975
- wallets,
14976
- defaultToken: defaultToken ?? null
15628
+ amountQuickSelect: browserWalletAmountQuickSelect,
15629
+ onWalletDisconnect: handleWalletDisconnect,
15630
+ onWalletConnected: (info, dw) => {
15631
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
15632
+ setStoredWalletState(info.type);
15633
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15634
+ },
15635
+ onBack: handleBack,
15636
+ onClose: handleClose,
15637
+ defaultSourceChainType,
15638
+ defaultSourceChainId,
15639
+ defaultSourceTokenAddress,
15640
+ defaultSourceSymbol,
15641
+ canGoBack: sessionOpenedFromMenu,
15642
+ depositWalletsLoading: walletsLoading
14977
15643
  }
14978
15644
  ),
14979
15645
  depositPoweredByFooter
14980
- ] })
14981
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14982
- /* @__PURE__ */ jsx55(
14983
- CoinbaseConnect,
14984
- {
14985
- publishableKey,
14986
- userId,
14987
- wallets,
14988
- recipientAddress,
14989
- destinationTokenAddress: destinationTokenAddress ?? "",
14990
- destinationChainId: destinationChainId ?? "",
14991
- destinationChainType: destinationChainType ?? "",
14992
- onTransferSuccess: (result) => {
14993
- onDepositSuccess?.({
14994
- message: "Transfer completed via Coinbase Connect",
14995
- transaction: result
14996
- });
14997
- },
14998
- onTransferError: (error) => {
14999
- onDepositError?.({
15000
- message: error.message,
15001
- error
15002
- });
15003
- },
15004
- onBack: handleBack,
15005
- onClose: handleClose,
15006
- onDisconnect: handleExchangeDisconnect,
15007
- skipToHoldings: coinbaseSkipToHoldings,
15008
- canGoBack: sessionOpenedFromMenu,
15009
- onExecutionsChange: setDepositExecutions
15010
- }
15011
- ),
15012
- depositPoweredByFooter
15013
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15014
- /* @__PURE__ */ jsx55(
15015
- WalletConnect,
15016
- {
15017
- walletInfo: browserWalletInfo ?? void 0,
15018
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
15019
- wallets,
15020
- userId,
15021
- publishableKey,
15022
- assetCdnUrl: projectConfig?.asset_cdn_url,
15023
- projectName: projectConfig?.project_name,
15024
- onSuccess: (txHash) => {
15025
- onDepositSuccess?.({
15026
- message: "Transaction sent successfully",
15027
- transaction: { txHash }
15028
- });
15029
- },
15030
- onError: (error) => {
15031
- onDepositError?.({
15032
- message: error.message,
15033
- error
15034
- });
15035
- },
15036
- onDepositSuccess,
15037
- onDepositError,
15038
- amountQuickSelect: browserWalletAmountQuickSelect,
15039
- onWalletDisconnect: handleWalletDisconnect,
15040
- onWalletConnected: (info, dw) => {
15041
- setBrowserWalletInfo({ ...info, depositWallet: dw });
15042
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15043
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15044
- },
15045
- onBack: handleBack,
15046
- onClose: handleClose,
15047
- canGoBack: sessionOpenedFromMenu,
15048
- depositWalletsLoading: walletsLoading
15049
- }
15050
- ),
15051
- depositPoweredByFooter
15052
- ] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15053
- /* @__PURE__ */ jsx55(
15054
- DepositHeader,
15055
- {
15056
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15057
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15058
- onBack: handleBack,
15059
- onClose: handleClose
15060
- }
15061
- ),
15062
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15646
+ ] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15063
15647
  /* @__PURE__ */ jsx55(
15064
- PayWithCashApp,
15648
+ DepositHeader,
15065
15649
  {
15066
- userId,
15067
- publishableKey,
15068
- recipientAddress,
15069
- destinationChainType,
15070
- destinationChainId,
15071
- destinationTokenAddress,
15072
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
15073
- view: cashAppView,
15074
- onViewChange: setCashAppView,
15075
- onAmountChange: setCashAppAmount,
15076
- onEvent,
15077
- onDepositSuccess,
15078
- onDepositError
15650
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15651
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15652
+ onBack: handleBack,
15653
+ onClose: handleClose
15079
15654
  }
15080
15655
  ),
15081
- depositPoweredByFooter
15082
- ] })
15083
- ] }) : null })
15656
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15657
+ /* @__PURE__ */ jsx55(
15658
+ PayWithCashApp,
15659
+ {
15660
+ userId,
15661
+ publishableKey,
15662
+ recipientAddress,
15663
+ destinationChainType,
15664
+ destinationChainId,
15665
+ destinationTokenAddress,
15666
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
15667
+ view: cashAppView,
15668
+ onViewChange: setCashAppView,
15669
+ onAmountChange: setCashAppAmount,
15670
+ onEvent,
15671
+ onDepositSuccess,
15672
+ onDepositError
15673
+ }
15674
+ ),
15675
+ depositPoweredByFooter
15676
+ ] })
15677
+ ] }) : null })
15678
+ ]
15084
15679
  }
15085
15680
  )
15086
15681
  }
@@ -15099,7 +15694,7 @@ import {
15099
15694
  import { AlertTriangle as AlertTriangle3, ChevronRight as ChevronRight15 } from "lucide-react";
15100
15695
 
15101
15696
  // src/hooks/use-payment-intent.ts
15102
- import { useQuery as useQuery13 } from "@tanstack/react-query";
15697
+ import { useQuery as useQuery14 } from "@tanstack/react-query";
15103
15698
  import { retrievePaymentIntent } from "@unifold/core";
15104
15699
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
15105
15700
  "succeeded",
@@ -15114,7 +15709,7 @@ function usePaymentIntent(params) {
15114
15709
  enabled = true,
15115
15710
  pollingInterval = 3e3
15116
15711
  } = params;
15117
- return useQuery13({
15712
+ return useQuery14({
15118
15713
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
15119
15714
  queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
15120
15715
  enabled: enabled && !!clientSecret && !!publishableKey,
@@ -15164,7 +15759,8 @@ function CheckoutModal({
15164
15759
  clientSecret,
15165
15760
  publishableKey,
15166
15761
  modalTitle,
15167
- enableConnectWallet = false,
15762
+ enableTransferCrypto,
15763
+ enableConnectWallet,
15168
15764
  defaultSourceChainType,
15169
15765
  defaultSourceChainId,
15170
15766
  defaultSourceTokenAddress,
@@ -15181,8 +15777,7 @@ function CheckoutModal({
15181
15777
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState33(false);
15182
15778
  const [browserWalletInfo, setBrowserWalletInfo] = useState33(null);
15183
15779
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState33(false);
15184
- const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletChainType());
15185
- const isMobileView = useIsMobileViewport();
15780
+ const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletState()?.chainType);
15186
15781
  const [resolvedTheme, setResolvedTheme] = useState33(
15187
15782
  theme === "auto" ? "dark" : theme
15188
15783
  );
@@ -15214,6 +15809,15 @@ function CheckoutModal({
15214
15809
  publishableKey,
15215
15810
  enabled: open
15216
15811
  });
15812
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
15813
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
15814
+ useEffect27(() => {
15815
+ if (view === "transfer" && !showTransferCrypto) {
15816
+ setView("main");
15817
+ } else if (view === "wallet_connect" && !showConnectWallet) {
15818
+ setView("main");
15819
+ }
15820
+ }, [showConnectWallet, showTransferCrypto, view]);
15217
15821
  const prevStatusRef = useRef10(null);
15218
15822
  useEffect27(() => {
15219
15823
  if (!paymentIntent) return;
@@ -15304,7 +15908,7 @@ function CheckoutModal({
15304
15908
  const handleBrowserWalletClick = useCallback6(
15305
15909
  (walletInfo) => {
15306
15910
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
15307
- setStoredWalletChainType(walletChainType);
15911
+ setStoredWalletState(walletInfo.type);
15308
15912
  setBrowserWalletChainType(walletChainType);
15309
15913
  const matchingDepositWallet = wallets.find(
15310
15914
  (w) => w.chain_type === walletChainType
@@ -15331,7 +15935,7 @@ function CheckoutModal({
15331
15935
  const handleWalletConnected = useCallback6(
15332
15936
  (walletInfo) => {
15333
15937
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
15334
- setStoredWalletChainType(walletChainType);
15938
+ setStoredWalletState(walletInfo.type);
15335
15939
  setBrowserWalletChainType(walletChainType);
15336
15940
  const matchingDepositWallet = wallets.find(
15337
15941
  (w) => w.chain_type === walletChainType
@@ -15355,7 +15959,7 @@ function CheckoutModal({
15355
15959
  );
15356
15960
  const handleWalletDisconnect = useCallback6(() => {
15357
15961
  setUserDisconnectedWallet(true);
15358
- clearStoredWalletChainType();
15962
+ clearStoredWalletState();
15359
15963
  setBrowserWalletChainType(void 0);
15360
15964
  setBrowserWalletInfo(null);
15361
15965
  setBrowserWalletModalOpen(false);
@@ -15590,7 +16194,7 @@ function CheckoutModal({
15590
16194
  ] }) : paymentIntent ? /* @__PURE__ */ jsxs50("div", { className: "uf-space-y-3", children: [
15591
16195
  progressSection,
15592
16196
  (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ jsxs50(Fragment12, { children: [
15593
- /* @__PURE__ */ jsx56(
16197
+ showTransferCrypto && /* @__PURE__ */ jsx56(
15594
16198
  TransferCryptoButton,
15595
16199
  {
15596
16200
  onClick: () => setView("transfer"),
@@ -15599,7 +16203,7 @@ function CheckoutModal({
15599
16203
  featuredTokens: projectConfig?.transfer_crypto.networks
15600
16204
  }
15601
16205
  ),
15602
- enableConnectWallet && !isMobileView && /* @__PURE__ */ jsx56(
16206
+ showConnectWallet && /* @__PURE__ */ jsx56(
15603
16207
  BrowserWalletButton,
15604
16208
  {
15605
16209
  onClick: handleBrowserWalletClick,
@@ -15740,14 +16344,18 @@ function CheckoutModal({
15740
16344
  onWalletDisconnect: handleWalletDisconnect,
15741
16345
  onWalletConnected: (info, dw) => {
15742
16346
  setBrowserWalletInfo({ ...info, depositWallet: dw });
15743
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
16347
+ setStoredWalletState(info.type);
15744
16348
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15745
16349
  },
15746
16350
  onNewDeposit: () => setView("main"),
15747
16351
  onDone: () => setView("main"),
15748
16352
  paymentIntentStatus: paymentIntent.status,
15749
16353
  onBack: handleBack,
15750
- onClose: handleClose
16354
+ onClose: handleClose,
16355
+ defaultSourceChainType,
16356
+ defaultSourceChainId,
16357
+ defaultSourceTokenAddress,
16358
+ defaultSourceSymbol
15751
16359
  }
15752
16360
  ),
15753
16361
  poweredByFooter
@@ -15767,12 +16375,12 @@ import {
15767
16375
  import { AlertTriangle as AlertTriangle5, ChevronRight as ChevronRight17, Clock as Clock6 } from "lucide-react";
15768
16376
 
15769
16377
  // src/hooks/use-supported-destination-tokens.ts
15770
- import { useQuery as useQuery14 } from "@tanstack/react-query";
16378
+ import { useQuery as useQuery15 } from "@tanstack/react-query";
15771
16379
  import {
15772
16380
  getSupportedDestinationTokens
15773
16381
  } from "@unifold/core";
15774
16382
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
15775
- return useQuery14({
16383
+ return useQuery15({
15776
16384
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
15777
16385
  queryFn: () => getSupportedDestinationTokens(publishableKey),
15778
16386
  staleTime: 1e3 * 60 * 5,
@@ -15801,7 +16409,7 @@ function useDefaultDestinationToken({
15801
16409
  }
15802
16410
 
15803
16411
  // src/hooks/use-source-token-validation.ts
15804
- import { useQuery as useQuery15 } from "@tanstack/react-query";
16412
+ import { useQuery as useQuery16 } from "@tanstack/react-query";
15805
16413
  import { getSupportedDepositTokens as getSupportedDepositTokens3 } from "@unifold/core";
15806
16414
  function useSourceTokenValidation(params) {
15807
16415
  const {
@@ -15813,7 +16421,7 @@ function useSourceTokenValidation(params) {
15813
16421
  enabled = true
15814
16422
  } = params;
15815
16423
  const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
15816
- return useQuery15({
16424
+ return useQuery16({
15817
16425
  queryKey: [
15818
16426
  "unifold",
15819
16427
  "sourceTokenValidation",
@@ -15861,7 +16469,7 @@ function useSourceTokenValidation(params) {
15861
16469
  }
15862
16470
 
15863
16471
  // src/hooks/use-address-balance.ts
15864
- import { useQuery as useQuery16 } from "@tanstack/react-query";
16472
+ import { useQuery as useQuery17 } from "@tanstack/react-query";
15865
16473
  import { getAddressBalance as getAddressBalance2 } from "@unifold/core";
15866
16474
  function useAddressBalance(params) {
15867
16475
  const {
@@ -15873,7 +16481,7 @@ function useAddressBalance(params) {
15873
16481
  enabled = true
15874
16482
  } = params;
15875
16483
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
15876
- return useQuery16({
16484
+ return useQuery17({
15877
16485
  queryKey: [
15878
16486
  "unifold",
15879
16487
  "addressBalance",
@@ -15922,11 +16530,11 @@ function useAddressBalance(params) {
15922
16530
  }
15923
16531
 
15924
16532
  // src/hooks/use-executions.ts
15925
- import { useQuery as useQuery17 } from "@tanstack/react-query";
16533
+ import { useQuery as useQuery18 } from "@tanstack/react-query";
15926
16534
  import { queryExecutions as queryExecutions4, ActionType as ActionType4 } from "@unifold/core";
15927
16535
  function useExecutions(userId, publishableKey, options) {
15928
16536
  const actionType = options?.actionType ?? ActionType4.Deposit;
15929
- return useQuery17({
16537
+ return useQuery18({
15930
16538
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
15931
16539
  queryFn: () => queryExecutions4(userId, publishableKey, actionType),
15932
16540
  enabled: (options?.enabled ?? true) && !!userId,
@@ -15942,7 +16550,7 @@ import { useState as useState34, useEffect as useEffect28, useRef as useRef11 }
15942
16550
  import {
15943
16551
  queryExecutions as queryExecutions5,
15944
16552
  pollDirectExecutions as pollDirectExecutions2,
15945
- ExecutionStatus as ExecutionStatus5,
16553
+ ExecutionStatus as ExecutionStatus6,
15946
16554
  ActionType as ActionType5
15947
16555
  } from "@unifold/core";
15948
16556
  var POLL_INTERVAL_MS3 = 2500;
@@ -15991,8 +16599,8 @@ function useWithdrawPolling({
15991
16599
  const tB = b.created_at ? new Date(b.created_at).getTime() : 0;
15992
16600
  return tB - tA;
15993
16601
  });
15994
- const inProgress = [ExecutionStatus5.PENDING, ExecutionStatus5.WAITING, ExecutionStatus5.DELAYED];
15995
- const terminal = [ExecutionStatus5.SUCCEEDED, ExecutionStatus5.FAILED];
16602
+ const inProgress = [ExecutionStatus6.PENDING, ExecutionStatus6.WAITING, ExecutionStatus6.DELAYED];
16603
+ const terminal = [ExecutionStatus6.SUCCEEDED, ExecutionStatus6.FAILED];
15996
16604
  let target = null;
15997
16605
  for (const ex of sorted) {
15998
16606
  const t12 = ex.created_at ? new Date(ex.created_at) : null;
@@ -16022,9 +16630,9 @@ function useWithdrawPolling({
16022
16630
  }
16023
16631
  return [...list, ex];
16024
16632
  });
16025
- if (ex.status === ExecutionStatus5.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16633
+ if (ex.status === ExecutionStatus6.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16026
16634
  onSuccessRef.current?.({ message: "Withdrawal completed successfully", executionId: ex.id, transaction: ex });
16027
- } else if (ex.status === ExecutionStatus5.FAILED && prev !== ExecutionStatus5.FAILED) {
16635
+ } else if (ex.status === ExecutionStatus6.FAILED && prev !== ExecutionStatus6.FAILED) {
16028
16636
  onErrorRef.current?.({ message: "Withdrawal failed", code: "WITHDRAW_FAILED", error: ex });
16029
16637
  }
16030
16638
  }
@@ -16230,7 +16838,7 @@ import {
16230
16838
  } from "@unifold/core";
16231
16839
 
16232
16840
  // src/hooks/use-verify-recipient-address.ts
16233
- import { useQuery as useQuery18 } from "@tanstack/react-query";
16841
+ import { useQuery as useQuery19 } from "@tanstack/react-query";
16234
16842
  import { verifyRecipientAddress as verifyRecipientAddress2 } from "@unifold/core";
16235
16843
  function useVerifyRecipientAddress(params) {
16236
16844
  const {
@@ -16243,7 +16851,7 @@ function useVerifyRecipientAddress(params) {
16243
16851
  } = params;
16244
16852
  const trimmedAddress = recipientAddress?.trim() || "";
16245
16853
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
16246
- return useQuery18({
16854
+ return useQuery19({
16247
16855
  queryKey: [
16248
16856
  "unifold",
16249
16857
  "verifyRecipientAddress",
@@ -16515,7 +17123,7 @@ import { useMemo as useMemo12 } from "react";
16515
17123
  import { ActionType as ActionType6 } from "@unifold/core";
16516
17124
 
16517
17125
  // src/hooks/use-get-deposit-address.ts
16518
- import { useQuery as useQuery19 } from "@tanstack/react-query";
17126
+ import { useQuery as useQuery20 } from "@tanstack/react-query";
16519
17127
  import {
16520
17128
  getDepositAddress
16521
17129
  } from "@unifold/core";
@@ -16531,7 +17139,7 @@ function useGetDepositAddress(params) {
16531
17139
  enabled = true
16532
17140
  } = params;
16533
17141
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
16534
- return useQuery19({
17142
+ return useQuery20({
16535
17143
  queryKey: [
16536
17144
  "unifold",
16537
17145
  "getDepositAddress",
@@ -17184,7 +17792,7 @@ function WithdrawForm({
17184
17792
  // src/components/withdrawals/WithdrawExecutionItem.tsx
17185
17793
  import { ChevronRight as ChevronRight16 } from "lucide-react";
17186
17794
  import {
17187
- ExecutionStatus as ExecutionStatus6,
17795
+ ExecutionStatus as ExecutionStatus7,
17188
17796
  getIconUrl as getIconUrl5
17189
17797
  } from "@unifold/core";
17190
17798
  import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
@@ -17193,7 +17801,7 @@ function WithdrawExecutionItem({
17193
17801
  onClick
17194
17802
  }) {
17195
17803
  const { colors: colors2, fonts, components } = useTheme();
17196
- const isPending = execution.status === ExecutionStatus6.PENDING || execution.status === ExecutionStatus6.WAITING || execution.status === ExecutionStatus6.DELAYED;
17804
+ const isPending = execution.status === ExecutionStatus7.PENDING || execution.status === ExecutionStatus7.WAITING || execution.status === ExecutionStatus7.DELAYED;
17197
17805
  const formatDateTime = (timestamp) => {
17198
17806
  try {
17199
17807
  const date = new Date(timestamp);