@unifold/connect-react 0.1.63 → 0.1.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6624,6 +6624,40 @@ async function getAddressBalances(address, chainType, publishableKey) {
6624
6624
  const data = await response.json();
6625
6625
  return data;
6626
6626
  }
6627
+ async function getExternalWallets(publishableKey) {
6628
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6629
+ validatePublishableKey(pk);
6630
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets`, {
6631
+ method: "GET",
6632
+ headers: {
6633
+ accept: "application/json",
6634
+ "x-publishable-key": pk
6635
+ }
6636
+ });
6637
+ if (!response.ok) {
6638
+ throw new Error(`Failed to fetch external wallets: ${response.statusText}`);
6639
+ }
6640
+ const data = await response.json();
6641
+ return data;
6642
+ }
6643
+ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey) {
6644
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6645
+ validatePublishableKey(pk);
6646
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets/mobile_deeplink`, {
6647
+ method: "POST",
6648
+ headers: {
6649
+ "Content-Type": "application/json",
6650
+ accept: "application/json",
6651
+ "x-publishable-key": pk
6652
+ },
6653
+ body: JSON.stringify({ wallet, deposit_addresses: depositAddresses })
6654
+ });
6655
+ if (!response.ok) {
6656
+ throw new Error(`Failed to generate wallet deep link: ${response.statusText}`);
6657
+ }
6658
+ const data = await response.json();
6659
+ return data;
6660
+ }
6627
6661
  async function getAddressBalance(address, chainType, chainId, tokenAddress, publishableKey) {
6628
6662
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6629
6663
  validatePublishableKey(pk);
@@ -13466,6 +13500,7 @@ var import_jsx_runtime64 = require("react/jsx-runtime");
13466
13500
  var import_jsx_runtime65 = require("react/jsx-runtime");
13467
13501
  var React302 = __toESM(require("react"), 1);
13468
13502
  var import_react_query14 = require("@tanstack/react-query");
13503
+ var import_react_query15 = require("@tanstack/react-query");
13469
13504
  var import_jsx_runtime66 = require("react/jsx-runtime");
13470
13505
  var import_jsx_runtime67 = require("react/jsx-runtime");
13471
13506
  var import_jsx_runtime68 = require("react/jsx-runtime");
@@ -13475,19 +13510,19 @@ var import_jsx_runtime70 = require("react/jsx-runtime");
13475
13510
  var import_jsx_runtime71 = require("react/jsx-runtime");
13476
13511
  var import_jsx_runtime72 = require("react/jsx-runtime");
13477
13512
  var import_react28 = require("react");
13478
- var import_react_query15 = require("@tanstack/react-query");
13513
+ var import_react_query16 = require("@tanstack/react-query");
13479
13514
  var import_jsx_runtime73 = require("react/jsx-runtime");
13480
13515
  var import_react29 = require("react");
13481
- var import_react_query16 = require("@tanstack/react-query");
13482
13516
  var import_react_query17 = require("@tanstack/react-query");
13483
13517
  var import_react_query18 = require("@tanstack/react-query");
13484
13518
  var import_react_query19 = require("@tanstack/react-query");
13519
+ var import_react_query20 = require("@tanstack/react-query");
13485
13520
  var import_react30 = require("react");
13486
13521
  var import_jsx_runtime74 = require("react/jsx-runtime");
13487
13522
  var import_react31 = require("react");
13488
- var import_react_query20 = require("@tanstack/react-query");
13489
- var import_react32 = require("react");
13490
13523
  var import_react_query21 = require("@tanstack/react-query");
13524
+ var import_react32 = require("react");
13525
+ var import_react_query22 = require("@tanstack/react-query");
13491
13526
  var import_jsx_runtime75 = require("react/jsx-runtime");
13492
13527
  var import_jsx_runtime76 = require("react/jsx-runtime");
13493
13528
  var import_react33 = require("react");
@@ -13931,6 +13966,36 @@ function ThemeProvider({
13931
13966
  );
13932
13967
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ThemeContext.Provider, { value: contextValue, children });
13933
13968
  }
