@unifold/ui-react 0.1.63 → 0.1.65

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.js CHANGED
@@ -205,6 +205,22 @@ function clearStoredWalletState() {
205
205
  } catch {
206
206
  }
207
207
  }
208
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
209
+ function getLastOpenedWallet() {
210
+ if (typeof window === "undefined") return void 0;
211
+ try {
212
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
213
+ } catch {
214
+ return void 0;
215
+ }
216
+ }
217
+ function setLastOpenedWallet(walletId) {
218
+ if (typeof window === "undefined") return;
219
+ try {
220
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
221
+ } catch {
222
+ }
223
+ }
208
224
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
209
225
  function isMobileViewport() {
210
226
  if (typeof window === "undefined") return false;
@@ -572,6 +588,36 @@ function ThemeProvider({
572
588
  );
573
589
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value: contextValue, children });
574
590
  }
591
+ function AccentColorOverride({
592
+ accentColor,
593
+ accentForeground,
594
+ children
595
+ }) {
596
+ const parent = useTheme();
597
+ const value = React.useMemo(() => {
598
+ if (!accentColor) return parent;
599
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
600
+ const nextColors = {
601
+ ...parent.colors,
602
+ primary: accentColor,
603
+ primaryForeground: foreground
604
+ };
605
+ const nextComponents = {
606
+ ...parent.components,
607
+ button: {
608
+ ...parent.components.button,
609
+ primaryBackground: accentColor,
610
+ primaryText: foreground
611
+ },
612
+ card: {
613
+ ...parent.components.card,
614
+ iconBackgroundColor: `${accentColor}26`
615
+ }
616
+ };
617
+ return { ...parent, colors: nextColors, components: nextComponents };
618
+ }, [parent, accentColor, accentForeground]);
619
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value, children });
620
+ }
575
621
  function useTheme() {
576
622
  const context = React.useContext(ThemeContext);
577
623
  if (!context) {
@@ -1022,7 +1068,7 @@ function DepositHeader({
1022
1068
  setShowBalanceSkeleton(false);
1023
1069
  return;
1024
1070
  }
1025
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
1071
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
1026
1072
  if (!supportedChainTypes.includes(
1027
1073
  balanceChainType
1028
1074
  )) {
@@ -1678,6 +1724,7 @@ function useDepositPolling({
1678
1724
  clientSecret,
1679
1725
  depositConfirmationMode = "auto_ui",
1680
1726
  depositWalletId,
1727
+ depositWalletIds,
1681
1728
  enabled = true,
1682
1729
  immediateDirectPolling = false,
1683
1730
  onDepositSuccess,
@@ -1823,21 +1870,25 @@ function useDepositPolling({
1823
1870
  setIsPolling(false);
1824
1871
  };
1825
1872
  }, [userId, publishableKey, clientSecret, enabled]);
1873
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
1826
1874
  (0, import_react3.useEffect)(() => {
1827
- if (!pollingEnabled || !depositWalletId) return;
1875
+ if (!pollingEnabled || !pollWalletIdsKey) return;
1876
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
1828
1877
  const triggerPoll = async () => {
1829
- try {
1830
- await (0, import_core6.pollDirectExecutions)(
1831
- { deposit_wallet_id: depositWalletId },
1832
- publishableKey
1833
- );
1834
- } catch {
1835
- }
1878
+ await Promise.all(
1879
+ ids.map(
1880
+ (id) => (0, import_core6.pollDirectExecutions)(
1881
+ { deposit_wallet_id: id },
1882
+ publishableKey
1883
+ ).catch(() => {
1884
+ })
1885
+ )
1886
+ );
1836
1887
  };
1837
1888
  triggerPoll();
1838
1889
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
1839
1890
  return () => clearInterval(interval);
1840
- }, [pollingEnabled, depositWalletId, publishableKey]);
1891
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
1841
1892
  const handleIveDeposited = () => {
1842
1893
  setPollingEnabled(true);
1843
1894
  setShowWaitingUi(true);
@@ -3053,6 +3104,7 @@ function BuyWithCard({
3053
3104
  if (!selectedProvider) return "0.000000";
3054
3105
  return selectedProvider.destination_amount.toFixed(6);
3055
3106
  };
3107
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
3056
3108
  const selectedCurrencyData = fiatCurrencies.find(
3057
3109
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
3058
3110
  );
@@ -3238,9 +3290,12 @@ function BuyWithCard({
3238
3290
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3239
3291
  "button",
3240
3292
  {
3241
- onClick: () => handleViewChange("quotes"),
3293
+ onClick: () => {
3294
+ if (canOpenProviderSelector) handleViewChange("quotes");
3295
+ },
3242
3296
  disabled: quotesLoading || quotes.length === 0,
3243
- 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",
3297
+ "aria-disabled": !canOpenProviderSelector,
3298
+ 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"}`,
3244
3299
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
3245
3300
  children: quotesLoading ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
3246
3301
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
@@ -3267,7 +3322,7 @@ function BuyWithCard({
3267
3322
  )
3268
3323
  ] })
3269
3324
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "uf-w-full uf-text-left", children: [
3270
- isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3325
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3271
3326
  "div",
3272
3327
  {
3273
3328
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -3303,7 +3358,7 @@ function BuyWithCard({
3303
3358
  ),
3304
3359
  selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
3305
3360
  ] }),
3306
- quotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3361
+ canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3307
3362
  import_lucide_react7.ChevronRight,
3308
3363
  {
3309
3364
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -10071,7 +10126,7 @@ function useDefaultOnrampToken({
10071
10126
  }
10072
10127
 
10073
10128
  // src/components/deposits/DepositModal.tsx
10074
- var import_core29 = require("@unifold/core");
10129
+ var import_core31 = require("@unifold/core");
10075
10130
 
10076
10131
  // src/hooks/use-allowed-country.ts
10077
10132
  var import_react_query9 = require("@tanstack/react-query");
@@ -11342,7 +11397,7 @@ function useHypercoreActivation(params) {
11342
11397
  publishableKey,
11343
11398
  enabled = true
11344
11399
  } = params;
11345
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
11400
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
11346
11401
  const recipient = recipientAddress?.trim() ?? "";
11347
11402
  const source = sourceAddress?.trim() ?? "";
11348
11403
  const hasAddresses = !!recipient && !!source;
@@ -12514,11 +12569,54 @@ function TransferCryptoDoubleInput({
12514
12569
  // src/components/deposits/WalletConnect.tsx
12515
12570
  var React30 = __toESM(require("react"));
12516
12571
  var import_lucide_react28 = require("lucide-react");
12517
- var import_core28 = require("@unifold/core");
12572
+ var import_core30 = require("@unifold/core");
12573
+
12574
+ // src/lib/send-hypercore.ts
12575
+ var import_core27 = require("@unifold/core");
12576
+ function isHypercoreChain(chainId) {
12577
+ return chainId === HYPERCORE_CHAIN_ID;
12578
+ }
12579
+ async function sendHypercoreEvmTransfer(params) {
12580
+ const {
12581
+ provider,
12582
+ fromAddress,
12583
+ recipientAddress,
12584
+ sourceTokenAddress,
12585
+ amount,
12586
+ publishableKey
12587
+ } = params;
12588
+ const currentChainHex = await provider.request({
12589
+ method: "eth_chainId",
12590
+ params: []
12591
+ });
12592
+ const activeChainId = String(parseInt(currentChainHex, 16));
12593
+ const buildResult = await (0, import_core27.buildHypercoreTransaction)(
12594
+ {
12595
+ signature_chain_id: activeChainId,
12596
+ recipient_address: recipientAddress,
12597
+ token_address: sourceTokenAddress,
12598
+ amount
12599
+ },
12600
+ publishableKey
12601
+ );
12602
+ const signature = await provider.request({
12603
+ method: "eth_signTypedData_v4",
12604
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
12605
+ });
12606
+ await (0, import_core27.sendHypercoreTransaction)(
12607
+ {
12608
+ action_payload: buildResult.action_payload,
12609
+ signature,
12610
+ nonce: buildResult.nonce
12611
+ },
12612
+ publishableKey
12613
+ );
12614
+ return { signature };
12615
+ }
12518
12616
 
12519
12617
  // src/hooks/use-deposit-quote.ts
12520
12618
  var import_react_query12 = require("@tanstack/react-query");
12521
- var import_core27 = require("@unifold/core");
12619
+ var import_core28 = require("@unifold/core");
12522
12620
  function useDepositQuote(params) {
12523
12621
  const {
12524
12622
  publishableKey,
@@ -12559,7 +12657,7 @@ function useDepositQuote(params) {
12559
12657
  stablecoinParity,
12560
12658
  publishableKey
12561
12659
  ],
12562
- queryFn: () => (0, import_core27.getDepositQuote)(request, publishableKey),
12660
+ queryFn: () => (0, import_core28.getDepositQuote)(request, publishableKey),
12563
12661
  enabled: enabled && !!publishableKey && !!sourceChainType && !!sourceChainId && !!sourceTokenAddress && !!destinationAmount && destinationAmount !== "0" && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress,
12564
12662
  staleTime: 3e4,
12565
12663
  gcTime: 5 * 6e4,
@@ -12571,6 +12669,68 @@ function useDepositQuote(params) {
12571
12669
  });
12572
12670
  }
12573
12671
 
12672
+ // src/hooks/use-external-wallets.ts
12673
+ var import_react_query13 = require("@tanstack/react-query");
12674
+ var import_core29 = require("@unifold/core");
12675
+ function useExternalWallets({
12676
+ publishableKey,
12677
+ enabled = true
12678
+ }) {
12679
+ const { data: wallets = [], isLoading } = (0, import_react_query13.useQuery)({
12680
+ queryKey: ["unifold", "external-wallets", publishableKey],
12681
+ queryFn: () => (0, import_core29.getExternalWallets)(publishableKey).then((res) => res.data),
12682
+ enabled: enabled && !!publishableKey,
12683
+ staleTime: 1e3 * 60 * 30,
12684
+ refetchOnMount: false,
12685
+ refetchOnWindowFocus: false
12686
+ });
12687
+ return { wallets, isLoading };
12688
+ }
12689
+
12690
+ // src/theme/walletBrandColors.ts
12691
+ var WALLET_BRAND_COLORS = {
12692
+ phantom: "#AB9FF2",
12693
+ metamask: "#F6851B",
12694
+ coinbase: "#0052FF",
12695
+ trust: "#3375BB",
12696
+ rainbow: "#5B6CFF",
12697
+ rabby: "#7084FF",
12698
+ okx: "#000000"
12699
+ };
12700
+ function normalizeWalletId(type) {
12701
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
12702
+ }
12703
+ function getWalletBrandColor(type, mode = "dark") {
12704
+ if (!type) return void 0;
12705
+ const id = normalizeWalletId(type);
12706
+ const color = WALLET_BRAND_COLORS[id];
12707
+ if (!color) return void 0;
12708
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
12709
+ return color;
12710
+ }
12711
+ function getContrastingTextColor(hex) {
12712
+ const c = hex.replace("#", "");
12713
+ if (c.length !== 6) return "#FFFFFF";
12714
+ const r = parseInt(c.slice(0, 2), 16);
12715
+ const g = parseInt(c.slice(2, 4), 16);
12716
+ const b = parseInt(c.slice(4, 6), 16);
12717
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
12718
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
12719
+ }
12720
+
12721
+ // src/components/deposits/browser-wallets/mobileDeepLinks.ts
12722
+ function isMobileDevice() {
12723
+ if (typeof navigator === "undefined") return false;
12724
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
12725
+ }
12726
+ function getMobilePlatform() {
12727
+ if (typeof navigator === "undefined") return null;
12728
+ const ua = navigator.userAgent;
12729
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
12730
+ if (/android/i.test(ua)) return "android";
12731
+ return null;
12732
+ }
12733
+
12574
12734
  // src/components/deposits/browser-wallets/SelectTokenView.tsx
12575
12735
  var import_lucide_react25 = require("lucide-react");
12576
12736
 
@@ -12884,7 +13044,8 @@ function EnterAmountView({
12884
13044
  onClose,
12885
13045
  quickSelectMode,
12886
13046
  checkoutAmountUsd,
12887
- checkoutReceivedUsd
13047
+ checkoutReceivedUsd,
13048
+ footer
12888
13049
  }) {
12889
13050
  const { colors: colors2, fonts, components } = useTheme();
12890
13051
  const isCheckout = !!checkoutAmountUsd;
@@ -13140,6 +13301,7 @@ function EnterAmountView({
13140
13301
  )
13141
13302
  ] })
13142
13303
  ] }),
13304
+ footer && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
13143
13305
  /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
13144
13306
  "button",
13145
13307
  {
@@ -13599,18 +13761,33 @@ var WALLET_ICONS3 = {
13599
13761
  backpack: BackpackIcon,
13600
13762
  glow: GlowIcon
13601
13763
  };
13602
- var WALLET_DEFINITIONS = [
13603
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
13604
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
13605
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
13606
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
13607
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
13608
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
13609
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
13610
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
13611
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
13612
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
13764
+ var FALLBACK_WALLET_DEFINITIONS = [
13765
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
13766
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
13767
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
13768
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
13769
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
13770
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
13771
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
13613
13772
  ];
13773
+ function getMobileInstallUrl(walletId, defaultUrl) {
13774
+ if (!isMobileDevice()) return defaultUrl;
13775
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
13776
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
13777
+ const stores = {
13778
+ rabby: {
13779
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
13780
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
13781
+ },
13782
+ glow: {
13783
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
13784
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
13785
+ }
13786
+ };
13787
+ const entry = stores[walletId];
13788
+ if (!entry) return defaultUrl;
13789
+ return isIOS ? entry.ios : entry.android;
13790
+ }
13614
13791
  function normalizeTokenAddress(address) {
13615
13792
  const normalized = (address ?? "").toLowerCase();
13616
13793
  if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
@@ -13646,7 +13823,7 @@ function getLegacyEvmProviders() {
13646
13823
  okxEthereum: win.okxwallet
13647
13824
  };
13648
13825
  }
13649
- function detectAvailableWallets(filterChainType) {
13826
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
13650
13827
  const solProviders = getSolanaProviders();
13651
13828
  const legacyEvm = getLegacyEvmProviders();
13652
13829
  const eip6963List = getEip6963Providers();
@@ -13672,7 +13849,7 @@ function detectAvailableWallets(filterChainType) {
13672
13849
  return false;
13673
13850
  }
13674
13851
  });
13675
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13852
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13676
13853
  let isInstalled = false;
13677
13854
  const detectedNetworks = [];
13678
13855
  switch (wallet.id) {
@@ -13695,8 +13872,6 @@ function detectAvailableWallets(filterChainType) {
13695
13872
  isInstalled = true;
13696
13873
  detectedNetworks.push("ethereum");
13697
13874
  }
13698
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
13699
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
13700
13875
  break;
13701
13876
  case "trust":
13702
13877
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -13733,11 +13908,17 @@ function detectAvailableWallets(filterChainType) {
13733
13908
  }
13734
13909
  return { ...wallet, isInstalled, detectedNetworks };
13735
13910
  }).sort((a, b) => {
13911
+ if (recentWalletId) {
13912
+ const aRecent = a.id === recentWalletId ? 1 : 0;
13913
+ const bRecent = b.id === recentWalletId ? 1 : 0;
13914
+ if (aRecent !== bRecent) return bRecent - aRecent;
13915
+ }
13736
13916
  if (a.isInstalled && !b.isInstalled) return -1;
13737
13917
  if (!a.isInstalled && b.isInstalled) return 1;
13738
13918
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
13739
13919
  return 0;
13740
13920
  });
13921
+ return sorted;
13741
13922
  }
13742
13923
  function WalletConnect({
13743
13924
  walletInfo: initialWalletInfo,
@@ -13776,7 +13957,7 @@ function WalletConnect({
13776
13957
  depositWalletsLoading = false,
13777
13958
  onExecutionsChange
13778
13959
  }) {
13779
- const { colors: colors2, fonts, components } = useTheme();
13960
+ const { colors: colors2, fonts, components, mode } = useTheme();
13780
13961
  const walletProvidedAtMount = React30.useRef(!!initialWalletInfo && !!initialDepositWallet);
13781
13962
  const [activeWalletInfo, setActiveWalletInfo] = React30.useState(initialWalletInfo ?? null);
13782
13963
  const [activeDepositWallet, setActiveDepositWallet] = React30.useState(initialDepositWallet ?? null);
@@ -13800,7 +13981,43 @@ function WalletConnect({
13800
13981
  setEip6963ProviderCount(providers.length);
13801
13982
  });
13802
13983
  }, []);
13803
- const availableWallets = React30.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13984
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
13985
+ const walletDefinitions = React30.useMemo(
13986
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
13987
+ id: w.id,
13988
+ name: w.name,
13989
+ networks: w.chain_types,
13990
+ installUrl: w.install_url,
13991
+ supportsMobileBrowse: w.supports_mobile_browse,
13992
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
13993
+ })) : FALLBACK_WALLET_DEFINITIONS,
13994
+ [backendWallets]
13995
+ );
13996
+ const [recentWalletId, setRecentWalletIdState] = React30.useState(getLastOpenedWallet);
13997
+ React30.useEffect(() => {
13998
+ if (view === "select_wallet") {
13999
+ setRecentWalletIdState(getLastOpenedWallet());
14000
+ }
14001
+ }, [view]);
14002
+ const availableWallets = React30.useMemo(
14003
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
14004
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
14005
+ );
14006
+ const [isMobile, setIsMobile] = React30.useState(false);
14007
+ React30.useEffect(() => {
14008
+ setIsMobile(isMobileDevice());
14009
+ }, []);
14010
+ const mobileDepositAddresses = React30.useMemo(
14011
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
14012
+ [depositWallets]
14013
+ );
14014
+ const mobileDepositWalletIds = React30.useMemo(
14015
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
14016
+ [depositWallets]
14017
+ );
14018
+ const [mobileRedirect, setMobileRedirect] = React30.useState(null);
14019
+ const [pendingMobileWallet, setPendingMobileWallet] = React30.useState(null);
14020
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React30.useState(false);
13804
14021
  React30.useEffect(() => {
13805
14022
  if (!standalone || autoResolved || detectingWallet) return;
13806
14023
  if (!detectedWallet) {
@@ -13844,7 +14061,7 @@ function WalletConnect({
13844
14061
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
13845
14062
  const recipientAddress = activeDepositWallet?.address ?? "";
13846
14063
  const isCheckoutMode = !!checkoutAmountUsd;
13847
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
14064
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
13848
14065
  const transitionTo = React30.useCallback((nextView) => {
13849
14066
  if (nextView === viewRef.current) return;
13850
14067
  setIsTransitioning(true);
@@ -13859,9 +14076,38 @@ function WalletConnect({
13859
14076
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
13860
14077
  transition: "opacity 150ms ease, transform 150ms ease"
13861
14078
  };
13862
- const handleWalletClick = (wallet) => {
14079
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
14080
+ try {
14081
+ const res = await (0, import_core30.getWalletMobileDeepLink)(
14082
+ wallet.id,
14083
+ depositAddresses,
14084
+ publishableKey
14085
+ );
14086
+ if (res.deeplink) {
14087
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
14088
+ setLastOpenedWallet(wallet.id);
14089
+ setRecentWalletIdState(wallet.id);
14090
+ setAwaitingMobileDeposit(true);
14091
+ transitionTo("mobile_redirect");
14092
+ window.location.href = res.deeplink;
14093
+ return true;
14094
+ }
14095
+ } catch {
14096
+ }
14097
+ return false;
14098
+ };
14099
+ const handleWalletClick = async (wallet) => {
13863
14100
  if (!wallet.isInstalled) {
13864
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
14101
+ const platform = getMobilePlatform();
14102
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform ?? "");
14103
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
14104
+ if (mobileDepositAddresses.length === 0) {
14105
+ setPendingMobileWallet(wallet);
14106
+ return;
14107
+ }
14108
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
14109
+ }
14110
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
13865
14111
  return;
13866
14112
  }
13867
14113
  setSelectedWalletDef(wallet);
@@ -13877,9 +14123,32 @@ function WalletConnect({
13877
14123
  if (!selectedWalletDef) return;
13878
14124
  handleConnectWallet(selectedWalletDef, network);
13879
14125
  };
14126
+ React30.useEffect(() => {
14127
+ if (!pendingMobileWallet) return;
14128
+ if (mobileDepositAddresses.length > 0) {
14129
+ const wallet = pendingMobileWallet;
14130
+ setPendingMobileWallet(null);
14131
+ void (async () => {
14132
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
14133
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
14134
+ }
14135
+ })();
14136
+ return;
14137
+ }
14138
+ const timeout = setTimeout(() => {
14139
+ setPendingMobileWallet((current) => {
14140
+ if (!current) return null;
14141
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
14142
+ return null;
14143
+ });
14144
+ }, 8e3);
14145
+ return () => clearTimeout(timeout);
14146
+ }, [pendingMobileWallet, mobileDepositAddresses]);
13880
14147
  const handleConnectWallet = async (wallet, network) => {
13881
14148
  setConnectingNetwork(network);
13882
14149
  transitionTo("connecting");
14150
+ setLastOpenedWallet(wallet.id);
14151
+ setRecentWalletIdState(wallet.id);
13883
14152
  setWalletError(null);
13884
14153
  setIsWalletConnecting(true);
13885
14154
  try {
@@ -13984,6 +14253,13 @@ function WalletConnect({
13984
14253
  }
13985
14254
  };
13986
14255
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
14256
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
14257
+ recipientAddress,
14258
+ sourceAddress: activeWalletInfo?.address,
14259
+ destinationChainId: selectedToken?.chain_id,
14260
+ publishableKey,
14261
+ enabled: !!activeWalletInfo && !!recipientAddress
14262
+ });
13987
14263
  const effectiveDestinationAmount = React30.useMemo(() => {
13988
14264
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
13989
14265
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -14021,14 +14297,32 @@ function WalletConnect({
14021
14297
  userId,
14022
14298
  publishableKey,
14023
14299
  clientSecret,
14300
+ // In-tab flow: poll the single connected deposit wallet.
14024
14301
  depositWalletId: activeDepositWallet?.id ?? "",
14025
- enabled: hasSignedTransaction && !!activeDepositWallet,
14302
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
14303
+ // chain's deposit wallet. Detection still happens via the single /query by
14304
+ // external_user_id, which already spans all chains.
14305
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
14306
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
14026
14307
  onDepositSuccess,
14027
14308
  onDepositError
14028
14309
  });
14029
14310
  React30.useEffect(() => {
14030
14311
  onExecutionsChange?.(depositExecutions);
14031
14312
  }, [depositExecutions, onExecutionsChange]);
14313
+ const latestDepositExecution = React30.useMemo(() => {
14314
+ if (depositExecutions.length === 0) return null;
14315
+ return [...depositExecutions].sort((a, b) => {
14316
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
14317
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
14318
+ return tb - ta;
14319
+ })[0];
14320
+ }, [depositExecutions]);
14321
+ React30.useEffect(() => {
14322
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
14323
+ transitionTo("mobile_deposit_status");
14324
+ }
14325
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
14032
14326
  React30.useEffect(() => {
14033
14327
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
14034
14328
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -14047,7 +14341,7 @@ function WalletConnect({
14047
14341
  const token = getTokenFromBalance(selectedBalance);
14048
14342
  if (!token) return;
14049
14343
  const options = { destination_token_address: activeDepositWallet.destination_token_address, destination_chain_id: activeDepositWallet.destination_chain_id, destination_chain_type: activeDepositWallet.destination_chain_type, ...productType ? { product_type: productType } : {} };
14050
- const response = await (0, import_core28.getSupportedDepositTokens)(publishableKey, options);
14344
+ const response = await (0, import_core30.getSupportedDepositTokens)(publishableKey, options);
14051
14345
  if (cancelled) return;
14052
14346
  const supportedToken = response.data.find((t12) => t12.symbol.toLowerCase() === token.symbol.toLowerCase());
14053
14347
  if (supportedToken) {
@@ -14070,8 +14364,8 @@ function WalletConnect({
14070
14364
  let cancelled = false;
14071
14365
  setIsLoading(true);
14072
14366
  setError(null);
14073
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
14074
- (0, import_core28.getAddressBalances)(activeWalletInfo.address, sct, publishableKey).then((response) => {
14367
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
14368
+ (0, import_core30.getAddressBalances)(activeWalletInfo.address, sct, publishableKey).then((response) => {
14075
14369
  if (cancelled) return;
14076
14370
  const nonZero = response.balances.filter((b) => b.amount !== "0");
14077
14371
  const defaultSource = {
@@ -14159,6 +14453,16 @@ function WalletConnect({
14159
14453
  setSelectedWalletDef(null);
14160
14454
  setConnectingNetwork(null);
14161
14455
  break;
14456
+ case "mobile_redirect":
14457
+ transitionTo("select_wallet");
14458
+ setMobileRedirect(null);
14459
+ setAwaitingMobileDeposit(false);
14460
+ break;
14461
+ case "mobile_deposit_status":
14462
+ transitionTo("select_wallet");
14463
+ setMobileRedirect(null);
14464
+ setAwaitingMobileDeposit(false);
14465
+ break;
14162
14466
  case "select_token":
14163
14467
  if (walletProvidedAtMount.current) parentOnBack?.();
14164
14468
  else transitionTo("select_wallet");
@@ -14226,9 +14530,16 @@ function WalletConnect({
14226
14530
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
14227
14531
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
14228
14532
  };
14229
- const sendEthereumTransaction = async (token, amountStr) => {
14230
- if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
14231
- const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
14533
+ const resolveEvmProvider = () => {
14534
+ const walletIdMap = {
14535
+ "phantom-ethereum": "phantom",
14536
+ coinbase: "coinbase",
14537
+ trust: "trust",
14538
+ okx: "okx",
14539
+ rainbow: "rainbow",
14540
+ rabby: "rabby",
14541
+ metamask: "metamask"
14542
+ };
14232
14543
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
14233
14544
  const eip6963Match = findProviderByWalletId(lookupId);
14234
14545
  let provider = eip6963Match?.provider;
@@ -14237,6 +14548,11 @@ function WalletConnect({
14237
14548
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
14238
14549
  else provider = window.ethereum;
14239
14550
  }
14551
+ return provider;
14552
+ };
14553
+ const sendEthereumTransaction = async (token, amountStr) => {
14554
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
14555
+ const provider = resolveEvmProvider();
14240
14556
  if (!provider) throw new Error("Ethereum wallet not found");
14241
14557
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
14242
14558
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -14285,7 +14601,7 @@ function WalletConnect({
14285
14601
  if (!provider.publicKey) await provider.connect();
14286
14602
  const isNative = token.token_address === "native" || token.token_address === "So11111111111111111111111111111111111111112" || token.token_address === "";
14287
14603
  const smallestUnit = isNative ? decimalToSmallestUnit(amountStr, 9) : decimalToSmallestUnit(amountStr, token.decimals);
14288
- const buildResp = await (0, import_core28.buildSolanaTransaction)({ chain_id: "mainnet", token_address: token.token_address === "" ? "native" : token.token_address, source_address: walletInfo.address, destination_address: recipientAddress, amount: smallestUnit }, publishableKey);
14604
+ const buildResp = await (0, import_core30.buildSolanaTransaction)({ chain_id: "mainnet", token_address: token.token_address === "" ? "native" : token.token_address, source_address: walletInfo.address, destination_address: recipientAddress, amount: smallestUnit }, publishableKey);
14289
14605
  const { VersionedTransaction } = await import(
14290
14606
  /* @vite-ignore */
14291
14607
  "@solana/web3.js"
@@ -14298,9 +14614,22 @@ function WalletConnect({
14298
14614
  const ser = signed.serialize();
14299
14615
  let bs = "";
14300
14616
  for (let i = 0; i < ser.length; i++) bs += String.fromCharCode(ser[i]);
14301
- const resp = await (0, import_core28.sendSolanaTransaction)({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
14617
+ const resp = await (0, import_core30.sendSolanaTransaction)({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
14302
14618
  return resp.signature;
14303
14619
  };
14620
+ const sendHypercoreDeposit = async (token, amountStr) => {
14621
+ const provider = resolveEvmProvider();
14622
+ if (!provider) throw new Error("Ethereum wallet not found");
14623
+ const { signature } = await sendHypercoreEvmTransfer({
14624
+ provider,
14625
+ fromAddress: walletInfo.address,
14626
+ recipientAddress,
14627
+ sourceTokenAddress: token.token_address,
14628
+ amount: amountStr,
14629
+ publishableKey
14630
+ });
14631
+ return signature;
14632
+ };
14304
14633
  const handleConfirm = async () => {
14305
14634
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
14306
14635
  const token = getTokenFromBalance(selectedBalance);
@@ -14320,7 +14649,33 @@ function WalletConnect({
14320
14649
  setIsConfirming(true);
14321
14650
  setError(null);
14322
14651
  try {
14323
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
14652
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
14653
+ let txHash;
14654
+ if (token.chain_type === "solana") {
14655
+ txHash = await sendSolanaTransaction(token, tokenAmount.toString());
14656
+ } else if (isHypercoreToken) {
14657
+ let sendAmount = tokenAmount;
14658
+ try {
14659
+ const activation = await (0, import_core30.checkHypercoreActivation)(
14660
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
14661
+ publishableKey
14662
+ );
14663
+ if (!activation.user_exists) {
14664
+ const fee = activation.activation_fee;
14665
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
14666
+ throw new Error(
14667
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
14668
+ );
14669
+ }
14670
+ sendAmount = tokenAmount - fee;
14671
+ }
14672
+ } catch (e) {
14673
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
14674
+ }
14675
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
14676
+ } else {
14677
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
14678
+ }
14324
14679
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
14325
14680
  setHasSignedTransaction(true);
14326
14681
  handleIveDeposited();
@@ -14344,33 +14699,40 @@ function WalletConnect({
14344
14699
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14345
14700
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14346
14701
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-pb-4", children: [
14347
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Select a wallet to connect" }),
14348
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
14349
- "button",
14350
- {
14351
- onClick: () => handleWalletClick(wallet),
14352
- disabled: isWalletConnecting,
14353
- 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",
14354
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
14355
- children: [
14356
- /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
14357
- WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
14358
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
14359
- ] }),
14360
- wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("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__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
14361
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
14362
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react28.ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
14363
- ] })
14364
- ]
14365
- },
14366
- wallet.id
14367
- )) }),
14702
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("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" }),
14703
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
14704
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
14705
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
14706
+ const isPending = pendingMobileWallet?.id === wallet.id;
14707
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
14708
+ "button",
14709
+ {
14710
+ onClick: () => void handleWalletClick(wallet),
14711
+ disabled: isWalletConnecting || !!pendingMobileWallet,
14712
+ 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",
14713
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
14714
+ children: [
14715
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
14716
+ WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
14717
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
14718
+ ] }),
14719
+ isPending ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react28.Loader2, { className: "uf-w-4 uf-h-4 uf-animate-spin", style: { color: colors2.primary } }) : wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("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__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
14720
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
14721
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react28.ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
14722
+ ] })
14723
+ ]
14724
+ },
14725
+ wallet.id
14726
+ );
14727
+ }) }),
14368
14728
  walletError && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
14369
14729
  ] })
14370
14730
  ] });
14371
14731
  }
14732
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
14733
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
14372
14734
  if (view === "select_network" && selectedWalletDef) {
14373
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14735
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14374
14736
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
14375
14737
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-pb-4", children: [
14376
14738
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -14400,10 +14762,10 @@ function WalletConnect({
14400
14762
  )) }),
14401
14763
  walletError && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
14402
14764
  ] })
14403
- ] });
14765
+ ] }) });
14404
14766
  }
14405
14767
  if (view === "connecting") {
14406
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14768
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14407
14769
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
14408
14770
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
14409
14771
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react28.Loader2, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -14414,24 +14776,132 @@ function WalletConnect({
14414
14776
  ] }),
14415
14777
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: "Please approve the connection in your wallet" })
14416
14778
  ] })
