@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.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);
@@ -13439,6 +13473,7 @@ import { jsx as jsx47, jsxs as jsxs422 } from "react/jsx-runtime";
13439
13473
  import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
13440
13474
  import * as React302 from "react";
13441
13475
  import { useQuery as useQuery12 } from "@tanstack/react-query";
13476
+ import { useQuery as useQuery13 } from "@tanstack/react-query";
13442
13477
  import { jsx as jsx49 } from "react/jsx-runtime";
13443
13478
  import { jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
13444
13479
  import { Fragment as Fragment82, jsx as jsx51, jsxs as jsxs45 } from "react/jsx-runtime";
@@ -13455,7 +13490,7 @@ import {
13455
13490
  useRef as useRef102,
13456
13491
  useMemo as useMemo112
13457
13492
  } from "react";
13458
- import { useQuery as useQuery13 } from "@tanstack/react-query";
13493
+ import { useQuery as useQuery14 } from "@tanstack/react-query";
13459
13494
  import { Fragment as Fragment12, jsx as jsx56, jsxs as jsxs50 } from "react/jsx-runtime";
13460
13495
  import {
13461
13496
  useState as useState37,
@@ -13464,16 +13499,16 @@ import {
13464
13499
  useCallback as useCallback82,
13465
13500
  useRef as useRef122
13466
13501
  } from "react";
13467
- import { useQuery as useQuery14 } from "@tanstack/react-query";
13468
13502
  import { useQuery as useQuery15 } from "@tanstack/react-query";
13469
13503
  import { useQuery as useQuery16 } from "@tanstack/react-query";
13470
13504
  import { useQuery as useQuery17 } from "@tanstack/react-query";
13505
+ import { useQuery as useQuery18 } from "@tanstack/react-query";
13471
13506
  import { useState as useState34, useEffect as useEffect282, useRef as useRef112 } from "react";
13472
13507
  import { jsx as jsx57, jsxs as jsxs51 } from "react/jsx-runtime";
13473
13508
  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
13509
  import { useQuery as useQuery19 } from "@tanstack/react-query";
13510
+ import { useMemo as useMemo122 } from "react";
13511
+ import { useQuery as useQuery20 } from "@tanstack/react-query";
13477
13512
  import { Fragment as Fragment13, jsx as jsx58, jsxs as jsxs52 } from "react/jsx-runtime";
13478
13513
  import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
13479
13514
  import { useState as useState36, useEffect as useEffect302 } from "react";
@@ -13917,6 +13952,36 @@ function ThemeProvider({
13917
13952
  );
13918
13953
  return /* @__PURE__ */ jsx17(ThemeContext.Provider, { value: contextValue, children });
13919
13954
  }
13955
+ function AccentColorOverride({
13956
+ accentColor,
13957
+ accentForeground,
13958
+ children
13959
+ }) {
13960
+ const parent = useTheme();
13961
+ const value = React37.useMemo(() => {
13962
+ if (!accentColor) return parent;
13963
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
13964
+ const nextColors = {
13965
+ ...parent.colors,
13966
+ primary: accentColor,
13967
+ primaryForeground: foreground
13968
+ };
13969
+ const nextComponents = {
13970
+ ...parent.components,
13971
+ button: {
13972
+ ...parent.components.button,
13973
+ primaryBackground: accentColor,
13974
+ primaryText: foreground
13975
+ },
13976
+ card: {
13977
+ ...parent.components.card,
13978
+ iconBackgroundColor: `${accentColor}26`
13979
+ }
13980
+ };
13981
+ return { ...parent, colors: nextColors, components: nextComponents };
13982
+ }, [parent, accentColor, accentForeground]);
13983
+ return /* @__PURE__ */ jsx17(ThemeContext.Provider, { value, children });
13984
+ }
13920
13985
  function useTheme() {
13921
13986
  const context = React37.useContext(ThemeContext);
13922
13987
  if (!context) {
@@ -14968,6 +15033,7 @@ function useDepositPolling({
14968
15033
  clientSecret,
14969
15034
  depositConfirmationMode = "auto_ui",
14970
15035
  depositWalletId,
15036
+ depositWalletIds,
14971
15037
  enabled = true,
14972
15038
  immediateDirectPolling = false,
14973
15039
  onDepositSuccess,
@@ -15113,21 +15179,25 @@ function useDepositPolling({
15113
15179
  setIsPolling(false);
15114
15180
  };
15115
15181
  }, [userId, publishableKey, clientSecret, enabled]);
15182
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
15116
15183
  useEffect32(() => {
15117
- if (!pollingEnabled || !depositWalletId) return;
15184
+ if (!pollingEnabled || !pollWalletIdsKey) return;
15185
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
15118
15186
  const triggerPoll = async () => {
15119
- try {
15120
- await pollDirectExecutions(
15121
- { deposit_wallet_id: depositWalletId },
15122
- publishableKey
15123
- );
15124
- } catch {
15125
- }
15187
+ await Promise.all(
15188
+ ids.map(
15189
+ (id) => pollDirectExecutions(
15190
+ { deposit_wallet_id: id },
15191
+ publishableKey
15192
+ ).catch(() => {
15193
+ })
15194
+ )
15195
+ );
15126
15196
  };
15127
15197
  triggerPoll();
15128
15198
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
15129
15199
  return () => clearInterval(interval);
15130
- }, [pollingEnabled, depositWalletId, publishableKey]);
15200
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
15131
15201
  const handleIveDeposited = () => {
15132
15202
  setPollingEnabled(true);
15133
15203
  setShowWaitingUi(true);
@@ -16316,6 +16386,7 @@ function BuyWithCard({
16316
16386
  if (!selectedProvider) return "0.000000";
16317
16387
  return selectedProvider.destination_amount.toFixed(6);
16318
16388
  };
16389
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
16319
16390
  const selectedCurrencyData = fiatCurrencies.find(
16320
16391
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
16321
16392
  );
@@ -16501,9 +16572,12 @@ function BuyWithCard({
16501
16572
  /* @__PURE__ */ jsx112(
16502
16573
  "button",
16503
16574
  {
16504
- onClick: () => handleViewChange("quotes"),
16575
+ onClick: () => {
16576
+ if (canOpenProviderSelector) handleViewChange("quotes");
16577
+ },
16505
16578
  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",
16579
+ "aria-disabled": !canOpenProviderSelector,
16580
+ 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
16581
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
16508
16582
  children: quotesLoading ? /* @__PURE__ */ jsxs9("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
16509
16583
  /* @__PURE__ */ jsx112(
@@ -16530,7 +16604,7 @@ function BuyWithCard({
16530
16604
  )
16531
16605
  ] })
16532
16606
  ] }) : /* @__PURE__ */ jsxs9("div", { className: "uf-w-full uf-text-left", children: [
16533
- isAutoSelected && /* @__PURE__ */ jsx112(
16607
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ jsx112(
16534
16608
  "div",
16535
16609
  {
16536
16610
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -16566,7 +16640,7 @@ function BuyWithCard({
16566
16640
  ),
16567
16641
  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
16642
  ] }),
16569
- quotes.length > 0 && /* @__PURE__ */ jsx112(
16643
+ canOpenProviderSelector && /* @__PURE__ */ jsx112(
16570
16644
  ChevronRight,
16571
16645
  {
16572
16646
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -25542,6 +25616,60 @@ function useDepositQuote(params) {
25542
25616
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 5e3)
25543
25617
  });
25544
25618
  }
25619
+ function useExternalWallets({
25620
+ publishableKey,
25621
+ enabled = true
25622
+ }) {
25623
+ const { data: wallets = [], isLoading } = useQuery13({
25624
+ queryKey: ["unifold", "external-wallets", publishableKey],
25625
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
25626
+ enabled: enabled && !!publishableKey,
25627
+ staleTime: 1e3 * 60 * 30,
25628
+ refetchOnMount: false,
25629
+ refetchOnWindowFocus: false
25630
+ });
25631
+ return { wallets, isLoading };
25632
+ }
25633
+ var WALLET_BRAND_COLORS = {
25634
+ phantom: "#AB9FF2",
25635
+ metamask: "#F6851B",
25636
+ coinbase: "#0052FF",
25637
+ trust: "#3375BB",
25638
+ rainbow: "#5B6CFF",
25639
+ rabby: "#7084FF",
25640
+ okx: "#000000"
25641
+ };
25642
+ function normalizeWalletId(type) {
25643
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
25644
+ }
25645
+ function getWalletBrandColor(type, mode = "dark") {
25646
+ if (!type) return void 0;
25647
+ const id = normalizeWalletId(type);
25648
+ const color = WALLET_BRAND_COLORS[id];
25649
+ if (!color) return void 0;
25650
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
25651
+ return color;
25652
+ }
25653
+ function getContrastingTextColor(hex) {
25654
+ const c = hex.replace("#", "");
25655
+ if (c.length !== 6) return "#FFFFFF";
25656
+ const r2 = parseInt(c.slice(0, 2), 16);
25657
+ const g = parseInt(c.slice(2, 4), 16);
25658
+ const b = parseInt(c.slice(4, 6), 16);
25659
+ const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
25660
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
25661
+ }
25662
+ function isMobileDevice() {
25663
+ if (typeof navigator === "undefined") return false;
25664
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
25665
+ }
25666
+ function getMobilePlatform() {
25667
+ if (typeof navigator === "undefined") return null;
25668
+ const ua = navigator.userAgent;
25669
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
25670
+ if (/android/i.test(ua)) return "android";
25671
+ return null;
25672
+ }
25545
25673
  var WALLET_ICONS = {
25546
25674
  metamask: MetamaskIcon,
25547
25675
  phantom: PhantomIcon,
@@ -26547,18 +26675,33 @@ var WALLET_ICONS3 = {
26547
26675
  backpack: BackpackIcon,
26548
26676
  glow: GlowIcon
26549
26677
  };
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/" }
26678
+ var FALLBACK_WALLET_DEFINITIONS = [
26679
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
26680
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
26681
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
26682
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
26683
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
26684
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
26685
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
26561
26686
  ];
26687
+ function getMobileInstallUrl(walletId, defaultUrl) {
26688
+ if (!isMobileDevice()) return defaultUrl;
26689
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
26690
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
26691
+ const stores = {
26692
+ rabby: {
26693
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
26694
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
26695
+ },
26696
+ glow: {
26697
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
26698
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
26699
+ }
26700
+ };
26701
+ const entry = stores[walletId];
26702
+ if (!entry) return defaultUrl;
26703
+ return isIOS ? entry.ios : entry.android;
26704
+ }
26562
26705
  function normalizeTokenAddress(address) {
26563
26706
  const normalized = (address ?? "").toLowerCase();
26564
26707
  if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
@@ -26594,7 +26737,7 @@ function getLegacyEvmProviders() {
26594
26737
  okxEthereum: win.okxwallet
26595
26738
  };
26596
26739
  }
26597
- function detectAvailableWallets(filterChainType) {
26740
+ function detectAvailableWallets(definitions, filterChainType) {
26598
26741
  const solProviders = getSolanaProviders();
26599
26742
  const legacyEvm = getLegacyEvmProviders();
26600
26743
  const eip6963List = getEip6963Providers();
@@ -26620,7 +26763,7 @@ function detectAvailableWallets(filterChainType) {
26620
26763
  return false;
26621
26764
  }
26622
26765
  });
26623
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26766
+ return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26624
26767
  let isInstalled = false;
26625
26768
  const detectedNetworks = [];
26626
26769
  switch (wallet.id) {
@@ -26724,7 +26867,7 @@ function WalletConnect({
26724
26867
  depositWalletsLoading = false,
26725
26868
  onExecutionsChange
26726
26869
  }) {
26727
- const { colors: colors2, fonts, components } = useTheme();
26870
+ const { colors: colors2, fonts, components, mode } = useTheme();
26728
26871
  const walletProvidedAtMount = React302.useRef(!!initialWalletInfo && !!initialDepositWallet);
26729
26872
  const [activeWalletInfo, setActiveWalletInfo] = React302.useState(initialWalletInfo ?? null);
26730
26873
  const [activeDepositWallet, setActiveDepositWallet] = React302.useState(initialDepositWallet ?? null);
@@ -26748,7 +26891,37 @@ function WalletConnect({
26748
26891
  setEip6963ProviderCount(providers.length);
26749
26892
  });
26750
26893
  }, []);
26751
- const availableWallets = React302.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
26894
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
26895
+ const walletDefinitions = React302.useMemo(
26896
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
26897
+ id: w.id,
26898
+ name: w.name,
26899
+ networks: w.chain_types,
26900
+ installUrl: w.install_url,
26901
+ supportsMobileBrowse: w.supports_mobile_browse,
26902
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
26903
+ })) : FALLBACK_WALLET_DEFINITIONS,
26904
+ [backendWallets]
26905
+ );
26906
+ const availableWallets = React302.useMemo(
26907
+ () => detectAvailableWallets(walletDefinitions),
26908
+ [walletDefinitions, eip6963ProviderCount]
26909
+ );
26910
+ const [isMobile, setIsMobile] = React302.useState(false);
26911
+ React302.useEffect(() => {
26912
+ setIsMobile(isMobileDevice());
26913
+ }, []);
26914
+ const mobileDepositAddresses = React302.useMemo(
26915
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
26916
+ [depositWallets]
26917
+ );
26918
+ const mobileDepositWalletIds = React302.useMemo(
26919
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
26920
+ [depositWallets]
26921
+ );
26922
+ const [mobileRedirect, setMobileRedirect] = React302.useState(null);
26923
+ const [pendingMobileWallet, setPendingMobileWallet] = React302.useState(null);
26924
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React302.useState(false);
26752
26925
  React302.useEffect(() => {
26753
26926
  if (!standalone || autoResolved || detectingWallet) return;
26754
26927
  if (!detectedWallet) {
@@ -26807,9 +26980,36 @@ function WalletConnect({
26807
26980
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
26808
26981
  transition: "opacity 150ms ease, transform 150ms ease"
26809
26982
  };
26810
- const handleWalletClick = (wallet) => {
26983
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
26984
+ try {
26985
+ const res = await getWalletMobileDeepLink(
26986
+ wallet.id,
26987
+ depositAddresses,
26988
+ publishableKey
26989
+ );
26990
+ if (res.deeplink) {
26991
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
26992
+ setAwaitingMobileDeposit(true);
26993
+ transitionTo("mobile_redirect");
26994
+ window.location.href = res.deeplink;
26995
+ return true;
26996
+ }
26997
+ } catch {
26998
+ }
26999
+ return false;
27000
+ };
27001
+ const handleWalletClick = async (wallet) => {
26811
27002
  if (!wallet.isInstalled) {
26812
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
27003
+ const platform2 = getMobilePlatform();
27004
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform2 ?? "");
27005
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
27006
+ if (mobileDepositAddresses.length === 0) {
27007
+ setPendingMobileWallet(wallet);
27008
+ return;
27009
+ }
27010
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
27011
+ }
27012
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
26813
27013
  return;
26814
27014
  }
26815
27015
  setSelectedWalletDef(wallet);
@@ -26825,6 +27025,27 @@ function WalletConnect({
26825
27025
  if (!selectedWalletDef) return;
26826
27026
  handleConnectWallet(selectedWalletDef, network);
26827
27027
  };
27028
+ React302.useEffect(() => {
27029
+ if (!pendingMobileWallet) return;
27030
+ if (mobileDepositAddresses.length > 0) {
27031
+ const wallet = pendingMobileWallet;
27032
+ setPendingMobileWallet(null);
27033
+ void (async () => {
27034
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
27035
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
27036
+ }
27037
+ })();
27038
+ return;
27039
+ }
27040
+ const timeout = setTimeout(() => {
27041
+ setPendingMobileWallet((current) => {
27042
+ if (!current) return null;
27043
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
27044
+ return null;
27045
+ });
27046
+ }, 8e3);
27047
+ return () => clearTimeout(timeout);
27048
+ }, [pendingMobileWallet, mobileDepositAddresses]);
26828
27049
  const handleConnectWallet = async (wallet, network) => {
26829
27050
  setConnectingNetwork(network);
26830
27051
  transitionTo("connecting");
@@ -26969,14 +27190,32 @@ function WalletConnect({
26969
27190
  userId,
26970
27191
  publishableKey,
26971
27192
  clientSecret,
27193
+ // In-tab flow: poll the single connected deposit wallet.
26972
27194
  depositWalletId: activeDepositWallet?.id ?? "",
26973
- enabled: hasSignedTransaction && !!activeDepositWallet,
27195
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
27196
+ // chain's deposit wallet. Detection still happens via the single /query by
27197
+ // external_user_id, which already spans all chains.
27198
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
27199
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
26974
27200
  onDepositSuccess,
26975
27201
  onDepositError
26976
27202
  });
26977
27203
  React302.useEffect(() => {
26978
27204
  onExecutionsChange?.(depositExecutions);
26979
27205
  }, [depositExecutions, onExecutionsChange]);
27206
+ const latestDepositExecution = React302.useMemo(() => {
27207
+ if (depositExecutions.length === 0) return null;
27208
+ return [...depositExecutions].sort((a, b) => {
27209
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
27210
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
27211
+ return tb - ta;
27212
+ })[0];
27213
+ }, [depositExecutions]);
27214
+ React302.useEffect(() => {
27215
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
27216
+ transitionTo("mobile_deposit_status");
27217
+ }
27218
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
26980
27219
  React302.useEffect(() => {
26981
27220
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
26982
27221
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -27107,6 +27346,16 @@ function WalletConnect({
27107
27346
  setSelectedWalletDef(null);
27108
27347
  setConnectingNetwork(null);
27109
27348
  break;
27349
+ case "mobile_redirect":
27350
+ transitionTo("select_wallet");
27351
+ setMobileRedirect(null);
27352
+ setAwaitingMobileDeposit(false);
27353
+ break;
27354
+ case "mobile_deposit_status":
27355
+ transitionTo("select_wallet");
27356
+ setMobileRedirect(null);
27357
+ setAwaitingMobileDeposit(false);
27358
+ break;
27110
27359
  case "select_token":
27111
27360
  if (walletProvidedAtMount.current) parentOnBack?.();
27112
27361
  else transitionTo("select_wallet");
@@ -27292,33 +27541,40 @@ function WalletConnect({
27292
27541
  return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27293
27542
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
27294
27543
  /* @__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
- )) }),
27544
+ /* @__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" }),
27545
+ /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
27546
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
27547
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
27548
+ const isPending = pendingMobileWallet?.id === wallet.id;
27549
+ return /* @__PURE__ */ jsxs48(
27550
+ "button",
27551
+ {
27552
+ onClick: () => void handleWalletClick(wallet),
27553
+ disabled: isWalletConnecting || !!pendingMobileWallet,
27554
+ 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",
27555
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
27556
+ children: [
27557
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27558
+ 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" }),
27559
+ /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
27560
+ ] }),
27561
+ 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: [
27562
+ /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
27563
+ /* @__PURE__ */ jsx54(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
27564
+ ] })
27565
+ ]
27566
+ },
27567
+ wallet.id
27568
+ );
27569
+ }) }),
27316
27570
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
27317
27571
  ] })
27318
27572
  ] });
27319
27573
  }
27574
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
27575
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
27320
27576
  if (view === "select_network" && selectedWalletDef) {
27321
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27577
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27322
27578
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
27323
27579
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
27324
27580
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -27348,10 +27604,10 @@ function WalletConnect({
27348
27604
  )) }),
27349
27605
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
27350
27606
  ] })
27351
- ] });
27607
+ ] }) });
27352
27608
  }