13969
+ function AccentColorOverride({
13970
+ accentColor,
13971
+ accentForeground,
13972
+ children
13973
+ }) {
13974
+ const parent = useTheme();
13975
+ const value = React37.useMemo(() => {
13976
+ if (!accentColor) return parent;
13977
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
13978
+ const nextColors = {
13979
+ ...parent.colors,
13980
+ primary: accentColor,
13981
+ primaryForeground: foreground
13982
+ };
13983
+ const nextComponents = {
13984
+ ...parent.components,
13985
+ button: {
13986
+ ...parent.components.button,
13987
+ primaryBackground: accentColor,
13988
+ primaryText: foreground
13989
+ },
13990
+ card: {
13991
+ ...parent.components.card,
13992
+ iconBackgroundColor: `${accentColor}26`
13993
+ }
13994
+ };
13995
+ return { ...parent, colors: nextColors, components: nextComponents };
13996
+ }, [parent, accentColor, accentForeground]);
13997
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ThemeContext.Provider, { value, children });
13998
+ }
13934
13999
  function useTheme() {
13935
14000
  const context = React37.useContext(ThemeContext);
13936
14001
  if (!context) {
@@ -14982,6 +15047,7 @@ function useDepositPolling({
14982
15047
  clientSecret,
14983
15048
  depositConfirmationMode = "auto_ui",
14984
15049
  depositWalletId,
15050
+ depositWalletIds,
14985
15051
  enabled = true,
14986
15052
  immediateDirectPolling = false,
14987
15053
  onDepositSuccess,
@@ -15127,21 +15193,25 @@ function useDepositPolling({
15127
15193
  setIsPolling(false);
15128
15194
  };
15129
15195
  }, [userId, publishableKey, clientSecret, enabled]);
15196
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
15130
15197
  (0, import_react12.useEffect)(() => {
15131
- if (!pollingEnabled || !depositWalletId) return;
15198
+ if (!pollingEnabled || !pollWalletIdsKey) return;
15199
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
15132
15200
  const triggerPoll = async () => {
15133
- try {
15134
- await pollDirectExecutions(
15135
- { deposit_wallet_id: depositWalletId },
15136
- publishableKey
15137
- );
15138
- } catch {
15139
- }
15201
+ await Promise.all(
15202
+ ids.map(
15203
+ (id) => pollDirectExecutions(
15204
+ { deposit_wallet_id: id },
15205
+ publishableKey
15206
+ ).catch(() => {
15207
+ })
15208
+ )
15209
+ );
15140
15210
  };
15141
15211
  triggerPoll();
15142
15212
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
15143
15213
  return () => clearInterval(interval);
15144
- }, [pollingEnabled, depositWalletId, publishableKey]);
15214
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
15145
15215
  const handleIveDeposited = () => {
15146
15216
  setPollingEnabled(true);
15147
15217
  setShowWaitingUi(true);
@@ -16330,6 +16400,7 @@ function BuyWithCard({
16330
16400
  if (!selectedProvider) return "0.000000";
16331
16401
  return selectedProvider.destination_amount.toFixed(6);
16332
16402
  };
16403
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
16333
16404
  const selectedCurrencyData = fiatCurrencies.find(
16334
16405
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
16335
16406
  );
@@ -16515,9 +16586,12 @@ function BuyWithCard({
16515
16586
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
16516
16587
  "button",
16517
16588
  {
16518
- onClick: () => handleViewChange("quotes"),
16589
+ onClick: () => {
16590
+ if (canOpenProviderSelector) handleViewChange("quotes");
16591
+ },
16519
16592
  disabled: quotesLoading || quotes.length === 0,
16520
- 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",
16593
+ "aria-disabled": !canOpenProviderSelector,
16594
+ 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"}`,
16521
16595
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
16522
16596
  children: quotesLoading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
16523
16597
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
@@ -16544,7 +16618,7 @@ function BuyWithCard({
16544
16618
  )
16545
16619
  ] })
16546
16620
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "uf-w-full uf-text-left", children: [
16547
- isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
16621
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
16548
16622
  "div",
16549
16623
  {
16550
16624
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -16580,7 +16654,7 @@ function BuyWithCard({
16580
16654
  ),
16581
16655
  selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
16582
16656
  ] }),
16583
- quotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
16657
+ canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
16584
16658
  ChevronRight,
16585
16659
  {
16586
16660
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -25556,6 +25630,60 @@ function useDepositQuote(params) {
25556
25630
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 5e3)
25557
25631
  });
25558
25632
  }
25633
+ function useExternalWallets({
25634
+ publishableKey,
25635
+ enabled = true
25636
+ }) {
25637
+ const { data: wallets = [], isLoading } = (0, import_react_query15.useQuery)({
25638
+ queryKey: ["unifold", "external-wallets", publishableKey],
25639
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
25640
+ enabled: enabled && !!publishableKey,
25641
+ staleTime: 1e3 * 60 * 30,
25642
+ refetchOnMount: false,
25643
+ refetchOnWindowFocus: false
25644
+ });
25645
+ return { wallets, isLoading };
25646
+ }
25647
+ var WALLET_BRAND_COLORS = {
25648
+ phantom: "#AB9FF2",
25649
+ metamask: "#F6851B",
25650
+ coinbase: "#0052FF",
25651
+ trust: "#3375BB",
25652
+ rainbow: "#5B6CFF",
25653
+ rabby: "#7084FF",
25654
+ okx: "#000000"
25655
+ };
25656
+ function normalizeWalletId(type) {
25657
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
25658
+ }
25659
+ function getWalletBrandColor(type, mode = "dark") {
25660
+ if (!type) return void 0;
25661
+ const id = normalizeWalletId(type);
25662
+ const color = WALLET_BRAND_COLORS[id];
25663
+ if (!color) return void 0;
25664
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
25665
+ return color;
25666
+ }
25667
+ function getContrastingTextColor(hex) {
25668
+ const c = hex.replace("#", "");
25669
+ if (c.length !== 6) return "#FFFFFF";
25670
+ const r2 = parseInt(c.slice(0, 2), 16);
25671
+ const g = parseInt(c.slice(2, 4), 16);
25672
+ const b = parseInt(c.slice(4, 6), 16);
25673
+ const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
25674
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
25675
+ }
25676
+ function isMobileDevice() {
25677
+ if (typeof navigator === "undefined") return false;
25678
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
25679
+ }
25680
+ function getMobilePlatform() {
25681
+ if (typeof navigator === "undefined") return null;
25682
+ const ua = navigator.userAgent;
25683
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
25684
+ if (/android/i.test(ua)) return "android";
25685
+ return null;
25686
+ }
25559
25687
  var WALLET_ICONS = {
25560
25688
  metamask: MetamaskIcon,
25561
25689
  phantom: PhantomIcon,
@@ -26561,18 +26689,33 @@ var WALLET_ICONS3 = {
26561
26689
  backpack: BackpackIcon,
26562
26690
  glow: GlowIcon
26563
26691
  };
26564
- var WALLET_DEFINITIONS = [
26565
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
26566
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
26567
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
26568
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
26569
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
26570
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
26571
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
26572
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
26573
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
26574
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
26692
+ var FALLBACK_WALLET_DEFINITIONS = [
26693
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
26694
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
26695
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
26696
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
26697
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
26698
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
26699
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
26575
26700
  ];
26701
+ function getMobileInstallUrl(walletId, defaultUrl) {
26702
+ if (!isMobileDevice()) return defaultUrl;
26703
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
26704
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
26705
+ const stores = {
26706
+ rabby: {
26707
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
26708
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
26709
+ },
26710
+ glow: {
26711
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
26712
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
26713
+ }
26714
+ };
26715
+ const entry = stores[walletId];
26716
+ if (!entry) return defaultUrl;
26717
+ return isIOS ? entry.ios : entry.android;
26718
+ }
26576
26719
  function normalizeTokenAddress(address) {
26577
26720
  const normalized = (address ?? "").toLowerCase();
26578
26721
  if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
@@ -26608,7 +26751,7 @@ function getLegacyEvmProviders() {
26608
26751
  okxEthereum: win.okxwallet
26609
26752
  };
26610
26753
  }
26611
- function detectAvailableWallets(filterChainType) {
26754
+ function detectAvailableWallets(definitions, filterChainType) {
26612
26755
  const solProviders = getSolanaProviders();
26613
26756
  const legacyEvm = getLegacyEvmProviders();
26614
26757
  const eip6963List = getEip6963Providers();
@@ -26634,7 +26777,7 @@ function detectAvailableWallets(filterChainType) {
26634
26777
  return false;
26635
26778
  }
26636
26779
  });
26637
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26780
+ return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26638
26781
  let isInstalled = false;
26639
26782
  const detectedNetworks = [];
26640
26783
  switch (wallet.id) {
@@ -26738,7 +26881,7 @@ function WalletConnect({
26738
26881
  depositWalletsLoading = false,
26739
26882
  onExecutionsChange
26740
26883
  }) {
26741
- const { colors: colors2, fonts, components } = useTheme();
26884
+ const { colors: colors2, fonts, components, mode } = useTheme();
26742
26885
  const walletProvidedAtMount = React302.useRef(!!initialWalletInfo && !!initialDepositWallet);
26743
26886
  const [activeWalletInfo, setActiveWalletInfo] = React302.useState(initialWalletInfo ?? null);
26744
26887
  const [activeDepositWallet, setActiveDepositWallet] = React302.useState(initialDepositWallet ?? null);
@@ -26762,7 +26905,37 @@ function WalletConnect({
26762
26905
  setEip6963ProviderCount(providers.length);
26763
26906
  });
26764
26907
  }, []);
26765
- const availableWallets = React302.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
26908
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
26909
+ const walletDefinitions = React302.useMemo(
26910
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
26911
+ id: w.id,
26912
+ name: w.name,
26913
+ networks: w.chain_types,
26914
+ installUrl: w.install_url,
26915
+ supportsMobileBrowse: w.supports_mobile_browse,
26916
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
26917
+ })) : FALLBACK_WALLET_DEFINITIONS,
26918
+ [backendWallets]
26919
+ );
26920
+ const availableWallets = React302.useMemo(
26921
+ () => detectAvailableWallets(walletDefinitions),
26922
+ [walletDefinitions, eip6963ProviderCount]
26923
+ );
26924
+ const [isMobile, setIsMobile] = React302.useState(false);
26925
+ React302.useEffect(() => {
26926
+ setIsMobile(isMobileDevice());
26927
+ }, []);
26928
+ const mobileDepositAddresses = React302.useMemo(
26929
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
26930
+ [depositWallets]
26931
+ );
26932
+ const mobileDepositWalletIds = React302.useMemo(
26933
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
26934
+ [depositWallets]
26935
+ );
26936
+ const [mobileRedirect, setMobileRedirect] = React302.useState(null);
26937
+ const [pendingMobileWallet, setPendingMobileWallet] = React302.useState(null);
26938
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React302.useState(false);
26766
26939
  React302.useEffect(() => {
26767
26940
  if (!standalone || autoResolved || detectingWallet) return;
26768
26941
  if (!detectedWallet) {
@@ -26821,9 +26994,36 @@ function WalletConnect({
26821
26994
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
26822
26995
  transition: "opacity 150ms ease, transform 150ms ease"
26823
26996
  };
26824
- const handleWalletClick = (wallet) => {
26997
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
26998
+ try {
26999
+ const res = await getWalletMobileDeepLink(
27000
+ wallet.id,
27001
+ depositAddresses,
27002
+ publishableKey
27003
+ );
27004
+ if (res.deeplink) {
27005
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
27006
+ setAwaitingMobileDeposit(true);
27007
+ transitionTo("mobile_redirect");
27008
+ window.location.href = res.deeplink;
27009
+ return true;
27010
+ }
27011
+ } catch {
27012
+ }
27013
+ return false;
27014
+ };
27015
+ const handleWalletClick = async (wallet) => {
26825
27016
  if (!wallet.isInstalled) {
26826
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
27017
+ const platform2 = getMobilePlatform();
27018
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform2 ?? "");
27019
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
27020
+ if (mobileDepositAddresses.length === 0) {
27021
+ setPendingMobileWallet(wallet);
27022
+ return;
27023
+ }
27024
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
27025
+ }
27026
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
26827
27027
  return;
26828
27028
  }
26829
27029
  setSelectedWalletDef(wallet);
@@ -26839,6 +27039,27 @@ function WalletConnect({
26839
27039
  if (!selectedWalletDef) return;
26840
27040
  handleConnectWallet(selectedWalletDef, network);
26841
27041
  };
27042
+ React302.useEffect(() => {
27043
+ if (!pendingMobileWallet) return;
27044
+ if (mobileDepositAddresses.length > 0) {
27045
+ const wallet = pendingMobileWallet;
27046
+ setPendingMobileWallet(null);
27047
+ void (async () => {
27048
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
27049
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
27050
+ }
27051
+ })();
27052
+ return;
27053
+ }
27054
+ const timeout = setTimeout(() => {
27055
+ setPendingMobileWallet((current) => {
27056
+ if (!current) return null;
27057
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
27058
+ return null;
27059
+ });
27060
+ }, 8e3);
27061
+ return () => clearTimeout(timeout);
27062
+ }, [pendingMobileWallet, mobileDepositAddresses]);
26842
27063
  const handleConnectWallet = async (wallet, network) => {
26843
27064
  setConnectingNetwork(network);
26844
27065
  transitionTo("connecting");
@@ -26983,14 +27204,32 @@ function WalletConnect({
26983
27204
  userId,
26984
27205
  publishableKey,
26985
27206
  clientSecret,
27207
+ // In-tab flow: poll the single connected deposit wallet.
26986
27208
  depositWalletId: activeDepositWallet?.id ?? "",
26987
- enabled: hasSignedTransaction && !!activeDepositWallet,
27209
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
27210
+ // chain's deposit wallet. Detection still happens via the single /query by
27211
+ // external_user_id, which already spans all chains.
27212
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
27213
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
26988
27214
  onDepositSuccess,
26989
27215
  onDepositError
26990
27216
  });
26991
27217
  React302.useEffect(() => {
26992
27218
  onExecutionsChange?.(depositExecutions);
26993
27219
  }, [depositExecutions, onExecutionsChange]);
27220
+ const latestDepositExecution = React302.useMemo(() => {
27221
+ if (depositExecutions.length === 0) return null;
27222
+ return [...depositExecutions].sort((a, b) => {
27223
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
27224
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
27225
+ return tb - ta;
27226
+ })[0];
27227
+ }, [depositExecutions]);
27228
+ React302.useEffect(() => {
27229
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
27230
+ transitionTo("mobile_deposit_status");
27231
+ }
27232
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
26994
27233
  React302.useEffect(() => {
26995
27234
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
26996
27235
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -27121,6 +27360,16 @@ function WalletConnect({
27121
27360
  setSelectedWalletDef(null);
27122
27361
  setConnectingNetwork(null);
27123
27362
  break;
27363
+ case "mobile_redirect":
27364
+ transitionTo("select_wallet");
27365
+ setMobileRedirect(null);
27366
+ setAwaitingMobileDeposit(false);
27367
+ break;
27368
+ case "mobile_deposit_status":
27369
+ transitionTo("select_wallet");
27370
+ setMobileRedirect(null);
27371
+ setAwaitingMobileDeposit(false);
27372
+ break;
27124
27373
  case "select_token":
27125
27374
  if (walletProvidedAtMount.current) parentOnBack?.();
27126
27375
  else transitionTo("select_wallet");
@@ -27306,33 +27555,40 @@ function WalletConnect({
27306
27555
  return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { style: viewTransitionStyle, children: [
27307
27556
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
27308
27557
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-pb-4", children: [
27309
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Select a wallet to connect" }),
27310
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
27311
- "button",
27312
- {
27313
- onClick: () => handleWalletClick(wallet),
27314
- disabled: isWalletConnecting,
27315
- 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",
27316
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
27317
- children: [
27318
- /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27319
- WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
27320
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
27321
- ] }),
27322
- wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Detected" }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
27323
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
27324
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
27325
- ] })
27326
- ]
27327
- },
27328
- wallet.id
27329
- )) }),
27558
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: isMobile ? "Open this page in your wallet's app to connect" : "Select a wallet to connect" }),
27559
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
27560
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
27561
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
27562
+ const isPending = pendingMobileWallet?.id === wallet.id;
27563
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
27564
+ "button",
27565
+ {
27566
+ onClick: () => void handleWalletClick(wallet),
27567
+ disabled: isWalletConnecting || !!pendingMobileWallet,
27568
+ 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",
27569
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
27570
+ children: [
27571
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27572
+ WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
27573
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
27574
+ ] }),
27575
+ isPending ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin", style: { color: colors2.primary } }) : wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Detected" }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
27576
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
27577
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
27578
+ ] })
27579
+ ]
27580
+ },
27581
+ wallet.id
27582
+ );
27583
+ }) }),
27330
27584
  walletError && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