14417
- ] });
14779
+ ] }) });
14780
+ }
14781
+ if (view === "mobile_redirect" && mobileRedirect) {
14782
+ const Icon2 = WALLET_ICONS3[mobileRedirect.walletId];
14783
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14784
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
14785
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-px-6 uf-py-10", children: [
14786
+ Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Icon2, { size: 64, className: "uf-rounded-2xl uf-mb-5" }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-w-16 uf-h-16 uf-rounded-2xl uf-bg-gray-500 uf-mb-5" }),
14787
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
14788
+ "div",
14789
+ {
14790
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
14791
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
14792
+ children: [
14793
+ "Continue in ",
14794
+ mobileRedirect.walletName
14795
+ ]
14796
+ }
14797
+ ),
14798
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
14799
+ "div",
14800
+ {
14801
+ className: "uf-text-sm uf-text-center uf-mb-6",
14802
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
14803
+ children: [
14804
+ "Complete your deposit in the ",
14805
+ mobileRedirect.walletName,
14806
+ " app"
14807
+ ]
14808
+ }
14809
+ ),
14810
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
14811
+ "button",
14812
+ {
14813
+ type: "button",
14814
+ onClick: () => {
14815
+ window.location.href = mobileRedirect.deeplink;
14816
+ },
14817
+ 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",
14818
+ style: {
14819
+ backgroundColor: components.card.backgroundColor,
14820
+ borderRadius: components.card.borderRadius,
14821
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
14822
+ color: components.card.titleColor,
14823
+ fontFamily: fonts.medium
14824
+ },
14825
+ children: [
14826
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react28.ExternalLink, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
14827
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("span", { className: "uf-text-sm uf-font-medium", children: [
14828
+ "Open in ",
14829
+ mobileRedirect.walletName
14830
+ ] })
14831
+ ]
14832
+ }
14833
+ ),
14834
+ awaitingMobileDeposit && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
14835
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
14836
+ import_lucide_react28.Loader2,
14837
+ {
14838
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
14839
+ style: { color: colors2.foregroundMuted }
14840
+ }
14841
+ ),
14842
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
14843
+ "span",
14844
+ {
14845
+ className: "uf-text-sm",
14846
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
14847
+ children: "Checking for deposit..."
14848
+ }
14849
+ )
14850
+ ] })
14851
+ ] })
14852
+ ] }) });
14853
+ }
14854
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
14855
+ const isComplete = latestDepositExecution.status === import_core30.ExecutionStatus.SUCCEEDED;
14856
+ const isFailed = latestDepositExecution.status === import_core30.ExecutionStatus.FAILED;
14857
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
14858
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14859
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
14860
+ DepositHeader,
14861
+ {
14862
+ title,
14863
+ showBack: false,
14864
+ onClose: isComplete && onDone ? onDone : onClose
14865
+ }
14866
+ ),
14867
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositDetailContent, { execution: latestDepositExecution }),
14868
+ isComplete && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-4 uf-pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
14869
+ "button",
14870
+ {
14871
+ type: "button",
14872
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
14873
+ }),
14874
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
14875
+ style: {
14876
+ backgroundColor: colors2.primary,
14877
+ color: colors2.primaryForeground,
14878
+ fontFamily: fonts.medium,
14879
+ borderRadius: components.button.borderRadius,
14880
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
14881
+ },
14882
+ children: "Done"
14883
+ }
14884
+ ) })
14885
+ ] }) });
14418
14886
  }
