@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.mjs CHANGED
@@ -97,6 +97,22 @@ function clearStoredWalletState() {
97
97
  } catch {
98
98
  }
99
99
  }
100
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
101
+ function getLastOpenedWallet() {
102
+ if (typeof window === "undefined") return void 0;
103
+ try {
104
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
105
+ } catch {
106
+ return void 0;
107
+ }
108
+ }
109
+ function setLastOpenedWallet(walletId) {
110
+ if (typeof window === "undefined") return;
111
+ try {
112
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
113
+ } catch {
114
+ }
115
+ }
100
116
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
101
117
  function isMobileViewport() {
102
118
  if (typeof window === "undefined") return false;
@@ -464,6 +480,36 @@ function ThemeProvider({
464
480
  );
465
481
  return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: contextValue, children });
466
482
  }
483
+ function AccentColorOverride({
484
+ accentColor,
485
+ accentForeground,
486
+ children
487
+ }) {
488
+ const parent = useTheme();
489
+ const value = React.useMemo(() => {
490
+ if (!accentColor) return parent;
491
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
492
+ const nextColors = {
493
+ ...parent.colors,
494
+ primary: accentColor,
495
+ primaryForeground: foreground
496
+ };
497
+ const nextComponents = {
498
+ ...parent.components,
499
+ button: {
500
+ ...parent.components.button,
501
+ primaryBackground: accentColor,
502
+ primaryText: foreground
503
+ },
504
+ card: {
505
+ ...parent.components.card,
506
+ iconBackgroundColor: `${accentColor}26`
507
+ }
508
+ };
509
+ return { ...parent, colors: nextColors, components: nextComponents };
510
+ }, [parent, accentColor, accentForeground]);
511
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
512
+ }
467
513
  function useTheme() {
468
514
  const context = React.useContext(ThemeContext);
469
515
  if (!context) {
@@ -929,7 +975,7 @@ function DepositHeader({
929
975
  setShowBalanceSkeleton(false);
930
976
  return;
931
977
  }
932
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
978
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
933
979
  if (!supportedChainTypes.includes(
934
980
  balanceChainType
935
981
  )) {
@@ -1591,6 +1637,7 @@ function useDepositPolling({
1591
1637
  clientSecret,
1592
1638
  depositConfirmationMode = "auto_ui",
1593
1639
  depositWalletId,
1640
+ depositWalletIds,
1594
1641
  enabled = true,
1595
1642
  immediateDirectPolling = false,
1596
1643
  onDepositSuccess,
@@ -1736,21 +1783,25 @@ function useDepositPolling({
1736
1783
  setIsPolling(false);
1737
1784
  };
1738
1785
  }, [userId, publishableKey, clientSecret, enabled]);
1786
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
1739
1787
  useEffect3(() => {
1740
- if (!pollingEnabled || !depositWalletId) return;
1788
+ if (!pollingEnabled || !pollWalletIdsKey) return;
1789
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
1741
1790
  const triggerPoll = async () => {
1742
- try {
1743
- await pollDirectExecutions(
1744
- { deposit_wallet_id: depositWalletId },
1745
- publishableKey
1746
- );
1747
- } catch {
1748
- }
1791
+ await Promise.all(
1792
+ ids.map(
1793
+ (id) => pollDirectExecutions(
1794
+ { deposit_wallet_id: id },
1795
+ publishableKey
1796
+ ).catch(() => {
1797
+ })
1798
+ )
1799
+ );
1749
1800
  };
1750
1801
  triggerPoll();
1751
1802
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
1752
1803
  return () => clearInterval(interval);
1753
- }, [pollingEnabled, depositWalletId, publishableKey]);
1804
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
1754
1805
  const handleIveDeposited = () => {
1755
1806
  setPollingEnabled(true);
1756
1807
  setShowWaitingUi(true);
@@ -2974,6 +3025,7 @@ function BuyWithCard({
2974
3025
  if (!selectedProvider) return "0.000000";
2975
3026
  return selectedProvider.destination_amount.toFixed(6);
2976
3027
  };
3028
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
2977
3029
  const selectedCurrencyData = fiatCurrencies.find(
2978
3030
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
2979
3031
  );
@@ -3159,9 +3211,12 @@ function BuyWithCard({
3159
3211
  /* @__PURE__ */ jsx11(
3160
3212
  "button",
3161
3213
  {
3162
- onClick: () => handleViewChange("quotes"),
3214
+ onClick: () => {
3215
+ if (canOpenProviderSelector) handleViewChange("quotes");
3216
+ },
3163
3217
  disabled: quotesLoading || quotes.length === 0,
3164
- 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",
3218
+ "aria-disabled": !canOpenProviderSelector,
3219
+ 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"}`,
3165
3220
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
3166
3221
  children: quotesLoading ? /* @__PURE__ */ jsxs9("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
3167
3222
  /* @__PURE__ */ jsx11(
@@ -3188,7 +3243,7 @@ function BuyWithCard({
3188
3243
  )
3189
3244
  ] })
3190
3245
  ] }) : /* @__PURE__ */ jsxs9("div", { className: "uf-w-full uf-text-left", children: [
3191
- isAutoSelected && /* @__PURE__ */ jsx11(
3246
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ jsx11(
3192
3247
  "div",
3193
3248
  {
3194
3249
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -3224,7 +3279,7 @@ function BuyWithCard({
3224
3279
  ),
3225
3280
  selectedProvider.low_kyc === false && /* @__PURE__ */ jsx11("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ jsx11("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
3226
3281
  ] }),
3227
- quotes.length > 0 && /* @__PURE__ */ jsx11(
3282
+ canOpenProviderSelector && /* @__PURE__ */ jsx11(
3228
3283
  ChevronRight,
3229
3284
  {
3230
3285
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -11326,7 +11381,7 @@ function useHypercoreActivation(params) {
11326
11381
  publishableKey,
11327
11382
  enabled = true
11328
11383
  } = params;
11329
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
11384
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
11330
11385
  const recipient = recipientAddress?.trim() ?? "";
11331
11386
  const source = sourceAddress?.trim() ?? "";
11332
11387
  const hasAddresses = !!recipient && !!source;
@@ -12514,9 +12569,58 @@ import { ExternalLink as ExternalLink3, Loader2 as Loader28 } from "lucide-react
12514
12569
  import {
12515
12570
  getAddressBalances as getAddressBalances2,
12516
12571
  getSupportedDepositTokens as getSupportedDepositTokens2,
12572
+ ExecutionStatus as ExecutionStatus5,
12517
12573
  buildSolanaTransaction,
12518
- sendSolanaTransaction as sendSolanaTransactionToBackend
12574
+ sendSolanaTransaction as sendSolanaTransactionToBackend,
12575
+ getWalletMobileDeepLink,
12576
+ checkHypercoreActivation as checkHypercoreActivation2
12577
+ } from "@unifold/core";
12578
+
12579
+ // src/lib/send-hypercore.ts
12580
+ import {
12581
+ buildHypercoreTransaction as buildHypercoreTransactionFromBackend,
12582
+ sendHypercoreTransaction as sendHypercoreTransactionToBackend
12519
12583
  } from "@unifold/core";
12584
+ function isHypercoreChain(chainId) {
12585
+ return chainId === HYPERCORE_CHAIN_ID;
12586
+ }
12587
+ async function sendHypercoreEvmTransfer(params) {
12588
+ const {
12589
+ provider,
12590
+ fromAddress,
12591
+ recipientAddress,
12592
+ sourceTokenAddress,
12593
+ amount,
12594
+ publishableKey
12595
+ } = params;
12596
+ const currentChainHex = await provider.request({
12597
+ method: "eth_chainId",
12598
+ params: []
12599
+ });
12600
+ const activeChainId = String(parseInt(currentChainHex, 16));
12601
+ const buildResult = await buildHypercoreTransactionFromBackend(
12602
+ {
12603
+ signature_chain_id: activeChainId,
12604
+ recipient_address: recipientAddress,
12605
+ token_address: sourceTokenAddress,
12606
+ amount
12607
+ },
12608
+ publishableKey
12609
+ );
12610
+ const signature = await provider.request({
12611
+ method: "eth_signTypedData_v4",
12612
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
12613
+ });
12614
+ await sendHypercoreTransactionToBackend(
12615
+ {
12616
+ action_payload: buildResult.action_payload,
12617
+ signature,
12618
+ nonce: buildResult.nonce
12619
+ },
12620
+ publishableKey
12621
+ );
12622
+ return { signature };
12623
+ }
12520
12624
 
12521
12625
  // src/hooks/use-deposit-quote.ts
12522
12626
  import { useQuery as useQuery12 } from "@tanstack/react-query";
@@ -12575,6 +12679,68 @@ function useDepositQuote(params) {
12575
12679
  });
12576
12680
  }
12577
12681
 
12682
+ // src/hooks/use-external-wallets.ts
12683
+ import { useQuery as useQuery13 } from "@tanstack/react-query";
12684
+ import { getExternalWallets } from "@unifold/core";
12685
+ function useExternalWallets({
12686
+ publishableKey,
12687
+ enabled = true
12688
+ }) {
12689
+ const { data: wallets = [], isLoading } = useQuery13({
12690
+ queryKey: ["unifold", "external-wallets", publishableKey],
12691
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
12692
+ enabled: enabled && !!publishableKey,
12693
+ staleTime: 1e3 * 60 * 30,
12694
+ refetchOnMount: false,
12695
+ refetchOnWindowFocus: false
12696
+ });
12697
+ return { wallets, isLoading };
12698
+ }
12699
+
12700
+ // src/theme/walletBrandColors.ts
12701
+ var WALLET_BRAND_COLORS = {
12702
+ phantom: "#AB9FF2",
12703
+ metamask: "#F6851B",
12704
+ coinbase: "#0052FF",
12705
+ trust: "#3375BB",
12706
+ rainbow: "#5B6CFF",
12707
+ rabby: "#7084FF",
12708
+ okx: "#000000"
12709
+ };
12710
+ function normalizeWalletId(type) {
12711
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
12712
+ }
12713
+ function getWalletBrandColor(type, mode = "dark") {
12714
+ if (!type) return void 0;
12715
+ const id = normalizeWalletId(type);
12716
+ const color = WALLET_BRAND_COLORS[id];
12717
+ if (!color) return void 0;
12718
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
12719
+ return color;
12720
+ }
12721
+ function getContrastingTextColor(hex) {
12722
+ const c = hex.replace("#", "");
12723
+ if (c.length !== 6) return "#FFFFFF";
12724
+ const r = parseInt(c.slice(0, 2), 16);
12725
+ const g = parseInt(c.slice(2, 4), 16);
12726
+ const b = parseInt(c.slice(4, 6), 16);
12727
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
12728
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
12729
+ }
12730
+
12731
+ // src/components/deposits/browser-wallets/mobileDeepLinks.ts
12732
+ function isMobileDevice() {
12733
+ if (typeof navigator === "undefined") return false;
12734
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
12735
+ }
12736
+ function getMobilePlatform() {
12737
+ if (typeof navigator === "undefined") return null;
12738
+ const ua = navigator.userAgent;
12739
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
12740
+ if (/android/i.test(ua)) return "android";
12741
+ return null;
12742
+ }
12743
+
12578
12744
  // src/components/deposits/browser-wallets/SelectTokenView.tsx
12579
12745
  import { Loader2 as Loader25 } from "lucide-react";
12580
12746
 
@@ -12888,7 +13054,8 @@ function EnterAmountView({
12888
13054
  onClose,
12889
13055
  quickSelectMode,
12890
13056
  checkoutAmountUsd,
12891
- checkoutReceivedUsd
13057
+ checkoutReceivedUsd,
13058
+ footer
12892
13059
  }) {
12893
13060
  const { colors: colors2, fonts, components } = useTheme();
12894
13061
  const isCheckout = !!checkoutAmountUsd;
@@ -13144,6 +13311,7 @@ function EnterAmountView({
13144
13311
  )
13145
13312
  ] })
13146
13313
  ] }),
13314
+ footer && /* @__PURE__ */ jsx51("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
13147
13315
  /* @__PURE__ */ jsx51("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ jsx51(
13148
13316
  "button",
13149
13317
  {
@@ -13603,18 +13771,33 @@ var WALLET_ICONS3 = {
13603
13771
  backpack: BackpackIcon,
13604
13772
  glow: GlowIcon
13605
13773
  };
13606
- var WALLET_DEFINITIONS = [
13607
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
13608
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
13609
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
13610
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
13611
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
13612
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
13613
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
13614
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
13615
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
13616
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
13774
+ var FALLBACK_WALLET_DEFINITIONS = [
13775
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
13776
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
13777
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
13778
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
13779
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
13780
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
13781
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
13617
13782
  ];
13783
+ function getMobileInstallUrl(walletId, defaultUrl) {
13784
+ if (!isMobileDevice()) return defaultUrl;
13785
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
13786
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
13787
+ const stores = {
13788
+ rabby: {
13789
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
13790
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
13791
+ },
13792
+ glow: {
13793
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
13794
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
13795
+ }
13796
+ };
13797
+ const entry = stores[walletId];
13798
+ if (!entry) return defaultUrl;
13799
+ return isIOS ? entry.ios : entry.android;
13800
+ }
13618
13801
  function normalizeTokenAddress(address) {
13619
13802
  const normalized = (address ?? "").toLowerCase();
13620
13803
  if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
@@ -13650,7 +13833,7 @@ function getLegacyEvmProviders() {
13650
13833
  okxEthereum: win.okxwallet
13651
13834
  };
13652
13835
  }
13653
- function detectAvailableWallets(filterChainType) {
13836
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
13654
13837
  const solProviders = getSolanaProviders();
13655
13838
  const legacyEvm = getLegacyEvmProviders();
13656
13839
  const eip6963List = getEip6963Providers();
@@ -13676,7 +13859,7 @@ function detectAvailableWallets(filterChainType) {
13676
13859
  return false;
13677
13860
  }
13678
13861
  });
13679
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13862
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13680
13863
  let isInstalled = false;
13681
13864
  const detectedNetworks = [];
13682
13865
  switch (wallet.id) {
@@ -13699,8 +13882,6 @@ function detectAvailableWallets(filterChainType) {
13699
13882
  isInstalled = true;
13700
13883
  detectedNetworks.push("ethereum");
13701
13884
  }
13702
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
13703
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
13704
13885
  break;
13705
13886
  case "trust":
13706
13887
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -13737,11 +13918,17 @@ function detectAvailableWallets(filterChainType) {
13737
13918
  }
13738
13919
  return { ...wallet, isInstalled, detectedNetworks };
13739
13920
  }).sort((a, b) => {
13921
+ if (recentWalletId) {
13922
+ const aRecent = a.id === recentWalletId ? 1 : 0;
13923
+ const bRecent = b.id === recentWalletId ? 1 : 0;
13924
+ if (aRecent !== bRecent) return bRecent - aRecent;
13925
+ }
13740
13926
  if (a.isInstalled && !b.isInstalled) return -1;
13741
13927
  if (!a.isInstalled && b.isInstalled) return 1;
13742
13928
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
13743
13929
  return 0;
13744
13930
  });
13931
+ return sorted;
13745
13932
  }
13746
13933
  function WalletConnect({
13747
13934
  walletInfo: initialWalletInfo,
@@ -13780,7 +13967,7 @@ function WalletConnect({
13780
13967
  depositWalletsLoading = false,
13781
13968
  onExecutionsChange
13782
13969
  }) {
13783
- const { colors: colors2, fonts, components } = useTheme();
13970
+ const { colors: colors2, fonts, components, mode } = useTheme();
13784
13971
  const walletProvidedAtMount = React30.useRef(!!initialWalletInfo && !!initialDepositWallet);
13785
13972
  const [activeWalletInfo, setActiveWalletInfo] = React30.useState(initialWalletInfo ?? null);
13786
13973
  const [activeDepositWallet, setActiveDepositWallet] = React30.useState(initialDepositWallet ?? null);
@@ -13804,7 +13991,43 @@ function WalletConnect({
13804
13991
  setEip6963ProviderCount(providers.length);
13805
13992
  });
13806
13993
  }, []);
13807
- const availableWallets = React30.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13994
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
13995
+ const walletDefinitions = React30.useMemo(
13996
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
13997
+ id: w.id,
13998
+ name: w.name,
13999
+ networks: w.chain_types,
14000
+ installUrl: w.install_url,
14001
+ supportsMobileBrowse: w.supports_mobile_browse,
14002
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
14003
+ })) : FALLBACK_WALLET_DEFINITIONS,
14004
+ [backendWallets]
14005
+ );
14006
+ const [recentWalletId, setRecentWalletIdState] = React30.useState(getLastOpenedWallet);
14007
+ React30.useEffect(() => {
14008
+ if (view === "select_wallet") {
14009
+ setRecentWalletIdState(getLastOpenedWallet());
14010
+ }
14011
+ }, [view]);
14012
+ const availableWallets = React30.useMemo(
14013
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
14014
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
14015
+ );
14016
+ const [isMobile, setIsMobile] = React30.useState(false);
14017
+ React30.useEffect(() => {
14018
+ setIsMobile(isMobileDevice());
14019
+ }, []);
14020
+ const mobileDepositAddresses = React30.useMemo(
14021
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
14022
+ [depositWallets]
14023
+ );
14024
+ const mobileDepositWalletIds = React30.useMemo(
14025
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
14026
+ [depositWallets]
14027
+ );
14028
+ const [mobileRedirect, setMobileRedirect] = React30.useState(null);
14029
+ const [pendingMobileWallet, setPendingMobileWallet] = React30.useState(null);
14030
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React30.useState(false);
13808
14031
  React30.useEffect(() => {
13809
14032
  if (!standalone || autoResolved || detectingWallet) return;
13810
14033
  if (!detectedWallet) {
@@ -13848,7 +14071,7 @@ function WalletConnect({
13848
14071
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
13849
14072
  const recipientAddress = activeDepositWallet?.address ?? "";
13850
14073
  const isCheckoutMode = !!checkoutAmountUsd;
13851
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
14074
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
13852
14075
  const transitionTo = React30.useCallback((nextView) => {
13853
14076
  if (nextView === viewRef.current) return;
13854
14077
  setIsTransitioning(true);
@@ -13863,9 +14086,38 @@ function WalletConnect({
13863
14086
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
13864
14087
  transition: "opacity 150ms ease, transform 150ms ease"
13865
14088
  };
13866
- const handleWalletClick = (wallet) => {
14089
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
14090
+ try {
14091
+ const res = await getWalletMobileDeepLink(
14092
+ wallet.id,
14093
+ depositAddresses,
14094
+ publishableKey
14095
+ );
14096
+ if (res.deeplink) {
14097
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
14098
+ setLastOpenedWallet(wallet.id);
14099
+ setRecentWalletIdState(wallet.id);
14100
+ setAwaitingMobileDeposit(true);
14101
+ transitionTo("mobile_redirect");
14102
+ window.location.href = res.deeplink;
14103
+ return true;
14104
+ }
14105
+ } catch {
14106
+ }
14107
+ return false;
14108
+ };
14109
+ const handleWalletClick = async (wallet) => {
13867
14110
  if (!wallet.isInstalled) {
13868
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
14111
+ const platform = getMobilePlatform();
14112
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform ?? "");
14113
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
14114
+ if (mobileDepositAddresses.length === 0) {
14115
+ setPendingMobileWallet(wallet);
14116
+ return;
14117
+ }
14118
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
14119
+ }
14120
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
13869
14121
  return;
13870
14122
  }
13871
14123
  setSelectedWalletDef(wallet);
@@ -13881,9 +14133,32 @@ function WalletConnect({
13881
14133
  if (!selectedWalletDef) return;
13882
14134
  handleConnectWallet(selectedWalletDef, network);
13883
14135
  };
14136
+ React30.useEffect(() => {
14137
+ if (!pendingMobileWallet) return;
14138
+ if (mobileDepositAddresses.length > 0) {
14139
+ const wallet = pendingMobileWallet;
14140
+ setPendingMobileWallet(null);
14141
+ void (async () => {
14142
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
14143
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
14144
+ }
14145
+ })();
14146
+ return;
14147
+ }
14148
+ const timeout = setTimeout(() => {
14149
+ setPendingMobileWallet((current) => {
14150
+ if (!current) return null;
14151
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
14152
+ return null;
14153
+ });
14154
+ }, 8e3);
14155
+ return () => clearTimeout(timeout);
14156
+ }, [pendingMobileWallet, mobileDepositAddresses]);
13884
14157
  const handleConnectWallet = async (wallet, network) => {
13885
14158
  setConnectingNetwork(network);
13886
14159
  transitionTo("connecting");
14160
+ setLastOpenedWallet(wallet.id);
14161
+ setRecentWalletIdState(wallet.id);
13887
14162
  setWalletError(null);
13888
14163
  setIsWalletConnecting(true);
13889
14164
  try {
@@ -13988,6 +14263,13 @@ function WalletConnect({
13988
14263
  }
13989
14264
  };
13990
14265
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
14266
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
14267
+ recipientAddress,
14268
+ sourceAddress: activeWalletInfo?.address,
14269
+ destinationChainId: selectedToken?.chain_id,
14270
+ publishableKey,
14271
+ enabled: !!activeWalletInfo && !!recipientAddress
14272
+ });
13991
14273
  const effectiveDestinationAmount = React30.useMemo(() => {
13992
14274
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
13993
14275
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -14025,14 +14307,32 @@ function WalletConnect({
14025
14307
  userId,
14026
14308
  publishableKey,
14027
14309
  clientSecret,
14310
+ // In-tab flow: poll the single connected deposit wallet.
14028
14311
  depositWalletId: activeDepositWallet?.id ?? "",
14029
- enabled: hasSignedTransaction && !!activeDepositWallet,
14312
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
14313
+ // chain's deposit wallet. Detection still happens via the single /query by
14314
+ // external_user_id, which already spans all chains.
14315
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
14316
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
14030
14317
  onDepositSuccess,
14031
14318
  onDepositError
14032
14319
  });
14033
14320
  React30.useEffect(() => {
14034
14321
  onExecutionsChange?.(depositExecutions);
14035
14322
  }, [depositExecutions, onExecutionsChange]);
14323
+ const latestDepositExecution = React30.useMemo(() => {
14324
+ if (depositExecutions.length === 0) return null;
14325
+ return [...depositExecutions].sort((a, b) => {
14326
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
14327
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
14328
+ return tb - ta;
14329
+ })[0];
14330
+ }, [depositExecutions]);
14331
+ React30.useEffect(() => {
14332
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
14333
+ transitionTo("mobile_deposit_status");
14334
+ }
14335
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
14036
14336
  React30.useEffect(() => {
14037
14337
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
14038
14338
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -14074,7 +14374,7 @@ function WalletConnect({
14074
14374
  let cancelled = false;
14075
14375
  setIsLoading(true);
14076
14376
  setError(null);
14077
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
14377
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
14078
14378
  getAddressBalances2(activeWalletInfo.address, sct, publishableKey).then((response) => {
14079
14379
  if (cancelled) return;
14080
14380
  const nonZero = response.balances.filter((b) => b.amount !== "0");
@@ -14163,6 +14463,16 @@ function WalletConnect({
14163
14463
  setSelectedWalletDef(null);
14164
14464
  setConnectingNetwork(null);
14165
14465
  break;
14466
+ case "mobile_redirect":
14467
+ transitionTo("select_wallet");
14468
+ setMobileRedirect(null);
14469
+ setAwaitingMobileDeposit(false);
14470
+ break;
14471
+ case "mobile_deposit_status":
14472
+ transitionTo("select_wallet");
14473
+ setMobileRedirect(null);
14474
+ setAwaitingMobileDeposit(false);
14475
+ break;
14166
14476
  case "select_token":
14167
14477
  if (walletProvidedAtMount.current) parentOnBack?.();
14168
14478
  else transitionTo("select_wallet");
@@ -14230,9 +14540,16 @@ function WalletConnect({
14230
14540
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
14231
14541
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
14232
14542
  };
14233
- const sendEthereumTransaction = async (token, amountStr) => {
14234
- if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
14235
- const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
14543
+ const resolveEvmProvider = () => {
14544
+ const walletIdMap = {
14545
+ "phantom-ethereum": "phantom",
14546
+ coinbase: "coinbase",
14547
+ trust: "trust",
14548
+ okx: "okx",
14549
+ rainbow: "rainbow",
14550
+ rabby: "rabby",
14551
+ metamask: "metamask"
14552
+ };
14236
14553
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
14237
14554
  const eip6963Match = findProviderByWalletId(lookupId);
14238
14555
  let provider = eip6963Match?.provider;
@@ -14241,6 +14558,11 @@ function WalletConnect({
14241
14558
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
14242
14559
  else provider = window.ethereum;
14243
14560
  }
14561
+ return provider;
14562
+ };
14563
+ const sendEthereumTransaction = async (token, amountStr) => {
14564
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
14565
+ const provider = resolveEvmProvider();
14244
14566
  if (!provider) throw new Error("Ethereum wallet not found");
14245
14567
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
14246
14568
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -14305,6 +14627,19 @@ function WalletConnect({
14305
14627
  const resp = await sendSolanaTransactionToBackend({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
14306
14628
  return resp.signature;
14307
14629
  };
14630
+ const sendHypercoreDeposit = async (token, amountStr) => {
14631
+ const provider = resolveEvmProvider();
14632
+ if (!provider) throw new Error("Ethereum wallet not found");
14633
+ const { signature } = await sendHypercoreEvmTransfer({
14634
+ provider,
14635
+ fromAddress: walletInfo.address,
14636
+ recipientAddress,
14637
+ sourceTokenAddress: token.token_address,
14638
+ amount: amountStr,
14639
+ publishableKey
14640
+ });
14641
+ return signature;
14642
+ };
14308
14643
  const handleConfirm = async () => {
14309
14644
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
14310
14645
  const token = getTokenFromBalance(selectedBalance);
@@ -14324,7 +14659,33 @@ function WalletConnect({
14324
14659
  setIsConfirming(true);
14325
14660
  setError(null);
14326
14661
  try {
14327
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
14662
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
14663
+ let txHash;
14664
+ if (token.chain_type === "solana") {
14665
+ txHash = await sendSolanaTransaction(token, tokenAmount.toString());
14666
+ } else if (isHypercoreToken) {
14667
+ let sendAmount = tokenAmount;
14668
+ try {
14669
+ const activation = await checkHypercoreActivation2(
14670
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
14671
+ publishableKey
14672
+ );
14673
+ if (!activation.user_exists) {
14674
+ const fee = activation.activation_fee;
14675
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
14676
+ throw new Error(
14677
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
14678
+ );
14679
+ }
14680
+ sendAmount = tokenAmount - fee;
14681
+ }
14682
+ } catch (e) {
14683
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
14684
+ }
14685
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
14686
+ } else {
14687
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
14688
+ }
14328
14689
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
14329
14690
  setHasSignedTransaction(true);
14330
14691
  handleIveDeposited();
@@ -14348,33 +14709,40 @@ function WalletConnect({
14348
14709
  return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14349
14710
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14350
14711
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
14351
- /* @__PURE__ */ jsx54("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Select a wallet to connect" }),
14352
- /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ jsxs48(
14353
- "button",
14354
- {
14355
- onClick: () => handleWalletClick(wallet),
14356
- disabled: isWalletConnecting,
14357
- 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",
14358
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
14359
- children: [
14360
- /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
14361
- WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ jsx54(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ jsx54("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
14362
- /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
14363
- ] }),
14364
- wallet.isInstalled ? /* @__PURE__ */ jsx54("span", { className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Detected" }) : /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
14365
- /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
14366
- /* @__PURE__ */ jsx54(ExternalLink3, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
14367
- ] })
14368
- ]
14369
- },
14370
- wallet.id
14371
- )) }),
14712
+ /* @__PURE__ */ jsx54("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: isMobile ? "Open this page in your wallet's app to connect" : "Select a wallet to connect" }),
14713
+ /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
14714
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
14715
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
14716
+ const isPending = pendingMobileWallet?.id === wallet.id;
14717
+ return /* @__PURE__ */ jsxs48(
14718
+ "button",
14719
+ {
14720
+ onClick: () => void handleWalletClick(wallet),
14721
+ disabled: isWalletConnecting || !!pendingMobileWallet,
14722
+ 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",
14723
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
14724
+ children: [
14725
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
14726
+ WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ jsx54(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ jsx54("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
14727
+ /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
14728
+ ] }),
14729
+ isPending ? /* @__PURE__ */ jsx54(Loader28, { className: "uf-w-4 uf-h-4 uf-animate-spin", style: { color: colors2.primary } }) : wallet.isInstalled ? /* @__PURE__ */ jsx54("span", { className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Detected" }) : /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
14730
+ /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
14731
+ /* @__PURE__ */ jsx54(ExternalLink3, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
14732
+ ] })
14733
+ ]
14734
+ },
14735
+ wallet.id
14736
+ );
14737
+ }) }),
14372
14738
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
14373
14739
  ] })
14374
14740
  ] });
14375
14741
  }
14742
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
14743
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
14376
14744
  if (view === "select_network" && selectedWalletDef) {
14377
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14745
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14378
14746
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
14379
14747
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
14380
14748
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -14404,10 +14772,10 @@ function WalletConnect({
14404
14772
  )) }),
14405
14773
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
14406
14774
  ] })
14407
- ] });
14775
+ ] }) });
14408
14776
  }
14409
14777
  if (view === "connecting") {
14410
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14778
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14411
14779
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
14412
14780
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
14413
14781
  /* @__PURE__ */ jsx54(Loader28, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -14418,24 +14786,132 @@ function WalletConnect({
14418
14786
  ] }),
14419
14787
  /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: "Please approve the connection in your wallet" })
14420
14788
  ] })
14421
- ] });
14789
+ ] }) });
14790
+ }
14791
+ if (view === "mobile_redirect" && mobileRedirect) {
14792
+ const Icon2 = WALLET_ICONS3[mobileRedirect.walletId];
14793
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14794
+ /* @__PURE__ */ jsx54(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
14795
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-px-6 uf-py-10", children: [
14796
+ Icon2 ? /* @__PURE__ */ jsx54(Icon2, { size: 64, className: "uf-rounded-2xl uf-mb-5" }) : /* @__PURE__ */ jsx54("div", { className: "uf-w-16 uf-h-16 uf-rounded-2xl uf-bg-gray-500 uf-mb-5" }),
14797
+ /* @__PURE__ */ jsxs48(
14798
+ "div",
14799
+ {
14800
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
14801
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
14802
+ children: [
14803
+ "Continue in ",
14804
+ mobileRedirect.walletName
14805
+ ]
14806
+ }
14807
+ ),
14808
+ /* @__PURE__ */ jsxs48(
14809
+ "div",
14810
+ {
14811
+ className: "uf-text-sm uf-text-center uf-mb-6",
14812
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
14813
+ children: [
14814
+ "Complete your deposit in the ",
14815
+ mobileRedirect.walletName,
14816
+ " app"
14817
+ ]
14818
+ }
14819
+ ),
14820
+ /* @__PURE__ */ jsxs48(
14821
+ "button",
14822
+ {
14823
+ type: "button",
14824
+ onClick: () => {
14825
+ window.location.href = mobileRedirect.deeplink;
14826
+ },
14827
+ 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",
14828
+ style: {
14829
+ backgroundColor: components.card.backgroundColor,
14830
+ borderRadius: components.card.borderRadius,
14831
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
14832
+ color: components.card.titleColor,
14833
+ fontFamily: fonts.medium
14834
+ },
14835
+ children: [
14836
+ /* @__PURE__ */ jsx54(ExternalLink3, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
14837
+ /* @__PURE__ */ jsxs48("span", { className: "uf-text-sm uf-font-medium", children: [
14838
+ "Open in ",
14839
+ mobileRedirect.walletName
14840
+ ] })
14841
+ ]
14842
+ }
14843
+ ),
14844
+ awaitingMobileDeposit && /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
14845
+ /* @__PURE__ */ jsx54(
14846
+ Loader28,
14847
+ {
14848
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
14849
+ style: { color: colors2.foregroundMuted }
14850
+ }
14851
+ ),
14852
+ /* @__PURE__ */ jsx54(
14853
+ "span",
14854
+ {
14855
+ className: "uf-text-sm",
14856
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
14857
+ children: "Checking for deposit..."
14858
+ }
14859
+ )
14860
+ ] })
14861
+ ] })
14862
+ ] }) });
14863
+ }
14864
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
14865
+ const isComplete = latestDepositExecution.status === ExecutionStatus5.SUCCEEDED;
14866
+ const isFailed = latestDepositExecution.status === ExecutionStatus5.FAILED;
14867
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
14868
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
14869
+ /* @__PURE__ */ jsx54(
14870
+ DepositHeader,
14871
+ {
14872
+ title,
14873
+ showBack: false,
14874
+ onClose: isComplete && onDone ? onDone : onClose
14875
+ }
14876
+ ),
14877
+ /* @__PURE__ */ jsx54(DepositDetailContent, { execution: latestDepositExecution }),
14878
+ isComplete && /* @__PURE__ */ jsx54("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-4 uf-pb-4", children: /* @__PURE__ */ jsx54(
14879
+ "button",
14880
+ {
14881
+ type: "button",
14882
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
14883
+ }),
14884
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
14885
+ style: {
14886
+ backgroundColor: colors2.primary,
14887
+ color: colors2.primaryForeground,
14888
+ fontFamily: fonts.medium,
14889
+ borderRadius: components.button.borderRadius,
14890
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
14891
+ },
14892
+ children: "Done"
14893
+ }
14894
+ ) })
14895
+ ] }) });
14422
14896
  }