27331
27585
  ] })
27332
27586
  ] });
27333
27587
  }
27588
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
27589
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
27334
27590
  if (view === "select_network" && selectedWalletDef) {
27335
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { style: viewTransitionStyle, children: [
27591
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { style: viewTransitionStyle, children: [
27336
27592
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
27337
27593
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-pb-4", children: [
27338
27594
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -27362,10 +27618,10 @@ function WalletConnect({
27362
27618
  )) }),
27363
27619
  walletError && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
27364
27620
  ] })
27365
- ] });
27621
+ ] }) });
27366
27622
  }
27367
27623
  if (view === "connecting") {
27368
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { style: viewTransitionStyle, children: [
27624
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { style: viewTransitionStyle, children: [
27369
27625
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
27370
27626
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
27371
27627
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(LoaderCircle, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -27376,24 +27632,132 @@ function WalletConnect({
27376
27632
  ] }),
27377
27633
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: "Please approve the connection in your wallet" })
27378
27634
  ] })
27379
- ] });
27635
+ ] }) });
27636
+ }
27637
+ if (view === "mobile_redirect" && mobileRedirect) {
27638
+ const Icon22 = WALLET_ICONS3[mobileRedirect.walletId];
27639
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { style: viewTransitionStyle, children: [
27640
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
27641
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-px-6 uf-py-10", children: [
27642
+ Icon22 ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Icon22, { size: 64, className: "uf-rounded-2xl uf-mb-5" }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-w-16 uf-h-16 uf-rounded-2xl uf-bg-gray-500 uf-mb-5" }),
27643
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
27644
+ "div",
27645
+ {
27646
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
27647
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
27648
+ children: [
27649
+ "Continue in ",
27650
+ mobileRedirect.walletName
27651
+ ]
27652
+ }
27653
+ ),
27654
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
27655
+ "div",
27656
+ {
27657
+ className: "uf-text-sm uf-text-center uf-mb-6",
27658
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
27659
+ children: [
27660
+ "Complete your deposit in the ",
27661
+ mobileRedirect.walletName,
27662
+ " app"
27663
+ ]
27664
+ }
27665
+ ),
27666
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
27667
+ "button",
27668
+ {
27669
+ type: "button",
27670
+ onClick: () => {
27671
+ window.location.href = mobileRedirect.deeplink;
27672
+ },
27673
+ 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",
27674
+ style: {
27675
+ backgroundColor: components.card.backgroundColor,
27676
+ borderRadius: components.card.borderRadius,
27677
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
27678
+ color: components.card.titleColor,
27679
+ fontFamily: fonts.medium
27680
+ },
27681
+ children: [
27682
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ExternalLink, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
27683
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { className: "uf-text-sm uf-font-medium", children: [
27684
+ "Open in ",
27685
+ mobileRedirect.walletName
27686
+ ] })
27687
+ ]
27688
+ }
27689
+ ),
27690
+ awaitingMobileDeposit && /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
27691
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
27692
+ LoaderCircle,
27693
+ {
27694
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
27695
+ style: { color: colors2.foregroundMuted }
27696
+ }
27697
+ ),
27698
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
27699
+ "span",
27700
+ {
27701
+ className: "uf-text-sm",
27702
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
27703
+ children: "Checking for deposit..."
27704
+ }
27705
+ )
27706
+ ] })
27707
+ ] })
27708
+ ] }) });
27709
+ }
27710
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
27711
+ const isComplete = latestDepositExecution.status === ExecutionStatus.SUCCEEDED;
27712
+ const isFailed = latestDepositExecution.status === ExecutionStatus.FAILED;
27713
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
27714
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { style: viewTransitionStyle, children: [
27715
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
27716
+ DepositHeader,
27717
+ {
27718
+ title,
27719
+ showBack: false,
27720
+ onClose: isComplete && onDone ? onDone : onClose
27721
+ }
27722
+ ),
27723
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(DepositDetailContent, { execution: latestDepositExecution }),
27724
+ isComplete && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-4 uf-pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
27725
+ "button",
27726
+ {
27727
+ type: "button",
27728
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
27729
+ }),
27730
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
27731
+ style: {
27732
+ backgroundColor: colors2.primary,
27733
+ color: colors2.primaryForeground,
27734
+ fontFamily: fonts.medium,
27735
+ borderRadius: components.button.borderRadius,
27736
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
27737
+ },
27738
+ children: "Done"
27739
+ }
27740
+ ) })
27741
+ ] }) });
27380
27742
  }