14419
14887
  if (!hasWallet) return null;
14888
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
14889
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
14420
14890
  if (view === "select_token") {
14421
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
14422
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
14891
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
14892
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
14423
14893
  }
14424
14894
  if (view === "enter_amount" && selectedToken && selectedBalance) {
14425
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
14426
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
14895
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
14896
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
14427
14897
  }
14428
14898
  if (view === "review" && selectedToken) {
14429
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
14430
- }) }) });
14899
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
14900
+ }) }) }) });
14431
14901
  }
14432
14902
  if (view === "confirming") {
14433
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
14434
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
14903
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
14904
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
14435
14905
  }
14436
14906
  return null;
14437
14907
  }
@@ -14462,6 +14932,9 @@ function SkeletonButton({
14462
14932
  ] });
14463
14933
  }
14464
14934
  var t7 = i18n.depositModal;
14935
+ function depositTabForScreen(screen) {
14936
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
14937
+ }
14465
14938
  function DepositModal({
14466
14939
  open,
14467
14940
  onOpenChange,
@@ -14497,6 +14970,7 @@ function DepositModal({
14497
14970
  theme = "dark",
14498
14971
  hideOverlay = false,
14499
14972
  initialScreen = "main",
14973
+ displayMode = "stacked",
14500
14974
  transferCryptoTitle = t7.transferCrypto.title,
14501
14975
  depositWithCardTitle = t7.depositWithCard.title,
14502
14976
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -14531,6 +15005,9 @@ function DepositModal({
14531
15005
  effectiveInitialScreen
14532
15006
  );
14533
15007
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = (0, import_react20.useState)(false);
15008
+ const [depositTab, setDepositTab] = (0, import_react20.useState)(
15009
+ () => depositTabForScreen(effectiveInitialScreen)
15010
+ );
14534
15011
  const resetViewTimeoutRef = (0, import_react20.useRef)(null);
14535
15012
  const [cardView, setCardView] = (0, import_react20.useState)(
14536
15013
  "amount"
@@ -14546,7 +15023,6 @@ function DepositModal({
14546
15023
  const [allExecutions, setAllExecutions] = (0, import_react20.useState)([]);
14547
15024
  const [selectedExecution, setSelectedExecution] = (0, import_react20.useState)(null);
14548
15025
  const [depositExecutions, setDepositExecutions] = (0, import_react20.useState)([]);
14549
- const isMobileView = useIsMobileViewport();
14550
15026
  const { projectConfig } = useProjectConfig({
14551
15027
  publishableKey,
14552
15028
  enabled: open
@@ -14561,18 +15037,18 @@ function DepositModal({
14561
15037
  const [integrationExchanges, setIntegrationExchanges] = (0, import_react20.useState)([]);
14562
15038
  (0, import_react20.useEffect)(() => {
14563
15039
  if (!showConnectExchange || !open) return;
14564
- (0, import_core29.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
15040
+ (0, import_core31.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
14565
15041
  });
14566
15042
  }, [showConnectExchange, open, publishableKey]);
14567
15043
  const [connectedExchange, setConnectedExchange] = (0, import_react20.useState)(() => {
14568
15044
  if (!showConnectExchange) return null;
14569
- const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
15045
+ const stored = getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
14570
15046
  if (!stored) return null;
14571
15047
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
14572
15048
  });
14573
15049
  (0, import_react20.useEffect)(() => {
14574
15050
  if (!showConnectExchange || !open || view !== "main") return;
14575
- const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
15051
+ const stored = getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
14576
15052
  if (!stored) {
14577
15053
  setConnectedExchange(null);
14578
15054
  return;
@@ -14589,20 +15065,20 @@ function DepositModal({
14589
15065
  const balanceUsd = totalUsd > 0 ? totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : null;
14590
15066
  setConnectedExchange((prev) => prev ? { ...prev, balanceUsd, isLoading: false } : null);
14591
15067
  };
14592
- (0, import_core29.getIntegrationHoldings)(import_core29.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
15068
+ (0, import_core31.getIntegrationHoldings)(import_core31.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
14593
15069
  try {
14594
- const refreshResult = await (0, import_core29.refreshIntegrationToken)(stored.access_token, publishableKey);
14595
- if (!getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE)) return;
15070
+ const refreshResult = await (0, import_core31.refreshIntegrationToken)(stored.access_token, publishableKey);
15071
+ if (!getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE)) return;
14596
15072
  setStoredIntegrationToken({
14597
- integration_provider: import_core29.IntegrationProvider.COINBASE,
15073
+ integration_provider: import_core31.IntegrationProvider.COINBASE,
14598
15074
  access_token: refreshResult.access_token,
14599
15075
  expires_at: refreshResult.expires_at
14600
15076
  });
14601
- const retryResult = await (0, import_core29.getIntegrationHoldings)(import_core29.IntegrationProvider.COINBASE, refreshResult.access_token, publishableKey);
15077
+ const retryResult = await (0, import_core31.getIntegrationHoldings)(import_core31.IntegrationProvider.COINBASE, refreshResult.access_token, publishableKey);
14602
15078
  processHoldings(retryResult);
14603
15079
  } catch {
14604
- if (!getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE)) return;
14605
- clearStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
15080
+ if (!getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE)) return;
15081
+ clearStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
14606
15082
  setConnectedExchange(null);
14607
15083
  }
14608
15084
  });
@@ -14610,7 +15086,7 @@ function DepositModal({
14610
15086
  (0, import_react20.useEffect)(() => {
14611
15087
  if (!connectedExchange || integrationExchanges.length === 0) return;
14612
15088
  const cbExchange = integrationExchanges.find(
14613
- (e) => e.service_provider === import_core29.IntegrationProvider.COINBASE
15089
+ (e) => e.service_provider === import_core31.IntegrationProvider.COINBASE
14614
15090
  );
14615
15091
  const iconUrl = cbExchange?.icon_urls?.find((u) => u.format === "svg")?.url || cbExchange?.icon_urls?.find((u) => u.format === "png")?.url || cbExchange?.icon_url;
14616
15092
  if (iconUrl && iconUrl !== connectedExchange.iconUrl) {
@@ -14696,7 +15172,7 @@ function DepositModal({
14696
15172
  if (view !== "tracker" || !userId) return;
14697
15173
  const fetchExecutions = async () => {
14698
15174
  try {
14699
- const response = await (0, import_core29.queryExecutions)(userId, publishableKey, import_core29.ActionType.Deposit);
15175
+ const response = await (0, import_core31.queryExecutions)(userId, publishableKey, import_core31.ActionType.Deposit);
14700
15176
  const sorted = [...response.data].sort((a, b) => {
14701
15177
  const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
14702
15178
  const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
@@ -14800,11 +15276,11 @@ function DepositModal({
14800
15276
  if (view === "wallet_connect" && sessionOpenedFromMenu) setView("main");
14801
15277
  };
14802
15278
  const handleExchangeDisconnect = () => {
14803
- const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
15279
+ const stored = getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
14804
15280
  if (stored) {
14805
- (0, import_core29.revokeIntegrationToken)(stored.access_token, publishableKey);
15281
+ (0, import_core31.revokeIntegrationToken)(stored.access_token, publishableKey);
14806
15282
  }
14807
- clearStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
15283
+ clearStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
14808
15284
  setConnectedExchange(null);
14809
15285
  if (view === "coinbase_connect" && sessionOpenedFromMenu) setView("main");
14810
15286
  };
@@ -14829,6 +15305,7 @@ function DepositModal({
14829
15305
  resetViewTimeoutRef.current = null;
14830
15306
  }
14831
15307
  setView(effectiveInitialScreen);
15308
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
14832
15309
  setCardView("amount");
14833
15310
  setExchangeView("providers");
14834
15311
  setBrowserWalletInfo(null);
@@ -14857,6 +15334,7 @@ function DepositModal({
14857
15334
  } else if (view === "cashapp" && cashAppView !== "amount") {
14858
15335
  setCashAppView("amount");
14859
15336
  } else {
15337
+ setDepositTab(depositTabForScreen(view));
14860
15338
  setView("main");
14861
15339
  setCardView("amount");
14862
15340
  setExchangeView("providers");
@@ -14936,13 +15414,181 @@ function DepositModal({
14936
15414
  className: "uf-flex uf-justify-center uf-shrink-0"
14937
15415
  }
14938
15416
  ) });
14939
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14940
- Dialog,
15417
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15418
+ TransferCryptoButton,
14941
15419
  {
14942
- open: hideOverlay || open,
15420
+ onClick: () => setView("transfer"),
15421
+ title: transferCryptoTitle,
15422
+ subtitle: t7.transferCrypto.subtitle,
15423
+ featuredTokens: projectConfig?.transfer_crypto.networks
15424
+ },
15425
+ "transfer"
15426
+ ) : null;
15427
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15428
+ BrowserWalletButton,
15429
+ {
15430
+ onClick: handleBrowserWalletClick,
15431
+ onConnectClick: handleWalletConnectClick,
15432
+ onDisconnect: handleWalletDisconnect,
15433
+ chainType: browserWalletChainType,
15434
+ publishableKey,
15435
+ featuredWallets: projectConfig?.connect_wallet?.wallets
15436
+ },
15437
+ "wallet"
15438
+ ) : null;
15439
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15440
+ DepositWithCardButton,
15441
+ {
15442
+ onClick: () => setView("card"),
15443
+ title: depositWithCardTitle,
15444
+ subtitle: t7.depositWithCard.subtitle,
15445
+ paymentNetworks: projectConfig?.payment_networks.networks
15446
+ },
15447
+ "card"
15448
+ ) : null;
15449
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15450
+ PayWithExchangeButton,
15451
+ {
15452
+ onClick: () => setView("exchange"),
15453
+ title: payWithExchangeTitle,
15454
+ subtitle: t7.payWithExchange.subtitle,
15455
+ exchanges,
15456
+ loading: exchangesLoading
15457
+ },
15458
+ "exchange"
15459
+ ) : null;
15460
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15461
+ ConnectExchangeButton,
15462
+ {
15463
+ onClick: () => {
15464
+ setCoinbaseSkipToHoldings(true);
15465
+ setView("coinbase_connect");
15466
+ },
15467
+ onDisconnect: handleExchangeDisconnect,
15468
+ title: i18n.connectExchange.title,
15469
+ subtitle: i18n.connectExchange.subtitle,
15470
+ exchanges: integrationExchanges,
15471
+ connectedExchange
15472
+ },
15473
+ "connect-exchange"
15474
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15475
+ ConnectExchangeButton,
15476
+ {
15477
+ onClick: () => {
15478
+ setCoinbaseSkipToHoldings(false);
15479
+ setView("coinbase_connect");
15480
+ },
15481
+ title: i18n.connectExchange.title,
15482
+ subtitle: i18n.connectExchange.subtitle,
15483
+ exchanges: integrationExchanges
15484
+ },
15485
+ "connect-exchange"
15486
+ ) : null;
15487
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15488
+ CashAppButton,
15489
+ {
15490
+ onClick: () => setView("cashapp"),
15491
+ title: "Pay with Cash App",
15492
+ subtitle: "Deposit via Cash App",
15493
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
15494
+ },
15495
+ "cashapp"
15496
+ ) : null;
15497
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15498
+ DepositTrackerButton,
15499
+ {
15500
+ onClick: () => {
15501
+ setAllExecutions(depositExecutions);
15502
+ setView("tracker");
15503
+ },
15504
+ title: depositTrackerTitle,
15505
+ subtitle: depositTrackerSubTitle,
15506
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
15507
+ },
15508
+ "tracker"
15509
+ ) : null;
15510
+ const cryptoMenuButtons = [
15511
+ transferCryptoMenuButton,
15512
+ connectWalletMenuButton,
15513
+ payWithExchangeMenuButton,
15514
+ connectExchangeMenuButton
15515
+ ].filter(Boolean);
15516
+ const cashMenuButtons = [
15517
+ depositWithCardMenuButton,
15518
+ cashAppMenuButton
15519
+ ].filter(Boolean);
15520
+ const depositTabs = [
15521
+ { id: "crypto", label: "Use Crypto", buttons: cryptoMenuButtons },
15522
+ { id: "cash", label: "Use Cash", buttons: cashMenuButtons }
15523
+ ].filter((tab) => tab.buttons.length > 0);
15524
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
15525
+ const renderMainMenuBody = () => {
15526
+ if (depositPrerequisiteBody) {
15527
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
15528
+ }
15529
+ if (displayMode === "tabs" && activeDepositTab) {
15530
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { children: [
15531
+ depositTabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15532
+ "div",
15533
+ {
15534
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
15535
+ style: {
15536
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
15537
+ // the control reads as a soft surface rather than a solid bar.
15538
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
15539
+ backdropFilter: "blur(12px)",
15540
+ WebkitBackdropFilter: "blur(12px)"
15541
+ },
15542
+ role: "tablist",
15543
+ children: depositTabs.map((tab) => {
15544
+ const active = activeDepositTab.id === tab.id;
15545
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15546
+ "button",
15547
+ {
15548
+ type: "button",
15549
+ role: "tab",
15550
+ "aria-selected": active,
15551
+ onClick: () => setDepositTab(tab.id),
15552
+ className: "uf-flex-1 uf-py-2 uf-px-3 uf-rounded-lg uf-text-sm uf-transition-all",
15553
+ style: {
15554
+ // Active tab is a soft, blurred glass pill — a faint accent
15555
+ // tint with its own backdrop blur and a subtle border/shadow,
15556
+ // so it looks frosted instead of like a hard solid button.
15557
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
15558
+ backdropFilter: active ? "blur(8px)" : void 0,
15559
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
15560
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
15561
+ color: active ? colors2.foreground : colors2.foregroundMuted,
15562
+ fontFamily: fonts.medium
15563
+ },
15564
+ children: tab.label
15565
+ },
15566
+ tab.id
15567
+ );
15568
+ })
15569
+ }
15570
+ ),
15571
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
15572
+ depositTrackerMenuButton && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
15573
+ ] });
15574
+ }
15575
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-space-y-3", children: [
15576
+ transferCryptoMenuButton,
15577
+ connectWalletMenuButton,
15578
+ depositWithCardMenuButton,
15579
+ payWithExchangeMenuButton,
15580
+ connectExchangeMenuButton,
15581
+ cashAppMenuButton,
15582
+ depositTrackerMenuButton
15583
+ ] });
15584
+ };
15585
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15586
+ Dialog,
15587
+ {
15588
+ open: hideOverlay || open,
14943
15589
  onOpenChange: hideOverlay ? void 0 : handleClose,
14944
15590
  modal: !hideOverlay,
14945
- children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15591
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
14946
15592
  DialogContent,
14947
15593
  {
14948
15594
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -14951,386 +15597,302 @@ function DepositModal({
14951
15597
  style: { backgroundColor: colors2.background },
14952
15598
  onPointerDownOutside: (e) => e.preventDefault(),
14953
15599
  onInteractOutside: (e) => e.preventDefault(),
14954
- children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
14955
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14956
- DepositHeader,
14957
- {
14958
- title: modalTitle || "Deposit",
14959
- showClose: !hideOverlay,
14960
- onClose: handleClose,
14961
- showBalance: showBalanceHeader,
14962
- balanceAddress: recipientAddress,
14963
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
14964
- balanceChainId: destinationChainId,
14965
- balanceTokenAddress: destinationTokenAddress,
14966
- projectName: projectConfig?.project_name,
14967
- publishableKey
14968
- }
14969
- ),
14970
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14971
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
14972
- showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14973
- TransferCryptoButton,
14974
- {
14975
- onClick: () => setView("transfer"),
14976
- title: transferCryptoTitle,
14977
- subtitle: t7.transferCrypto.subtitle,
14978
- featuredTokens: projectConfig?.transfer_crypto.networks
14979
- }
14980
- ),
14981
- showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14982
- BrowserWalletButton,
15600
+ children: [
15601
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(DialogTitle, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
15602
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15603
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15604
+ DepositHeader,
15605
+ {
15606
+ title: modalTitle || "Deposit",
15607
+ showClose: !hideOverlay,
15608
+ onClose: handleClose,
15609
+ showBalance: showBalanceHeader,
15610
+ balanceAddress: recipientAddress,
15611
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
15612
+ balanceChainId: destinationChainId,
15613
+ balanceTokenAddress: destinationTokenAddress,
15614
+ projectName: projectConfig?.project_name,
15615
+ publishableKey
15616
+ }
15617
+ ),
15618
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15619
+ renderMainMenuBody(),
15620
+ depositPoweredByFooter
15621
+ ] })
15622
+ ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15623
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15624
+ DepositHeader,
15625
+ {
15626
+ title: transferCryptoTitle,
15627
+ showBack: showBackTransfer,
15628
+ onBack: handleBack,
15629
+ onClose: handleClose,
15630
+ showBalance: showBalanceHeader,
15631
+ balanceAddress: recipientAddress,
15632
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
15633
+ balanceChainId: destinationChainId,
15634
+ balanceTokenAddress: destinationTokenAddress,
15635
+ projectName: projectConfig?.project_name,
15636
+ publishableKey
15637
+ }
15638
+ ),
15639
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15640
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15641
+ TransferCryptoSingleInput,
14983
15642
  {
14984
- onClick: handleBrowserWalletClick,
14985
- onConnectClick: handleWalletConnectClick,
14986
- onDisconnect: handleWalletDisconnect,
14987
- chainType: browserWalletChainType,
15643
+ userId,
14988
15644
  publishableKey,
14989
- featuredWallets: projectConfig?.connect_wallet?.wallets
15645
+ recipientAddress,
15646
+ destinationChainType,
15647
+ destinationChainId,
15648
+ destinationTokenAddress,
15649
+ defaultSourceChainType,
15650
+ defaultSourceChainId,
15651
+ defaultSourceTokenAddress,
15652
+ defaultSourceSymbol,
15653
+ depositConfirmationMode,
15654
+ onExecutionsChange: setDepositExecutions,
15655
+ onDepositSuccess,
15656
+ onDepositError,
15657
+ wallets
14990
15658
  }
14991
- ),
14992
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14993
- DepositWithCardButton,
15659
+ ) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15660
+ TransferCryptoDoubleInput,
14994
15661
  {
14995
- onClick: () => setView("card"),
14996
- title: depositWithCardTitle,
14997
- subtitle: t7.depositWithCard.subtitle,
14998
- paymentNetworks: projectConfig?.payment_networks.networks
15662
+ userId,
15663
+ publishableKey,
15664
+ recipientAddress,
15665
+ destinationChainType,
15666
+ destinationChainId,
15667
+ destinationTokenAddress,
15668
+ defaultSourceChainType,
15669
+ defaultSourceChainId,
15670
+ defaultSourceTokenAddress,
15671
+ defaultSourceSymbol,
15672
+ depositConfirmationMode,
15673
+ onExecutionsChange: setDepositExecutions,
15674
+ onDepositSuccess,
15675
+ onDepositError,
15676
+ wallets
14999
15677
  }
15000
15678
  ),
15001
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15002
- PayWithExchangeButton,
15679
+ depositPoweredByFooter
15680
+ ] })
15681
+ ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15682
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15683
+ DepositHeader,
15684
+ {
15685
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
15686
+ showBack: showBackTracker,
15687
+ onBack: handleBack,
15688
+ onClose: handleClose
15689
+ }
15690
+ ),
15691
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15692
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15693
+ "div",
15003
15694
  {
15004
- onClick: () => setView("exchange"),
15005
- title: payWithExchangeTitle,
15006
- subtitle: t7.payWithExchange.subtitle,
15007
- exchanges,
15008
- loading: exchangesLoading
15695
+ className: "uf-text-sm",
15696
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
15697
+ children: "No deposits yet"
15009
15698
  }
15010
- ),
15011
- showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15012
- ConnectExchangeButton,
15699
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15700
+ DepositExecutionItem,
15013
15701
  {
15014
- onClick: () => {
15015
- setCoinbaseSkipToHoldings(true);
15016
- setView("coinbase_connect");
15017
- },
15018
- onDisconnect: handleExchangeDisconnect,
15019
- title: i18n.connectExchange.title,
15020
- subtitle: i18n.connectExchange.subtitle,
15021
- exchanges: integrationExchanges,
15022
- connectedExchange
15023
- }
15024
- ),
15025
- showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15026
- ConnectExchangeButton,
15702
+ execution,
15703
+ onClick: () => setSelectedExecution(execution)
15704
+ },
15705
+ execution.id
15706
+ )) }) }),
15707
+ depositPoweredByFooter
15708
+ ] })
15709
+ ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15710
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15711
+ DepositHeader,
15712
+ {
15713
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
15714
+ showBack: showBackCard,
15715
+ onBack: handleBack,
15716
+ onClose: handleClose,
15717
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
15718
+ showBalance: showBalanceHeader,
15719
+ balanceAddress: recipientAddress,
15720
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
15721
+ balanceChainId: destinationChainId,
15722
+ balanceTokenAddress: destinationTokenAddress,
15723
+ projectName: projectConfig?.project_name,
15724
+ publishableKey
15725
+ }
15726
+ ),
15727
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15728
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15729
+ BuyWithCard,
15027
15730
  {
15028
- onClick: () => {
15029
- setCoinbaseSkipToHoldings(false);
15030
- setView("coinbase_connect");
15031
- },
15032
- title: i18n.connectExchange.title,
15033
- subtitle: i18n.connectExchange.subtitle,
15034
- exchanges: integrationExchanges
15731
+ userId,
15732
+ publishableKey,
15733
+ view: cardView,
15734
+ onViewChange: handleCardViewChange,
15735
+ destinationTokenSymbol,
15736
+ recipientAddress,
15737
+ destinationChainType,
15738
+ destinationChainId,
15739
+ destinationTokenAddress,
15740
+ onDepositSuccess,
15741
+ onDepositError,
15742
+ onEvent,
15743
+ themeClass,
15744
+ wallets,
15745
+ assetCdnUrl: projectConfig?.asset_cdn_url,
15746
+ hideDepositFlowInfo,
15747
+ hideDisplayDescription
15035
15748
  }