14423
14897
  if (!hasWallet) return null;
14898
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
14899
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
14424
14900
  if (view === "select_token") {
14425
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
14426
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
14901
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
14902
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
14427
14903
  }
14428
14904
  if (view === "enter_amount" && selectedToken && selectedBalance) {
14429
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
14430
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
14905
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
14906
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ jsx54(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
14431
14907
  }
14432
14908
  if (view === "review" && selectedToken) {
14433
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
14434
- }) }) });
14909
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
14910
+ }) }) }) });
14435
14911
  }
14436
14912
  if (view === "confirming") {
14437
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
14438
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
14913
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
14914
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
14439
14915
  }
14440
14916
  return null;
14441
14917
  }
@@ -14466,6 +14942,9 @@ function SkeletonButton({
14466
14942
  ] });
14467
14943
  }
14468
14944
  var t7 = i18n.depositModal;
14945
+ function depositTabForScreen(screen) {
14946
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
14947
+ }
14469
14948
  function DepositModal({
14470
14949
  open,
14471
14950
  onOpenChange,
@@ -14501,6 +14980,7 @@ function DepositModal({
14501
14980
  theme = "dark",
14502
14981
  hideOverlay = false,
14503
14982
  initialScreen = "main",
14983
+ displayMode = "stacked",
14504
14984
  transferCryptoTitle = t7.transferCrypto.title,
14505
14985
  depositWithCardTitle = t7.depositWithCard.title,
14506
14986
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -14535,6 +15015,9 @@ function DepositModal({
14535
15015
  effectiveInitialScreen
14536
15016
  );
14537
15017
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = useState32(false);
15018
+ const [depositTab, setDepositTab] = useState32(
15019
+ () => depositTabForScreen(effectiveInitialScreen)
15020
+ );
14538
15021
  const resetViewTimeoutRef = useRef9(null);
14539
15022
  const [cardView, setCardView] = useState32(
14540
15023
  "amount"
@@ -14550,7 +15033,6 @@ function DepositModal({
14550
15033
  const [allExecutions, setAllExecutions] = useState32([]);
14551
15034
  const [selectedExecution, setSelectedExecution] = useState32(null);
14552
15035
  const [depositExecutions, setDepositExecutions] = useState32([]);
14553
- const isMobileView = useIsMobileViewport();
14554
15036
  const { projectConfig } = useProjectConfig({
14555
15037
  publishableKey,
14556
15038
  enabled: open
@@ -14833,6 +15315,7 @@ function DepositModal({
14833
15315
  resetViewTimeoutRef.current = null;
14834
15316
  }
14835
15317
  setView(effectiveInitialScreen);
15318
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
14836
15319
  setCardView("amount");
14837
15320
  setExchangeView("providers");
14838
15321
  setBrowserWalletInfo(null);
@@ -14861,6 +15344,7 @@ function DepositModal({
14861
15344
  } else if (view === "cashapp" && cashAppView !== "amount") {
14862
15345
  setCashAppView("amount");
14863
15346
  } else {
15347
+ setDepositTab(depositTabForScreen(view));
14864
15348
  setView("main");
14865
15349
  setCardView("amount");
14866
15350
  setExchangeView("providers");
@@ -14940,13 +15424,181 @@ function DepositModal({
14940
15424
  className: "uf-flex uf-justify-center uf-shrink-0"
14941
15425
  }
14942
15426
  ) });
14943
- return /* @__PURE__ */ jsx55(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ jsx55(
14944
- Dialog,
15427
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ jsx55(
15428
+ TransferCryptoButton,
14945
15429
  {
14946
- open: hideOverlay || open,
15430
+ onClick: () => setView("transfer"),
15431
+ title: transferCryptoTitle,
15432
+ subtitle: t7.transferCrypto.subtitle,
15433
+ featuredTokens: projectConfig?.transfer_crypto.networks
15434
+ },
15435
+ "transfer"
15436
+ ) : null;
15437
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ jsx55(
15438
+ BrowserWalletButton,
15439
+ {
15440
+ onClick: handleBrowserWalletClick,
15441
+ onConnectClick: handleWalletConnectClick,
15442
+ onDisconnect: handleWalletDisconnect,
15443
+ chainType: browserWalletChainType,
15444
+ publishableKey,
15445
+ featuredWallets: projectConfig?.connect_wallet?.wallets
15446
+ },
15447
+ "wallet"
15448
+ ) : null;
15449
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ jsx55(
15450
+ DepositWithCardButton,
15451
+ {
15452
+ onClick: () => setView("card"),
15453
+ title: depositWithCardTitle,
15454
+ subtitle: t7.depositWithCard.subtitle,
15455
+ paymentNetworks: projectConfig?.payment_networks.networks
15456
+ },
15457
+ "card"
15458
+ ) : null;
15459
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ jsx55(
15460
+ PayWithExchangeButton,
15461
+ {
15462
+ onClick: () => setView("exchange"),
15463
+ title: payWithExchangeTitle,
15464
+ subtitle: t7.payWithExchange.subtitle,
15465
+ exchanges,
15466
+ loading: exchangesLoading
15467
+ },
15468
+ "exchange"
15469
+ ) : null;
15470
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ jsx55(
15471
+ ConnectExchangeButton,
15472
+ {
15473
+ onClick: () => {
15474
+ setCoinbaseSkipToHoldings(true);
15475
+ setView("coinbase_connect");
15476
+ },
15477
+ onDisconnect: handleExchangeDisconnect,
15478
+ title: i18n.connectExchange.title,
15479
+ subtitle: i18n.connectExchange.subtitle,
15480
+ exchanges: integrationExchanges,
15481
+ connectedExchange
15482
+ },
15483
+ "connect-exchange"
15484
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ jsx55(
15485
+ ConnectExchangeButton,
15486
+ {
15487
+ onClick: () => {
15488
+ setCoinbaseSkipToHoldings(false);
15489
+ setView("coinbase_connect");
15490
+ },
15491
+ title: i18n.connectExchange.title,
15492
+ subtitle: i18n.connectExchange.subtitle,
15493
+ exchanges: integrationExchanges
15494
+ },
15495
+ "connect-exchange"
15496
+ ) : null;
15497
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ jsx55(
15498
+ CashAppButton,
15499
+ {
15500
+ onClick: () => setView("cashapp"),
15501
+ title: "Pay with Cash App",
15502
+ subtitle: "Deposit via Cash App",
15503
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
15504
+ },
15505
+ "cashapp"
15506
+ ) : null;
15507
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ jsx55(
15508
+ DepositTrackerButton,
15509
+ {
15510
+ onClick: () => {
15511
+ setAllExecutions(depositExecutions);
15512
+ setView("tracker");
15513
+ },
15514
+ title: depositTrackerTitle,
15515
+ subtitle: depositTrackerSubTitle,
15516
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
15517
+ },
15518
+ "tracker"
15519
+ ) : null;
15520
+ const cryptoMenuButtons = [
15521
+ transferCryptoMenuButton,
15522
+ connectWalletMenuButton,
15523
+ payWithExchangeMenuButton,
15524
+ connectExchangeMenuButton
15525
+ ].filter(Boolean);
15526
+ const cashMenuButtons = [
15527
+ depositWithCardMenuButton,
15528
+ cashAppMenuButton
15529
+ ].filter(Boolean);
15530
+ const depositTabs = [
15531
+ { id: "crypto", label: "Use Crypto", buttons: cryptoMenuButtons },
15532
+ { id: "cash", label: "Use Cash", buttons: cashMenuButtons }
15533
+ ].filter((tab) => tab.buttons.length > 0);
15534
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
15535
+ const renderMainMenuBody = () => {
15536
+ if (depositPrerequisiteBody) {
15537
+ return /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
15538
+ }
15539
+ if (displayMode === "tabs" && activeDepositTab) {
15540
+ return /* @__PURE__ */ jsxs49("div", { children: [
15541
+ depositTabs.length > 1 && /* @__PURE__ */ jsx55(
15542
+ "div",
15543
+ {
15544
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
15545
+ style: {
15546
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
15547
+ // the control reads as a soft surface rather than a solid bar.
15548
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
15549
+ backdropFilter: "blur(12px)",
15550
+ WebkitBackdropFilter: "blur(12px)"
15551
+ },
15552
+ role: "tablist",
15553
+ children: depositTabs.map((tab) => {
15554
+ const active = activeDepositTab.id === tab.id;
15555
+ return /* @__PURE__ */ jsx55(
15556
+ "button",
15557
+ {
15558
+ type: "button",
15559
+ role: "tab",
15560
+ "aria-selected": active,
15561
+ onClick: () => setDepositTab(tab.id),
15562
+ className: "uf-flex-1 uf-py-2 uf-px-3 uf-rounded-lg uf-text-sm uf-transition-all",
15563
+ style: {
15564
+ // Active tab is a soft, blurred glass pill — a faint accent
15565
+ // tint with its own backdrop blur and a subtle border/shadow,
15566
+ // so it looks frosted instead of like a hard solid button.
15567
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
15568
+ backdropFilter: active ? "blur(8px)" : void 0,
15569
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
15570
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
15571
+ color: active ? colors2.foreground : colors2.foregroundMuted,
15572
+ fontFamily: fonts.medium
15573
+ },
15574
+ children: tab.label
15575
+ },
15576
+ tab.id
15577
+ );
15578
+ })
15579
+ }
15580
+ ),
15581
+ /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
15582
+ depositTrackerMenuButton && /* @__PURE__ */ jsx55("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
15583
+ ] });
15584
+ }
15585
+ return /* @__PURE__ */ jsxs49("div", { className: "uf-space-y-3", children: [
15586
+ transferCryptoMenuButton,
15587
+ connectWalletMenuButton,
15588
+ depositWithCardMenuButton,
15589
+ payWithExchangeMenuButton,
15590
+ connectExchangeMenuButton,
15591
+ cashAppMenuButton,
15592
+ depositTrackerMenuButton
15593
+ ] });
15594
+ };
15595
+ return /* @__PURE__ */ jsx55(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ jsx55(
15596
+ Dialog,
15597
+ {
15598
+ open: hideOverlay || open,
14947
15599
  onOpenChange: hideOverlay ? void 0 : handleClose,
14948
15600
  modal: !hideOverlay,
14949
- children: /* @__PURE__ */ jsx55(
15601
+ children: /* @__PURE__ */ jsxs49(
14950
15602
  DialogContent,
14951
15603
  {
14952
15604
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -14955,386 +15607,302 @@ function DepositModal({
14955
15607
  style: { backgroundColor: colors2.background },
14956
15608
  onPointerDownOutside: (e) => e.preventDefault(),
14957
15609
  onInteractOutside: (e) => e.preventDefault(),
14958
- children: /* @__PURE__ */ jsx55(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
14959
- /* @__PURE__ */ jsx55(
14960
- DepositHeader,
14961
- {
14962
- title: modalTitle || "Deposit",
14963
- showClose: !hideOverlay,
14964
- onClose: handleClose,
14965
- showBalance: showBalanceHeader,
14966
- balanceAddress: recipientAddress,
14967
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
14968
- balanceChainId: destinationChainId,
14969
- balanceTokenAddress: destinationTokenAddress,
14970
- projectName: projectConfig?.project_name,
14971
- publishableKey
14972
- }
14973
- ),
14974
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14975
- /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ jsxs49(Fragment11, { children: [
14976
- showTransferCrypto && /* @__PURE__ */ jsx55(
14977
- TransferCryptoButton,
14978
- {
14979
- onClick: () => setView("transfer"),
14980
- title: transferCryptoTitle,
14981
- subtitle: t7.transferCrypto.subtitle,
14982
- featuredTokens: projectConfig?.transfer_crypto.networks
14983
- }
14984
- ),
14985
- showConnectWallet && !isMobileView && /* @__PURE__ */ jsx55(
14986
- BrowserWalletButton,
15610
+ children: [
15611
+ /* @__PURE__ */ jsx55(DialogTitle, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
15612
+ /* @__PURE__ */ jsx55(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15613
+ /* @__PURE__ */ jsx55(
15614
+ DepositHeader,
15615
+ {
15616
+ title: modalTitle || "Deposit",
15617
+ showClose: !hideOverlay,
15618
+ onClose: handleClose,
15619
+ showBalance: showBalanceHeader,
15620
+ balanceAddress: recipientAddress,
15621
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
15622
+ balanceChainId: destinationChainId,
15623
+ balanceTokenAddress: destinationTokenAddress,
15624
+ projectName: projectConfig?.project_name,
15625
+ publishableKey
15626
+ }
15627
+ ),
15628
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15629
+ renderMainMenuBody(),
15630
+ depositPoweredByFooter
15631
+ ] })
15632
+ ] }) : view === "transfer" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15633
+ /* @__PURE__ */ jsx55(
15634
+ DepositHeader,
15635
+ {
15636
+ title: transferCryptoTitle,
15637
+ showBack: showBackTransfer,
15638
+ onBack: handleBack,
15639
+ onClose: handleClose,
15640
+ showBalance: showBalanceHeader,
15641
+ balanceAddress: recipientAddress,
15642
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
15643
+ balanceChainId: destinationChainId,
15644
+ balanceTokenAddress: destinationTokenAddress,
15645
+ projectName: projectConfig?.project_name,
15646
+ publishableKey
15647
+ }
15648
+ ),
15649
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15650
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ jsx55(
15651
+ TransferCryptoSingleInput,
14987
15652
  {
14988
- onClick: handleBrowserWalletClick,
14989
- onConnectClick: handleWalletConnectClick,
14990
- onDisconnect: handleWalletDisconnect,
14991
- chainType: browserWalletChainType,
15653
+ userId,
14992
15654
  publishableKey,
14993
- featuredWallets: projectConfig?.connect_wallet?.wallets
15655
+ recipientAddress,
15656
+ destinationChainType,
15657
+ destinationChainId,
15658
+ destinationTokenAddress,
15659
+ defaultSourceChainType,
15660
+ defaultSourceChainId,
15661
+ defaultSourceTokenAddress,
15662
+ defaultSourceSymbol,
15663
+ depositConfirmationMode,
15664
+ onExecutionsChange: setDepositExecutions,
15665
+ onDepositSuccess,
15666
+ onDepositError,
15667
+ wallets
14994
15668
  }
14995
- ),
14996
- showFiatOnramp && /* @__PURE__ */ jsx55(
14997
- DepositWithCardButton,
15669
+ ) : /* @__PURE__ */ jsx55(
15670
+ TransferCryptoDoubleInput,
14998
15671
  {
14999
- onClick: () => setView("card"),
15000
- title: depositWithCardTitle,
15001
- subtitle: t7.depositWithCard.subtitle,
15002
- paymentNetworks: projectConfig?.payment_networks.networks
15672
+ userId,
15673
+ publishableKey,
15674
+ recipientAddress,
15675
+ destinationChainType,
15676
+ destinationChainId,
15677
+ destinationTokenAddress,
15678
+ defaultSourceChainType,
15679
+ defaultSourceChainId,
15680
+ defaultSourceTokenAddress,
15681
+ defaultSourceSymbol,
15682
+ depositConfirmationMode,
15683
+ onExecutionsChange: setDepositExecutions,
15684
+ onDepositSuccess,
15685
+ onDepositError,
15686
+ wallets
15003
15687
  }
15004
15688
  ),
15005
- showPayWithExchange && /* @__PURE__ */ jsx55(
15006
- PayWithExchangeButton,
15689
+ depositPoweredByFooter
15690
+ ] })
15691
+ ] }) : view === "tracker" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15692
+ /* @__PURE__ */ jsx55(
15693
+ DepositHeader,
15694
+ {
15695
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
15696
+ showBack: showBackTracker,
15697
+ onBack: handleBack,
15698
+ onClose: handleClose
15699
+ }
15700
+ ),
15701
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15702
+ /* @__PURE__ */ jsx55("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ jsx55(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ jsx55("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ jsx55("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ jsx55(
15703
+ "div",
15007
15704
  {
15008
- onClick: () => setView("exchange"),
15009
- title: payWithExchangeTitle,
15010
- subtitle: t7.payWithExchange.subtitle,
15011
- exchanges,
15012
- loading: exchangesLoading
15705
+ className: "uf-text-sm",
15706
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
15707
+ children: "No deposits yet"
15013
15708
  }
15014
- ),
15015
- showConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
15016
- ConnectExchangeButton,
15709
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ jsx55(
15710
+ DepositExecutionItem,
15017
15711
  {
15018
- onClick: () => {
15019
- setCoinbaseSkipToHoldings(true);
15020
- setView("coinbase_connect");
15021
- },
15022
- onDisconnect: handleExchangeDisconnect,
15023
- title: i18n.connectExchange.title,
15024
- subtitle: i18n.connectExchange.subtitle,
15025
- exchanges: integrationExchanges,
15026
- connectedExchange
15027
- }
15028
- ),
15029
- showConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
15030
- ConnectExchangeButton,
15712
+ execution,
15713
+ onClick: () => setSelectedExecution(execution)
15714
+ },
15715
+ execution.id
15716
+ )) }) }),
15717
+ depositPoweredByFooter
15718
+ ] })
15719
+ ] }) : view === "card" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15720
+ /* @__PURE__ */ jsx55(
15721
+ DepositHeader,
15722
+ {
15723
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
15724
+ showBack: showBackCard,
15725
+ onBack: handleBack,
15726
+ onClose: handleClose,
15727
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
15728
+ showBalance: showBalanceHeader,
15729
+ balanceAddress: recipientAddress,
15730
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
15731
+ balanceChainId: destinationChainId,
15732
+ balanceTokenAddress: destinationTokenAddress,
15733
+ projectName: projectConfig?.project_name,
15734
+ publishableKey
15735
+ }
15736
+ ),
15737
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15738
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ jsx55(
15739
+ BuyWithCard,
15031
15740
  {
15032
- onClick: () => {
15033
- setCoinbaseSkipToHoldings(false);
15034
- setView("coinbase_connect");
15035
- },
15036
- title: i18n.connectExchange.title,
15037
- subtitle: i18n.connectExchange.subtitle,
15038
- exchanges: integrationExchanges
15741
+ userId,
15742
+ publishableKey,
15743
+ view: cardView,
15744
+ onViewChange: handleCardViewChange,
15745
+ destinationTokenSymbol,
15746
+ recipientAddress,
15747
+ destinationChainType,
15748
+ destinationChainId,
15749
+ destinationTokenAddress,
15750
+ onDepositSuccess,
15751
+ onDepositError,
15752
+ onEvent,
15753
+ themeClass,
15754
+ wallets,
15755
+ assetCdnUrl: projectConfig?.asset_cdn_url,
15756
+ hideDepositFlowInfo,
15757
+ hideDisplayDescription
15039
15758
  }
15040
15759
  ),
15041
- showCashApp && /* @__PURE__ */ jsx55(
15042
- CashAppButton,
15760
+ depositPoweredByFooter
15761
+ ] })
15762
+ ] }) : view === "exchange" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15763
+ /* @__PURE__ */ jsx55(
15764
+ DepositHeader,
15765
+ {
15766
+ title: payWithExchangeTitle,
15767
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
15768
+ onBack: handleBack,
15769
+ onClose: handleClose
15770
+ }
15771
+ ),
15772
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15773
+ /* @__PURE__ */ jsx55(
15774
+ PayWithExchange,
15043
15775
  {
15044
- onClick: () => setView("cashapp"),
15045
- title: "Pay with Cash App",
15046
- subtitle: "Deposit via Cash App",
15047
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
15776
+ userId,
15777
+ publishableKey,
15778
+ exchanges,
15779
+ view: exchangeView,
15780
+ onViewChange: setExchangeView,
15781
+ destinationTokenSymbol,
15782
+ recipientAddress,
15783
+ destinationChainType,
15784
+ destinationChainId,
15785
+ destinationTokenAddress,
15786
+ onDepositSuccess,
15787
+ onDepositError,
15788
+ wallets,
15789
+ defaultToken: defaultToken ?? null
15048
15790
  }
15049
15791
  ),
15050
- showDepositTracker && /* @__PURE__ */ jsx55(
15051
- DepositTrackerButton,
15052
- {
15053
- onClick: () => {
15054
- setAllExecutions(depositExecutions);
15055
- setView("tracker");
15056
- },
15057
- title: depositTrackerTitle,
15058
- subtitle: depositTrackerSubTitle,
15059
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
15060
- }
15061
- )
15062
- ] }) }),
15063
- depositPoweredByFooter
15064
- ] })
15065
- ] }) : view === "transfer" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15066
- /* @__PURE__ */ jsx55(
15067
- DepositHeader,
15068
- {
15069
- title: transferCryptoTitle,
15070
- showBack: showBackTransfer,
15071
- onBack: handleBack,
15072
- onClose: handleClose,
15073
- showBalance: showBalanceHeader,
15074
- balanceAddress: recipientAddress,
15075
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15076
- balanceChainId: destinationChainId,
15077
- balanceTokenAddress: destinationTokenAddress,
15078
- projectName: projectConfig?.project_name,
15079
- publishableKey
15080
- }
15081
- ),
15082
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15083
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ jsx55(
15084
- TransferCryptoSingleInput,
15792
+ depositPoweredByFooter
15793
+ ] })
15794
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15795
+ /* @__PURE__ */ jsx55(
15796
+ CoinbaseConnect,
15085
15797
  {
15086
- userId,
15087
15798
  publishableKey,
15088
- recipientAddress,
15089
- destinationChainType,
15090
- destinationChainId,
15091
- destinationTokenAddress,
15092
- defaultSourceChainType,
15093
- defaultSourceChainId,
15094
- defaultSourceTokenAddress,
15095
- defaultSourceSymbol,
15096
- depositConfirmationMode,
15097
- onExecutionsChange: setDepositExecutions,
15098
- onDepositSuccess,
15099
- onDepositError,
15100
- wallets
15101
- }
15102
- ) : /* @__PURE__ */ jsx55(
15103
- TransferCryptoDoubleInput,
15104
- {
15105
15799
  userId,
15106
- publishableKey,
15800
+ wallets,
15107
15801
  recipientAddress,
15108
- destinationChainType,
15109
- destinationChainId,
15110
- destinationTokenAddress,
15802
+ destinationTokenAddress: destinationTokenAddress ?? "",
15803
+ destinationChainId: destinationChainId ?? "",
15804
+ destinationChainType: destinationChainType ?? "",
15805
+ onTransferSuccess: (result) => {
15806
+ onDepositSuccess?.({
15807
+ message: "Transfer completed via Coinbase Connect",
15808
+ transaction: result
15809
+ });
15810
+ },
15811
+ onTransferError: (error) => {
15812
+ onDepositError?.({
15813
+ message: error.message,
15814
+ error
15815
+ });
15816
+ },
15817
+ onBack: handleBack,
15818
+ onClose: handleClose,
15819
+ onDisconnect: handleExchangeDisconnect,
15820
+ skipToHoldings: coinbaseSkipToHoldings,
15821
+ canGoBack: sessionOpenedFromMenu,
15822
+ onExecutionsChange: setDepositExecutions,
15111
15823
  defaultSourceChainType,
15112
15824
  defaultSourceChainId,
15113
15825
  defaultSourceTokenAddress,
15114
- defaultSourceSymbol,
15115
- depositConfirmationMode,
15116
- onExecutionsChange: setDepositExecutions,
15117
- onDepositSuccess,
15118
- onDepositError,
15119
- wallets
15120
- }
15121
- ),
15122
- depositPoweredByFooter
15123
- ] })
15124
- ] }) : view === "tracker" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15125
- /* @__PURE__ */ jsx55(
15126
- DepositHeader,
15127
- {
15128
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
15129
- showBack: showBackTracker,
15130
- onBack: handleBack,
15131
- onClose: handleClose
15132
- }
15133
- ),
15134
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15135
- /* @__PURE__ */ jsx55("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ jsx55(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ jsx55("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ jsx55("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ jsx55(
15136
- "div",
15137
- {
15138
- className: "uf-text-sm",
15139
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
15140
- children: "No deposits yet"
15141
- }
15142
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ jsx55(
15143
- DepositExecutionItem,
15144
- {
15145
- execution,
15146
- onClick: () => setSelectedExecution(execution)
15147
- },
15148
- execution.id
15149
- )) }) }),
15150
- depositPoweredByFooter
15151
- ] })
15152
- ] }) : view === "card" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15153
- /* @__PURE__ */ jsx55(
15154
- DepositHeader,
15155
- {
15156
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
15157
- showBack: showBackCard,
15158
- onBack: handleBack,
15159
- onClose: handleClose,
15160
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
15161
- showBalance: showBalanceHeader,
15162
- balanceAddress: recipientAddress,
15163
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15164
- balanceChainId: destinationChainId,
15165
- balanceTokenAddress: destinationTokenAddress,
15166
- projectName: projectConfig?.project_name,
15167
- publishableKey
15168
- }
15169
- ),
15170
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15171
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ jsx55(
15172
- BuyWithCard,
15173
- {
15174
- userId,
15175
- publishableKey,
15176
- view: cardView,
15177
- onViewChange: handleCardViewChange,
15178
- destinationTokenSymbol,
15179
- recipientAddress,
15180
- destinationChainType,
15181
- destinationChainId,
15182
- destinationTokenAddress,
15183
- onDepositSuccess,
15184
- onDepositError,
15185
- onEvent,
15186
- themeClass,
15187
- wallets,
15188
- assetCdnUrl: projectConfig?.asset_cdn_url,
15189
- hideDepositFlowInfo,
15190
- hideDisplayDescription
15826
+ defaultSourceSymbol
15191
15827
  }
15192
15828
  ),