27353
27609
  if (view === "connecting") {
27354
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27610
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27355
27611
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
27356
27612
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
27357
27613
  /* @__PURE__ */ jsx54(LoaderCircle, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -27362,24 +27618,132 @@ function WalletConnect({
27362
27618
  ] }),
27363
27619
  /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: "Please approve the connection in your wallet" })
27364
27620
  ] })
27365
- ] });
27621
+ ] }) });
27622
+ }
27623
+ if (view === "mobile_redirect" && mobileRedirect) {
27624
+ const Icon22 = WALLET_ICONS3[mobileRedirect.walletId];
27625
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27626
+ /* @__PURE__ */ jsx54(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
27627
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-px-6 uf-py-10", children: [
27628
+ 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" }),
27629
+ /* @__PURE__ */ jsxs48(
27630
+ "div",
27631
+ {
27632
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
27633
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
27634
+ children: [
27635
+ "Continue in ",
27636
+ mobileRedirect.walletName
27637
+ ]
27638
+ }
27639
+ ),
27640
+ /* @__PURE__ */ jsxs48(
27641
+ "div",
27642
+ {
27643
+ className: "uf-text-sm uf-text-center uf-mb-6",
27644
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
27645
+ children: [
27646
+ "Complete your deposit in the ",
27647
+ mobileRedirect.walletName,
27648
+ " app"
27649
+ ]
27650
+ }
27651
+ ),
27652
+ /* @__PURE__ */ jsxs48(
27653
+ "button",
27654
+ {
27655
+ type: "button",
27656
+ onClick: () => {
27657
+ window.location.href = mobileRedirect.deeplink;
27658
+ },
27659
+ 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",
27660
+ style: {
27661
+ backgroundColor: components.card.backgroundColor,
27662
+ borderRadius: components.card.borderRadius,
27663
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
27664
+ color: components.card.titleColor,
27665
+ fontFamily: fonts.medium
27666
+ },
27667
+ children: [
27668
+ /* @__PURE__ */ jsx54(ExternalLink, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
27669
+ /* @__PURE__ */ jsxs48("span", { className: "uf-text-sm uf-font-medium", children: [
27670
+ "Open in ",
27671
+ mobileRedirect.walletName
27672
+ ] })
27673
+ ]
27674
+ }
27675
+ ),
27676
+ awaitingMobileDeposit && /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
27677
+ /* @__PURE__ */ jsx54(
27678
+ LoaderCircle,
27679
+ {
27680
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
27681
+ style: { color: colors2.foregroundMuted }
27682
+ }
27683
+ ),
27684
+ /* @__PURE__ */ jsx54(
27685
+ "span",
27686
+ {
27687
+ className: "uf-text-sm",
27688
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
27689
+ children: "Checking for deposit..."
27690
+ }
27691
+ )
27692
+ ] })
27693
+ ] })
27694
+ ] }) });
27695
+ }
27696
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
27697
+ const isComplete = latestDepositExecution.status === ExecutionStatus.SUCCEEDED;
27698
+ const isFailed = latestDepositExecution.status === ExecutionStatus.FAILED;
27699
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
27700
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27701
+ /* @__PURE__ */ jsx54(
27702
+ DepositHeader,
27703
+ {
27704
+ title,
27705
+ showBack: false,
27706
+ onClose: isComplete && onDone ? onDone : onClose
27707
+ }
27708
+ ),
27709
+ /* @__PURE__ */ jsx54(DepositDetailContent, { execution: latestDepositExecution }),
27710
+ isComplete && /* @__PURE__ */ jsx54("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-4 uf-pb-4", children: /* @__PURE__ */ jsx54(
27711
+ "button",
27712
+ {
27713
+ type: "button",
27714
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
27715
+ }),
27716
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
27717
+ style: {
27718
+ backgroundColor: colors2.primary,
27719
+ color: colors2.primaryForeground,
27720
+ fontFamily: fonts.medium,
27721
+ borderRadius: components.button.borderRadius,
27722
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
27723
+ },
27724
+ children: "Done"
27725
+ }
27726
+ ) })
27727
+ ] }) });
27366
27728
  }