15036
15749
  ),
15037
- showCashApp && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15038
- CashAppButton,
15750
+ depositPoweredByFooter
15751
+ ] })
15752
+ ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15753
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15754
+ DepositHeader,
15755
+ {
15756
+ title: payWithExchangeTitle,
15757
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
15758
+ onBack: handleBack,
15759
+ onClose: handleClose
15760
+ }
15761
+ ),
15762
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15763
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15764
+ PayWithExchange,
15039
15765
  {
15040
- onClick: () => setView("cashapp"),
15041
- title: "Pay with Cash App",
15042
- subtitle: "Deposit via Cash App",
15043
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
15766
+ userId,
15767
+ publishableKey,
15768
+ exchanges,
15769
+ view: exchangeView,
15770
+ onViewChange: setExchangeView,
15771
+ destinationTokenSymbol,
15772
+ recipientAddress,
15773
+ destinationChainType,
15774
+ destinationChainId,
15775
+ destinationTokenAddress,
15776
+ onDepositSuccess,
15777
+ onDepositError,
15778
+ wallets,
15779
+ defaultToken: defaultToken ?? null
15044
15780
  }
15045
15781
  ),
15046
- showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15047
- DepositTrackerButton,
15048
- {
15049
- onClick: () => {
15050
- setAllExecutions(depositExecutions);
15051
- setView("tracker");
15052
- },
15053
- title: depositTrackerTitle,
15054
- subtitle: depositTrackerSubTitle,
15055
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
15056
- }
15057
- )
15058
- ] }) }),
15059
- depositPoweredByFooter
15060
- ] })
15061
- ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15062
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15063
- DepositHeader,
15064
- {
15065
- title: transferCryptoTitle,
15066
- showBack: showBackTransfer,
15067
- onBack: handleBack,
15068
- onClose: handleClose,
15069
- showBalance: showBalanceHeader,
15070
- balanceAddress: recipientAddress,
15071
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15072
- balanceChainId: destinationChainId,
15073
- balanceTokenAddress: destinationTokenAddress,
15074
- projectName: projectConfig?.project_name,
15075
- publishableKey
15076
- }
15077
- ),
15078
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15079
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15080
- TransferCryptoSingleInput,
15782
+ depositPoweredByFooter
15783
+ ] })
15784
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15785
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15786
+ CoinbaseConnect,
15081
15787
  {
15082
- userId,
15083
15788
  publishableKey,
15084
- recipientAddress,
15085
- destinationChainType,
15086
- destinationChainId,
15087
- destinationTokenAddress,
15088
- defaultSourceChainType,
15089
- defaultSourceChainId,
15090
- defaultSourceTokenAddress,
15091
- defaultSourceSymbol,
15092
- depositConfirmationMode,
15093
- onExecutionsChange: setDepositExecutions,
15094
- onDepositSuccess,
15095
- onDepositError,
15096
- wallets
15097
- }
15098
- ) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15099
- TransferCryptoDoubleInput,
15100
- {
15101
15789
  userId,
15102
- publishableKey,
15790
+ wallets,
15103
15791
  recipientAddress,
15104
- destinationChainType,
15105
- destinationChainId,
15106
- destinationTokenAddress,
15792
+ destinationTokenAddress: destinationTokenAddress ?? "",
15793
+ destinationChainId: destinationChainId ?? "",
15794
+ destinationChainType: destinationChainType ?? "",
15795
+ onTransferSuccess: (result) => {
15796
+ onDepositSuccess?.({
15797
+ message: "Transfer completed via Coinbase Connect",
15798
+ transaction: result
15799
+ });
15800
+ },
15801
+ onTransferError: (error) => {
15802
+ onDepositError?.({
15803
+ message: error.message,
15804
+ error
15805
+ });
15806
+ },
15807
+ onBack: handleBack,
15808
+ onClose: handleClose,
15809
+ onDisconnect: handleExchangeDisconnect,
15810
+ skipToHoldings: coinbaseSkipToHoldings,
15811
+ canGoBack: sessionOpenedFromMenu,
15812
+ onExecutionsChange: setDepositExecutions,
15107
15813
  defaultSourceChainType,
15108
15814
  defaultSourceChainId,
15109
15815
  defaultSourceTokenAddress,
15110
- defaultSourceSymbol,
15111
- depositConfirmationMode,
15112
- onExecutionsChange: setDepositExecutions,
15113
- onDepositSuccess,
15114
- onDepositError,
15115
- wallets
15116
- }
15117
- ),
15118
- depositPoweredByFooter
15119
- ] })
15120
- ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15121
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15122
- DepositHeader,
15123
- {
15124
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
15125
- showBack: showBackTracker,
15126
- onBack: handleBack,
15127
- onClose: handleClose
15128
- }
15129
- ),
15130
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15131
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15132
- "div",
15133
- {
15134
- className: "uf-text-sm",
15135
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
15136
- children: "No deposits yet"
15137
- }
15138
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15139
- DepositExecutionItem,
15140
- {
15141
- execution,
15142
- onClick: () => setSelectedExecution(execution)
15143
- },
15144
- execution.id
15145
- )) }) }),
15146
- depositPoweredByFooter
15147
- ] })
15148
- ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15149
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15150
- DepositHeader,
15151
- {
15152
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
15153
- showBack: showBackCard,
15154
- onBack: handleBack,
15155
- onClose: handleClose,
15156
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
15157
- showBalance: showBalanceHeader,
15158
- balanceAddress: recipientAddress,
15159
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15160
- balanceChainId: destinationChainId,
15161
- balanceTokenAddress: destinationTokenAddress,
15162
- projectName: projectConfig?.project_name,
15163
- publishableKey
15164
- }
15165
- ),
15166
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15167
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15168
- BuyWithCard,
15169
- {
15170
- userId,
15171
- publishableKey,
15172
- view: cardView,
15173
- onViewChange: handleCardViewChange,
15174
- destinationTokenSymbol,
15175
- recipientAddress,
15176
- destinationChainType,
15177
- destinationChainId,
15178
- destinationTokenAddress,
15179
- onDepositSuccess,
15180
- onDepositError,
15181
- onEvent,
15182
- themeClass,
15183
- wallets,
15184
- assetCdnUrl: projectConfig?.asset_cdn_url,
15185
- hideDepositFlowInfo,
15186
- hideDisplayDescription
15816
+ defaultSourceSymbol
15187
15817
  }