27381
27743
  if (!hasWallet) return null;
27744
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
27745
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
27382
27746
  if (view === "select_token") {
27383
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
27384
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
27747
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
27748
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
27385
27749
  }
27386
27750
  if (view === "enter_amount" && selectedToken && selectedBalance) {
27387
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
27388
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
27751
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
27752
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
27389
27753
  }
27390
27754
  if (view === "review" && selectedToken) {
27391
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
27392
- }) }) });
27755
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
27756
+ }) }) }) });
27393
27757
  }
27394
27758
  if (view === "confirming") {
27395
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
27396
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
27759
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
27760
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
27397
27761
  }
27398
27762
  return null;
27399
27763
  }
@@ -27505,7 +27869,6 @@ function DepositModal({
27505
27869
  const [allExecutions, setAllExecutions] = (0, import_react8.useState)([]);
27506
27870
  const [selectedExecution, setSelectedExecution] = (0, import_react8.useState)(null);
27507
27871
  const [depositExecutions, setDepositExecutions] = (0, import_react8.useState)([]);
27508
- const isMobileView = useIsMobileViewport();
27509
27872
  const { projectConfig } = useProjectConfig({
27510
27873
  publishableKey,
27511
27874
  enabled: open
@@ -27901,7 +28264,7 @@ function DepositModal({
27901
28264
  open: hideOverlay || open,
27902
28265
  onOpenChange: hideOverlay ? void 0 : handleClose,
27903
28266
  modal: !hideOverlay,
27904
- children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28267
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
27905
28268
  DialogContent2,
27906
28269
  {
27907
28270
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -27910,386 +28273,389 @@ function DepositModal({
27910
28273
  style: { backgroundColor: colors2.background },
27911
28274
  onPointerDownOutside: (e) => e.preventDefault(),
27912
28275
  onInteractOutside: (e) => e.preventDefault(),
27913
- children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
27914
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
27915
- DepositHeader,
27916
- {
27917
- title: modalTitle || "Deposit",
27918
- showClose: !hideOverlay,
27919
- onClose: handleClose,
27920
- showBalance: showBalanceHeader,
27921
- balanceAddress: recipientAddress,
27922
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
27923
- balanceChainId: destinationChainId,
27924
- balanceTokenAddress: destinationTokenAddress,
27925
- projectName: projectConfig?.project_name,
27926
- publishableKey
27927
- }
27928
- ),
27929
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27930
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
27931
- showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
27932
- TransferCryptoButton,
27933
- {
27934
- onClick: () => setView("transfer"),
27935
- title: transferCryptoTitle,
27936
- subtitle: t7.transferCrypto.subtitle,
27937
- featuredTokens: projectConfig?.transfer_crypto.networks
27938
- }
27939
- ),
27940
- showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
27941
- BrowserWalletButton,
28276
+ children: [
28277
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(DialogTitle2, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
28278
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28279
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28280
+ DepositHeader,
28281
+ {
28282
+ title: modalTitle || "Deposit",
28283
+ showClose: !hideOverlay,
28284
+ onClose: handleClose,
28285
+ showBalance: showBalanceHeader,
28286
+ balanceAddress: recipientAddress,
28287
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28288
+ balanceChainId: destinationChainId,
28289
+ balanceTokenAddress: destinationTokenAddress,
28290
+ projectName: projectConfig?.project_name,
28291
+ publishableKey
28292
+ }
28293
+ ),
28294
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28295
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28296
+ showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28297
+ TransferCryptoButton,
28298
+ {
28299
+ onClick: () => setView("transfer"),
28300
+ title: transferCryptoTitle,
28301
+ subtitle: t7.transferCrypto.subtitle,
28302
+ featuredTokens: projectConfig?.transfer_crypto.networks
28303
+ }
28304
+ ),
28305
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28306
+ BrowserWalletButton,
28307
+ {
28308
+ onClick: handleBrowserWalletClick,
28309
+ onConnectClick: handleWalletConnectClick,
28310
+ onDisconnect: handleWalletDisconnect,
28311
+ chainType: browserWalletChainType,
28312
+ publishableKey,
28313
+ featuredWallets: projectConfig?.connect_wallet?.wallets
28314
+ }
28315
+ ),
28316
+ showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28317
+ DepositWithCardButton,
28318
+ {
28319
+ onClick: () => setView("card"),
28320
+ title: depositWithCardTitle,
28321
+ subtitle: t7.depositWithCard.subtitle,
28322
+ paymentNetworks: projectConfig?.payment_networks.networks
28323
+ }
28324
+ ),
28325
+ showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28326
+ PayWithExchangeButton,
28327
+ {
28328
+ onClick: () => setView("exchange"),
28329
+ title: payWithExchangeTitle,
28330
+ subtitle: t7.payWithExchange.subtitle,
28331
+ exchanges,
28332
+ loading: exchangesLoading
28333
+ }
28334
+ ),
28335
+ showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28336
+ ConnectExchangeButton,
28337
+ {
28338
+ onClick: () => {
28339
+ setCoinbaseSkipToHoldings(true);
28340
+ setView("coinbase_connect");
28341
+ },
28342
+ onDisconnect: handleExchangeDisconnect,
28343
+ title: i18n2.connectExchange.title,
28344
+ subtitle: i18n2.connectExchange.subtitle,
28345
+ exchanges: integrationExchanges,
28346
+ connectedExchange
28347
+ }
28348
+ ),
28349
+ showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28350
+ ConnectExchangeButton,
28351
+ {
28352
+ onClick: () => {
28353
+ setCoinbaseSkipToHoldings(false);
28354
+ setView("coinbase_connect");
28355
+ },
28356
+ title: i18n2.connectExchange.title,
28357
+ subtitle: i18n2.connectExchange.subtitle,
28358
+ exchanges: integrationExchanges
28359
+ }
28360
+ ),
28361
+ showCashApp && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28362
+ CashAppButton,
28363
+ {
28364
+ onClick: () => setView("cashapp"),
28365
+ title: "Pay with Cash App",
28366
+ subtitle: "Deposit via Cash App",
28367
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28368
+ }
28369
+ ),
28370
+ showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28371
+ DepositTrackerButton,
28372
+ {
28373
+ onClick: () => {
28374
+ setAllExecutions(depositExecutions);
28375
+ setView("tracker");
28376
+ },
28377
+ title: depositTrackerTitle,
28378
+ subtitle: depositTrackerSubTitle,
28379
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
28380
+ }
28381
+ )
28382
+ ] }) }),
28383
+ depositPoweredByFooter
28384
+ ] })
28385
+ ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28386
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28387
+ DepositHeader,
28388
+ {
28389
+ title: transferCryptoTitle,
28390
+ showBack: showBackTransfer,
28391
+ onBack: handleBack,
28392
+ onClose: handleClose,
28393
+ showBalance: showBalanceHeader,
28394
+ balanceAddress: recipientAddress,
28395
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28396
+ balanceChainId: destinationChainId,
28397
+ balanceTokenAddress: destinationTokenAddress,
28398
+ projectName: projectConfig?.project_name,
28399
+ publishableKey
28400
+ }
28401
+ ),
28402
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28403
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28404
+ TransferCryptoSingleInput,
27942
28405
  {
27943
- onClick: handleBrowserWalletClick,
27944
- onConnectClick: handleWalletConnectClick,
27945
- onDisconnect: handleWalletDisconnect,
27946
- chainType: browserWalletChainType,
28406
+ userId,
27947
28407
  publishableKey,
27948
- featuredWallets: projectConfig?.connect_wallet?.wallets
28408
+ recipientAddress,
28409
+ destinationChainType,
28410
+ destinationChainId,
28411
+ destinationTokenAddress,
28412
+ defaultSourceChainType,
28413
+ defaultSourceChainId,
28414
+ defaultSourceTokenAddress,
28415
+ defaultSourceSymbol,
28416
+ depositConfirmationMode,
28417
+ onExecutionsChange: setDepositExecutions,
28418
+ onDepositSuccess,
28419
+ onDepositError,
28420
+ wallets
27949
28421
  }