27367
27729
  if (!hasWallet) return null;
27730
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
27731
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
27368
27732
  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 }) });
27733
+ 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 ?? (() => {
27734
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
27371
27735
  }
27372
27736
  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 }) });
27737
+ 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 ?? (() => {
27738
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
27375
27739
  }
27376
27740
  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
- }) }) });
27741
+ 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 ?? (() => {
27742
+ }) }) }) });
27379
27743
  }
27380
27744
  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 }) });
27745
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
27746
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
27383
27747
  }
27384
27748
  return null;
27385
27749
  }
@@ -27491,7 +27855,6 @@ function DepositModal({
27491
27855
  const [allExecutions, setAllExecutions] = useState32([]);
27492
27856
  const [selectedExecution, setSelectedExecution] = useState32(null);
27493
27857
  const [depositExecutions, setDepositExecutions] = useState32([]);
27494
- const isMobileView = useIsMobileViewport();
27495
27858
  const { projectConfig } = useProjectConfig({
27496
27859
  publishableKey,
27497
27860
  enabled: open
@@ -27887,7 +28250,7 @@ function DepositModal({
27887
28250
  open: hideOverlay || open,
27888
28251
  onOpenChange: hideOverlay ? void 0 : handleClose,
27889
28252
  modal: !hideOverlay,
27890
- children: /* @__PURE__ */ jsx55(
28253
+ children: /* @__PURE__ */ jsxs49(
27891
28254
  DialogContent2,
27892
28255
  {
27893
28256
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -27896,386 +28259,389 @@ function DepositModal({
27896
28259
  style: { backgroundColor: colors2.background },
27897
28260
  onPointerDownOutside: (e) => e.preventDefault(),
27898
28261
  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,
28262
+ children: [
28263
+ /* @__PURE__ */ jsx55(DialogTitle2, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
28264
+ /* @__PURE__ */ jsx55(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28265
+ /* @__PURE__ */ jsx55(
28266
+ DepositHeader,
28267
+ {
28268
+ title: modalTitle || "Deposit",
28269
+ showClose: !hideOverlay,
28270
+ onClose: handleClose,
28271
+ showBalance: showBalanceHeader,
28272
+ balanceAddress: recipientAddress,
28273
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28274
+ balanceChainId: destinationChainId,
28275
+ balanceTokenAddress: destinationTokenAddress,
28276
+ projectName: projectConfig?.project_name,
28277
+ publishableKey
28278
+ }
28279
+ ),
28280
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28281
+ /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28282
+ showTransferCrypto && /* @__PURE__ */ jsx55(
28283
+ TransferCryptoButton,
28284
+ {
28285
+ onClick: () => setView("transfer"),
28286
+ title: transferCryptoTitle,
28287
+ subtitle: t7.transferCrypto.subtitle,
28288
+ featuredTokens: projectConfig?.transfer_crypto.networks
28289
+ }
28290
+ ),
28291
+ showConnectWallet && /* @__PURE__ */ jsx55(
28292
+ BrowserWalletButton,
28293
+ {
28294
+ onClick: handleBrowserWalletClick,
28295
+ onConnectClick: handleWalletConnectClick,
28296
+ onDisconnect: handleWalletDisconnect,
28297
+ chainType: browserWalletChainType,
28298
+ publishableKey,
28299
+ featuredWallets: projectConfig?.connect_wallet?.wallets
28300
+ }
28301
+ ),
28302
+ showFiatOnramp && /* @__PURE__ */ jsx55(
28303
+ DepositWithCardButton,
28304
+ {
28305
+ onClick: () => setView("card"),
28306
+ title: depositWithCardTitle,
28307
+ subtitle: t7.depositWithCard.subtitle,
28308
+ paymentNetworks: projectConfig?.payment_networks.networks
28309
+ }
28310
+ ),
28311
+ showPayWithExchange && /* @__PURE__ */ jsx55(
28312
+ PayWithExchangeButton,
28313
+ {
28314
+ onClick: () => setView("exchange"),
28315
+ title: payWithExchangeTitle,
28316
+ subtitle: t7.payWithExchange.subtitle,
28317
+ exchanges,
28318
+ loading: exchangesLoading
28319
+ }
28320
+ ),
28321
+ showConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
28322
+ ConnectExchangeButton,
28323
+ {
28324
+ onClick: () => {
28325
+ setCoinbaseSkipToHoldings(true);
28326
+ setView("coinbase_connect");
28327
+ },
28328
+ onDisconnect: handleExchangeDisconnect,
28329
+ title: i18n2.connectExchange.title,
28330
+ subtitle: i18n2.connectExchange.subtitle,
28331
+ exchanges: integrationExchanges,
28332
+ connectedExchange
28333
+ }
28334
+ ),
28335
+ showConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
28336
+ ConnectExchangeButton,
28337
+ {
28338
+ onClick: () => {
28339
+ setCoinbaseSkipToHoldings(false);
28340
+ setView("coinbase_connect");
28341
+ },
28342
+ title: i18n2.connectExchange.title,
28343
+ subtitle: i18n2.connectExchange.subtitle,
28344
+ exchanges: integrationExchanges
28345
+ }
28346
+ ),
28347
+ showCashApp && /* @__PURE__ */ jsx55(
28348
+ CashAppButton,
28349
+ {
28350
+ onClick: () => setView("cashapp"),
28351
+ title: "Pay with Cash App",
28352
+ subtitle: "Deposit via Cash App",
28353
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28354
+ }
28355
+ ),
28356
+ showDepositTracker && /* @__PURE__ */ jsx55(
28357
+ DepositTrackerButton,
28358
+ {
28359
+ onClick: () => {
28360
+ setAllExecutions(depositExecutions);
28361
+ setView("tracker");
28362
+ },
28363
+ title: depositTrackerTitle,
28364
+ subtitle: depositTrackerSubTitle,
28365
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
28366
+ }
28367
+ )
28368
+ ] }) }),
28369
+ depositPoweredByFooter
28370
+ ] })
28371
+ ] }) : view === "transfer" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28372
+ /* @__PURE__ */ jsx55(
28373
+ DepositHeader,
28374
+ {
28375
+ title: transferCryptoTitle,
28376
+ showBack: showBackTransfer,
28377
+ onBack: handleBack,
28378
+ onClose: handleClose,
28379
+ showBalance: showBalanceHeader,
28380
+ balanceAddress: recipientAddress,
28381
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28382
+ balanceChainId: destinationChainId,
28383
+ balanceTokenAddress: destinationTokenAddress,
28384
+ projectName: projectConfig?.project_name,
28385
+ publishableKey
28386
+ }
28387
+ ),
28388
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28389
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ jsx55(
28390
+ TransferCryptoSingleInput,
27928
28391
  {
27929
- onClick: handleBrowserWalletClick,
27930
- onConnectClick: handleWalletConnectClick,
27931
- onDisconnect: handleWalletDisconnect,
27932
- chainType: browserWalletChainType,
28392
+ userId,
27933
28393
  publishableKey,
27934
- featuredWallets: projectConfig?.connect_wallet?.wallets
28394
+ recipientAddress,
28395
+ destinationChainType,
28396
+ destinationChainId,
28397
+ destinationTokenAddress,
28398
+ defaultSourceChainType,
28399
+ defaultSourceChainId,
28400
+ defaultSourceTokenAddress,
28401
+ defaultSourceSymbol,
28402
+ depositConfirmationMode,
28403
+ onExecutionsChange: setDepositExecutions,
28404
+ onDepositSuccess,
28405
+ onDepositError,
28406
+ wallets
27935
28407
  }
27936
- ),
27937
- showFiatOnramp && /* @__PURE__ */ jsx55(
27938
- DepositWithCardButton,
28408
+ ) : /* @__PURE__ */ jsx55(
28409
+ TransferCryptoDoubleInput,
27939
28410
  {
27940
- onClick: () => setView("card"),
27941
- title: depositWithCardTitle,
27942
- subtitle: t7.depositWithCard.subtitle,
27943
- paymentNetworks: projectConfig?.payment_networks.networks
28411
+ userId,
28412
+ publishableKey,
28413
+ recipientAddress,
28414
+ destinationChainType,
28415
+ destinationChainId,
28416
+ destinationTokenAddress,
28417
+ defaultSourceChainType,
28418
+ defaultSourceChainId,
28419
+ defaultSourceTokenAddress,
28420
+ defaultSourceSymbol,
28421
+ depositConfirmationMode,
28422
+ onExecutionsChange: setDepositExecutions,
28423
+ onDepositSuccess,
28424
+ onDepositError,
28425
+ wallets
27944
28426
  }
27945
28427
  ),
27946
- showPayWithExchange && /* @__PURE__ */ jsx55(
27947
- PayWithExchangeButton,
28428
+ depositPoweredByFooter
28429
+ ] })
28430
+ ] }) : view === "tracker" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28431
+ /* @__PURE__ */ jsx55(
28432
+ DepositHeader,
28433
+ {
28434
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
28435
+ showBack: showBackTracker,
28436
+ onBack: handleBack,
28437
+ onClose: handleClose
28438
+ }
28439
+ ),
28440
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28441
+ /* @__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(
28442
+ "div",
27948
28443
  {
27949
- onClick: () => setView("exchange"),
27950
- title: payWithExchangeTitle,
27951
- subtitle: t7.payWithExchange.subtitle,
27952
- exchanges,
27953
- loading: exchangesLoading
28444
+ className: "uf-text-sm",
28445
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
28446
+ children: "No deposits yet"
27954
28447
  }
27955
- ),
27956
- showConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
27957
- ConnectExchangeButton,
28448
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ jsx55(
28449
+ DepositExecutionItem,
27958
28450
  {
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,
28451
+ execution,
28452
+ onClick: () => setSelectedExecution(execution)
28453
+ },
28454
+ execution.id
28455
+ )) }) }),
28456
+ depositPoweredByFooter
28457
+ ] })
28458
+ ] }) : view === "card" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28459
+ /* @__PURE__ */ jsx55(
28460
+ DepositHeader,
28461
+ {
28462
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
28463
+ showBack: showBackCard,
28464
+ onBack: handleBack,
28465
+ onClose: handleClose,
28466
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
28467
+ showBalance: showBalanceHeader,
28468
+ balanceAddress: recipientAddress,
28469
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28470
+ balanceChainId: destinationChainId,
28471
+ balanceTokenAddress: destinationTokenAddress,
28472
+ projectName: projectConfig?.project_name,
28473
+ publishableKey
28474
+ }
28475
+ ),
28476
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28477
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ jsx55(
28478
+ BuyWithCard,
27972
28479
  {
27973
- onClick: () => {
27974
- setCoinbaseSkipToHoldings(false);
27975
- setView("coinbase_connect");
27976
- },
27977
- title: i18n2.connectExchange.title,
27978
- subtitle: i18n2.connectExchange.subtitle,
27979
- exchanges: integrationExchanges
28480
+ userId,
28481
+ publishableKey,
28482
+ view: cardView,
28483
+ onViewChange: handleCardViewChange,
28484
+ destinationTokenSymbol,
28485
+ recipientAddress,
28486
+ destinationChainType,
28487
+ destinationChainId,
28488
+ destinationTokenAddress,
28489
+ onDepositSuccess,
28490
+ onDepositError,
28491
+ onEvent,
28492
+ themeClass,
28493
+ wallets,
28494
+ assetCdnUrl: projectConfig?.asset_cdn_url,
28495
+ hideDepositFlowInfo,
28496
+ hideDisplayDescription
27980
28497
  }
27981
28498
  ),