15188
15818
  ),
15189
15819
  depositPoweredByFooter
15190
- ] })
15191
- ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15192
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15193
- DepositHeader,
15194
- {
15195
- title: payWithExchangeTitle,
15196
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
15197
- onBack: handleBack,
15198
- onClose: handleClose
15199
- }
15200
- ),
15201
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15820
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15202
15821
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15203
- PayWithExchange,
15822
+ WalletConnect,
15204
15823
  {
15824
+ walletInfo: browserWalletInfo ?? void 0,
15825
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
15826
+ wallets,
15205
15827
  userId,
15206
15828
  publishableKey,
15207
- exchanges,
15208
- view: exchangeView,
15209
- onViewChange: setExchangeView,
15210
- destinationTokenSymbol,
15211
- recipientAddress,
15212
- destinationChainType,
15213
- destinationChainId,
15214
- destinationTokenAddress,
15829
+ assetCdnUrl: projectConfig?.asset_cdn_url,
15830
+ projectName: projectConfig?.project_name,
15831
+ onSuccess: (txHash) => {
15832
+ onDepositSuccess?.({
15833
+ message: "Transaction sent successfully",
15834
+ transaction: { txHash }
15835
+ });
15836
+ },
15837
+ onError: (error) => {
15838
+ onDepositError?.({
15839
+ message: error.message,
15840
+ error
15841
+ });
15842
+ },
15215
15843
  onDepositSuccess,
15216
15844
  onDepositError,
15217
- wallets,
15218
- defaultToken: defaultToken ?? null
15845
+ amountQuickSelect: browserWalletAmountQuickSelect,
15846
+ onWalletDisconnect: handleWalletDisconnect,
15847
+ onWalletConnected: (info, dw) => {
15848
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
15849
+ setStoredWalletState(info.type);
15850
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15851
+ },
15852
+ onBack: handleBack,
15853
+ onClose: handleClose,
15854
+ defaultSourceChainType,
15855
+ defaultSourceChainId,
15856
+ defaultSourceTokenAddress,
15857
+ defaultSourceSymbol,
15858
+ canGoBack: sessionOpenedFromMenu,
15859
+ depositWalletsLoading: walletsLoading
15219
15860
  }