27950
- ),
27951
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
27952
- DepositWithCardButton,
28422
+ ) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28423
+ TransferCryptoDoubleInput,
27953
28424
  {
27954
- onClick: () => setView("card"),
27955
- title: depositWithCardTitle,
27956
- subtitle: t7.depositWithCard.subtitle,
27957
- paymentNetworks: projectConfig?.payment_networks.networks
28425
+ userId,
28426
+ publishableKey,
28427
+ recipientAddress,
28428
+ destinationChainType,
28429
+ destinationChainId,
28430
+ destinationTokenAddress,
28431
+ defaultSourceChainType,
28432
+ defaultSourceChainId,
28433
+ defaultSourceTokenAddress,
28434
+ defaultSourceSymbol,
28435
+ depositConfirmationMode,
28436
+ onExecutionsChange: setDepositExecutions,
28437
+ onDepositSuccess,
28438
+ onDepositError,
28439
+ wallets
27958
28440
  }
27959
28441
  ),
27960
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
27961
- PayWithExchangeButton,
28442
+ depositPoweredByFooter
28443
+ ] })
28444
+ ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28445
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28446
+ DepositHeader,
28447
+ {
28448
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
28449
+ showBack: showBackTracker,
28450
+ onBack: handleBack,
28451
+ onClose: handleClose
28452
+ }
28453
+ ),
28454
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28455
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28456
+ "div",
27962
28457
  {
27963
- onClick: () => setView("exchange"),
27964
- title: payWithExchangeTitle,
27965
- subtitle: t7.payWithExchange.subtitle,
27966
- exchanges,
27967
- loading: exchangesLoading
28458
+ className: "uf-text-sm",
28459
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
28460
+ children: "No deposits yet"
27968
28461
  }
