@unifold/connect-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
@@ -6597,6 +6597,40 @@ async function getAddressBalances(address, chainType, publishableKey) {
6597
6597
  const data = await response.json();
6598
6598
  return data;
6599
6599
  }
6600
+ async function getExternalWallets(publishableKey) {
6601
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6602
+ validatePublishableKey(pk);
6603
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets`, {
6604
+ method: "GET",
6605
+ headers: {
6606
+ accept: "application/json",
6607
+ "x-publishable-key": pk
6608
+ }
6609
+ });
6610
+ if (!response.ok) {
6611
+ throw new Error(`Failed to fetch external wallets: ${response.statusText}`);
6612
+ }
6613
+ const data = await response.json();
6614
+ return data;
6615
+ }
6616
+ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey) {
6617
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6618
+ validatePublishableKey(pk);
6619
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets/mobile_deeplink`, {
6620
+ method: "POST",
6621
+ headers: {
6622
+ "Content-Type": "application/json",
6623
+ accept: "application/json",
6624
+ "x-publishable-key": pk
6625
+ },
6626
+ body: JSON.stringify({ wallet, deposit_addresses: depositAddresses })
6627
+ });
6628
+ if (!response.ok) {
6629
+ throw new Error(`Failed to generate wallet deep link: ${response.statusText}`);
6630
+ }
6631
+ const data = await response.json();
6632
+ return data;
6633
+ }
6600
6634
  async function getAddressBalance(address, chainType, chainId, tokenAddress, publishableKey) {
6601
6635
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6602
6636
  validatePublishableKey(pk);
@@ -6970,6 +7004,29 @@ async function getDepositQuote(request, publishableKey) {
6970
7004
  const json = await response.json();
6971
7005
  return json.data;
6972
7006
  }
7007
+ async function buildHypercoreTransaction(request, publishableKey) {
7008
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
7009
+ validatePublishableKey(pk);
7010
+ const response = await fetch(
7011
+ `${API_BASE_URL}/v1/public/transactions/hypercore/build`,
7012
+ {
7013
+ method: "POST",
7014
+ headers: {
7015
+ accept: "application/json",
7016
+ "x-publishable-key": pk,
7017
+ "Content-Type": "application/json"
7018
+ },
7019
+ body: JSON.stringify(request)
7020
+ }
7021
+ );
7022
+ if (!response.ok) {
7023
+ const error = await response.json().catch(() => ({ message: response.statusText }));
7024
+ throw new Error(
7025
+ `Failed to build HyperCore transaction: ${error.message || response.statusText}`
7026
+ );
7027
+ }
7028
+ return response.json();
7029
+ }
6973
7030
  async function getCashAppLimits(currency = "usd", publishableKey) {
6974
7031
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6975
7032
  validatePublishableKey(pk);
@@ -7035,6 +7092,29 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
7035
7092
  }
7036
7093
  return response.json();
7037
7094
  }
7095
+ async function sendHypercoreTransaction(request, publishableKey) {
7096
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
7097
+ validatePublishableKey(pk);
7098
+ const response = await fetch(
7099
+ `${API_BASE_URL}/v1/public/transactions/hypercore/send`,
7100
+ {
7101
+ method: "POST",
7102
+ headers: {
7103
+ accept: "application/json",
7104
+ "x-publishable-key": pk,
7105
+ "Content-Type": "application/json"
7106
+ },
7107
+ body: JSON.stringify(request)
7108
+ }
7109
+ );
7110
+ if (!response.ok) {
7111
+ const error = await response.json().catch(() => ({ message: response.statusText }));
7112
+ throw new Error(
7113
+ `Failed to send HyperCore transaction: ${error.message || response.statusText}`
7114
+ );
7115
+ }
7116
+ return response.json();
7117
+ }
7038
7118
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
7039
7119
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
7040
7120
  return DepositEventType2;
@@ -13439,6 +13519,7 @@ import { jsx as jsx47, jsxs as jsxs422 } from "react/jsx-runtime";
13439
13519
  import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
13440
13520
  import * as React302 from "react";
13441
13521
  import { useQuery as useQuery12 } from "@tanstack/react-query";
13522
+ import { useQuery as useQuery13 } from "@tanstack/react-query";
13442
13523
  import { jsx as jsx49 } from "react/jsx-runtime";