15220
15861
  ),
15221
15862
  depositPoweredByFooter
15222
- ] })
15223
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15224
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15225
- CoinbaseConnect,
15226
- {
15227
- publishableKey,
15228
- userId,
15229
- wallets,
15230
- recipientAddress,
15231
- destinationTokenAddress: destinationTokenAddress ?? "",
15232
- destinationChainId: destinationChainId ?? "",
15233
- destinationChainType: destinationChainType ?? "",
15234
- onTransferSuccess: (result) => {
15235
- onDepositSuccess?.({
15236
- message: "Transfer completed via Coinbase Connect",
15237
- transaction: result
15238
- });
15239
- },
15240
- onTransferError: (error) => {
15241
- onDepositError?.({
15242
- message: error.message,
15243
- error
15244
- });
15245
- },
15246
- onBack: handleBack,
15247
- onClose: handleClose,
15248
- onDisconnect: handleExchangeDisconnect,
15249
- skipToHoldings: coinbaseSkipToHoldings,
15250
- canGoBack: sessionOpenedFromMenu,
15251
- onExecutionsChange: setDepositExecutions,
15252
- defaultSourceChainType,
15253
- defaultSourceChainId,
15254
- defaultSourceTokenAddress,
15255
- defaultSourceSymbol
15256
- }
15257
- ),
15258
- depositPoweredByFooter
15259
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15260
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15261
- WalletConnect,
15262
- {
15263
- walletInfo: browserWalletInfo ?? void 0,
15264
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
15265
- wallets,
15266
- userId,
15267
- publishableKey,
15268
- assetCdnUrl: projectConfig?.asset_cdn_url,
15269
- projectName: projectConfig?.project_name,
15270
- onSuccess: (txHash) => {
15271
- onDepositSuccess?.({
15272
- message: "Transaction sent successfully",
15273
- transaction: { txHash }
15274
- });
15275
- },
15276
- onError: (error) => {
15277
- onDepositError?.({
15278
- message: error.message,
15279
- error
15280
- });
15281
- },
15282
- onDepositSuccess,
15283
- onDepositError,
15284
- amountQuickSelect: browserWalletAmountQuickSelect,
15285
- onWalletDisconnect: handleWalletDisconnect,
15286
- onWalletConnected: (info, dw) => {
15287
- setBrowserWalletInfo({ ...info, depositWallet: dw });
15288
- setStoredWalletState(info.type);
15289
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15290
- },
15291
- onBack: handleBack,
15292
- onClose: handleClose,
15293
- defaultSourceChainType,
15294
- defaultSourceChainId,
15295
- defaultSourceTokenAddress,
15296
- defaultSourceSymbol,
15297
- canGoBack: sessionOpenedFromMenu,
15298
- depositWalletsLoading: walletsLoading
15299
- }
15300
- ),
15301
- depositPoweredByFooter
15302
- ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15303
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15304
- DepositHeader,
15305
- {
15306
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15307
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15308
- onBack: handleBack,
15309
- onClose: handleClose
15310
- }
15311
- ),
15312
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15863
+ ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15313
15864
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15314
- PayWithCashApp,
15865
+ DepositHeader,
15315
15866
  {
15316
- userId,
15317
- publishableKey,
15318
- recipientAddress,
15319
- destinationChainType,
15320
- destinationChainId,
15321
- destinationTokenAddress,
15322
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
15323
- view: cashAppView,
15324
- onViewChange: setCashAppView,
15325
- onAmountChange: setCashAppAmount,
15326
- onEvent,
15327
- onDepositSuccess,
15328
- onDepositError
15867
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15868
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15869
+ onBack: handleBack,
15870
+ onClose: handleClose
15329
15871
  }
15330
15872
  ),