27969
- ),
27970
- showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
27971
- ConnectExchangeButton,
28462
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28463
+ DepositExecutionItem,
27972
28464
  {
27973
- onClick: () => {
27974
- setCoinbaseSkipToHoldings(true);
27975
- setView("coinbase_connect");
27976
- },
27977
- onDisconnect: handleExchangeDisconnect,
27978
- title: i18n2.connectExchange.title,
27979
- subtitle: i18n2.connectExchange.subtitle,
27980
- exchanges: integrationExchanges,
27981
- connectedExchange
27982
- }
27983
- ),
27984
- showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
27985
- ConnectExchangeButton,
28465
+ execution,
28466
+ onClick: () => setSelectedExecution(execution)
28467
+ },
28468
+ execution.id
28469
+ )) }) }),
28470
+ depositPoweredByFooter
28471
+ ] })
28472
+ ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28473
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28474
+ DepositHeader,
28475
+ {
28476
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
28477
+ showBack: showBackCard,
28478
+ onBack: handleBack,
28479
+ onClose: handleClose,
28480
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
28481
+ showBalance: showBalanceHeader,
28482
+ balanceAddress: recipientAddress,
28483
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28484
+ balanceChainId: destinationChainId,
28485
+ balanceTokenAddress: destinationTokenAddress,
28486
+ projectName: projectConfig?.project_name,
28487
+ publishableKey
28488
+ }
28489
+ ),
28490
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28491
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28492
+ BuyWithCard,
27986
28493
  {
27987
- onClick: () => {
27988
- setCoinbaseSkipToHoldings(false);
27989
- setView("coinbase_connect");
27990
- },
27991
- title: i18n2.connectExchange.title,
27992
- subtitle: i18n2.connectExchange.subtitle,
27993
- exchanges: integrationExchanges
28494
+ userId,
28495
+ publishableKey,
28496
+ view: cardView,
28497
+ onViewChange: handleCardViewChange,
28498
+ destinationTokenSymbol,
28499
+ recipientAddress,
28500
+ destinationChainType,
28501
+ destinationChainId,
28502
+ destinationTokenAddress,
28503
+ onDepositSuccess,
28504
+ onDepositError,
28505
+ onEvent,
28506
+ themeClass,
28507
+ wallets,
28508
+ assetCdnUrl: projectConfig?.asset_cdn_url,
28509
+ hideDepositFlowInfo,
28510
+ hideDisplayDescription
27994
28511
  }
27995
28512
  ),
27996
- showCashApp && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
27997
- CashAppButton,
28513
+ depositPoweredByFooter
28514
+ ] })
28515
+ ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28516
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28517
+ DepositHeader,
28518
+ {
28519
+ title: payWithExchangeTitle,
28520
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
28521
+ onBack: handleBack,
28522
+ onClose: handleClose
28523
+ }
28524
+ ),
28525
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28526
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28527
+ PayWithExchange,
27998
28528
  {
27999
- onClick: () => setView("cashapp"),
28000
- title: "Pay with Cash App",
28001
- subtitle: "Deposit via Cash App",
28002
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28529
+ userId,
28530
+ publishableKey,
28531
+ exchanges,
28532
+ view: exchangeView,
28533
+ onViewChange: setExchangeView,
28534
+ destinationTokenSymbol,
28535
+ recipientAddress,
28536
+ destinationChainType,
28537
+ destinationChainId,
28538
+ destinationTokenAddress,
28539
+ onDepositSuccess,
28540
+ onDepositError,
28541
+ wallets,
28542
+ defaultToken: defaultToken ?? null
28003
28543
  }
28004
28544
  ),
28005
- showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28006
- DepositTrackerButton,
28007
- {
28008
- onClick: () => {
28009
- setAllExecutions(depositExecutions);
28010
- setView("tracker");
28011
- },
28012
- title: depositTrackerTitle,
28013
- subtitle: depositTrackerSubTitle,
28014
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
28015
- }
28016
- )
28017
- ] }) }),
28018
- depositPoweredByFooter
28019
- ] })
28020
- ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28021
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28022
- DepositHeader,
28023
- {
28024
- title: transferCryptoTitle,
28025
- showBack: showBackTransfer,
28026
- onBack: handleBack,
28027
- onClose: handleClose,
28028
- showBalance: showBalanceHeader,
28029
- balanceAddress: recipientAddress,
28030
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28031
- balanceChainId: destinationChainId,
28032
- balanceTokenAddress: destinationTokenAddress,
28033
- projectName: projectConfig?.project_name,
28034
- publishableKey
28035
- }
28036
- ),
28037
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28038
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28039
- TransferCryptoSingleInput,
28545
+ depositPoweredByFooter
28546
+ ] })
28547
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28548
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28549
+ CoinbaseConnect,
28040
28550
  {
28041
- userId,
28042
28551
  publishableKey,
28043
- recipientAddress,
28044
- destinationChainType,
28045
- destinationChainId,
28046
- destinationTokenAddress,
28047
- defaultSourceChainType,
28048
- defaultSourceChainId,
28049
- defaultSourceTokenAddress,
28050
- defaultSourceSymbol,
28051
- depositConfirmationMode,
28052
- onExecutionsChange: setDepositExecutions,
28053
- onDepositSuccess,
28054
- onDepositError,
28055
- wallets
28056
- }
28057
- ) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28058
- TransferCryptoDoubleInput,
28059
- {
28060
28552
  userId,
28061
- publishableKey,
28553
+ wallets,
28062
28554
  recipientAddress,
28063
- destinationChainType,
28064
- destinationChainId,
28065
- destinationTokenAddress,
28555
+ destinationTokenAddress: destinationTokenAddress ?? "",
28556
+ destinationChainId: destinationChainId ?? "",
28557
+ destinationChainType: destinationChainType ?? "",
28558
+ onTransferSuccess: (result) => {
28559
+ onDepositSuccess?.({
28560
+ message: "Transfer completed via Coinbase Connect",
28561
+ transaction: result
28562
+ });
28563
+ },
28564
+ onTransferError: (error) => {
28565
+ onDepositError?.({
28566
+ message: error.message,
28567
+ error
28568
+ });
28569
+ },
28570
+ onBack: handleBack,
28571
+ onClose: handleClose,
28572
+ onDisconnect: handleExchangeDisconnect,
28573
+ skipToHoldings: coinbaseSkipToHoldings,
28574
+ canGoBack: sessionOpenedFromMenu,
28575
+ onExecutionsChange: setDepositExecutions,
28066
28576
  defaultSourceChainType,
28067
28577
  defaultSourceChainId,
28068
28578
  defaultSourceTokenAddress,
28069
- defaultSourceSymbol,
28070
- depositConfirmationMode,
28071
- onExecutionsChange: setDepositExecutions,
28072
- onDepositSuccess,
28073
- onDepositError,
28074
- wallets
28579
+ defaultSourceSymbol
28075
28580
  }