15193
15829
  depositPoweredByFooter
15194
- ] })
15195
- ] }) : view === "exchange" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15196
- /* @__PURE__ */ jsx55(
15197
- DepositHeader,
15198
- {
15199
- title: payWithExchangeTitle,
15200
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
15201
- onBack: handleBack,
15202
- onClose: handleClose
15203
- }
15204
- ),
15205
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15830
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15206
15831
  /* @__PURE__ */ jsx55(
15207
- PayWithExchange,
15832
+ WalletConnect,
15208
15833
  {
15834
+ walletInfo: browserWalletInfo ?? void 0,
15835
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
15836
+ wallets,
15209
15837
  userId,
15210
15838
  publishableKey,
15211
- exchanges,
15212
- view: exchangeView,
15213
- onViewChange: setExchangeView,
15214
- destinationTokenSymbol,
15215
- recipientAddress,
15216
- destinationChainType,
15217
- destinationChainId,
15218
- destinationTokenAddress,
15839
+ assetCdnUrl: projectConfig?.asset_cdn_url,
15840
+ projectName: projectConfig?.project_name,
15841
+ onSuccess: (txHash) => {
15842
+ onDepositSuccess?.({
15843
+ message: "Transaction sent successfully",
15844
+ transaction: { txHash }
15845
+ });
15846
+ },
15847
+ onError: (error) => {
15848
+ onDepositError?.({
15849
+ message: error.message,
15850
+ error
15851
+ });
15852
+ },
15219
15853
  onDepositSuccess,
15220
15854
  onDepositError,
15221
- wallets,
15222
- defaultToken: defaultToken ?? null
15855
+ amountQuickSelect: browserWalletAmountQuickSelect,
15856
+ onWalletDisconnect: handleWalletDisconnect,
15857
+ onWalletConnected: (info, dw) => {
15858
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
15859
+ setStoredWalletState(info.type);
15860
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15861
+ },
15862
+ onBack: handleBack,
15863
+ onClose: handleClose,
15864
+ defaultSourceChainType,
15865
+ defaultSourceChainId,
15866
+ defaultSourceTokenAddress,
15867
+ defaultSourceSymbol,
15868
+ canGoBack: sessionOpenedFromMenu,
15869
+ depositWalletsLoading: walletsLoading
15223
15870
  }
15224
15871
  ),