27982
- showCashApp && /* @__PURE__ */ jsx55(
27983
- CashAppButton,
28499
+ depositPoweredByFooter
28500
+ ] })
28501
+ ] }) : view === "exchange" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28502
+ /* @__PURE__ */ jsx55(
28503
+ DepositHeader,
28504
+ {
28505
+ title: payWithExchangeTitle,
28506
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
28507
+ onBack: handleBack,
28508
+ onClose: handleClose
28509
+ }
28510
+ ),
28511
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28512
+ /* @__PURE__ */ jsx55(
28513
+ PayWithExchange,
27984
28514
  {
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
28515
+ userId,
28516
+ publishableKey,
28517
+ exchanges,
28518
+ view: exchangeView,
28519
+ onViewChange: setExchangeView,
28520
+ destinationTokenSymbol,
28521
+ recipientAddress,
28522
+ destinationChainType,
28523
+ destinationChainId,
28524
+ destinationTokenAddress,
28525
+ onDepositSuccess,
28526
+ onDepositError,
28527
+ wallets,
28528
+ defaultToken: defaultToken ?? null
27989
28529
  }
27990
28530
  ),
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,
28531
+ depositPoweredByFooter
28532
+ ] })
28533
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28534
+ /* @__PURE__ */ jsx55(
28535
+ CoinbaseConnect,
28026
28536
  {
28027
- userId,
28028
28537
  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
28538
  userId,
28047
- publishableKey,
28539
+ wallets,
28048
28540
  recipientAddress,
28049
- destinationChainType,
28050
- destinationChainId,
28051
- destinationTokenAddress,
28541
+ destinationTokenAddress: destinationTokenAddress ?? "",
28542
+ destinationChainId: destinationChainId ?? "",
28543
+ destinationChainType: destinationChainType ?? "",
28544
+ onTransferSuccess: (result) => {
28545
+ onDepositSuccess?.({
28546
+ message: "Transfer completed via Coinbase Connect",
28547
+ transaction: result
28548
+ });
28549
+ },
28550
+ onTransferError: (error) => {
28551
+ onDepositError?.({
28552
+ message: error.message,
28553
+ error
28554
+ });
28555
+ },
28556
+ onBack: handleBack,
28557
+ onClose: handleClose,
28558
+ onDisconnect: handleExchangeDisconnect,
28559
+ skipToHoldings: coinbaseSkipToHoldings,
28560
+ canGoBack: sessionOpenedFromMenu,
28561
+ onExecutionsChange: setDepositExecutions,
28052
28562
  defaultSourceChainType,
28053
28563
  defaultSourceChainId,
28054
28564
  defaultSourceTokenAddress,
28055
- defaultSourceSymbol,
28056
- depositConfirmationMode,
28057
- onExecutionsChange: setDepositExecutions,
28058
- onDepositSuccess,
28059
- onDepositError,
28060
- wallets
28565
+ defaultSourceSymbol
28061
28566
  }
28062
28567
  ),