28076
28581
  ),
28077
28582
  depositPoweredByFooter
28078
- ] })
28079
- ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28080
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28081
- DepositHeader,
28082
- {
28083
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
28084
- showBack: showBackTracker,
28085
- onBack: handleBack,
28086
- onClose: handleClose
28087
- }
28088
- ),
28089
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28090
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28091
- "div",
28092
- {
28093
- className: "uf-text-sm",
28094
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
28095
- children: "No deposits yet"
28096
- }
28097
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28098
- DepositExecutionItem,
28099
- {
28100
- execution,
28101
- onClick: () => setSelectedExecution(execution)
28102
- },
28103
- execution.id
28104
- )) }) }),
28105
- depositPoweredByFooter
28106
- ] })
28107
- ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28108
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28109
- DepositHeader,
28110
- {
28111
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
28112
- showBack: showBackCard,
28113
- onBack: handleBack,
28114
- onClose: handleClose,
28115
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
28116
- showBalance: showBalanceHeader,
28117
- balanceAddress: recipientAddress,
28118
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28119
- balanceChainId: destinationChainId,
28120
- balanceTokenAddress: destinationTokenAddress,
28121
- projectName: projectConfig?.project_name,
28122
- publishableKey
28123
- }
28124
- ),
28125
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28126
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28127
- BuyWithCard,
28128
- {
28129
- userId,
28130
- publishableKey,
28131
- view: cardView,
28132
- onViewChange: handleCardViewChange,
28133
- destinationTokenSymbol,
28134
- recipientAddress,
28135
- destinationChainType,
28136
- destinationChainId,
28137
- destinationTokenAddress,
28138
- onDepositSuccess,
28139
- onDepositError,
28140
- onEvent,
28141
- themeClass,
28142
- wallets,
28143
- assetCdnUrl: projectConfig?.asset_cdn_url,
28144
- hideDepositFlowInfo,
28145
- hideDisplayDescription
28146
- }
28147
- ),
28148
- depositPoweredByFooter
28149
- ] })
28150
- ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28151
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28152
- DepositHeader,
28153
- {
28154
- title: payWithExchangeTitle,
28155
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
28156
- onBack: handleBack,
28157
- onClose: handleClose
28158
- }
28159
- ),
28160
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28583
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28161
28584
  /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28162
- PayWithExchange,
28585
+ WalletConnect,
28163
28586
  {
28587
+ walletInfo: browserWalletInfo ?? void 0,
28588
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
28589
+ wallets,
28164
28590
  userId,
28165
28591
  publishableKey,
28166
- exchanges,
28167
- view: exchangeView,
28168
- onViewChange: setExchangeView,
28169
- destinationTokenSymbol,
28170
- recipientAddress,
28171
- destinationChainType,
28172
- destinationChainId,
28173
- destinationTokenAddress,
28592
+ assetCdnUrl: projectConfig?.asset_cdn_url,
28593
+ projectName: projectConfig?.project_name,
28594
+ onSuccess: (txHash) => {
28595
+ onDepositSuccess?.({
28596
+ message: "Transaction sent successfully",
28597
+ transaction: { txHash }
28598
+ });
28599
+ },
28600
+ onError: (error) => {
28601
+ onDepositError?.({
28602
+ message: error.message,
28603
+ error
28604
+ });
28605
+ },
28174
28606
  onDepositSuccess,
28175
28607
  onDepositError,
28176
- wallets,
28177
- defaultToken: defaultToken ?? null
28608
+ amountQuickSelect: browserWalletAmountQuickSelect,
28609
+ onWalletDisconnect: handleWalletDisconnect,
28610
+ onWalletConnected: (info, dw) => {
28611
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
28612
+ setStoredWalletState(info.type);
28613
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28614
+ },
28615
+ onBack: handleBack,
28616
+ onClose: handleClose,
28617
+ defaultSourceChainType,
28618
+ defaultSourceChainId,
28619
+ defaultSourceTokenAddress,
28620
+ defaultSourceSymbol,
28621
+ canGoBack: sessionOpenedFromMenu,
28622
+ depositWalletsLoading: walletsLoading
28178
28623
  }
28179
28624
  ),
28180
28625
  depositPoweredByFooter
28181
- ] })
28182
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28183
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28184
- CoinbaseConnect,
28185
- {
28186
- publishableKey,
28187
- userId,
28188
- wallets,
28189
- recipientAddress,
28190
- destinationTokenAddress: destinationTokenAddress ?? "",
28191
- destinationChainId: destinationChainId ?? "",
28192
- destinationChainType: destinationChainType ?? "",
28193
- onTransferSuccess: (result) => {
28194
- onDepositSuccess?.({
28195
- message: "Transfer completed via Coinbase Connect",
28196
- transaction: result
28197
- });
28198
- },
28199
- onTransferError: (error) => {
28200
- onDepositError?.({
28201
- message: error.message,
28202
- error
28203
- });
28204
- },
28205
- onBack: handleBack,
28206
- onClose: handleClose,
28207
- onDisconnect: handleExchangeDisconnect,
28208
- skipToHoldings: coinbaseSkipToHoldings,
28209
- canGoBack: sessionOpenedFromMenu,
28210
- onExecutionsChange: setDepositExecutions,
28211
- defaultSourceChainType,
28212
- defaultSourceChainId,
28213
- defaultSourceTokenAddress,
28214
- defaultSourceSymbol
28215
- }
28216
- ),
28217
- depositPoweredByFooter
28218
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28219
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28220
- WalletConnect,
28221
- {
28222
- walletInfo: browserWalletInfo ?? void 0,
28223
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
28224
- wallets,
28225
- userId,
28226
- publishableKey,
28227
- assetCdnUrl: projectConfig?.asset_cdn_url,
28228
- projectName: projectConfig?.project_name,
28229
- onSuccess: (txHash) => {
28230
- onDepositSuccess?.({
28231
- message: "Transaction sent successfully",
28232
- transaction: { txHash }
28233
- });
28234
- },
28235
- onError: (error) => {
28236
- onDepositError?.({
28237
- message: error.message,
28238
- error
28239
- });
28240
- },
28241
- onDepositSuccess,
28242
- onDepositError,
28243
- amountQuickSelect: browserWalletAmountQuickSelect,
28244
- onWalletDisconnect: handleWalletDisconnect,
28245
- onWalletConnected: (info, dw) => {
28246
- setBrowserWalletInfo({ ...info, depositWallet: dw });
28247
- setStoredWalletState(info.type);
28248
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28249
- },
28250
- onBack: handleBack,
28251
- onClose: handleClose,
28252
- defaultSourceChainType,
28253
- defaultSourceChainId,
28254
- defaultSourceTokenAddress,
28255
- defaultSourceSymbol,
28256
- canGoBack: sessionOpenedFromMenu,
28257
- depositWalletsLoading: walletsLoading
28258
- }
28259
- ),
28260
- depositPoweredByFooter
28261
- ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28262
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28263
- DepositHeader,
28264
- {
28265
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
28266
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
28267
- onBack: handleBack,
28268
- onClose: handleClose
28269
- }
28270
- ),
28271
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28626
+ ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28272
28627
  /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28273