13443
13524
  import { jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
13444
13525
  import { Fragment as Fragment82, jsx as jsx51, jsxs as jsxs45 } from "react/jsx-runtime";
@@ -13455,7 +13536,7 @@ import {
13455
13536
  useRef as useRef102,
13456
13537
  useMemo as useMemo112
13457
13538
  } from "react";
13458
- import { useQuery as useQuery13 } from "@tanstack/react-query";
13539
+ import { useQuery as useQuery14 } from "@tanstack/react-query";
13459
13540
  import { Fragment as Fragment12, jsx as jsx56, jsxs as jsxs50 } from "react/jsx-runtime";
13460
13541
  import {
13461
13542
  useState as useState37,
@@ -13464,16 +13545,16 @@ import {
13464
13545
  useCallback as useCallback82,
13465
13546
  useRef as useRef122
13466
13547
  } from "react";
13467
- import { useQuery as useQuery14 } from "@tanstack/react-query";
13468
13548
  import { useQuery as useQuery15 } from "@tanstack/react-query";
13469
13549
  import { useQuery as useQuery16 } from "@tanstack/react-query";
13470
13550
  import { useQuery as useQuery17 } from "@tanstack/react-query";
13551
+ import { useQuery as useQuery18 } from "@tanstack/react-query";
13471
13552
  import { useState as useState34, useEffect as useEffect282, useRef as useRef112 } from "react";
13472
13553
  import { jsx as jsx57, jsxs as jsxs51 } from "react/jsx-runtime";
13473
13554
  import { useState as useState35, useCallback as useCallback72, useMemo as useMemo132, useEffect as useEffect292 } from "react";
13474
- import { useQuery as useQuery18 } from "@tanstack/react-query";
13475
- import { useMemo as useMemo122 } from "react";
13476
13555
  import { useQuery as useQuery19 } from "@tanstack/react-query";
13556
+ import { useMemo as useMemo122 } from "react";
13557
+ import { useQuery as useQuery20 } from "@tanstack/react-query";
13477
13558
  import { Fragment as Fragment13, jsx as jsx58, jsxs as jsxs52 } from "react/jsx-runtime";
13478
13559
  import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
13479
13560
  import { useState as useState36, useEffect as useEffect302 } from "react";
@@ -13561,6 +13642,22 @@ function clearStoredWalletState() {
13561
13642
  } catch {
13562
13643
  }
13563
13644
  }
13645
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
13646
+ function getLastOpenedWallet() {
13647
+ if (typeof window === "undefined") return void 0;
13648
+ try {
13649
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
13650
+ } catch {
13651
+ return void 0;
13652
+ }
13653
+ }
13654
+ function setLastOpenedWallet(walletId) {
13655
+ if (typeof window === "undefined") return;
13656
+ try {
13657
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
13658
+ } catch {
13659
+ }
13660
+ }
13564
13661
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
13565
13662
  function isMobileViewport() {
13566
13663
  if (typeof window === "undefined") return false;
@@ -13917,6 +14014,36 @@ function ThemeProvider({
13917
14014
  );
13918
14015
  return /* @__PURE__ */ jsx17(ThemeContext.Provider, { value: contextValue, children });
13919
14016
  }
14017
+ function AccentColorOverride({
14018
+ accentColor,
14019
+ accentForeground,
14020
+ children
14021
+ }) {
14022
+ const parent = useTheme();
14023
+ const value = React37.useMemo(() => {
14024
+ if (!accentColor) return parent;
14025
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
14026
+ const nextColors = {
14027
+ ...parent.colors,
14028
+ primary: accentColor,
14029
+ primaryForeground: foreground
14030
+ };
14031
+ const nextComponents = {
14032
+ ...parent.components,
14033
+ button: {
14034
+ ...parent.components.button,
14035
+ primaryBackground: accentColor,
14036
+ primaryText: foreground
14037
+ },
14038
+ card: {
14039
+ ...parent.components.card,
14040
+ iconBackgroundColor: `${accentColor}26`
14041
+ }
14042
+ };
14043
+ return { ...parent, colors: nextColors, components: nextComponents };
14044
+ }, [parent, accentColor, accentForeground]);
14045
+ return /* @__PURE__ */ jsx17(ThemeContext.Provider, { value, children });
14046
+ }
13920
14047
  function useTheme() {
13921
14048
  const context = React37.useContext(ThemeContext);
13922
14049
  if (!context) {
@@ -14336,7 +14463,7 @@ function DepositHeader({
14336
14463
  setShowBalanceSkeleton(false);
14337
14464
  return;
14338
14465
  }
14339
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
14466
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
14340
14467
  if (!supportedChainTypes.includes(
14341
14468
  balanceChainType
14342
14469
  )) {
@@ -14968,6 +15095,7 @@ function useDepositPolling({
14968
15095
  clientSecret,
14969
15096
  depositConfirmationMode = "auto_ui",
14970
15097
  depositWalletId,
15098
+ depositWalletIds,
14971
15099
  enabled = true,
14972
15100
  immediateDirectPolling = false,
14973
15101
  onDepositSuccess,
@@ -15113,21 +15241,25 @@ function useDepositPolling({
15113
15241
  setIsPolling(false);
15114
15242
  };
15115
15243
  }, [userId, publishableKey, clientSecret, enabled]);
15244
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
15116
15245
  useEffect32(() => {
15117
- if (!pollingEnabled || !depositWalletId) return;
15246
+ if (!pollingEnabled || !pollWalletIdsKey) return;
15247
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
15118
15248
  const triggerPoll = async () => {
15119
- try {
15120
- await pollDirectExecutions(
15121
- { deposit_wallet_id: depositWalletId },
15122
- publishableKey
15123
- );
15124
- } catch {
15125
- }
15249
+ await Promise.all(
15250
+ ids.map(
15251
+ (id) => pollDirectExecutions(
15252
+ { deposit_wallet_id: id },
15253
+ publishableKey
15254
+ ).catch(() => {
15255
+ })
15256
+ )
15257
+ );
15126
15258
  };
15127
15259
  triggerPoll();
15128
15260
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
15129
15261
  return () => clearInterval(interval);
15130
- }, [pollingEnabled, depositWalletId, publishableKey]);
15262
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
15131
15263
  const handleIveDeposited = () => {
15132
15264
  setPollingEnabled(true);
15133
15265
  setShowWaitingUi(true);
@@ -16316,6 +16448,7 @@ function BuyWithCard({
16316
16448
  if (!selectedProvider) return "0.000000";
16317
16449
  return selectedProvider.destination_amount.toFixed(6);
16318
16450
  };
16451
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
16319
16452
  const selectedCurrencyData = fiatCurrencies.find(
16320
16453
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
16321
16454
  );
@@ -16501,9 +16634,12 @@ function BuyWithCard({
16501
16634
  /* @__PURE__ */ jsx112(
16502
16635
  "button",
16503
16636
  {
16504
- onClick: () => handleViewChange("quotes"),
16637
+ onClick: () => {
16638
+ if (canOpenProviderSelector) handleViewChange("quotes");
16639
+ },
16505
16640
  disabled: quotesLoading || quotes.length === 0,
16506
- 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",
16641
+ "aria-disabled": !canOpenProviderSelector,
16642
+ 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"}`,
16507
16643
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
16508
16644
  children: quotesLoading ? /* @__PURE__ */ jsxs9("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
16509
16645
  /* @__PURE__ */ jsx112(
@@ -16530,7 +16666,7 @@ function BuyWithCard({
16530
16666
  )
16531
16667
  ] })
16532
16668
  ] }) : /* @__PURE__ */ jsxs9("div", { className: "uf-w-full uf-text-left", children: [
16533
- isAutoSelected && /* @__PURE__ */ jsx112(
16669
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ jsx112(
16534
16670
  "div",
16535
16671
  {
16536
16672
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -16566,7 +16702,7 @@ function BuyWithCard({
16566
16702
  ),
16567
16703
  selectedProvider.low_kyc === false && /* @__PURE__ */ jsx112("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ jsx112("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
16568
16704
  ] }),
16569
- quotes.length > 0 && /* @__PURE__ */ jsx112(
16705
+ canOpenProviderSelector && /* @__PURE__ */ jsx112(
16570
16706
  ChevronRight,
16571
16707
  {
16572
16708
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -24345,7 +24481,7 @@ function useHypercoreActivation(params) {
24345
24481
  publishableKey,
24346
24482
  enabled = true
24347
24483
  } = params;
24348
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
24484
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
24349
24485
  const recipient = recipientAddress?.trim() ?? "";
24350
24486
  const source = sourceAddress?.trim() ?? "";
24351
24487
  const hasAddresses = !!recipient && !!source;
@@ -25491,6 +25627,46 @@ function TransferCryptoDoubleInput({
25491
25627
  }
25492
25628
  ) });
25493
25629
  }
25630
+ function isHypercoreChain(chainId) {
25631
+ return chainId === HYPERCORE_CHAIN_ID;
25632
+ }
25633
+ async function sendHypercoreEvmTransfer(params) {
25634
+ const {
25635
+ provider,
25636
+ fromAddress,
25637
+ recipientAddress,
25638
+ sourceTokenAddress,
25639
+ amount,
25640
+ publishableKey
25641
+ } = params;
25642
+ const currentChainHex = await provider.request({
25643
+ method: "eth_chainId",
25644
+ params: []
25645
+ });
25646
+ const activeChainId = String(parseInt(currentChainHex, 16));
25647
+ const buildResult = await buildHypercoreTransaction(
25648
+ {
25649
+ signature_chain_id: activeChainId,
25650
+ recipient_address: recipientAddress,
25651
+ token_address: sourceTokenAddress,
25652
+ amount
25653
+ },
25654
+ publishableKey
25655
+ );
25656
+ const signature = await provider.request({
25657
+ method: "eth_signTypedData_v4",
25658
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
25659
+ });
25660
+ await sendHypercoreTransaction(
25661
+ {
25662
+ action_payload: buildResult.action_payload,
25663
+ signature,
25664
+ nonce: buildResult.nonce
25665
+ },
25666
+ publishableKey
25667
+ );
25668
+ return { signature };
25669
+ }
25494
25670
  function useDepositQuote(params) {
25495
25671
  const {
25496
25672
  publishableKey,
@@ -25542,6 +25718,60 @@ function useDepositQuote(params) {
25542
25718
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 5e3)
25543
25719
  });
25544
25720
  }
25721
+ function useExternalWallets({
25722
+ publishableKey,
25723
+ enabled = true
25724
+ }) {
25725
+ const { data: wallets = [], isLoading } = useQuery13({
25726
+ queryKey: ["unifold", "external-wallets", publishableKey],
25727
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
25728
+ enabled: enabled && !!publishableKey,
25729
+ staleTime: 1e3 * 60 * 30,
25730
+ refetchOnMount: false,
25731
+ refetchOnWindowFocus: false
25732
+ });
25733
+ return { wallets, isLoading };
25734
+ }
25735
+ var WALLET_BRAND_COLORS = {
25736
+ phantom: "#AB9FF2",
25737
+ metamask: "#F6851B",
25738
+ coinbase: "#0052FF",
25739
+ trust: "#3375BB",
25740
+ rainbow: "#5B6CFF",
25741
+ rabby: "#7084FF",
25742
+ okx: "#000000"
25743
+ };
25744
+ function normalizeWalletId(type) {
25745
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
25746
+ }
25747
+ function getWalletBrandColor(type, mode = "dark") {
25748
+ if (!type) return void 0;
25749
+ const id = normalizeWalletId(type);
25750
+ const color = WALLET_BRAND_COLORS[id];
25751
+ if (!color) return void 0;
25752
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
25753
+ return color;
25754
+ }
25755
+ function getContrastingTextColor(hex) {
25756
+ const c = hex.replace("#", "");
25757
+ if (c.length !== 6) return "#FFFFFF";
25758
+ const r2 = parseInt(c.slice(0, 2), 16);
25759
+ const g = parseInt(c.slice(2, 4), 16);
25760
+ const b = parseInt(c.slice(4, 6), 16);
25761
+ const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
25762
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
25763
+ }
25764
+ function isMobileDevice() {
25765
+ if (typeof navigator === "undefined") return false;
25766
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
25767
+ }
25768
+ function getMobilePlatform() {
25769
+ if (typeof navigator === "undefined") return null;
25770
+ const ua = navigator.userAgent;
25771
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
25772
+ if (/android/i.test(ua)) return "android";
25773
+ return null;
25774
+ }
25545
25775
  var WALLET_ICONS = {
25546
25776
  metamask: MetamaskIcon,
25547
25777
  phantom: PhantomIcon,
@@ -25844,7 +26074,8 @@ function EnterAmountView({
25844
26074
  onClose,
25845
26075
  quickSelectMode,
25846
26076
  checkoutAmountUsd,
25847
- checkoutReceivedUsd
26077
+ checkoutReceivedUsd,
26078
+ footer
25848
26079
  }) {
25849
26080
  const { colors: colors2, fonts, components } = useTheme();
25850
26081
  const isCheckout = !!checkoutAmountUsd;
@@ -26100,6 +26331,7 @@ function EnterAmountView({
26100
26331
  )
26101
26332
  ] })
26102
26333
  ] }),
26334
+ footer && /* @__PURE__ */ jsx51("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
26103
26335
  /* @__PURE__ */ jsx51("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ jsx51(
26104
26336
  "button",
26105
26337
  {
@@ -26547,18 +26779,33 @@ var WALLET_ICONS3 = {
26547
26779
  backpack: BackpackIcon,
26548
26780
  glow: GlowIcon
26549
26781
  };
26550
- var WALLET_DEFINITIONS = [
26551
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
26552
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
26553
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
26554
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
26555
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
26556
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
26557
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
26558
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
26559
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
26560
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
26782
+ var FALLBACK_WALLET_DEFINITIONS = [
26783
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
26784
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
26785
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
26786
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
26787
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
26788
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
26789
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
26561
26790
  ];
26791
+ function getMobileInstallUrl(walletId, defaultUrl) {
26792
+ if (!isMobileDevice()) return defaultUrl;
26793
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
26794
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
26795
+ const stores = {
26796
+ rabby: {
26797
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
26798
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
26799
+ },
26800
+ glow: {
26801
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
26802
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
26803
+ }
26804
+ };
26805
+ const entry = stores[walletId];
26806
+ if (!entry) return defaultUrl;
26807
+ return isIOS ? entry.ios : entry.android;
26808
+ }
26562
26809
  function normalizeTokenAddress(address) {
26563
26810
  const normalized = (address ?? "").toLowerCase();
26564
26811
  if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
@@ -26594,7 +26841,7 @@ function getLegacyEvmProviders() {
26594
26841
  okxEthereum: win.okxwallet
26595
26842
  };
26596
26843
  }
26597
- function detectAvailableWallets(filterChainType) {
26844
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
26598
26845
  const solProviders = getSolanaProviders();
26599
26846
  const legacyEvm = getLegacyEvmProviders();
26600
26847
  const eip6963List = getEip6963Providers();
@@ -26620,7 +26867,7 @@ function detectAvailableWallets(filterChainType) {
26620
26867
  return false;
26621
26868
  }
26622
26869
  });
26623
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26870
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26624
26871
  let isInstalled = false;
26625
26872
  const detectedNetworks = [];
26626
26873
  switch (wallet.id) {
@@ -26643,8 +26890,6 @@ function detectAvailableWallets(filterChainType) {
26643
26890
  isInstalled = true;
26644
26891
  detectedNetworks.push("ethereum");
26645
26892
  }
26646
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
26647
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
26648
26893
  break;
26649
26894
  case "trust":
26650
26895
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -26681,11 +26926,17 @@ function detectAvailableWallets(filterChainType) {
26681
26926
  }
26682
26927
  return { ...wallet, isInstalled, detectedNetworks };
26683
26928
  }).sort((a, b) => {
26929
+ if (recentWalletId) {
26930
+ const aRecent = a.id === recentWalletId ? 1 : 0;
26931
+ const bRecent = b.id === recentWalletId ? 1 : 0;
26932
+ if (aRecent !== bRecent) return bRecent - aRecent;
26933
+ }
26684
26934
  if (a.isInstalled && !b.isInstalled) return -1;
26685
26935
  if (!a.isInstalled && b.isInstalled) return 1;
26686
26936
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
26687
26937
  return 0;
26688
26938
  });
26939
+ return sorted;
26689
26940
  }
26690
26941
  function WalletConnect({
26691
26942
  walletInfo: initialWalletInfo,
@@ -26724,7 +26975,7 @@ function WalletConnect({
26724
26975
  depositWalletsLoading = false,
26725
26976
  onExecutionsChange
26726
26977
  }) {
26727
- const { colors: colors2, fonts, components } = useTheme();
26978
+ const { colors: colors2, fonts, components, mode } = useTheme();
26728
26979
  const walletProvidedAtMount = React302.useRef(!!initialWalletInfo && !!initialDepositWallet);
26729
26980
  const [activeWalletInfo, setActiveWalletInfo] = React302.useState(initialWalletInfo ?? null);
26730
26981
  const [activeDepositWallet, setActiveDepositWallet] = React302.useState(initialDepositWallet ?? null);
@@ -26748,7 +26999,43 @@ function WalletConnect({
26748
26999
  setEip6963ProviderCount(providers.length);
26749
27000
  });
26750
27001
  }, []);
26751
- const availableWallets = React302.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
27002
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
27003
+ const walletDefinitions = React302.useMemo(
27004
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
27005
+ id: w.id,
27006
+ name: w.name,
27007
+ networks: w.chain_types,
27008
+ installUrl: w.install_url,
27009
+ supportsMobileBrowse: w.supports_mobile_browse,
27010
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
27011
+ })) : FALLBACK_WALLET_DEFINITIONS,
27012
+ [backendWallets]
27013
+ );
27014
+ const [recentWalletId, setRecentWalletIdState] = React302.useState(getLastOpenedWallet);
27015
+ React302.useEffect(() => {
27016
+ if (view === "select_wallet") {
27017
+ setRecentWalletIdState(getLastOpenedWallet());
27018
+ }
27019
+ }, [view]);
27020
+ const availableWallets = React302.useMemo(
27021
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
27022
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
27023
+ );
27024
+ const [isMobile, setIsMobile] = React302.useState(false);
27025
+ React302.useEffect(() => {
27026
+ setIsMobile(isMobileDevice());
27027
+ }, []);
27028
+ const mobileDepositAddresses = React302.useMemo(
27029
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
27030
+ [depositWallets]
27031
+ );
27032
+ const mobileDepositWalletIds = React302.useMemo(
27033
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
27034
+ [depositWallets]
27035
+ );
27036
+ const [mobileRedirect, setMobileRedirect] = React302.useState(null);
27037
+ const [pendingMobileWallet, setPendingMobileWallet] = React302.useState(null);
27038
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React302.useState(false);
26752
27039
  React302.useEffect(() => {
26753
27040
  if (!standalone || autoResolved || detectingWallet) return;
26754
27041
  if (!detectedWallet) {
@@ -26792,7 +27079,7 @@ function WalletConnect({
26792
27079
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
26793
27080
  const recipientAddress = activeDepositWallet?.address ?? "";
26794
27081
  const isCheckoutMode = !!checkoutAmountUsd;
26795
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
27082
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
26796
27083
  const transitionTo = React302.useCallback((nextView) => {
26797
27084
  if (nextView === viewRef.current) return;
26798
27085
  setIsTransitioning(true);
@@ -26807,9 +27094,38 @@ function WalletConnect({
26807
27094
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
26808
27095
  transition: "opacity 150ms ease, transform 150ms ease"
26809
27096
  };
26810
- const handleWalletClick = (wallet) => {
27097
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
27098
+ try {
27099
+ const res = await getWalletMobileDeepLink(
27100
+ wallet.id,
27101
+ depositAddresses,
27102
+ publishableKey
27103
+ );
27104
+ if (res.deeplink) {
27105
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
27106
+ setLastOpenedWallet(wallet.id);
27107
+ setRecentWalletIdState(wallet.id);
27108
+ setAwaitingMobileDeposit(true);
27109
+ transitionTo("mobile_redirect");
27110
+ window.location.href = res.deeplink;
27111
+ return true;
27112
+ }
27113
+ } catch {
27114
+ }
27115
+ return false;
27116
+ };
27117
+ const handleWalletClick = async (wallet) => {
26811
27118
  if (!wallet.isInstalled) {
26812
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
27119
+ const platform2 = getMobilePlatform();
27120
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform2 ?? "");
27121
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
27122
+ if (mobileDepositAddresses.length === 0) {
27123
+ setPendingMobileWallet(wallet);
27124
+ return;
27125
+ }
27126
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
27127
+ }
27128
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
26813
27129
  return;
26814
27130
  }
26815
27131
  setSelectedWalletDef(wallet);
@@ -26825,9 +27141,32 @@ function WalletConnect({
26825
27141
  if (!selectedWalletDef) return;
26826
27142
  handleConnectWallet(selectedWalletDef, network);
26827
27143
  };
27144
+ React302.useEffect(() => {
27145
+ if (!pendingMobileWallet) return;
27146
+ if (mobileDepositAddresses.length > 0) {
27147
+ const wallet = pendingMobileWallet;
27148
+ setPendingMobileWallet(null);
27149
+ void (async () => {
27150
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
27151
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
27152
+ }
27153
+ })();
27154
+ return;
27155
+ }
27156
+ const timeout = setTimeout(() => {
27157
+ setPendingMobileWallet((current) => {
27158
+ if (!current) return null;
27159
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
27160
+ return null;
27161
+ });
27162
+ }, 8e3);
27163
+ return () => clearTimeout(timeout);
27164
+ }, [pendingMobileWallet, mobileDepositAddresses]);
26828
27165
  const handleConnectWallet = async (wallet, network) => {
26829
27166
  setConnectingNetwork(network);
26830
27167
  transitionTo("connecting");
27168
+ setLastOpenedWallet(wallet.id);
27169
+ setRecentWalletIdState(wallet.id);
26831
27170
  setWalletError(null);
26832
27171
  setIsWalletConnecting(true);
26833
27172
  try {
@@ -26932,6 +27271,13 @@ function WalletConnect({
26932
27271
  }
26933
27272
  };
26934
27273
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
27274
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
27275
+ recipientAddress,
27276
+ sourceAddress: activeWalletInfo?.address,
27277
+ destinationChainId: selectedToken?.chain_id,
27278
+ publishableKey,
27279
+ enabled: !!activeWalletInfo && !!recipientAddress
27280
+ });
26935
27281
  const effectiveDestinationAmount = React302.useMemo(() => {
26936
27282
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
26937
27283
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -26969,14 +27315,32 @@ function WalletConnect({
26969
27315
  userId,
26970
27316
  publishableKey,
26971
27317
  clientSecret,
27318
+ // In-tab flow: poll the single connected deposit wallet.
26972
27319
  depositWalletId: activeDepositWallet?.id ?? "",
26973
- enabled: hasSignedTransaction && !!activeDepositWallet,
27320
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
27321
+ // chain's deposit wallet. Detection still happens via the single /query by
27322
+ // external_user_id, which already spans all chains.
27323
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
27324
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
26974
27325
  onDepositSuccess,
26975
27326
  onDepositError
26976
27327
  });
26977
27328
  React302.useEffect(() => {
26978
27329
  onExecutionsChange?.(depositExecutions);
26979
27330
  }, [depositExecutions, onExecutionsChange]);
27331
+ const latestDepositExecution = React302.useMemo(() => {
27332
+ if (depositExecutions.length === 0) return null;
27333
+ return [...depositExecutions].sort((a, b) => {
27334
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
27335
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
27336
+ return tb - ta;
27337
+ })[0];
27338
+ }, [depositExecutions]);
27339
+ React302.useEffect(() => {
27340
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
27341
+ transitionTo("mobile_deposit_status");
27342
+ }
27343
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
26980
27344
  React302.useEffect(() => {
26981
27345
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
26982
27346
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -27018,7 +27382,7 @@ function WalletConnect({
27018
27382
  let cancelled = false;
27019
27383
  setIsLoading(true);
27020
27384
  setError(null);
27021
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
27385
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
27022
27386
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
27023
27387
  if (cancelled) return;
27024
27388
  const nonZero = response.balances.filter((b) => b.amount !== "0");
@@ -27107,6 +27471,16 @@ function WalletConnect({
27107
27471
  setSelectedWalletDef(null);
27108
27472
  setConnectingNetwork(null);
27109
27473
  break;
27474
+ case "mobile_redirect":
27475
+ transitionTo("select_wallet");
27476
+ setMobileRedirect(null);
27477
+ setAwaitingMobileDeposit(false);
27478
+ break;
27479
+ case "mobile_deposit_status":
27480
+ transitionTo("select_wallet");
27481
+ setMobileRedirect(null);
27482
+ setAwaitingMobileDeposit(false);
27483
+ break;
27110
27484
  case "select_token":
27111
27485
  if (walletProvidedAtMount.current) parentOnBack?.();
27112
27486
  else transitionTo("select_wallet");
@@ -27174,9 +27548,16 @@ function WalletConnect({
27174
27548
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
27175
27549
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
27176
27550
  };
27177
- const sendEthereumTransaction = async (token, amountStr) => {
27178
- if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
27179
- const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
27551
+ const resolveEvmProvider = () => {
27552
+ const walletIdMap = {
27553
+ "phantom-ethereum": "phantom",
27554
+ coinbase: "coinbase",
27555
+ trust: "trust",
27556
+ okx: "okx",
27557
+ rainbow: "rainbow",
27558
+ rabby: "rabby",
27559
+ metamask: "metamask"
27560
+ };
27180
27561
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
27181
27562
  const eip6963Match = findProviderByWalletId(lookupId);
27182
27563
  let provider = eip6963Match?.provider;
@@ -27185,6 +27566,11 @@ function WalletConnect({
27185
27566
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
27186
27567
  else provider = window.ethereum;
27187
27568
  }
27569
+ return provider;
27570
+ };
27571
+ const sendEthereumTransaction = async (token, amountStr) => {
27572
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
27573
+ const provider = resolveEvmProvider();
27188
27574
  if (!provider) throw new Error("Ethereum wallet not found");
27189
27575
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
27190
27576
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -27249,6 +27635,19 @@ function WalletConnect({
27249
27635
  const resp = await sendSolanaTransaction({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
27250
27636
  return resp.signature;
27251
27637
  };
27638
+ const sendHypercoreDeposit = async (token, amountStr) => {
27639
+ const provider = resolveEvmProvider();
27640
+ if (!provider) throw new Error("Ethereum wallet not found");
27641
+ const { signature } = await sendHypercoreEvmTransfer({
27642
+ provider,
27643
+ fromAddress: walletInfo.address,
27644
+ recipientAddress,
27645
+ sourceTokenAddress: token.token_address,
27646
+ amount: amountStr,
27647
+ publishableKey
27648
+ });
27649
+ return signature;
27650
+ };
27252
27651
  const handleConfirm = async () => {
27253
27652
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
27254
27653
  const token = getTokenFromBalance(selectedBalance);
@@ -27268,7 +27667,33 @@ function WalletConnect({
27268
27667
  setIsConfirming(true);
27269
27668
  setError(null);
27270
27669
  try {
27271
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction2(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
27670
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
27671
+ let txHash;
27672
+ if (token.chain_type === "solana") {
27673
+ txHash = await sendSolanaTransaction2(token, tokenAmount.toString());
27674
+ } else if (isHypercoreToken) {
27675
+ let sendAmount = tokenAmount;
27676
+ try {
27677
+ const activation = await checkHypercoreActivation(
27678
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
27679
+ publishableKey
27680
+ );
27681
+ if (!activation.user_exists) {
27682
+ const fee = activation.activation_fee;
27683
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
27684
+ throw new Error(
27685
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
27686
+ );
27687
+ }
27688
+ sendAmount = tokenAmount - fee;
27689
+ }
27690
+ } catch (e) {
27691
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
27692
+ }
27693
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
27694
+ } else {
27695
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
27696
+ }
27272
27697
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
27273
27698
  setHasSignedTransaction(true);
27274
27699
  handleIveDeposited();
@@ -27292,33 +27717,40 @@ function WalletConnect({
27292
27717
  return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27293
27718
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
27294
27719
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
27295
- /* @__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" }),
27296
- /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ jsxs48(
27297
- "button",
27298
- {
27299
- onClick: () => handleWalletClick(wallet),
27300
- disabled: isWalletConnecting,
27301
- 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",
27302
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
27303
- children: [
27304
- /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27305
- 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" }),
27306
- /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
27307
- ] }),
27308
- 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: [
27309
- /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
27310
- /* @__PURE__ */ jsx54(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
27311
- ] })
27312
- ]
27313
- },
27314
- wallet.id
27315
- )) }),
27720
+ /* @__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" }),
27721
+ /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
27722
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
27723
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
27724
+ const isPending = pendingMobileWallet?.id === wallet.id;
27725
+ return /* @__PURE__ */ jsxs48(
27726
+ "button",
27727
+ {
27728
+ onClick: () => void handleWalletClick(wallet),
27729
+ disabled: isWalletConnecting || !!pendingMobileWallet,
27730
+ 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",
27731
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
27732
+ children: [
27733
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27734
+ 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" }),
27735
+ /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
27736
+ ] }),
27737
+ isPending ? /* @__PURE__ */ jsx54(LoaderCircle, { 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: [
27738
+ /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
27739
+ /* @__PURE__ */ jsx54(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
27740
+ ] })
27741
+ ]
27742
+ },
27743
+ wallet.id
27744
+ );
27745
+ }) }),
27316
27746
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
27317
27747
  ] })
27318
27748
  ] });
27319
27749
  }
27750
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
27751
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
27320
27752
  if (view === "select_network" && selectedWalletDef) {
27321
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27753
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27322
27754
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
27323
27755
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
27324
27756
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -27348,10 +27780,10 @@ function WalletConnect({
27348
27780
  )) }),
27349
27781
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
27350
27782
  ] })
27351
- ] });
27783
+ ] }) });
27352
27784
  }
27353
27785
  if (view === "connecting") {
27354
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27786
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27355
27787
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
27356
27788
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
27357
27789
  /* @__PURE__ */ jsx54(LoaderCircle, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -27362,40 +27794,148 @@ function WalletConnect({
27362
27794
  ] }),
27363
27795
  /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: "Please approve the connection in your wallet" })
27364
27796
  ] })
27365
- ] });
27366
- }
27367
- if (!hasWallet) return null;
27368
- if (view === "select_token") {
27369
- 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 ?? (() => {
27370
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
27371
- }
27372
- if (view === "enter_amount" && selectedToken && selectedBalance) {
27373
- 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 ?? (() => {
27374
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
27375
- }
27376
- if (view === "review" && selectedToken) {
27377
- 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 ?? (() => {
27378
- }) }) });
27379
- }
27380
- if (view === "confirming") {
27381
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
27382
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
27797
+ ] }) });
27383
27798
  }