15331
- depositPoweredByFooter
15332
- ] })
15333
- ] }) : null })
15873
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15874
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15875
+ PayWithCashApp,
15876
+ {
15877
+ userId,
15878
+ publishableKey,
15879
+ recipientAddress,
15880
+ destinationChainType,
15881
+ destinationChainId,
15882
+ destinationTokenAddress,
15883
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
15884
+ view: cashAppView,
15885
+ onViewChange: setCashAppView,
15886
+ onAmountChange: setCashAppAmount,
15887
+ onEvent,
15888
+ onDepositSuccess,
15889
+ onDepositError
15890
+ }
15891
+ ),
15892
+ depositPoweredByFooter
15893
+ ] })
15894
+ ] }) : null })
15895
+ ]
15334
15896
  }
15335
15897
  )
15336
15898
  }
@@ -15342,8 +15904,8 @@ var import_react21 = require("react");
15342
15904
  var import_lucide_react30 = require("lucide-react");
15343
15905
 
15344
15906
  // src/hooks/use-payment-intent.ts
15345
- var import_react_query13 = require("@tanstack/react-query");
15346
- var import_core30 = require("@unifold/core");
15907
+ var import_react_query14 = require("@tanstack/react-query");
15908
+ var import_core32 = require("@unifold/core");
15347
15909
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
15348
15910
  "succeeded",
15349
15911
  "expired",
@@ -15357,9 +15919,9 @@ function usePaymentIntent(params) {
15357
15919
  enabled = true,
15358
15920
  pollingInterval = 3e3
15359
15921
  } = params;