- PayWithCashApp,
28628
+ DepositHeader,
28274
28629
  {
28275
- userId,
28276
- publishableKey,
28277
- recipientAddress,
28278
- destinationChainType,
28279
- destinationChainId,
28280
- destinationTokenAddress,
28281
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
28282
- view: cashAppView,
28283
- onViewChange: setCashAppView,
28284
- onAmountChange: setCashAppAmount,
28285
- onEvent,
28286
- onDepositSuccess,
28287
- onDepositError
28630
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
28631
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
28632
+ onBack: handleBack,
28633
+ onClose: handleClose
28288
28634
  }
28289
28635
  ),
28290
- depositPoweredByFooter
28291
- ] })
28292
- ] }) : null })
28636
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28637
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28638
+ PayWithCashApp,
28639
+ {
28640
+ userId,
28641
+ publishableKey,
28642
+ recipientAddress,
28643
+ destinationChainType,
28644
+ destinationChainId,
28645
+ destinationTokenAddress,
28646
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
28647
+ view: cashAppView,
28648
+ onViewChange: setCashAppView,
28649
+ onAmountChange: setCashAppAmount,
28650
+ onEvent,
28651
+ onDepositSuccess,
28652
+ onDepositError
28653
+ }
28654
+ ),
28655
+ depositPoweredByFooter
28656
+ ] })
28657
+ ] }) : null })
28658
+ ]
28293
28659
  }
28294
28660
  )
28295
28661
  }
@@ -28308,7 +28674,7 @@ function usePaymentIntent(params) {
28308
28674
  enabled = true,
28309
28675
  pollingInterval = 3e3
28310
28676
  } = params;
28311
- return (0, import_react_query15.useQuery)({
28677
+ return (0, import_react_query16.useQuery)({
28312
28678
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
28313
28679
  queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
28314
28680
  enabled: enabled && !!clientSecret && !!publishableKey,
@@ -28374,7 +28740,6 @@ function CheckoutModal({
28374
28740
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react28.useState)(null);
28375
28741
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react28.useState)(false);
28376
28742
  const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react28.useState)(() => getStoredWalletState()?.chainType);
28377
- const isMobileView = useIsMobileViewport();
28378
28743
  const [resolvedTheme, setResolvedTheme] = (0, import_react28.useState)(
28379
28744
  theme === "auto" ? "dark" : theme
28380
28745
  );
@@ -28800,7 +29165,7 @@ function CheckoutModal({
28800
29165
  featuredTokens: projectConfig?.transfer_crypto.networks
28801
29166
  }
28802
29167
  ),
28803
- showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
29168
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
28804
29169
  BrowserWalletButton,
28805
29170
  {
28806
29171
  onClick: handleBrowserWalletClick,
@@ -28961,7 +29326,7 @@ function CheckoutModal({
28961
29326
  ) }) });
28962
29327
  }
28963
29328
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
28964
- return (0, import_react_query16.useQuery)({
29329
+ return (0, import_react_query17.useQuery)({
28965
29330
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
28966
29331
  queryFn: () => getSupportedDestinationTokens(publishableKey),
28967
29332
  staleTime: 1e3 * 60 * 5,
@@ -28996,7 +29361,7 @@ function useSourceTokenValidation(params) {
28996
29361
  enabled = true
28997
29362
  } = params;
28998
29363
  const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
28999
- return (0, import_react_query17.useQuery)({
29364
+ return (0, import_react_query18.useQuery)({
29000
29365
  queryKey: [
29001
29366
  "unifold",
29002
29367
  "sourceTokenValidation",
@@ -29052,7 +29417,7 @@ function useAddressBalance(params) {
29052
29417
  enabled = true
29053
29418
  } = params;
29054
29419
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
29055
- return (0, import_react_query18.useQuery)({
29420
+ return (0, import_react_query19.useQuery)({
29056
29421
  queryKey: [
29057
29422
  "unifold",
29058
29423
  "addressBalance",
@@ -29101,7 +29466,7 @@ function useAddressBalance(params) {
29101
29466
  }
29102
29467
  function useExecutions(userId, publishableKey, options) {
29103
29468
  const actionType = options?.actionType ?? ActionType.Deposit;
29104
- return (0, import_react_query19.useQuery)({
29469
+ return (0, import_react_query20.useQuery)({
29105
29470
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
29106
29471
  queryFn: () => queryExecutions(userId, publishableKey, actionType),
29107
29472
  enabled: (options?.enabled ?? true) && !!userId,
@@ -29384,7 +29749,7 @@ function useVerifyRecipientAddress(params) {
29384
29749
  } = params;
29385
29750
  const trimmedAddress = recipientAddress?.trim() || "";
29386
29751
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
29387
- return (0, import_react_query20.useQuery)({
29752
+ return (0, import_react_query21.useQuery)({
29388
29753
  queryKey: [
29389
29754
  "unifold",
29390
29755
  "verifyRecipientAddress",
@@ -29426,7 +29791,7 @@ function useGetDepositAddress(params) {
29426
29791
  enabled = true
29427
29792
  } = params;
29428
29793
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
29429
- return (0, import_react_query21.useQuery)({
29794
+ return (0, import_react_query22.useQuery)({
29430
29795
  queryKey: [
29431
29796
  "unifold",
29432
29797
  "getDepositAddress",
@@ -30709,6 +31074,16 @@ function UnifoldProvider2({
30709
31074
  });
30710
31075
  promise.catch(() => {
30711
31076
  });
31077
+ if (!config2.recipientAddress) {
31078
+ const error = {
31079
+ message: "beginDeposit requires a `recipientAddress`.",
31080
+ code: "MISSING_RECIPIENT"
31081
+ };
31082
+ console.error(`[UnifoldProvider] ${error.message}`);
31083
+ depositPromiseRef.current.reject(error);
31084
+ depositPromiseRef.current = null;
31085
+ return promise;
31086
+ }
30712
31087
  setDepositConfig(config2);
30713
31088
  setIsOpen(true);
30714
31089
  return promise;