27384
- return null;
27385
- }
27386
- function SkeletonButton({
27387
- variant = "default"
27388
- }) {
27389
- return /* @__PURE__ */ jsxs49("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-animate-pulse", children: [
27390
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27391
- /* @__PURE__ */ jsx55("div", { className: "uf-bg-muted uf-rounded-lg uf-w-9 uf-h-9" }),
27392
- /* @__PURE__ */ jsxs49("div", { className: "uf-space-y-1.5", children: [
27393
- /* @__PURE__ */ jsx55("div", { className: "uf-h-3.5 uf-w-24 uf-bg-muted uf-rounded" }),
27394
- /* @__PURE__ */ jsx55("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded" })
27395
- ] })
27396
- ] }),
27397
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
27398
- variant === "with-icons" && /* @__PURE__ */ jsx55("div", { className: "uf-flex uf--space-x-1", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx55(
27799
+ if (view === "mobile_redirect" && mobileRedirect) {
27800
+ const Icon22 = WALLET_ICONS3[mobileRedirect.walletId];
27801
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27802
+ /* @__PURE__ */ jsx54(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
27803
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-px-6 uf-py-10", children: [
27804
+ Icon22 ? /* @__PURE__ */ jsx54(Icon22, { 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" }),
27805
+ /* @__PURE__ */ jsxs48(
27806
+ "div",
27807
+ {
27808
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
27809
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
27810
+ children: [
27811
+ "Continue in ",
27812
+ mobileRedirect.walletName
27813
+ ]
27814
+ }
27815
+ ),
27816
+ /* @__PURE__ */ jsxs48(
27817
+ "div",
27818
+ {
27819
+ className: "uf-text-sm uf-text-center uf-mb-6",
27820
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
27821
+ children: [
27822
+ "Complete your deposit in the ",
27823
+ mobileRedirect.walletName,
27824
+ " app"
27825
+ ]
27826
+ }
27827
+ ),
27828
+ /* @__PURE__ */ jsxs48(
27829
+ "button",
27830
+ {
27831
+ type: "button",
27832
+ onClick: () => {
27833
+ window.location.href = mobileRedirect.deeplink;
27834
+ },
27835
+ 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",
27836
+ style: {
27837
+ backgroundColor: components.card.backgroundColor,
27838
+ borderRadius: components.card.borderRadius,
27839
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
27840
+ color: components.card.titleColor,
27841
+ fontFamily: fonts.medium
27842
+ },
27843
+ children: [
27844
+ /* @__PURE__ */ jsx54(ExternalLink, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
27845
+ /* @__PURE__ */ jsxs48("span", { className: "uf-text-sm uf-font-medium", children: [
27846
+ "Open in ",
27847
+ mobileRedirect.walletName
27848
+ ] })
27849
+ ]
27850
+ }
27851
+ ),
27852
+ awaitingMobileDeposit && /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
27853
+ /* @__PURE__ */ jsx54(
27854
+ LoaderCircle,
27855
+ {
27856
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
27857
+ style: { color: colors2.foregroundMuted }
27858
+ }
27859
+ ),
27860
+ /* @__PURE__ */ jsx54(
27861
+ "span",
27862
+ {
27863
+ className: "uf-text-sm",
27864
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
27865
+ children: "Checking for deposit..."
27866
+ }
27867
+ )
27868
+ ] })
27869
+ ] })
27870
+ ] }) });
27871
+ }
27872
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
27873
+ const isComplete = latestDepositExecution.status === ExecutionStatus.SUCCEEDED;
27874
+ const isFailed = latestDepositExecution.status === ExecutionStatus.FAILED;
27875
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
27876
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27877
+ /* @__PURE__ */ jsx54(
27878
+ DepositHeader,
27879
+ {
27880
+ title,
27881
+ showBack: false,
27882
+ onClose: isComplete && onDone ? onDone : onClose
27883
+ }
27884
+ ),
27885
+ /* @__PURE__ */ jsx54(DepositDetailContent, { execution: latestDepositExecution }),
27886
+ isComplete && /* @__PURE__ */ jsx54("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-4 uf-pb-4", children: /* @__PURE__ */ jsx54(
27887
+ "button",
27888
+ {
27889
+ type: "button",
27890
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
27891
+ }),
27892
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
27893
+ style: {
27894
+ backgroundColor: colors2.primary,
27895
+ color: colors2.primaryForeground,
27896
+ fontFamily: fonts.medium,
27897
+ borderRadius: components.button.borderRadius,
27898
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
27899
+ },
27900
+ children: "Done"
27901
+ }
27902
+ ) })
27903
+ ] }) });
27904
+ }
27905
+ if (!hasWallet) return null;
27906
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
27907
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
27908
+ if (view === "select_token") {
27909
+ 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 ?? (() => {
27910
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
27911
+ }
27912
+ if (view === "enter_amount" && selectedToken && selectedBalance) {
27913
+ 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 ?? (() => {
27914
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ jsx54(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
27915
+ }
27916
+ if (view === "review" && selectedToken) {
27917
+ 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 ?? (() => {
27918
+ }) }) }) });
27919
+ }
27920
+ if (view === "confirming") {
27921
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
27922
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
27923
+ }
27924
+ return null;
27925
+ }
27926
+ function SkeletonButton({
27927
+ variant = "default"
27928
+ }) {
27929
+ return /* @__PURE__ */ jsxs49("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-animate-pulse", children: [
27930
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27931
+ /* @__PURE__ */ jsx55("div", { className: "uf-bg-muted uf-rounded-lg uf-w-9 uf-h-9" }),
27932
+ /* @__PURE__ */ jsxs49("div", { className: "uf-space-y-1.5", children: [
27933
+ /* @__PURE__ */ jsx55("div", { className: "uf-h-3.5 uf-w-24 uf-bg-muted uf-rounded" }),
27934
+ /* @__PURE__ */ jsx55("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded" })
27935
+ ] })
27936
+ ] }),
27937
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
27938
+ variant === "with-icons" && /* @__PURE__ */ jsx55("div", { className: "uf-flex uf--space-x-1", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx55(
27399
27939
  "div",
27400
27940
  {
27401
27941
  className: "uf-w-5 uf-h-5 uf-rounded-full uf-bg-muted uf-border-2 uf-border-secondary"
@@ -27407,6 +27947,9 @@ function SkeletonButton({
27407
27947
  ] });
27408
27948
  }
27409
27949
  var t7 = i18n2.depositModal;
27950
+ function depositTabForScreen(screen) {
27951
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
27952
+ }
27410
27953
  function DepositModal({
27411
27954
  open,
27412
27955
  onOpenChange,
@@ -27442,6 +27985,7 @@ function DepositModal({
27442
27985
  theme = "dark",
27443
27986
  hideOverlay = false,
27444
27987
  initialScreen = "main",
27988
+ displayMode = "stacked",
27445
27989
  transferCryptoTitle = t7.transferCrypto.title,
27446
27990
  depositWithCardTitle = t7.depositWithCard.title,
27447
27991
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -27476,6 +28020,9 @@ function DepositModal({
27476
28020
  effectiveInitialScreen
27477
28021
  );
27478
28022
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = useState32(false);
28023
+ const [depositTab, setDepositTab] = useState32(
28024
+ () => depositTabForScreen(effectiveInitialScreen)
28025
+ );
27479
28026
  const resetViewTimeoutRef = useRef92(null);
27480
28027
  const [cardView, setCardView] = useState32(
27481
28028
  "amount"
@@ -27491,7 +28038,6 @@ function DepositModal({
27491
28038
  const [allExecutions, setAllExecutions] = useState32([]);
27492
28039
  const [selectedExecution, setSelectedExecution] = useState32(null);
27493
28040
  const [depositExecutions, setDepositExecutions] = useState32([]);
27494
- const isMobileView = useIsMobileViewport();
27495
28041
  const { projectConfig } = useProjectConfig({
27496
28042
  publishableKey,
27497
28043
  enabled: open
@@ -27774,6 +28320,7 @@ function DepositModal({
27774
28320
  resetViewTimeoutRef.current = null;
27775
28321
  }
27776
28322
  setView(effectiveInitialScreen);
28323
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
27777
28324
  setCardView("amount");
27778
28325
  setExchangeView("providers");
27779
28326
  setBrowserWalletInfo(null);
@@ -27802,6 +28349,7 @@ function DepositModal({
27802
28349
  } else if (view === "cashapp" && cashAppView !== "amount") {
27803
28350
  setCashAppView("amount");
27804
28351
  } else {
28352
+ setDepositTab(depositTabForScreen(view));
27805
28353
  setView("main");
27806
28354
  setCardView("amount");
27807
28355
  setExchangeView("providers");
@@ -27881,13 +28429,181 @@ function DepositModal({
27881
28429
  className: "uf-flex uf-justify-center uf-shrink-0"
27882
28430
  }
27883
28431
  ) });
28432
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ jsx55(
28433
+ TransferCryptoButton,
28434
+ {
28435
+ onClick: () => setView("transfer"),
28436
+ title: transferCryptoTitle,
28437
+ subtitle: t7.transferCrypto.subtitle,
28438
+ featuredTokens: projectConfig?.transfer_crypto.networks
28439
+ },
28440
+ "transfer"
28441
+ ) : null;
28442
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ jsx55(
28443
+ BrowserWalletButton,
28444
+ {
28445
+ onClick: handleBrowserWalletClick,
28446
+ onConnectClick: handleWalletConnectClick,
28447
+ onDisconnect: handleWalletDisconnect,
28448
+ chainType: browserWalletChainType,
28449
+ publishableKey,
28450
+ featuredWallets: projectConfig?.connect_wallet?.wallets
28451
+ },
28452
+ "wallet"
28453
+ ) : null;
28454
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ jsx55(
28455
+ DepositWithCardButton,
28456
+ {
28457
+ onClick: () => setView("card"),
28458
+ title: depositWithCardTitle,
28459
+ subtitle: t7.depositWithCard.subtitle,
28460
+ paymentNetworks: projectConfig?.payment_networks.networks
28461
+ },
28462
+ "card"
28463
+ ) : null;
28464
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ jsx55(
28465
+ PayWithExchangeButton,
28466
+ {
28467
+ onClick: () => setView("exchange"),
28468
+ title: payWithExchangeTitle,
28469
+ subtitle: t7.payWithExchange.subtitle,
28470
+ exchanges,
28471
+ loading: exchangesLoading
28472
+ },
28473
+ "exchange"
28474
+ ) : null;
28475
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ jsx55(
28476
+ ConnectExchangeButton,
28477
+ {
28478
+ onClick: () => {
28479
+ setCoinbaseSkipToHoldings(true);
28480
+ setView("coinbase_connect");
28481
+ },
28482
+ onDisconnect: handleExchangeDisconnect,
28483
+ title: i18n2.connectExchange.title,
28484
+ subtitle: i18n2.connectExchange.subtitle,
28485
+ exchanges: integrationExchanges,
28486
+ connectedExchange
28487
+ },
28488
+ "connect-exchange"
28489
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ jsx55(
28490
+ ConnectExchangeButton,
28491
+ {
28492
+ onClick: () => {
28493
+ setCoinbaseSkipToHoldings(false);
28494
+ setView("coinbase_connect");
28495
+ },
28496
+ title: i18n2.connectExchange.title,
28497
+ subtitle: i18n2.connectExchange.subtitle,
28498
+ exchanges: integrationExchanges
28499
+ },
28500
+ "connect-exchange"
28501
+ ) : null;
28502
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ jsx55(
28503
+ CashAppButton,
28504
+ {
28505
+ onClick: () => setView("cashapp"),
28506
+ title: "Pay with Cash App",
28507
+ subtitle: "Deposit via Cash App",
28508
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28509
+ },
28510
+ "cashapp"
28511
+ ) : null;
28512
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ jsx55(
28513
+ DepositTrackerButton,
28514
+ {
28515
+ onClick: () => {
28516
+ setAllExecutions(depositExecutions);
28517
+ setView("tracker");
28518
+ },
28519
+ title: depositTrackerTitle,
28520
+ subtitle: depositTrackerSubTitle,
28521
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
28522
+ },
28523
+ "tracker"
28524
+ ) : null;
28525
+ const cryptoMenuButtons = [
28526
+ transferCryptoMenuButton,
28527
+ connectWalletMenuButton,
28528
+ payWithExchangeMenuButton,
28529
+ connectExchangeMenuButton
28530
+ ].filter(Boolean);
28531
+ const cashMenuButtons = [
28532
+ depositWithCardMenuButton,
28533
+ cashAppMenuButton
28534
+ ].filter(Boolean);
28535
+ const depositTabs = [
28536
+ { id: "crypto", label: "Use Crypto", buttons: cryptoMenuButtons },
28537
+ { id: "cash", label: "Use Cash", buttons: cashMenuButtons }
28538
+ ].filter((tab) => tab.buttons.length > 0);
28539
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
28540
+ const renderMainMenuBody = () => {
28541
+ if (depositPrerequisiteBody) {
28542
+ return /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
28543
+ }
28544
+ if (displayMode === "tabs" && activeDepositTab) {
28545
+ return /* @__PURE__ */ jsxs49("div", { children: [
28546
+ depositTabs.length > 1 && /* @__PURE__ */ jsx55(
28547
+ "div",
28548
+ {
28549
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
28550
+ style: {
28551
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
28552
+ // the control reads as a soft surface rather than a solid bar.
28553
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
28554
+ backdropFilter: "blur(12px)",
28555
+ WebkitBackdropFilter: "blur(12px)"
28556
+ },
28557
+ role: "tablist",
28558
+ children: depositTabs.map((tab) => {
28559
+ const active = activeDepositTab.id === tab.id;
28560
+ return /* @__PURE__ */ jsx55(
28561
+ "button",
28562
+ {
28563
+ type: "button",
28564
+ role: "tab",
28565
+ "aria-selected": active,
28566
+ onClick: () => setDepositTab(tab.id),
28567
+ className: "uf-flex-1 uf-py-2 uf-px-3 uf-rounded-lg uf-text-sm uf-transition-all",
28568
+ style: {
28569
+ // Active tab is a soft, blurred glass pill — a faint accent
28570
+ // tint with its own backdrop blur and a subtle border/shadow,
28571
+ // so it looks frosted instead of like a hard solid button.
28572
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
28573
+ backdropFilter: active ? "blur(8px)" : void 0,
28574
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
28575
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
28576
+ color: active ? colors2.foreground : colors2.foregroundMuted,
28577
+ fontFamily: fonts.medium
28578
+ },
28579
+ children: tab.label
28580
+ },
28581
+ tab.id
28582
+ );
28583
+ })
28584
+ }
28585
+ ),
28586
+ /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
28587
+ depositTrackerMenuButton && /* @__PURE__ */ jsx55("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
28588
+ ] });
28589
+ }
28590
+ return /* @__PURE__ */ jsxs49("div", { className: "uf-space-y-3", children: [
28591
+ transferCryptoMenuButton,
28592
+ connectWalletMenuButton,
28593
+ depositWithCardMenuButton,
28594
+ payWithExchangeMenuButton,
28595
+ connectExchangeMenuButton,
28596
+ cashAppMenuButton,
28597
+ depositTrackerMenuButton
28598
+ ] });
28599
+ };
27884
28600
  return /* @__PURE__ */ jsx55(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ jsx55(
27885
28601
  Dialog2,
27886
28602
  {
27887
28603
  open: hideOverlay || open,
27888
28604
  onOpenChange: hideOverlay ? void 0 : handleClose,
27889
28605
  modal: !hideOverlay,
27890
- children: /* @__PURE__ */ jsx55(
28606
+ children: /* @__PURE__ */ jsxs49(
27891
28607
  DialogContent2,
27892
28608
  {
27893
28609
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -27896,386 +28612,302 @@ function DepositModal({
27896
28612
  style: { backgroundColor: colors2.background },
27897
28613
  onPointerDownOutside: (e) => e.preventDefault(),
27898
28614
  onInteractOutside: (e) => e.preventDefault(),
27899
- children: /* @__PURE__ */ jsx55(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27900
- /* @__PURE__ */ jsx55(
27901
- DepositHeader,
27902
- {
27903
- title: modalTitle || "Deposit",
27904
- showClose: !hideOverlay,
27905
- onClose: handleClose,
27906
- showBalance: showBalanceHeader,
27907
- balanceAddress: recipientAddress,
27908
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
27909
- balanceChainId: destinationChainId,
27910
- balanceTokenAddress: destinationTokenAddress,
27911
- projectName: projectConfig?.project_name,
27912
- publishableKey
27913
- }
27914
- ),
27915
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27916
- /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27917
- showTransferCrypto && /* @__PURE__ */ jsx55(
27918
- TransferCryptoButton,
27919
- {
27920
- onClick: () => setView("transfer"),
27921
- title: transferCryptoTitle,
27922
- subtitle: t7.transferCrypto.subtitle,
27923
- featuredTokens: projectConfig?.transfer_crypto.networks
27924
- }
27925
- ),
27926
- showConnectWallet && !isMobileView && /* @__PURE__ */ jsx55(
27927
- BrowserWalletButton,
28615
+ children: [
28616
+ /* @__PURE__ */ jsx55(DialogTitle2, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
28617
+ /* @__PURE__ */ jsx55(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28618
+ /* @__PURE__ */ jsx55(
28619
+ DepositHeader,
28620
+ {
28621
+ title: modalTitle || "Deposit",
28622
+ showClose: !hideOverlay,
28623
+ onClose: handleClose,
28624
+ showBalance: showBalanceHeader,
28625
+ balanceAddress: recipientAddress,
28626
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
28627
+ balanceChainId: destinationChainId,
28628
+ balanceTokenAddress: destinationTokenAddress,
28629
+ projectName: projectConfig?.project_name,
28630
+ publishableKey
28631
+ }
28632
+ ),
28633
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28634
+ renderMainMenuBody(),
28635
+ depositPoweredByFooter
28636
+ ] })
28637
+ ] }) : view === "transfer" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28638
+ /* @__PURE__ */ jsx55(
28639
+ DepositHeader,
28640
+ {
28641
+ title: transferCryptoTitle,
28642
+ showBack: showBackTransfer,
28643
+ onBack: handleBack,
28644
+ onClose: handleClose,
28645
+ showBalance: showBalanceHeader,
28646
+ balanceAddress: recipientAddress,
28647
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
28648
+ balanceChainId: destinationChainId,
28649
+ balanceTokenAddress: destinationTokenAddress,
28650
+ projectName: projectConfig?.project_name,
28651
+ publishableKey
28652
+ }
28653
+ ),
28654
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28655
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ jsx55(
28656
+ TransferCryptoSingleInput,
27928
28657
  {
27929
- onClick: handleBrowserWalletClick,
27930
- onConnectClick: handleWalletConnectClick,
27931
- onDisconnect: handleWalletDisconnect,
27932
- chainType: browserWalletChainType,
28658
+ userId,
27933
28659
  publishableKey,
27934
- featuredWallets: projectConfig?.connect_wallet?.wallets
28660
+ recipientAddress,
28661
+ destinationChainType,
28662
+ destinationChainId,
28663
+ destinationTokenAddress,
28664
+ defaultSourceChainType,
28665
+ defaultSourceChainId,
28666
+ defaultSourceTokenAddress,
28667
+ defaultSourceSymbol,
28668
+ depositConfirmationMode,
28669
+ onExecutionsChange: setDepositExecutions,
28670
+ onDepositSuccess,
28671
+ onDepositError,
28672
+ wallets
27935
28673
  }
27936
- ),
27937
- showFiatOnramp && /* @__PURE__ */ jsx55(
27938
- DepositWithCardButton,
28674
+ ) : /* @__PURE__ */ jsx55(
28675
+ TransferCryptoDoubleInput,
27939
28676
  {
27940
- onClick: () => setView("card"),
27941
- title: depositWithCardTitle,
27942
- subtitle: t7.depositWithCard.subtitle,
27943
- paymentNetworks: projectConfig?.payment_networks.networks
28677
+ userId,
28678
+ publishableKey,
28679
+ recipientAddress,
28680
+ destinationChainType,
28681
+ destinationChainId,
28682
+ destinationTokenAddress,
28683
+ defaultSourceChainType,
28684
+ defaultSourceChainId,
28685
+ defaultSourceTokenAddress,
28686
+ defaultSourceSymbol,
28687
+ depositConfirmationMode,
28688
+ onExecutionsChange: setDepositExecutions,
28689
+ onDepositSuccess,
28690
+ onDepositError,
28691
+ wallets
27944
28692
  }
27945
28693
  ),
27946
- showPayWithExchange && /* @__PURE__ */ jsx55(
27947
- PayWithExchangeButton,
28694
+ depositPoweredByFooter
28695
+ ] })
28696
+ ] }) : view === "tracker" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28697
+ /* @__PURE__ */ jsx55(
28698
+ DepositHeader,
28699
+ {
28700
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
28701
+ showBack: showBackTracker,
28702
+ onBack: handleBack,
28703
+ onClose: handleClose
28704
+ }
28705
+ ),
28706
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28707
+ /* @__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(
28708
+ "div",
27948
28709
  {
27949
- onClick: () => setView("exchange"),
27950
- title: payWithExchangeTitle,
27951
- subtitle: t7.payWithExchange.subtitle,
27952
- exchanges,
27953
- loading: exchangesLoading
28710
+ className: "uf-text-sm",
28711
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
28712
+ children: "No deposits yet"
27954
28713
  }
27955
- ),
27956
- showConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
27957
- ConnectExchangeButton,
28714
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ jsx55(
28715
+ DepositExecutionItem,
27958
28716
  {
27959
- onClick: () => {
27960
- setCoinbaseSkipToHoldings(true);
27961
- setView("coinbase_connect");
27962
- },
27963
- onDisconnect: handleExchangeDisconnect,
27964
- title: i18n2.connectExchange.title,
27965
- subtitle: i18n2.connectExchange.subtitle,
27966
- exchanges: integrationExchanges,
27967
- connectedExchange
27968
- }
27969
- ),
27970
- showConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
27971
- ConnectExchangeButton,
28717
+ execution,
28718
+ onClick: () => setSelectedExecution(execution)
28719
+ },
28720
+ execution.id
28721
+ )) }) }),
28722
+ depositPoweredByFooter
28723
+ ] })
28724
+ ] }) : view === "card" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28725
+ /* @__PURE__ */ jsx55(
28726
+ DepositHeader,
28727
+ {
28728
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
28729
+ showBack: showBackCard,
28730
+ onBack: handleBack,
28731
+ onClose: handleClose,
28732
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
28733
+ showBalance: showBalanceHeader,
28734
+ balanceAddress: recipientAddress,
28735
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
28736
+ balanceChainId: destinationChainId,
28737
+ balanceTokenAddress: destinationTokenAddress,
28738
+ projectName: projectConfig?.project_name,
28739
+ publishableKey
28740
+ }
28741
+ ),
28742
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28743
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ jsx55(
28744
+ BuyWithCard,
27972
28745
  {
27973
- onClick: () => {
27974
- setCoinbaseSkipToHoldings(false);
27975
- setView("coinbase_connect");
27976
- },
27977
- title: i18n2.connectExchange.title,
27978
- subtitle: i18n2.connectExchange.subtitle,
27979
- exchanges: integrationExchanges
28746
+ userId,
28747
+ publishableKey,
28748
+ view: cardView,
28749
+ onViewChange: handleCardViewChange,
28750
+ destinationTokenSymbol,
28751
+ recipientAddress,
28752
+ destinationChainType,
28753
+ destinationChainId,
28754
+ destinationTokenAddress,
28755
+ onDepositSuccess,
28756
+ onDepositError,
28757
+ onEvent,
28758
+ themeClass,
28759
+ wallets,
28760
+ assetCdnUrl: projectConfig?.asset_cdn_url,
28761
+ hideDepositFlowInfo,
28762
+ hideDisplayDescription
27980
28763
  }
27981
28764
  ),
27982
- showCashApp && /* @__PURE__ */ jsx55(
27983
- CashAppButton,
28765
+ depositPoweredByFooter
28766
+ ] })
28767
+ ] }) : view === "exchange" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28768
+ /* @__PURE__ */ jsx55(
28769
+ DepositHeader,
28770
+ {
28771
+ title: payWithExchangeTitle,
28772
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
28773
+ onBack: handleBack,
28774
+ onClose: handleClose
28775
+ }
28776
+ ),
28777
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28778
+ /* @__PURE__ */ jsx55(
28779
+ PayWithExchange,
27984
28780
  {
27985
- onClick: () => setView("cashapp"),
27986
- title: "Pay with Cash App",
27987
- subtitle: "Deposit via Cash App",
27988
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28781
+ userId,
28782
+ publishableKey,
28783
+ exchanges,
28784
+ view: exchangeView,
28785
+ onViewChange: setExchangeView,
28786
+ destinationTokenSymbol,
28787
+ recipientAddress,
28788
+ destinationChainType,
28789
+ destinationChainId,
28790
+ destinationTokenAddress,
28791
+ onDepositSuccess,
28792
+ onDepositError,
28793
+ wallets,
28794
+ defaultToken: defaultToken ?? null
27989
28795
  }
27990
28796
  ),
27991
- showDepositTracker && /* @__PURE__ */ jsx55(
27992
- DepositTrackerButton,
27993
- {
27994
- onClick: () => {
27995
- setAllExecutions(depositExecutions);
27996
- setView("tracker");
27997
- },
27998
- title: depositTrackerTitle,
27999
- subtitle: depositTrackerSubTitle,
28000
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
28001
- }
28002
- )
28003
- ] }) }),
28004
- depositPoweredByFooter
28005
- ] })
28006
- ] }) : view === "transfer" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28007
- /* @__PURE__ */ jsx55(
28008
- DepositHeader,
28009
- {
28010
- title: transferCryptoTitle,
28011
- showBack: showBackTransfer,
28012
- onBack: handleBack,
28013
- onClose: handleClose,
28014
- showBalance: showBalanceHeader,
28015
- balanceAddress: recipientAddress,
28016
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28017
- balanceChainId: destinationChainId,
28018
- balanceTokenAddress: destinationTokenAddress,
28019
- projectName: projectConfig?.project_name,
28020
- publishableKey
28021
- }
28022
- ),
28023
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28024
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ jsx55(
28025
- TransferCryptoSingleInput,
28797
+ depositPoweredByFooter
28798
+ ] })
28799
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28800
+ /* @__PURE__ */ jsx55(
28801
+ CoinbaseConnect,
28026
28802
  {
28027
- userId,
28028
28803
  publishableKey,
28029
- recipientAddress,
28030
- destinationChainType,
28031
- destinationChainId,
28032
- destinationTokenAddress,
28033
- defaultSourceChainType,
28034
- defaultSourceChainId,
28035
- defaultSourceTokenAddress,
28036
- defaultSourceSymbol,
28037
- depositConfirmationMode,
28038
- onExecutionsChange: setDepositExecutions,
28039
- onDepositSuccess,
28040
- onDepositError,
28041
- wallets
28042
- }
28043
- ) : /* @__PURE__ */ jsx55(
28044
- TransferCryptoDoubleInput,
28045
- {
28046
28804
  userId,
28047
- publishableKey,
28805
+ wallets,
28048
28806
  recipientAddress,
28049
- destinationChainType,
28050
- destinationChainId,
28051
- destinationTokenAddress,
28807
+ destinationTokenAddress: destinationTokenAddress ?? "",
28808
+ destinationChainId: destinationChainId ?? "",
28809
+ destinationChainType: destinationChainType ?? "",
28810
+ onTransferSuccess: (result) => {
28811
+ onDepositSuccess?.({
28812
+ message: "Transfer completed via Coinbase Connect",
28813
+ transaction: result
28814
+ });
28815
+ },
28816
+ onTransferError: (error) => {
28817
+ onDepositError?.({
28818
+ message: error.message,
28819
+ error
28820
+ });
28821
+ },
28822
+ onBack: handleBack,
28823
+ onClose: handleClose,
28824
+ onDisconnect: handleExchangeDisconnect,
28825
+ skipToHoldings: coinbaseSkipToHoldings,
28826
+ canGoBack: sessionOpenedFromMenu,
28827
+ onExecutionsChange: setDepositExecutions,
28052
28828
  defaultSourceChainType,
28053
28829
  defaultSourceChainId,
28054
28830
  defaultSourceTokenAddress,
28055
- defaultSourceSymbol,
28056
- depositConfirmationMode,
28057
- onExecutionsChange: setDepositExecutions,
28058
- onDepositSuccess,
28059
- onDepositError,
28060
- wallets
28831
+ defaultSourceSymbol
28061
28832
  }
28062
28833
  ),