28063
28568
  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: [
28569
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28147
28570
  /* @__PURE__ */ jsx55(
28148
- PayWithExchange,
28571
+ WalletConnect,
28149
28572
  {
28573
+ walletInfo: browserWalletInfo ?? void 0,
28574
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
28575
+ wallets,
28150
28576
  userId,
28151
28577
  publishableKey,
28152
- exchanges,
28153
- view: exchangeView,
28154
- onViewChange: setExchangeView,
28155
- destinationTokenSymbol,
28156
- recipientAddress,
28157
- destinationChainType,
28158
- destinationChainId,
28159
- destinationTokenAddress,
28578
+ assetCdnUrl: projectConfig?.asset_cdn_url,
28579
+ projectName: projectConfig?.project_name,
28580
+ onSuccess: (txHash) => {
28581
+ onDepositSuccess?.({
28582
+ message: "Transaction sent successfully",
28583
+ transaction: { txHash }
28584
+ });
28585
+ },
28586
+ onError: (error) => {
28587
+ onDepositError?.({
28588
+ message: error.message,
28589
+ error
28590
+ });
28591
+ },
28160
28592
  onDepositSuccess,
28161
28593
  onDepositError,
28162
- wallets,
28163
- defaultToken: defaultToken ?? null
28594
+ amountQuickSelect: browserWalletAmountQuickSelect,
28595
+ onWalletDisconnect: handleWalletDisconnect,
28596
+ onWalletConnected: (info, dw) => {
28597
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
28598
+ setStoredWalletState(info.type);
28599
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28600
+ },
28601
+ onBack: handleBack,
28602
+ onClose: handleClose,
28603
+ defaultSourceChainType,
28604
+ defaultSourceChainId,
28605
+ defaultSourceTokenAddress,
28606
+ defaultSourceSymbol,
28607
+ canGoBack: sessionOpenedFromMenu,
28608
+ depositWalletsLoading: walletsLoading
28164
28609
  }
28165
28610
  ),
28166
28611
  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: [
28612
+ ] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28258
28613
  /* @__PURE__ */ jsx55(
28259
- PayWithCashApp,
28614
+ DepositHeader,
28260
28615
  {
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
28616
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
28617
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
28618
+ onBack: handleBack,
28619
+ onClose: handleClose
28274
28620
  }
28275
28621
  ),
28276
- depositPoweredByFooter
28277
- ] })
28278
- ] }) : null })
28622
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28623
+ /* @__PURE__ */ jsx55(
28624
+ PayWithCashApp,
28625
+ {
28626
+ userId,
28627
+ publishableKey,
28628
+ recipientAddress,
28629
+ destinationChainType,
28630
+ destinationChainId,
28631
+ destinationTokenAddress,
28632
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
28633
+ view: cashAppView,
28634
+ onViewChange: setCashAppView,
28635
+ onAmountChange: setCashAppAmount,
28636
+ onEvent,
28637
+ onDepositSuccess,
28638
+ onDepositError
28639
+ }
28640
+ ),
28641
+ depositPoweredByFooter
28642
+ ] })
28643
+ ] }) : null })
28644
+ ]
28279
28645
  }