15225
15872
  depositPoweredByFooter
15226
- ] })
15227
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15228
- /* @__PURE__ */ jsx55(
15229
- CoinbaseConnect,
15230
- {
15231
- publishableKey,
15232
- userId,
15233
- wallets,
15234
- recipientAddress,
15235
- destinationTokenAddress: destinationTokenAddress ?? "",
15236
- destinationChainId: destinationChainId ?? "",
15237
- destinationChainType: destinationChainType ?? "",
15238
- onTransferSuccess: (result) => {
15239
- onDepositSuccess?.({
15240
- message: "Transfer completed via Coinbase Connect",
15241
- transaction: result
15242
- });
15243
- },
15244
- onTransferError: (error) => {
15245
- onDepositError?.({
15246
- message: error.message,
15247
- error
15248
- });
15249
- },
15250
- onBack: handleBack,
15251
- onClose: handleClose,
15252
- onDisconnect: handleExchangeDisconnect,
15253
- skipToHoldings: coinbaseSkipToHoldings,
15254
- canGoBack: sessionOpenedFromMenu,
15255
- onExecutionsChange: setDepositExecutions,
15256
- defaultSourceChainType,
15257
- defaultSourceChainId,
15258
- defaultSourceTokenAddress,
15259
- defaultSourceSymbol
15260
- }
15261
- ),
15262
- depositPoweredByFooter
15263
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15264
- /* @__PURE__ */ jsx55(
15265
- WalletConnect,
15266
- {
15267
- walletInfo: browserWalletInfo ?? void 0,
15268
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
15269
- wallets,
15270
- userId,
15271
- publishableKey,
15272
- assetCdnUrl: projectConfig?.asset_cdn_url,
15273
- projectName: projectConfig?.project_name,
15274
- onSuccess: (txHash) => {
15275
- onDepositSuccess?.({
15276
- message: "Transaction sent successfully",
15277
- transaction: { txHash }
15278
- });
15279
- },
15280
- onError: (error) => {
15281
- onDepositError?.({
15282
- message: error.message,
15283
- error
15284
- });
15285
- },
15286
- onDepositSuccess,
15287
- onDepositError,
15288
- amountQuickSelect: browserWalletAmountQuickSelect,
15289
- onWalletDisconnect: handleWalletDisconnect,
15290
- onWalletConnected: (info, dw) => {
15291
- setBrowserWalletInfo({ ...info, depositWallet: dw });
15292
- setStoredWalletState(info.type);
15293
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15294
- },
15295
- onBack: handleBack,
15296
- onClose: handleClose,
15297
- defaultSourceChainType,
15298
- defaultSourceChainId,
15299
- defaultSourceTokenAddress,
15300
- defaultSourceSymbol,
15301
- canGoBack: sessionOpenedFromMenu,
15302
- depositWalletsLoading: walletsLoading
15303
- }
15304
- ),
15305
- depositPoweredByFooter
15306
- ] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15307
- /* @__PURE__ */ jsx55(
15308
- DepositHeader,
15309
- {
15310
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15311
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15312
- onBack: handleBack,
15313
- onClose: handleClose
15314
- }
15315
- ),
15316
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15873
+ ] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
15317
15874
  /* @__PURE__ */ jsx55(
15318
- PayWithCashApp,
15875
+ DepositHeader,
15319
15876
  {
15320
- userId,
15321
- publishableKey,
15322
- recipientAddress,
15323
- destinationChainType,
15324
- destinationChainId,
15325
- destinationTokenAddress,
15326
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
15327
- view: cashAppView,
15328
- onViewChange: setCashAppView,
15329
- onAmountChange: setCashAppAmount,
15330
- onEvent,
15331
- onDepositSuccess,
15332
- onDepositError
15877
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15878
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15879
+ onBack: handleBack,
15880
+ onClose: handleClose
15333
15881
  }
15334
15882
  ),