28063
28834
  depositPoweredByFooter
28064
- ] })
28065
- ] }) : view === "tracker" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28066
- /* @__PURE__ */ jsx55(
28067
- DepositHeader,
28068
- {
28069
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
28070
- showBack: showBackTracker,
28071
- onBack: handleBack,
28072
- onClose: handleClose
28073
- }
28074
- ),
28075
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28076
- /* @__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(
28077
- "div",
28078
- {
28079
- className: "uf-text-sm",
28080
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
28081
- children: "No deposits yet"
28082
- }
28083
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ jsx55(
28084
- DepositExecutionItem,
28085
- {
28086
- execution,
28087
- onClick: () => setSelectedExecution(execution)
28088
- },
28089
- execution.id
28090
- )) }) }),
28091
- depositPoweredByFooter
28092
- ] })
28093
- ] }) : view === "card" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28094
- /* @__PURE__ */ jsx55(
28095
- DepositHeader,
28096
- {
28097
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
28098
- showBack: showBackCard,
28099
- onBack: handleBack,
28100
- onClose: handleClose,
28101
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
28102
- showBalance: showBalanceHeader,
28103
- balanceAddress: recipientAddress,
28104
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28105
- balanceChainId: destinationChainId,
28106
- balanceTokenAddress: destinationTokenAddress,
28107
- projectName: projectConfig?.project_name,
28108
- publishableKey
28109
- }
28110
- ),
28111
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28112
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ jsx55(
28113
- BuyWithCard,
28114
- {
28115
- userId,
28116
- publishableKey,
28117
- view: cardView,
28118
- onViewChange: handleCardViewChange,
28119
- destinationTokenSymbol,
28120
- recipientAddress,
28121
- destinationChainType,
28122
- destinationChainId,
28123
- destinationTokenAddress,
28124
- onDepositSuccess,
28125
- onDepositError,
28126
- onEvent,
28127
- themeClass,
28128
- wallets,
28129
- assetCdnUrl: projectConfig?.asset_cdn_url,
28130
- hideDepositFlowInfo,
28131
- hideDisplayDescription
28132
- }
28133
- ),
28134
- depositPoweredByFooter
28135
- ] })
28136
- ] }) : view === "exchange" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28137
- /* @__PURE__ */ jsx55(
28138
- DepositHeader,
28139
- {
28140
- title: payWithExchangeTitle,
28141
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
28142
- onBack: handleBack,
28143
- onClose: handleClose
28144
- }
28145
- ),
28146
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28835
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28147
28836
  /* @__PURE__ */ jsx55(
28148
- PayWithExchange,
28837
+ WalletConnect,
28149
28838
  {
28839
+ walletInfo: browserWalletInfo ?? void 0,
28840
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
28841
+ wallets,
28150
28842
  userId,
28151
28843
  publishableKey,
28152
- exchanges,
28153
- view: exchangeView,
28154
- onViewChange: setExchangeView,
28155
- destinationTokenSymbol,
28156
- recipientAddress,
28157
- destinationChainType,
28158
- destinationChainId,
28159
- destinationTokenAddress,
28844
+ assetCdnUrl: projectConfig?.asset_cdn_url,
28845
+ projectName: projectConfig?.project_name,
28846
+ onSuccess: (txHash) => {
28847
+ onDepositSuccess?.({
28848
+ message: "Transaction sent successfully",
28849
+ transaction: { txHash }
28850
+ });
28851
+ },
28852
+ onError: (error) => {
28853
+ onDepositError?.({
28854
+ message: error.message,
28855
+ error
28856
+ });
28857
+ },
28160
28858
  onDepositSuccess,
28161
28859
  onDepositError,
28162
- wallets,
28163
- defaultToken: defaultToken ?? null
28860
+ amountQuickSelect: browserWalletAmountQuickSelect,
28861
+ onWalletDisconnect: handleWalletDisconnect,
28862
+ onWalletConnected: (info, dw) => {
28863
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
28864
+ setStoredWalletState(info.type);
28865
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28866
+ },
28867
+ onBack: handleBack,
28868
+ onClose: handleClose,
28869
+ defaultSourceChainType,
28870
+ defaultSourceChainId,
28871
+ defaultSourceTokenAddress,
28872
+ defaultSourceSymbol,
28873
+ canGoBack: sessionOpenedFromMenu,
28874
+ depositWalletsLoading: walletsLoading
28164
28875
  }
28165
28876
  ),