28280
28646
  )
28281
28647
  }
@@ -28294,7 +28660,7 @@ function usePaymentIntent(params) {
28294
28660
  enabled = true,
28295
28661
  pollingInterval = 3e3
28296
28662
  } = params;
28297
- return useQuery13({
28663
+ return useQuery14({
28298
28664
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
28299
28665
  queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
28300
28666
  enabled: enabled && !!clientSecret && !!publishableKey,
@@ -28360,7 +28726,6 @@ function CheckoutModal({
28360
28726
  const [browserWalletInfo, setBrowserWalletInfo] = useState33(null);
28361
28727
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState33(false);
28362
28728
  const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletState()?.chainType);
28363
- const isMobileView = useIsMobileViewport();
28364
28729
  const [resolvedTheme, setResolvedTheme] = useState33(
28365
28730
  theme === "auto" ? "dark" : theme
28366
28731
  );
@@ -28786,7 +29151,7 @@ function CheckoutModal({
28786
29151
  featuredTokens: projectConfig?.transfer_crypto.networks
28787
29152
  }
28788
29153
  ),
28789
- showConnectWallet && !isMobileView && /* @__PURE__ */ jsx56(
29154
+ showConnectWallet && /* @__PURE__ */ jsx56(
28790
29155
  BrowserWalletButton,
28791
29156
  {
28792
29157
  onClick: handleBrowserWalletClick,
@@ -28947,7 +29312,7 @@ function CheckoutModal({
28947
29312
  ) }) });
28948
29313
  }
28949
29314
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
28950
- return useQuery14({
29315
+ return useQuery15({
28951
29316
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
28952
29317
  queryFn: () => getSupportedDestinationTokens(publishableKey),
28953
29318
  staleTime: 1e3 * 60 * 5,
@@ -28982,7 +29347,7 @@ function useSourceTokenValidation(params) {
28982
29347
  enabled = true
28983
29348
  } = params;
28984
29349
  const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
28985
- return useQuery15({
29350
+ return useQuery16({
28986
29351
  queryKey: [
28987
29352
  "unifold",
28988
29353
  "sourceTokenValidation",
@@ -29038,7 +29403,7 @@ function useAddressBalance(params) {
29038
29403
  enabled = true
29039
29404
  } = params;
29040
29405
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
29041
- return useQuery16({
29406
+ return useQuery17({
29042
29407
  queryKey: [
29043
29408
  "unifold",
29044
29409
  "addressBalance",
@@ -29087,7 +29452,7 @@ function useAddressBalance(params) {
29087
29452
  }
29088
29453
  function useExecutions(userId, publishableKey, options) {
29089
29454
  const actionType = options?.actionType ?? ActionType.Deposit;
29090
- return useQuery17({
29455
+ return useQuery18({
29091
29456
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
29092
29457
  queryFn: () => queryExecutions(userId, publishableKey, actionType),
29093
29458
  enabled: (options?.enabled ?? true) && !!userId,
@@ -29370,7 +29735,7 @@ function useVerifyRecipientAddress(params) {
29370
29735
  } = params;
29371
29736
  const trimmedAddress = recipientAddress?.trim() || "";
29372
29737
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
29373
- return useQuery18({
29738
+ return useQuery19({
29374
29739
  queryKey: [
29375
29740
  "unifold",
29376
29741
  "verifyRecipientAddress",
@@ -29412,7 +29777,7 @@ function useGetDepositAddress(params) {
29412
29777
  enabled = true
29413
29778
  } = params;
29414
29779
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
29415
- return useQuery19({
29780
+ return useQuery20({
29416
29781
  queryKey: [
29417
29782
  "unifold",
29418
29783
  "getDepositAddress",
@@ -30695,6 +31060,16 @@ function UnifoldProvider2({
30695
31060
  });
30696
31061
  promise.catch(() => {
30697
31062
  });
31063
+ if (!config2.recipientAddress) {
31064
+ const error = {
31065
+ message: "beginDeposit requires a `recipientAddress`.",
31066
+ code: "MISSING_RECIPIENT"
31067
+ };
31068
+ console.error(`[UnifoldProvider] ${error.message}`);
31069
+ depositPromiseRef.current.reject(error);
31070
+ depositPromiseRef.current = null;
31071
+ return promise;
31072
+ }
30698
31073
  setDepositConfig(config2);
30699
31074
  setIsOpen(true);
30700
31075
  return promise;