15360
- return (0, import_react_query13.useQuery)({
15922
+ return (0, import_react_query14.useQuery)({
15361
15923
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
15362
- queryFn: () => (0, import_core30.retrievePaymentIntent)(clientSecret, publishableKey),
15924
+ queryFn: () => (0, import_core32.retrievePaymentIntent)(clientSecret, publishableKey),
15363
15925
  enabled: enabled && !!clientSecret && !!publishableKey,
15364
15926
  staleTime: 0,
15365
15927
  refetchInterval: (query) => {
@@ -15426,7 +15988,6 @@ function CheckoutModal({
15426
15988
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react21.useState)(null);
15427
15989
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react21.useState)(false);
15428
15990
  const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react21.useState)(() => getStoredWalletState()?.chainType);
15429
- const isMobileView = useIsMobileViewport();
15430
15991
  const [resolvedTheme, setResolvedTheme] = (0, import_react21.useState)(
15431
15992
  theme === "auto" ? "dark" : theme
15432
15993
  );
@@ -15852,7 +16413,7 @@ function CheckoutModal({
15852
16413
  featuredTokens: projectConfig?.transfer_crypto.networks
15853
16414
  }
15854
16415
  ),
15855
- showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
16416
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15856
16417
  BrowserWalletButton,
15857
16418
  {
15858
16419
  onClick: handleBrowserWalletClick,
@@ -16018,12 +16579,12 @@ var import_react26 = require("react");
16018
16579
  var import_lucide_react33 = require("lucide-react");
16019
16580
 
16020
16581
  // src/hooks/use-supported-destination-tokens.ts
16021
- var import_react_query14 = require("@tanstack/react-query");
16022
- var import_core31 = require("@unifold/core");
16582
+ var import_react_query15 = require("@tanstack/react-query");
16583
+ var import_core33 = require("@unifold/core");
16023
16584
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
16024
- return (0, import_react_query14.useQuery)({
16585
+ return (0, import_react_query15.useQuery)({
16025
16586
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
16026
- queryFn: () => (0, import_core31.getSupportedDestinationTokens)(publishableKey),
16587
+ queryFn: () => (0, import_core33.getSupportedDestinationTokens)(publishableKey),
16027
16588
  staleTime: 1e3 * 60 * 5,
16028
16589
  gcTime: 1e3 * 60 * 30,
16029
16590
  refetchOnMount: false,
@@ -16050,8 +16611,8 @@ function useDefaultDestinationToken({
16050
16611
  }
16051
16612
 
16052
16613
  // src/hooks/use-source-token-validation.ts
16053
- var import_react_query15 = require("@tanstack/react-query");
16054
- var import_core32 = require("@unifold/core");
16614
+ var import_react_query16 = require("@tanstack/react-query");
16615
+ var import_core34 = require("@unifold/core");
16055
16616
  function useSourceTokenValidation(params) {
16056
16617
  const {
16057
16618
  sourceChainType,
@@ -16062,7 +16623,7 @@ function useSourceTokenValidation(params) {
16062
16623
  enabled = true
16063
16624
  } = params;
16064
16625
  const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
16065
- return (0, import_react_query15.useQuery)({
16626
+ return (0, import_react_query16.useQuery)({
16066
16627
  queryKey: [
16067
16628
  "unifold",
16068
16629
  "sourceTokenValidation",
@@ -16072,7 +16633,7 @@ function useSourceTokenValidation(params) {
16072
16633
  publishableKey
16073
16634
  ],
16074
16635
  queryFn: async () => {
16075
- const res = await (0, import_core32.getSupportedDepositTokens)(publishableKey);
16636
+ const res = await (0, import_core34.getSupportedDepositTokens)(publishableKey);
16076
16637
  let matchedMinUsd = null;
16077
16638
  let matchedProcessingTime = null;
16078
16639
  let matchedSlippage = null;
@@ -16110,8 +16671,8 @@ function useSourceTokenValidation(params) {
16110
16671
  }
16111
16672
 
16112
16673
  // src/hooks/use-address-balance.ts
16113
- var import_react_query16 = require("@tanstack/react-query");
16114
- var import_core33 = require("@unifold/core");
16674
+ var import_react_query17 = require("@tanstack/react-query");
16675
+ var import_core35 = require("@unifold/core");
16115
16676
  function useAddressBalance(params) {
16116
16677
  const {
16117
16678
  address,
@@ -16122,7 +16683,7 @@ function useAddressBalance(params) {
16122
16683
  enabled = true
16123
16684
  } = params;
16124
16685
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
16125
- return (0, import_react_query16.useQuery)({
16686
+ return (0, import_react_query17.useQuery)({
16126
16687
  queryKey: [
16127
16688
  "unifold",
16128
16689
  "addressBalance",
@@ -16133,7 +16694,7 @@ function useAddressBalance(params) {
16133
16694
  publishableKey
16134
16695
  ],
16135
16696
  queryFn: async () => {
16136
- const res = await (0, import_core33.getAddressBalance)(
16697
+ const res = await (0, import_core35.getAddressBalance)(
16137
16698
  address,
16138
16699
  chainType,
16139
16700
  chainId,
@@ -16171,13 +16732,13 @@ function useAddressBalance(params) {
16171
16732
  }
16172
16733
 
16173
16734
  // src/hooks/use-executions.ts
16174
- var import_react_query17 = require("@tanstack/react-query");
16175
- var import_core34 = require("@unifold/core");
16735
+ var import_react_query18 = require("@tanstack/react-query");
16736
+ var import_core36 = require("@unifold/core");
16176
16737
  function useExecutions(userId, publishableKey, options) {
16177
- const actionType = options?.actionType ?? import_core34.ActionType.Deposit;
16178
- return (0, import_react_query17.useQuery)({
16738
+ const actionType = options?.actionType ?? import_core36.ActionType.Deposit;
16739
+ return (0, import_react_query18.useQuery)({
16179
16740
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
16180
- queryFn: () => (0, import_core34.queryExecutions)(userId, publishableKey, actionType),
16741
+ queryFn: () => (0, import_core36.queryExecutions)(userId, publishableKey, actionType),
16181
16742
  enabled: (options?.enabled ?? true) && !!userId,
16182
16743
  refetchInterval: options?.refetchInterval ?? 3e3,
16183
16744
  staleTime: 0,
@@ -16188,7 +16749,7 @@ function useExecutions(userId, publishableKey, options) {
16188
16749
 
16189
16750
  // src/hooks/use-withdraw-polling.ts
16190
16751
  var import_react22 = require("react");
16191
- var import_core35 = require("@unifold/core");
16752
+ var import_core37 = require("@unifold/core");
16192
16753
  var POLL_INTERVAL_MS3 = 2500;
16193
16754
  var POLL_ENDPOINT_INTERVAL_MS2 = 5e3;
16194
16755
  var CUTOFF_BUFFER_MS2 = 6e4;
@@ -16228,15 +16789,15 @@ function useWithdrawPolling({
16228
16789
  const enabledAt = enabledAtRef.current;
16229
16790
  const poll = async () => {
16230
16791
  try {
16231
- const response = await (0, import_core35.queryExecutions)(userId, publishableKey, import_core35.ActionType.Withdraw);
16792
+ const response = await (0, import_core37.queryExecutions)(userId, publishableKey, import_core37.ActionType.Withdraw);
16232
16793
  const cutoff = new Date(enabledAt.getTime() - CUTOFF_BUFFER_MS2);
16233
16794
  const sorted = [...response.data].sort((a, b) => {
16234
16795
  const tA = a.created_at ? new Date(a.created_at).getTime() : 0;
16235
16796
  const tB = b.created_at ? new Date(b.created_at).getTime() : 0;
16236
16797
  return tB - tA;
16237
16798
  });
16238
- const inProgress = [import_core35.ExecutionStatus.PENDING, import_core35.ExecutionStatus.WAITING, import_core35.ExecutionStatus.DELAYED];
16239
- const terminal = [import_core35.ExecutionStatus.SUCCEEDED, import_core35.ExecutionStatus.FAILED];
16799
+ const inProgress = [import_core37.ExecutionStatus.PENDING, import_core37.ExecutionStatus.WAITING, import_core37.ExecutionStatus.DELAYED];
16800
+ const terminal = [import_core37.ExecutionStatus.SUCCEEDED, import_core37.ExecutionStatus.FAILED];
16240
16801
  let target = null;
16241
16802
  for (const ex of sorted) {
16242
16803
  const t12 = ex.created_at ? new Date(ex.created_at) : null;
@@ -16266,9 +16827,9 @@ function useWithdrawPolling({
16266
16827
  }
16267
16828
  return [...list, ex];
16268
16829
  });
16269
- if (ex.status === import_core35.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16830
+ if (ex.status === import_core37.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16270
16831
  onSuccessRef.current?.({ message: "Withdrawal completed successfully", executionId: ex.id, transaction: ex });
16271
- } else if (ex.status === import_core35.ExecutionStatus.FAILED && prev !== import_core35.ExecutionStatus.FAILED) {
16832
+ } else if (ex.status === import_core37.ExecutionStatus.FAILED && prev !== import_core37.ExecutionStatus.FAILED) {
16272
16833
  onErrorRef.current?.({ message: "Withdrawal failed", code: "WITHDRAW_FAILED", error: ex });
16273
16834
  }
16274
16835
  }
@@ -16289,7 +16850,7 @@ function useWithdrawPolling({
16289
16850
  if (!enabled || !depositWalletId) return;
16290
16851
  const trigger = async () => {
16291
16852
  try {
16292
- await (0, import_core35.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
16853
+ await (0, import_core37.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
16293
16854
  } catch {
16294
16855
  }
16295
16856
  };
@@ -16458,11 +17019,11 @@ function WithdrawDoubleInput({
16458
17019
  // src/components/withdrawals/WithdrawForm.tsx
16459
17020
  var import_react24 = require("react");
16460
17021
  var import_lucide_react31 = require("lucide-react");
16461
- var import_core40 = require("@unifold/core");
17022
+ var import_core42 = require("@unifold/core");
16462
17023
 
16463
17024
  // src/hooks/use-verify-recipient-address.ts
16464
- var import_react_query18 = require("@tanstack/react-query");
16465
- var import_core36 = require("@unifold/core");
17025
+ var import_react_query19 = require("@tanstack/react-query");
17026
+ var import_core38 = require("@unifold/core");
16466
17027
  function useVerifyRecipientAddress(params) {
16467
17028
  const {
16468
17029
  chainType,
@@ -16474,7 +17035,7 @@ function useVerifyRecipientAddress(params) {
16474
17035
  } = params;
16475
17036
  const trimmedAddress = recipientAddress?.trim() || "";
16476
17037
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
16477
- return (0, import_react_query18.useQuery)({
17038
+ return (0, import_react_query19.useQuery)({
16478
17039
  queryKey: [
16479
17040
  "unifold",
16480
17041
  "verifyRecipientAddress",
@@ -16484,7 +17045,7 @@ function useVerifyRecipientAddress(params) {
16484
17045
  trimmedAddress,
16485
17046
  publishableKey
16486
17047
  ],
16487
- queryFn: () => (0, import_core36.verifyRecipientAddress)(
17048
+ queryFn: () => (0, import_core38.verifyRecipientAddress)(
16488
17049
  {
16489
17050
  chain_type: chainType,
16490
17051
  chain_id: chainId,
@@ -16503,7 +17064,7 @@ function useVerifyRecipientAddress(params) {
16503
17064
  }
16504
17065
 
16505
17066
  // src/components/withdrawals/send-withdraw.ts
16506
- var import_core37 = require("@unifold/core");
17067
+ var import_core39 = require("@unifold/core");
16507
17068
  async function sendEvmWithdraw(params) {
16508
17069
  const {
16509
17070
  provider,
@@ -16581,7 +17142,7 @@ async function sendSolanaWithdraw(params) {
16581
17142
  if (!provider.publicKey) {
16582
17143
  await provider.connect();
16583
17144
  }
16584
- const buildResponse = await (0, import_core37.buildSolanaTransaction)(
17145
+ const buildResponse = await (0, import_core39.buildSolanaTransaction)(
16585
17146
  {
16586
17147
  chain_id: "mainnet",
16587
17148
  token_address: sourceTokenAddress === "" ? "native" : sourceTokenAddress,
@@ -16607,56 +17168,21 @@ async function sendSolanaWithdraw(params) {
16607
17168
  for (let i = 0; i < serialized.length; i++) {
16608
17169
  binaryStr += String.fromCharCode(serialized[i]);
16609
17170
  }
16610
- const sendResponse = await (0, import_core37.sendSolanaTransaction)(
17171
+ const sendResponse = await (0, import_core39.sendSolanaTransaction)(
16611
17172
  { chain_id: "mainnet", signed_transaction: btoa(binaryStr) },
16612
17173
  publishableKey
16613
17174
  );
16614
17175
  return sendResponse.signature;
16615
17176
  }
16616
- var HYPERCORE_SPOT_USDC_ADDRESS = "0x6d1e7cde53ba9467b783cb7c530ce054";
16617
- function isHypercoreChain(chainId) {
16618
- return chainId === HYPERCORE_CHAIN_ID;
16619
- }
16620
17177
  async function sendHypercoreWithdraw(params) {
16621
- const {
16622
- provider,
16623
- fromAddress,
16624
- depositWalletAddress,
16625
- sourceTokenAddress,
16626
- amount,
16627
- tokenSymbol,
16628
- publishableKey
16629
- } = params;
16630
- const isSpot = sourceTokenAddress.toLowerCase() === HYPERCORE_SPOT_USDC_ADDRESS;
16631
- const currentChainHex = await provider.request({
16632
- method: "eth_chainId",
16633
- params: []
17178
+ await sendHypercoreEvmTransfer({
17179
+ provider: params.provider,
17180
+ fromAddress: params.fromAddress,
17181
+ recipientAddress: params.depositWalletAddress,
17182
+ sourceTokenAddress: params.sourceTokenAddress,
17183
+ amount: params.amount,
17184
+ publishableKey: params.publishableKey
16634
17185
  });
16635
- const activeChainId = String(parseInt(currentChainHex, 16));
16636
- const buildResult = await (0, import_core37.buildHypercoreTransaction)(
16637
- {
16638
- action_type: isSpot ? "spot_send" : "usd_send",
16639
- signature_chain_type: "ethereum",
16640
- signature_chain_id: activeChainId,
16641
- recipient_address: depositWalletAddress,
16642
- token_address: sourceTokenAddress,
16643
- token_symbol: tokenSymbol || void 0,
16644
- amount
16645
- },
16646
- publishableKey
16647
- );
16648
- const signature = await provider.request({
16649
- method: "eth_signTypedData_v4",
16650
- params: [fromAddress, JSON.stringify(buildResult.typed_data)]
16651
- });
16652
- await (0, import_core37.sendHypercoreTransaction)(
16653
- {
16654
- action_payload: buildResult.action_payload,
16655
- signature,
16656
- nonce: buildResult.nonce
16657
- },
16658
- publishableKey
16659
- );
16660
17186
  }
16661
17187
  async function detectBrowserWallet(chainType, senderAddress) {
16662
17188
  const win = typeof window !== "undefined" ? window : null;
@@ -16738,11 +17264,11 @@ async function detectBrowserWallet(chainType, senderAddress) {
16738
17264
 
16739
17265
  // src/hooks/use-hypercore-withdraw-activation.ts
16740
17266
  var import_react23 = require("react");
16741
- var import_core39 = require("@unifold/core");
17267
+ var import_core41 = require("@unifold/core");
16742
17268
 
16743
17269
  // src/hooks/use-get-deposit-address.ts
16744
- var import_react_query19 = require("@tanstack/react-query");
16745
- var import_core38 = require("@unifold/core");
17270
+ var import_react_query20 = require("@tanstack/react-query");
17271
+ var import_core40 = require("@unifold/core");
16746
17272
  function useGetDepositAddress(params) {
16747
17273
  const {
16748
17274
  userId,
@@ -16755,7 +17281,7 @@ function useGetDepositAddress(params) {
16755
17281
  enabled = true
16756
17282
  } = params;
16757
17283
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
16758
- return (0, import_react_query19.useQuery)({
17284
+ return (0, import_react_query20.useQuery)({
16759
17285
  queryKey: [
16760
17286
  "unifold",
16761
17287
  "getDepositAddress",
@@ -16767,7 +17293,7 @@ function useGetDepositAddress(params) {
16767
17293
  actionType ?? null,
16768
17294
  publishableKey
16769
17295
  ],
16770
- queryFn: () => (0, import_core38.getDepositAddress)(
17296
+ queryFn: () => (0, import_core40.getDepositAddress)(
16771
17297
  {
16772
17298
  external_user_id: userId,
16773
17299
  recipient_address: recipientAddress,
@@ -16821,7 +17347,7 @@ function useHypercoreWithdrawActivation(params) {
16821
17347
  destinationChainType,
16822
17348
  destinationChainId,
16823
17349
  destinationTokenAddress,
16824
- actionType: import_core39.ActionType.Withdraw,
17350
+ actionType: import_core41.ActionType.Withdraw,
16825
17351
  enabled: enabled && isHypercore(sourceChainId)
16826
17352
  });
16827
17353
  const depositWalletAddress = (0, import_react23.useMemo)(() => {
@@ -17090,7 +17616,7 @@ function WithdrawForm({
17090
17616
  let humanAmount = isMaxed ? balanceData.balanceHuman : toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
17091
17617
  if (isHypercoreChain(sourceChainId)) {
17092
17618
  try {
17093
- const check = await (0, import_core40.checkHypercoreActivation)(
17619
+ const check = await (0, import_core42.checkHypercoreActivation)(
17094
17620
  {
17095
17621
  source_address: senderAddress,
17096
17622
  recipient_address: depositWallet.address
@@ -17407,14 +17933,14 @@ function WithdrawForm({
17407
17933
 
17408
17934
  // src/components/withdrawals/WithdrawExecutionItem.tsx
17409
17935
  var import_lucide_react32 = require("lucide-react");
17410
- var import_core41 = require("@unifold/core");
17936
+ var import_core43 = require("@unifold/core");
17411
17937
  var import_jsx_runtime59 = require("react/jsx-runtime");
17412
17938
  function WithdrawExecutionItem({
17413
17939
  execution,
17414
17940
  onClick
17415
17941
  }) {
17416
17942
  const { colors: colors2, fonts, components } = useTheme();
17417
- const isPending = execution.status === import_core41.ExecutionStatus.PENDING || execution.status === import_core41.ExecutionStatus.WAITING || execution.status === import_core41.ExecutionStatus.DELAYED;
17943
+ const isPending = execution.status === import_core43.ExecutionStatus.PENDING || execution.status === import_core43.ExecutionStatus.WAITING || execution.status === import_core43.ExecutionStatus.DELAYED;
17418
17944
  const formatDateTime = (timestamp) => {
17419
17945
  try {
17420
17946
  const date = new Date(timestamp);
@@ -17461,7 +17987,7 @@ function WithdrawExecutionItem({
17461
17987
  /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
17462
17988
  "img",
17463
17989
  {
17464
- src: execution.destination_token_metadata?.icon_url || (0, import_core41.getIconUrl)("/icons/tokens/svg/usdc.svg"),
17990
+ src: execution.destination_token_metadata?.icon_url || (0, import_core43.getIconUrl)("/icons/tokens/svg/usdc.svg"),
17465
17991
  alt: "Token",
17466
17992
  width: 36,
17467
17993
  height: 36,
@@ -17683,8 +18209,6 @@ function WithdrawConfirmingView({
17683
18209
  className: "uf-text-sm uf-text-center",
17684
18210
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
17685
18211
  children: [
17686
- txInfo.amount,
17687
- " ",
17688
18212
  txInfo.sourceTokenSymbol,
17689
18213
  " to",
17690
18214
  " ",
@@ -17720,7 +18244,7 @@ function WithdrawConfirmingView({
17720
18244
  }
17721
18245
 
17722
18246
  // src/components/withdrawals/WithdrawModal.tsx
17723
- var import_core42 = require("@unifold/core");
18247
+ var import_core44 = require("@unifold/core");
17724
18248
  var import_jsx_runtime61 = require("react/jsx-runtime");
17725
18249
  var t10 = i18n.withdrawModal;
17726
18250
  var getChainKey5 = (chainId, chainType) => `${chainType}:${chainId}`;
@@ -17811,25 +18335,25 @@ function WithdrawModal({
17811
18335
  onWithdrawError
17812
18336
  });
17813
18337
  const { data: allWithdrawalsData } = useExecutions(externalUserId, publishableKey, {
17814
- actionType: import_core42.ActionType.Withdraw,
18338
+ actionType: import_core44.ActionType.Withdraw,
17815
18339
  enabled: open,
17816
18340
  refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
17817
18341
  });
17818
18342
  const allWithdrawals = allWithdrawalsData?.data ?? [];
17819
18343
  const handleDepositWalletCreation = (0, import_react26.useCallback)(async (params) => {
17820
- const { data: wallets } = await (0, import_core42.createDepositAddress)(
18344
+ const { data: wallets } = await (0, import_core44.createDepositAddress)(
17821
18345
  {
17822
18346
  external_user_id: externalUserId,
17823
18347
  destination_chain_type: params.destinationChainType,
17824
18348
  destination_chain_id: params.destinationChainId,
17825
18349
  destination_token_address: params.destinationTokenAddress,
17826
18350
  recipient_address: params.recipientAddress,
17827
- action_type: import_core42.ActionType.Withdraw,
18351
+ action_type: import_core44.ActionType.Withdraw,
17828
18352
  source_chain_type: sourceChainType
17829
18353
  },
17830
18354
  publishableKey
17831
18355
  );
17832
- const depositWallet = (0, import_core42.getWalletByChainType)(wallets, sourceChainType);
18356
+ const depositWallet = (0, import_core44.getWalletByChainType)(wallets, sourceChainType);
17833
18357
  if (!depositWallet) {
17834
18358
  throw new Error(`No deposit wallet available for ${sourceChainType}`);
17835
18359
  }