28166
28877
  depositPoweredByFooter
28167
- ] })
28168
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28169
- /* @__PURE__ */ jsx55(
28170
- CoinbaseConnect,
28171
- {
28172
- publishableKey,
28173
- userId,
28174
- wallets,
28175
- recipientAddress,
28176
- destinationTokenAddress: destinationTokenAddress ?? "",
28177
- destinationChainId: destinationChainId ?? "",
28178
- destinationChainType: destinationChainType ?? "",
28179
- onTransferSuccess: (result) => {
28180
- onDepositSuccess?.({
28181
- message: "Transfer completed via Coinbase Connect",
28182
- transaction: result
28183
- });
28184
- },
28185
- onTransferError: (error) => {
28186
- onDepositError?.({
28187
- message: error.message,
28188
- error
28189
- });
28190
- },
28191
- onBack: handleBack,
28192
- onClose: handleClose,
28193
- onDisconnect: handleExchangeDisconnect,
28194
- skipToHoldings: coinbaseSkipToHoldings,
28195
- canGoBack: sessionOpenedFromMenu,
28196
- onExecutionsChange: setDepositExecutions,
28197
- defaultSourceChainType,
28198
- defaultSourceChainId,
28199
- defaultSourceTokenAddress,
28200
- defaultSourceSymbol
28201
- }
28202
- ),
28203
- depositPoweredByFooter
28204
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28205
- /* @__PURE__ */ jsx55(
28206
- WalletConnect,
28207
- {
28208
- walletInfo: browserWalletInfo ?? void 0,
28209
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
28210
- wallets,
28211
- userId,
28212
- publishableKey,
28213
- assetCdnUrl: projectConfig?.asset_cdn_url,
28214
- projectName: projectConfig?.project_name,
28215
- onSuccess: (txHash) => {
28216
- onDepositSuccess?.({
28217
- message: "Transaction sent successfully",
28218
- transaction: { txHash }
28219
- });
28220
- },
28221
- onError: (error) => {
28222
- onDepositError?.({
28223
- message: error.message,
28224
- error
28225
- });
28226
- },
28227
- onDepositSuccess,
28228
- onDepositError,
28229
- amountQuickSelect: browserWalletAmountQuickSelect,
28230
- onWalletDisconnect: handleWalletDisconnect,
28231
- onWalletConnected: (info, dw) => {
28232
- setBrowserWalletInfo({ ...info, depositWallet: dw });
28233
- setStoredWalletState(info.type);
28234
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28235
- },
28236
- onBack: handleBack,
28237
- onClose: handleClose,
28238
- defaultSourceChainType,
28239
- defaultSourceChainId,
28240
- defaultSourceTokenAddress,
28241
- defaultSourceSymbol,
28242
- canGoBack: sessionOpenedFromMenu,
28243
- depositWalletsLoading: walletsLoading
28244
- }
28245
- ),
28246
- depositPoweredByFooter
28247
- ] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28248
- /* @__PURE__ */ jsx55(
28249
- DepositHeader,
28250
- {
28251
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
28252
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
28253
- onBack: handleBack,
28254
- onClose: handleClose
28255
- }
28256
- ),
28257
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28878
+ ] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28258
28879
  /* @__PURE__ */ jsx55(
28259
- PayWithCashApp,
28880
+ DepositHeader,
28260
28881
  {
28261
- userId,
28262
- publishableKey,
28263
- recipientAddress,
28264
- destinationChainType,
28265
- destinationChainId,
28266
- destinationTokenAddress,
28267
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
28268
- view: cashAppView,
28269
- onViewChange: setCashAppView,
28270
- onAmountChange: setCashAppAmount,
28271
- onEvent,
28272
- onDepositSuccess,
28273
- onDepositError
28882
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
28883
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
28884
+ onBack: handleBack,
28885
+ onClose: handleClose
28274
28886
  }
28275
28887
  ),