15335
- depositPoweredByFooter
15336
- ] })
15337
- ] }) : null })
15883
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15884
+ /* @__PURE__ */ jsx55(
15885
+ PayWithCashApp,
15886
+ {
15887
+ userId,
15888
+ publishableKey,
15889
+ recipientAddress,
15890
+ destinationChainType,
15891
+ destinationChainId,
15892
+ destinationTokenAddress,
15893
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
15894
+ view: cashAppView,
15895
+ onViewChange: setCashAppView,
15896
+ onAmountChange: setCashAppAmount,
15897
+ onEvent,
15898
+ onDepositSuccess,
15899
+ onDepositError
15900
+ }
15901
+ ),
15902
+ depositPoweredByFooter
15903
+ ] })
15904
+ ] }) : null })
15905
+ ]
15338
15906
  }
15339
15907
  )
15340
15908
  }
@@ -15353,7 +15921,7 @@ import {
15353
15921
  import { AlertTriangle as AlertTriangle3, ChevronRight as ChevronRight15 } from "lucide-react";
15354
15922
 
15355
15923
  // src/hooks/use-payment-intent.ts
15356
- import { useQuery as useQuery13 } from "@tanstack/react-query";
15924
+ import { useQuery as useQuery14 } from "@tanstack/react-query";
15357
15925
  import { retrievePaymentIntent } from "@unifold/core";
15358
15926
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
15359
15927
  "succeeded",
@@ -15368,7 +15936,7 @@ function usePaymentIntent(params) {
15368
15936
  enabled = true,
15369
15937
  pollingInterval = 3e3
15370
15938
  } = params;
15371
- return useQuery13({
15939
+ return useQuery14({
15372
15940
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
15373
15941
  queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
15374
15942
  enabled: enabled && !!clientSecret && !!publishableKey,
@@ -15437,7 +16005,6 @@ function CheckoutModal({
15437
16005
  const [browserWalletInfo, setBrowserWalletInfo] = useState33(null);
15438
16006
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState33(false);
15439
16007
  const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletState()?.chainType);
15440
- const isMobileView = useIsMobileViewport();
15441
16008
  const [resolvedTheme, setResolvedTheme] = useState33(
15442
16009
  theme === "auto" ? "dark" : theme
15443
16010
  );
@@ -15863,7 +16430,7 @@ function CheckoutModal({
15863
16430
  featuredTokens: projectConfig?.transfer_crypto.networks
15864
16431
  }
15865
16432
  ),
15866
- showConnectWallet && !isMobileView && /* @__PURE__ */ jsx56(
16433
+ showConnectWallet && /* @__PURE__ */ jsx56(
15867
16434
  BrowserWalletButton,
15868
16435
  {
15869
16436
  onClick: handleBrowserWalletClick,
@@ -16035,12 +16602,12 @@ import {
16035
16602
  import { AlertTriangle as AlertTriangle5, ChevronRight as ChevronRight17, Clock as Clock6 } from "lucide-react";
16036
16603
 
16037
16604
  // src/hooks/use-supported-destination-tokens.ts
16038
- import { useQuery as useQuery14 } from "@tanstack/react-query";
16605
+ import { useQuery as useQuery15 } from "@tanstack/react-query";
16039
16606
  import {
16040
16607
  getSupportedDestinationTokens
16041
16608
  } from "@unifold/core";
16042
16609
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
16043
- return useQuery14({
16610
+ return useQuery15({
16044
16611
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
16045
16612
  queryFn: () => getSupportedDestinationTokens(publishableKey),
16046
16613
  staleTime: 1e3 * 60 * 5,
@@ -16069,7 +16636,7 @@ function useDefaultDestinationToken({
16069
16636
  }
16070
16637
 
16071
16638
  // src/hooks/use-source-token-validation.ts
16072
- import { useQuery as useQuery15 } from "@tanstack/react-query";
16639
+ import { useQuery as useQuery16 } from "@tanstack/react-query";
16073
16640
  import { getSupportedDepositTokens as getSupportedDepositTokens3 } from "@unifold/core";
16074
16641
  function useSourceTokenValidation(params) {
16075
16642
  const {
@@ -16081,7 +16648,7 @@ function useSourceTokenValidation(params) {
16081
16648
  enabled = true
16082
16649
  } = params;
16083
16650
  const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
16084
- return useQuery15({
16651
+ return useQuery16({
16085
16652
  queryKey: [
16086
16653
  "unifold",
16087
16654
  "sourceTokenValidation",
@@ -16129,7 +16696,7 @@ function useSourceTokenValidation(params) {
16129
16696
  }
16130
16697
 
16131
16698
  // src/hooks/use-address-balance.ts
16132
- import { useQuery as useQuery16 } from "@tanstack/react-query";
16699
+ import { useQuery as useQuery17 } from "@tanstack/react-query";
16133
16700
  import { getAddressBalance as getAddressBalance2 } from "@unifold/core";
16134
16701
  function useAddressBalance(params) {
16135
16702
  const {
@@ -16141,7 +16708,7 @@ function useAddressBalance(params) {
16141
16708
  enabled = true
16142
16709
  } = params;
16143
16710
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
16144
- return useQuery16({
16711
+ return useQuery17({
16145
16712
  queryKey: [
16146
16713
  "unifold",
16147
16714
  "addressBalance",
@@ -16190,11 +16757,11 @@ function useAddressBalance(params) {
16190
16757
  }
16191
16758
 
16192
16759
  // src/hooks/use-executions.ts
16193
- import { useQuery as useQuery17 } from "@tanstack/react-query";
16760
+ import { useQuery as useQuery18 } from "@tanstack/react-query";
16194
16761
  import { queryExecutions as queryExecutions4, ActionType as ActionType4 } from "@unifold/core";
16195
16762
  function useExecutions(userId, publishableKey, options) {
16196
16763
  const actionType = options?.actionType ?? ActionType4.Deposit;
16197
- return useQuery17({
16764
+ return useQuery18({
16198
16765
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
16199
16766
  queryFn: () => queryExecutions4(userId, publishableKey, actionType),
16200
16767
  enabled: (options?.enabled ?? true) && !!userId,
@@ -16210,7 +16777,7 @@ import { useState as useState34, useEffect as useEffect28, useRef as useRef11 }
16210
16777
  import {
16211
16778
  queryExecutions as queryExecutions5,
16212
16779
  pollDirectExecutions as pollDirectExecutions2,
16213
- ExecutionStatus as ExecutionStatus5,
16780
+ ExecutionStatus as ExecutionStatus6,
16214
16781
  ActionType as ActionType5
16215
16782
  } from "@unifold/core";
16216
16783
  var POLL_INTERVAL_MS3 = 2500;
@@ -16259,8 +16826,8 @@ function useWithdrawPolling({
16259
16826
  const tB = b.created_at ? new Date(b.created_at).getTime() : 0;
16260
16827
  return tB - tA;
16261
16828
  });
16262
- const inProgress = [ExecutionStatus5.PENDING, ExecutionStatus5.WAITING, ExecutionStatus5.DELAYED];
16263
- const terminal = [ExecutionStatus5.SUCCEEDED, ExecutionStatus5.FAILED];
16829
+ const inProgress = [ExecutionStatus6.PENDING, ExecutionStatus6.WAITING, ExecutionStatus6.DELAYED];
16830
+ const terminal = [ExecutionStatus6.SUCCEEDED, ExecutionStatus6.FAILED];
16264
16831
  let target = null;
16265
16832
  for (const ex of sorted) {
16266
16833
  const t12 = ex.created_at ? new Date(ex.created_at) : null;
@@ -16290,9 +16857,9 @@ function useWithdrawPolling({
16290
16857
  }
16291
16858
  return [...list, ex];
16292
16859
  });
16293
- if (ex.status === ExecutionStatus5.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16860
+ if (ex.status === ExecutionStatus6.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16294
16861
  onSuccessRef.current?.({ message: "Withdrawal completed successfully", executionId: ex.id, transaction: ex });
16295
- } else if (ex.status === ExecutionStatus5.FAILED && prev !== ExecutionStatus5.FAILED) {
16862
+ } else if (ex.status === ExecutionStatus6.FAILED && prev !== ExecutionStatus6.FAILED) {
16296
16863
  onErrorRef.current?.({ message: "Withdrawal failed", code: "WITHDRAW_FAILED", error: ex });
16297
16864
  }
16298
16865
  }
@@ -16494,11 +17061,11 @@ import {
16494
17061
  Wallet as Wallet3
16495
17062
  } from "lucide-react";
16496
17063
  import {
16497
- checkHypercoreActivation as checkHypercoreActivation2
17064
+ checkHypercoreActivation as checkHypercoreActivation3
16498
17065
  } from "@unifold/core";
16499
17066
 
16500
17067
  // src/hooks/use-verify-recipient-address.ts
16501
- import { useQuery as useQuery18 } from "@tanstack/react-query";
17068
+ import { useQuery as useQuery19 } from "@tanstack/react-query";
16502
17069
  import { verifyRecipientAddress as verifyRecipientAddress2 } from "@unifold/core";
16503
17070
  function useVerifyRecipientAddress(params) {
16504
17071
  const {
@@ -16511,7 +17078,7 @@ function useVerifyRecipientAddress(params) {
16511
17078
  } = params;
16512
17079
  const trimmedAddress = recipientAddress?.trim() || "";
16513
17080
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
16514
- return useQuery18({
17081
+ return useQuery19({
16515
17082
  queryKey: [
16516
17083
  "unifold",
16517
17084
  "verifyRecipientAddress",
@@ -16542,9 +17109,7 @@ function useVerifyRecipientAddress(params) {
16542
17109
  // src/components/withdrawals/send-withdraw.ts
16543
17110
  import {
16544
17111
  buildSolanaTransaction as buildSolanaTransaction2,
16545
- sendSolanaTransaction as sendSolanaTransactionToBackend2,
16546
- buildHypercoreTransaction as buildHypercoreTransactionFromBackend,
16547
- sendHypercoreTransaction as sendHypercoreTransactionToBackend
17112
+ sendSolanaTransaction as sendSolanaTransactionToBackend2
16548
17113
  } from "@unifold/core";
16549
17114
  async function sendEvmWithdraw(params) {
16550
17115
  const {
@@ -16655,50 +17220,15 @@ async function sendSolanaWithdraw(params) {
16655
17220
  );
16656
17221
  return sendResponse.signature;
16657
17222
  }
16658
- var HYPERCORE_SPOT_USDC_ADDRESS = "0x6d1e7cde53ba9467b783cb7c530ce054";
16659
- function isHypercoreChain(chainId) {
16660
- return chainId === HYPERCORE_CHAIN_ID;
16661
- }
16662
17223
  async function sendHypercoreWithdraw(params) {
16663
- const {
16664
- provider,
16665
- fromAddress,
16666
- depositWalletAddress,
16667
- sourceTokenAddress,
16668
- amount,
16669
- tokenSymbol,
16670
- publishableKey
16671
- } = params;
16672
- const isSpot = sourceTokenAddress.toLowerCase() === HYPERCORE_SPOT_USDC_ADDRESS;
16673
- const currentChainHex = await provider.request({
16674
- method: "eth_chainId",
16675
- params: []
17224
+ await sendHypercoreEvmTransfer({
17225
+ provider: params.provider,
17226
+ fromAddress: params.fromAddress,
17227
+ recipientAddress: params.depositWalletAddress,
17228
+ sourceTokenAddress: params.sourceTokenAddress,
17229
+ amount: params.amount,
17230
+ publishableKey: params.publishableKey
16676
17231
  });
16677
- const activeChainId = String(parseInt(currentChainHex, 16));
16678
- const buildResult = await buildHypercoreTransactionFromBackend(
16679
- {
16680
- action_type: isSpot ? "spot_send" : "usd_send",
16681
- signature_chain_type: "ethereum",
16682
- signature_chain_id: activeChainId,
16683
- recipient_address: depositWalletAddress,
16684
- token_address: sourceTokenAddress,
16685
- token_symbol: tokenSymbol || void 0,
16686
- amount
16687
- },
16688
- publishableKey
16689
- );
16690
- const signature = await provider.request({
16691
- method: "eth_signTypedData_v4",
16692
- params: [fromAddress, JSON.stringify(buildResult.typed_data)]
16693
- });
16694
- await sendHypercoreTransactionToBackend(
16695
- {
16696
- action_payload: buildResult.action_payload,
16697
- signature,
16698
- nonce: buildResult.nonce
16699
- },
16700
- publishableKey
16701
- );
16702
17232
  }
16703
17233
  async function detectBrowserWallet(chainType, senderAddress) {
16704
17234
  const win = typeof window !== "undefined" ? window : null;
@@ -16783,7 +17313,7 @@ import { useMemo as useMemo12 } from "react";
16783
17313
  import { ActionType as ActionType6 } from "@unifold/core";
16784
17314
 
16785
17315
  // src/hooks/use-get-deposit-address.ts
16786
- import { useQuery as useQuery19 } from "@tanstack/react-query";
17316
+ import { useQuery as useQuery20 } from "@tanstack/react-query";
16787
17317
  import {
16788
17318
  getDepositAddress
16789
17319
  } from "@unifold/core";
@@ -16799,7 +17329,7 @@ function useGetDepositAddress(params) {
16799
17329
  enabled = true
16800
17330
  } = params;
16801
17331
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
16802
- return useQuery19({
17332
+ return useQuery20({
16803
17333
  queryKey: [
16804
17334
  "unifold",
16805
17335
  "getDepositAddress",
@@ -17134,7 +17664,7 @@ function WithdrawForm({
17134
17664
  let humanAmount = isMaxed ? balanceData.balanceHuman : toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
17135
17665
  if (isHypercoreChain(sourceChainId)) {
17136
17666
  try {
17137
- const check = await checkHypercoreActivation2(
17667
+ const check = await checkHypercoreActivation3(
17138
17668
  {
17139
17669
  source_address: senderAddress,
17140
17670
  recipient_address: depositWallet.address
@@ -17452,7 +17982,7 @@ function WithdrawForm({
17452
17982
  // src/components/withdrawals/WithdrawExecutionItem.tsx
17453
17983
  import { ChevronRight as ChevronRight16 } from "lucide-react";
17454
17984
  import {
17455
- ExecutionStatus as ExecutionStatus6,
17985
+ ExecutionStatus as ExecutionStatus7,
17456
17986
  getIconUrl as getIconUrl5
17457
17987
  } from "@unifold/core";
17458
17988
  import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
@@ -17461,7 +17991,7 @@ function WithdrawExecutionItem({
17461
17991
  onClick
17462
17992
  }) {
17463
17993
  const { colors: colors2, fonts, components } = useTheme();
17464
- const isPending = execution.status === ExecutionStatus6.PENDING || execution.status === ExecutionStatus6.WAITING || execution.status === ExecutionStatus6.DELAYED;
17994
+ const isPending = execution.status === ExecutionStatus7.PENDING || execution.status === ExecutionStatus7.WAITING || execution.status === ExecutionStatus7.DELAYED;
17465
17995
  const formatDateTime = (timestamp) => {
17466
17996
  try {
17467
17997
  const date = new Date(timestamp);
@@ -17730,8 +18260,6 @@ function WithdrawConfirmingView({
17730
18260
  className: "uf-text-sm uf-text-center",
17731
18261
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
17732
18262
  children: [
17733
- txInfo.amount,
17734
- " ",
17735
18263
  txInfo.sourceTokenSymbol,
17736
18264
  " to",
17737
18265
  " ",