28276
- depositPoweredByFooter
28277
- ] })
28278
- ] }) : null })
28888
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28889
+ /* @__PURE__ */ jsx55(
28890
+ PayWithCashApp,
28891
+ {
28892
+ userId,
28893
+ publishableKey,
28894
+ recipientAddress,
28895
+ destinationChainType,
28896
+ destinationChainId,
28897
+ destinationTokenAddress,
28898
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
28899
+ view: cashAppView,
28900
+ onViewChange: setCashAppView,
28901
+ onAmountChange: setCashAppAmount,
28902
+ onEvent,
28903
+ onDepositSuccess,
28904
+ onDepositError
28905
+ }
28906
+ ),
28907
+ depositPoweredByFooter
28908
+ ] })
28909
+ ] }) : null })
28910
+ ]
28279
28911
  }
28280
28912
  )
28281
28913
  }
@@ -28294,7 +28926,7 @@ function usePaymentIntent(params) {
28294
28926
  enabled = true,
28295
28927
  pollingInterval = 3e3
28296
28928
  } = params;
28297
- return useQuery13({
28929
+ return useQuery14({
28298
28930
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
28299
28931
  queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
28300
28932
  enabled: enabled && !!clientSecret && !!publishableKey,
@@ -28360,7 +28992,6 @@ function CheckoutModal({
28360
28992
  const [browserWalletInfo, setBrowserWalletInfo] = useState33(null);
28361
28993
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState33(false);
28362
28994
  const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletState()?.chainType);
28363
- const isMobileView = useIsMobileViewport();
28364
28995
  const [resolvedTheme, setResolvedTheme] = useState33(
28365
28996
  theme === "auto" ? "dark" : theme
28366
28997
  );
@@ -28786,7 +29417,7 @@ function CheckoutModal({
28786
29417
  featuredTokens: projectConfig?.transfer_crypto.networks
28787
29418
  }
28788
29419
  ),
28789
- showConnectWallet && !isMobileView && /* @__PURE__ */ jsx56(
29420
+ showConnectWallet && /* @__PURE__ */ jsx56(
28790
29421
  BrowserWalletButton,
28791
29422
  {
28792
29423
  onClick: handleBrowserWalletClick,
@@ -28947,7 +29578,7 @@ function CheckoutModal({
28947
29578
  ) }) });
28948
29579
  }
28949
29580
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
28950
- return useQuery14({
29581
+ return useQuery15({
28951
29582
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
28952
29583
  queryFn: () => getSupportedDestinationTokens(publishableKey),
28953
29584
  staleTime: 1e3 * 60 * 5,
@@ -28982,7 +29613,7 @@ function useSourceTokenValidation(params) {
28982
29613
  enabled = true
28983
29614
  } = params;
28984
29615
  const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
28985
- return useQuery15({
29616
+ return useQuery16({
28986
29617
  queryKey: [
28987
29618
  "unifold",
28988
29619
  "sourceTokenValidation",
@@ -29038,7 +29669,7 @@ function useAddressBalance(params) {
29038
29669
  enabled = true
29039
29670
  } = params;
29040
29671
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
29041
- return useQuery16({
29672
+ return useQuery17({
29042
29673
  queryKey: [
29043
29674
  "unifold",
29044
29675
  "addressBalance",
@@ -29087,7 +29718,7 @@ function useAddressBalance(params) {
29087
29718
  }
29088
29719
  function useExecutions(userId, publishableKey, options) {
29089
29720
  const actionType = options?.actionType ?? ActionType.Deposit;
29090
- return useQuery17({
29721
+ return useQuery18({
29091
29722
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
29092
29723
  queryFn: () => queryExecutions(userId, publishableKey, actionType),
29093
29724
  enabled: (options?.enabled ?? true) && !!userId,
@@ -29370,7 +30001,7 @@ function useVerifyRecipientAddress(params) {
29370
30001
  } = params;
29371
30002
  const trimmedAddress = recipientAddress?.trim() || "";
29372
30003
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
29373
- return useQuery18({
30004
+ return useQuery19({
29374
30005
  queryKey: [
29375
30006
  "unifold",
29376
30007
  "verifyRecipientAddress",
@@ -29397,9 +30028,6 @@ function useVerifyRecipientAddress(params) {
29397
30028
  refetchOnWindowFocus: false
29398
30029
  });
29399
30030
  }
29400
- function isHypercoreChain(chainId) {
29401
- return chainId === HYPERCORE_CHAIN_ID;
29402
- }
29403
30031
  function useGetDepositAddress(params) {
29404
30032
  const {
29405
30033
  userId,
@@ -29412,7 +30040,7 @@ function useGetDepositAddress(params) {
29412
30040
  enabled = true
29413
30041
  } = params;
29414
30042
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
29415
- return useQuery19({
30043
+ return useQuery20({
29416
30044
  queryKey: [
29417
30045
  "unifold",
29418
30046
  "getDepositAddress",
@@ -30326,8 +30954,6 @@ function WithdrawConfirmingView({
30326
30954
  className: "uf-text-sm uf-text-center",
30327
30955
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
30328
30956
  children: [
30329
- txInfo.amount,
30330
- " ",
30331
30957
  txInfo.sourceTokenSymbol,
30332
30958
  " to",
30333
30959
  " ",
@@ -30695,6 +31321,16 @@ function UnifoldProvider2({
30695
31321
  });
30696
31322
  promise.catch(() => {
30697
31323
  });
31324
+ if (!config2.recipientAddress) {
31325
+ const error = {
31326
+ message: "beginDeposit requires a `recipientAddress`.",
31327
+ code: "MISSING_RECIPIENT"
31328
+ };
31329
+ console.error(`[UnifoldProvider] ${error.message}`);
31330
+ depositPromiseRef.current.reject(error);
31331
+ depositPromiseRef.current = null;
31332
+ return promise;
31333
+ }
30698
31334
  setDepositConfig(config2);
30699
31335
  setIsOpen(true);
30700
31336
  return promise;
@@ -30961,6 +31597,7 @@ function UnifoldProvider2({
30961
31597
  hideDepositTracker: config?.hideDepositTracker,
30962
31598
  showBalanceHeader: config?.showBalanceHeader,
30963
31599
  transferInputVariant: config?.transferInputVariant,
31600
+ displayMode: config?.displayMode,
30964
31601
  enableTransferCrypto: config?.enableTransferCrypto,
30965
31602
  enableConnectWallet: config?.enableConnectWallet,
30966
31603
  enablePayWithExchange: config?.enablePayWithExchange,