@unifold/ui-web 0.1.63 → 0.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -43566,6 +43566,40 @@ async function getAddressBalances(address, chainType, publishableKey) {
43566
43566
  const data = await response.json();
43567
43567
  return data;
43568
43568
  }
43569
+ async function getExternalWallets(publishableKey) {
43570
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43571
+ validatePublishableKey(pk);
43572
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets`, {
43573
+ method: "GET",
43574
+ headers: {
43575
+ accept: "application/json",
43576
+ "x-publishable-key": pk
43577
+ }
43578
+ });
43579
+ if (!response.ok) {
43580
+ throw new Error(`Failed to fetch external wallets: ${response.statusText}`);
43581
+ }
43582
+ const data = await response.json();
43583
+ return data;
43584
+ }
43585
+ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey) {
43586
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43587
+ validatePublishableKey(pk);
43588
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets/mobile_deeplink`, {
43589
+ method: "POST",
43590
+ headers: {
43591
+ "Content-Type": "application/json",
43592
+ accept: "application/json",
43593
+ "x-publishable-key": pk
43594
+ },
43595
+ body: JSON.stringify({ wallet, deposit_addresses: depositAddresses })
43596
+ });
43597
+ if (!response.ok) {
43598
+ throw new Error(`Failed to generate wallet deep link: ${response.statusText}`);
43599
+ }
43600
+ const data = await response.json();
43601
+ return data;
43602
+ }
43569
43603
  async function getAddressBalance(address, chainType, chainId, tokenAddress, publishableKey) {
43570
43604
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43571
43605
  validatePublishableKey(pk);
@@ -43939,6 +43973,29 @@ async function getDepositQuote(request, publishableKey) {
43939
43973
  const json = await response.json();
43940
43974
  return json.data;
43941
43975
  }
43976
+ async function buildHypercoreTransaction(request, publishableKey) {
43977
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43978
+ validatePublishableKey(pk);
43979
+ const response = await fetch(
43980
+ `${API_BASE_URL}/v1/public/transactions/hypercore/build`,
43981
+ {
43982
+ method: "POST",
43983
+ headers: {
43984
+ accept: "application/json",
43985
+ "x-publishable-key": pk,
43986
+ "Content-Type": "application/json"
43987
+ },
43988
+ body: JSON.stringify(request)
43989
+ }
43990
+ );
43991
+ if (!response.ok) {
43992
+ const error = await response.json().catch(() => ({ message: response.statusText }));
43993
+ throw new Error(
43994
+ `Failed to build HyperCore transaction: ${error.message || response.statusText}`
43995
+ );
43996
+ }
43997
+ return response.json();
43998
+ }
43942
43999
  async function getCashAppLimits(currency = "usd", publishableKey) {
43943
44000
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43944
44001
  validatePublishableKey(pk);
@@ -44004,6 +44061,29 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
44004
44061
  }
44005
44062
  return response.json();
44006
44063
  }
44064
+ async function sendHypercoreTransaction(request, publishableKey) {
44065
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
44066
+ validatePublishableKey(pk);
44067
+ const response = await fetch(
44068
+ `${API_BASE_URL}/v1/public/transactions/hypercore/send`,
44069
+ {
44070
+ method: "POST",
44071
+ headers: {
44072
+ accept: "application/json",
44073
+ "x-publishable-key": pk,
44074
+ "Content-Type": "application/json"
44075
+ },
44076
+ body: JSON.stringify(request)
44077
+ }
44078
+ );
44079
+ if (!response.ok) {
44080
+ const error = await response.json().catch(() => ({ message: response.statusText }));
44081
+ throw new Error(
44082
+ `Failed to send HyperCore transaction: ${error.message || response.statusText}`
44083
+ );
44084
+ }
44085
+ return response.json();
44086
+ }
44007
44087
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
44008
44088
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
44009
44089
  return DepositEventType2;
@@ -50180,6 +50260,22 @@ function clearStoredWalletState() {
50180
50260
  } catch {
50181
50261
  }
50182
50262
  }
50263
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
50264
+ function getLastOpenedWallet() {
50265
+ if (typeof window === "undefined") return void 0;
50266
+ try {
50267
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
50268
+ } catch {
50269
+ return void 0;
50270
+ }
50271
+ }
50272
+ function setLastOpenedWallet(walletId) {
50273
+ if (typeof window === "undefined") return;
50274
+ try {
50275
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
50276
+ } catch {
50277
+ }
50278
+ }
50183
50279
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
50184
50280
  function isMobileViewport() {
50185
50281
  if (typeof window === "undefined") return false;
@@ -50536,6 +50632,36 @@ function ThemeProvider({
50536
50632
  );
50537
50633
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThemeContext.Provider, { value: contextValue, children });
50538
50634
  }
50635
+ function AccentColorOverride({
50636
+ accentColor,
50637
+ accentForeground,
50638
+ children
50639
+ }) {
50640
+ const parent = useTheme();
50641
+ const value = React37.useMemo(() => {
50642
+ if (!accentColor) return parent;
50643
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
50644
+ const nextColors = {
50645
+ ...parent.colors,
50646
+ primary: accentColor,
50647
+ primaryForeground: foreground
50648
+ };
50649
+ const nextComponents = {
50650
+ ...parent.components,
50651
+ button: {
50652
+ ...parent.components.button,
50653
+ primaryBackground: accentColor,
50654
+ primaryText: foreground
50655
+ },
50656
+ card: {
50657
+ ...parent.components.card,
50658
+ iconBackgroundColor: `${accentColor}26`
50659
+ }
50660
+ };
50661
+ return { ...parent, colors: nextColors, components: nextComponents };
50662
+ }, [parent, accentColor, accentForeground]);
50663
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThemeContext.Provider, { value, children });
50664
+ }
50539
50665
  function useTheme() {
50540
50666
  const context = React37.useContext(ThemeContext);
50541
50667
  if (!context) {
@@ -50955,7 +51081,7 @@ function DepositHeader({
50955
51081
  setShowBalanceSkeleton(false);
50956
51082
  return;
50957
51083
  }
50958
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
51084
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
50959
51085
  if (!supportedChainTypes.includes(
50960
51086
  balanceChainType
50961
51087
  )) {
@@ -51587,6 +51713,7 @@ function useDepositPolling({
51587
51713
  clientSecret,
51588
51714
  depositConfirmationMode = "auto_ui",
51589
51715
  depositWalletId,
51716
+ depositWalletIds,
51590
51717
  enabled = true,
51591
51718
  immediateDirectPolling = false,
51592
51719
  onDepositSuccess,
@@ -51732,21 +51859,25 @@ function useDepositPolling({
51732
51859
  setIsPolling(false);
51733
51860
  };
51734
51861
  }, [userId, publishableKey, clientSecret, enabled]);
51862
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
51735
51863
  (0, import_react10.useEffect)(() => {
51736
- if (!pollingEnabled || !depositWalletId) return;
51864
+ if (!pollingEnabled || !pollWalletIdsKey) return;
51865
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
51737
51866
  const triggerPoll = async () => {
51738
- try {
51739
- await pollDirectExecutions(
51740
- { deposit_wallet_id: depositWalletId },
51741
- publishableKey
51742
- );
51743
- } catch {
51744
- }
51867
+ await Promise.all(
51868
+ ids.map(
51869
+ (id) => pollDirectExecutions(
51870
+ { deposit_wallet_id: id },
51871
+ publishableKey
51872
+ ).catch(() => {
51873
+ })
51874
+ )
51875
+ );
51745
51876
  };
51746
51877
  triggerPoll();
51747
51878
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
51748
51879
  return () => clearInterval(interval);
51749
- }, [pollingEnabled, depositWalletId, publishableKey]);
51880
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
51750
51881
  const handleIveDeposited = () => {
51751
51882
  setPollingEnabled(true);
51752
51883
  setShowWaitingUi(true);
@@ -52935,6 +53066,7 @@ function BuyWithCard({
52935
53066
  if (!selectedProvider) return "0.000000";
52936
53067
  return selectedProvider.destination_amount.toFixed(6);
52937
53068
  };
53069
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
52938
53070
  const selectedCurrencyData = fiatCurrencies.find(
52939
53071
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
52940
53072
  );
@@ -53120,9 +53252,12 @@ function BuyWithCard({
53120
53252
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53121
53253
  "button",
53122
53254
  {
53123
- onClick: () => handleViewChange("quotes"),
53255
+ onClick: () => {
53256
+ if (canOpenProviderSelector) handleViewChange("quotes");
53257
+ },
53124
53258
  disabled: quotesLoading || quotes.length === 0,
53125
- 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",
53259
+ "aria-disabled": !canOpenProviderSelector,
53260
+ 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"}`,
53126
53261
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
53127
53262
  children: quotesLoading ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
53128
53263
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
@@ -53149,7 +53284,7 @@ function BuyWithCard({
53149
53284
  )
53150
53285
  ] })
53151
53286
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "uf-w-full uf-text-left", children: [
53152
- isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53287
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53153
53288
  "div",
53154
53289
  {
53155
53290
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -53185,7 +53320,7 @@ function BuyWithCard({
53185
53320
  ),
53186
53321
  selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
53187
53322
  ] }),
53188
- quotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53323
+ canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53189
53324
  ChevronRight,
53190
53325
  {
53191
53326
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -60964,7 +61099,7 @@ function useHypercoreActivation(params) {
60964
61099
  publishableKey,
60965
61100
  enabled = true
60966
61101
  } = params;
60967
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
61102
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
60968
61103
  const recipient = recipientAddress?.trim() ?? "";
60969
61104
  const source = sourceAddress?.trim() ?? "";
60970
61105
  const hasAddresses = !!recipient && !!source;
@@ -62110,6 +62245,46 @@ function TransferCryptoDoubleInput({
62110
62245
  }
62111
62246
  ) });
62112
62247
  }
62248
+ function isHypercoreChain(chainId) {
62249
+ return chainId === HYPERCORE_CHAIN_ID;
62250
+ }
62251
+ async function sendHypercoreEvmTransfer(params) {
62252
+ const {
62253
+ provider,
62254
+ fromAddress,
62255
+ recipientAddress,
62256
+ sourceTokenAddress,
62257
+ amount,
62258
+ publishableKey
62259
+ } = params;
62260
+ const currentChainHex = await provider.request({
62261
+ method: "eth_chainId",
62262
+ params: []
62263
+ });
62264
+ const activeChainId = String(parseInt(currentChainHex, 16));
62265
+ const buildResult = await buildHypercoreTransaction(
62266
+ {
62267
+ signature_chain_id: activeChainId,
62268
+ recipient_address: recipientAddress,
62269
+ token_address: sourceTokenAddress,
62270
+ amount
62271
+ },
62272
+ publishableKey
62273
+ );
62274
+ const signature = await provider.request({
62275
+ method: "eth_signTypedData_v4",
62276
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
62277
+ });
62278
+ await sendHypercoreTransaction(
62279
+ {
62280
+ action_payload: buildResult.action_payload,
62281
+ signature,
62282
+ nonce: buildResult.nonce
62283
+ },
62284
+ publishableKey
62285
+ );
62286
+ return { signature };
62287
+ }
62113
62288
  function useDepositQuote(params) {
62114
62289
  const {
62115
62290
  publishableKey,
@@ -62161,6 +62336,60 @@ function useDepositQuote(params) {
62161
62336
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 5e3)
62162
62337
  });
62163
62338
  }
62339
+ function useExternalWallets({
62340
+ publishableKey,
62341
+ enabled = true
62342
+ }) {
62343
+ const { data: wallets = [], isLoading } = useQuery({
62344
+ queryKey: ["unifold", "external-wallets", publishableKey],
62345
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
62346
+ enabled: enabled && !!publishableKey,
62347
+ staleTime: 1e3 * 60 * 30,
62348
+ refetchOnMount: false,
62349
+ refetchOnWindowFocus: false
62350
+ });
62351
+ return { wallets, isLoading };
62352
+ }
62353
+ var WALLET_BRAND_COLORS = {
62354
+ phantom: "#AB9FF2",
62355
+ metamask: "#F6851B",
62356
+ coinbase: "#0052FF",
62357
+ trust: "#3375BB",
62358
+ rainbow: "#5B6CFF",
62359
+ rabby: "#7084FF",
62360
+ okx: "#000000"
62361
+ };
62362
+ function normalizeWalletId(type) {
62363
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
62364
+ }
62365
+ function getWalletBrandColor(type, mode = "dark") {
62366
+ if (!type) return void 0;
62367
+ const id = normalizeWalletId(type);
62368
+ const color = WALLET_BRAND_COLORS[id];
62369
+ if (!color) return void 0;
62370
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
62371
+ return color;
62372
+ }
62373
+ function getContrastingTextColor(hex) {
62374
+ const c = hex.replace("#", "");
62375
+ if (c.length !== 6) return "#FFFFFF";
62376
+ const r2 = parseInt(c.slice(0, 2), 16);
62377
+ const g = parseInt(c.slice(2, 4), 16);
62378
+ const b = parseInt(c.slice(4, 6), 16);
62379
+ const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
62380
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
62381
+ }
62382
+ function isMobileDevice() {
62383
+ if (typeof navigator === "undefined") return false;
62384
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
62385
+ }
62386
+ function getMobilePlatform() {
62387
+ if (typeof navigator === "undefined") return null;
62388
+ const ua = navigator.userAgent;
62389
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
62390
+ if (/android/i.test(ua)) return "android";
62391
+ return null;
62392
+ }
62164
62393
  var WALLET_ICONS = {
62165
62394
  metamask: MetamaskIcon,
62166
62395
  phantom: PhantomIcon,
@@ -62463,7 +62692,8 @@ function EnterAmountView({
62463
62692
  onClose,
62464
62693
  quickSelectMode,
62465
62694
  checkoutAmountUsd,
62466
- checkoutReceivedUsd
62695
+ checkoutReceivedUsd,
62696
+ footer
62467
62697
  }) {
62468
62698
  const { colors: colors2, fonts, components } = useTheme();
62469
62699
  const isCheckout = !!checkoutAmountUsd;
@@ -62719,6 +62949,7 @@ function EnterAmountView({
62719
62949
  )
62720
62950
  ] })
62721
62951
  ] }),
62952
+ footer && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
62722
62953
  /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
62723
62954
  "button",
62724
62955
  {
@@ -63166,18 +63397,33 @@ var WALLET_ICONS3 = {
63166
63397
  backpack: BackpackIcon,
63167
63398
  glow: GlowIcon
63168
63399
  };
63169
- var WALLET_DEFINITIONS = [
63170
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
63171
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
63172
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
63173
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
63174
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
63175
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
63176
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
63177
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
63178
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
63179
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
63400
+ var FALLBACK_WALLET_DEFINITIONS = [
63401
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
63402
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
63403
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
63404
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
63405
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
63406
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
63407
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
63180
63408
  ];
63409
+ function getMobileInstallUrl(walletId, defaultUrl) {
63410
+ if (!isMobileDevice()) return defaultUrl;
63411
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
63412
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
63413
+ const stores = {
63414
+ rabby: {
63415
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
63416
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
63417
+ },
63418
+ glow: {
63419
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
63420
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
63421
+ }
63422
+ };
63423
+ const entry = stores[walletId];
63424
+ if (!entry) return defaultUrl;
63425
+ return isIOS ? entry.ios : entry.android;
63426
+ }
63181
63427
  function normalizeTokenAddress(address) {
63182
63428
  const normalized = (address ?? "").toLowerCase();
63183
63429
  if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
@@ -63213,7 +63459,7 @@ function getLegacyEvmProviders() {
63213
63459
  okxEthereum: win.okxwallet
63214
63460
  };
63215
63461
  }
63216
- function detectAvailableWallets(filterChainType) {
63462
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
63217
63463
  const solProviders = getSolanaProviders();
63218
63464
  const legacyEvm = getLegacyEvmProviders();
63219
63465
  const eip6963List = getEip6963Providers();
@@ -63239,7 +63485,7 @@ function detectAvailableWallets(filterChainType) {
63239
63485
  return false;
63240
63486
  }
63241
63487
  });
63242
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63488
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63243
63489
  let isInstalled = false;
63244
63490
  const detectedNetworks = [];
63245
63491
  switch (wallet.id) {
@@ -63262,8 +63508,6 @@ function detectAvailableWallets(filterChainType) {
63262
63508
  isInstalled = true;
63263
63509
  detectedNetworks.push("ethereum");
63264
63510
  }
63265
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
63266
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
63267
63511
  break;
63268
63512
  case "trust":
63269
63513
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -63300,11 +63544,17 @@ function detectAvailableWallets(filterChainType) {
63300
63544
  }
63301
63545
  return { ...wallet, isInstalled, detectedNetworks };
63302
63546
  }).sort((a, b) => {
63547
+ if (recentWalletId) {
63548
+ const aRecent = a.id === recentWalletId ? 1 : 0;
63549
+ const bRecent = b.id === recentWalletId ? 1 : 0;
63550
+ if (aRecent !== bRecent) return bRecent - aRecent;
63551
+ }
63303
63552
  if (a.isInstalled && !b.isInstalled) return -1;
63304
63553
  if (!a.isInstalled && b.isInstalled) return 1;
63305
63554
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
63306
63555
  return 0;
63307
63556
  });
63557
+ return sorted;
63308
63558
  }
63309
63559
  function WalletConnect({
63310
63560
  walletInfo: initialWalletInfo,
@@ -63343,7 +63593,7 @@ function WalletConnect({
63343
63593
  depositWalletsLoading = false,
63344
63594
  onExecutionsChange
63345
63595
  }) {
63346
- const { colors: colors2, fonts, components } = useTheme();
63596
+ const { colors: colors2, fonts, components, mode } = useTheme();
63347
63597
  const walletProvidedAtMount = React302.useRef(!!initialWalletInfo && !!initialDepositWallet);
63348
63598
  const [activeWalletInfo, setActiveWalletInfo] = React302.useState(initialWalletInfo ?? null);
63349
63599
  const [activeDepositWallet, setActiveDepositWallet] = React302.useState(initialDepositWallet ?? null);
@@ -63367,7 +63617,43 @@ function WalletConnect({
63367
63617
  setEip6963ProviderCount(providers.length);
63368
63618
  });
63369
63619
  }, []);
63370
- const availableWallets = React302.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
63620
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
63621
+ const walletDefinitions = React302.useMemo(
63622
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
63623
+ id: w.id,
63624
+ name: w.name,
63625
+ networks: w.chain_types,
63626
+ installUrl: w.install_url,
63627
+ supportsMobileBrowse: w.supports_mobile_browse,
63628
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
63629
+ })) : FALLBACK_WALLET_DEFINITIONS,
63630
+ [backendWallets]
63631
+ );
63632
+ const [recentWalletId, setRecentWalletIdState] = React302.useState(getLastOpenedWallet);
63633
+ React302.useEffect(() => {
63634
+ if (view === "select_wallet") {
63635
+ setRecentWalletIdState(getLastOpenedWallet());
63636
+ }
63637
+ }, [view]);
63638
+ const availableWallets = React302.useMemo(
63639
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
63640
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
63641
+ );
63642
+ const [isMobile, setIsMobile] = React302.useState(false);
63643
+ React302.useEffect(() => {
63644
+ setIsMobile(isMobileDevice());
63645
+ }, []);
63646
+ const mobileDepositAddresses = React302.useMemo(
63647
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
63648
+ [depositWallets]
63649
+ );
63650
+ const mobileDepositWalletIds = React302.useMemo(
63651
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
63652
+ [depositWallets]
63653
+ );
63654
+ const [mobileRedirect, setMobileRedirect] = React302.useState(null);
63655
+ const [pendingMobileWallet, setPendingMobileWallet] = React302.useState(null);
63656
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React302.useState(false);
63371
63657
  React302.useEffect(() => {
63372
63658
  if (!standalone || autoResolved || detectingWallet) return;
63373
63659
  if (!detectedWallet) {
@@ -63411,7 +63697,7 @@ function WalletConnect({
63411
63697
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
63412
63698
  const recipientAddress = activeDepositWallet?.address ?? "";
63413
63699
  const isCheckoutMode = !!checkoutAmountUsd;
63414
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
63700
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
63415
63701
  const transitionTo = React302.useCallback((nextView) => {
63416
63702
  if (nextView === viewRef.current) return;
63417
63703
  setIsTransitioning(true);
@@ -63426,9 +63712,38 @@ function WalletConnect({
63426
63712
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
63427
63713
  transition: "opacity 150ms ease, transform 150ms ease"
63428
63714
  };
63429
- const handleWalletClick = (wallet) => {
63715
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
63716
+ try {
63717
+ const res = await getWalletMobileDeepLink(
63718
+ wallet.id,
63719
+ depositAddresses,
63720
+ publishableKey
63721
+ );
63722
+ if (res.deeplink) {
63723
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
63724
+ setLastOpenedWallet(wallet.id);
63725
+ setRecentWalletIdState(wallet.id);
63726
+ setAwaitingMobileDeposit(true);
63727
+ transitionTo("mobile_redirect");
63728
+ window.location.href = res.deeplink;
63729
+ return true;
63730
+ }
63731
+ } catch {
63732
+ }
63733
+ return false;
63734
+ };
63735
+ const handleWalletClick = async (wallet) => {
63430
63736
  if (!wallet.isInstalled) {
63431
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
63737
+ const platform2 = getMobilePlatform();
63738
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform2 ?? "");
63739
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
63740
+ if (mobileDepositAddresses.length === 0) {
63741
+ setPendingMobileWallet(wallet);
63742
+ return;
63743
+ }
63744
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
63745
+ }
63746
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
63432
63747
  return;
63433
63748
  }
63434
63749
  setSelectedWalletDef(wallet);
@@ -63444,9 +63759,32 @@ function WalletConnect({
63444
63759
  if (!selectedWalletDef) return;
63445
63760
  handleConnectWallet(selectedWalletDef, network);
63446
63761
  };
63762
+ React302.useEffect(() => {
63763
+ if (!pendingMobileWallet) return;
63764
+ if (mobileDepositAddresses.length > 0) {
63765
+ const wallet = pendingMobileWallet;
63766
+ setPendingMobileWallet(null);
63767
+ void (async () => {
63768
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
63769
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
63770
+ }
63771
+ })();
63772
+ return;
63773
+ }
63774
+ const timeout = setTimeout(() => {
63775
+ setPendingMobileWallet((current) => {
63776
+ if (!current) return null;
63777
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
63778
+ return null;
63779
+ });
63780
+ }, 8e3);
63781
+ return () => clearTimeout(timeout);
63782
+ }, [pendingMobileWallet, mobileDepositAddresses]);
63447
63783
  const handleConnectWallet = async (wallet, network) => {
63448
63784
  setConnectingNetwork(network);
63449
63785
  transitionTo("connecting");
63786
+ setLastOpenedWallet(wallet.id);
63787
+ setRecentWalletIdState(wallet.id);
63450
63788
  setWalletError(null);
63451
63789
  setIsWalletConnecting(true);
63452
63790
  try {
@@ -63551,6 +63889,13 @@ function WalletConnect({
63551
63889
  }
63552
63890
  };
63553
63891
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
63892
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
63893
+ recipientAddress,
63894
+ sourceAddress: activeWalletInfo?.address,
63895
+ destinationChainId: selectedToken?.chain_id,
63896
+ publishableKey,
63897
+ enabled: !!activeWalletInfo && !!recipientAddress
63898
+ });
63554
63899
  const effectiveDestinationAmount = React302.useMemo(() => {
63555
63900
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
63556
63901
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -63588,14 +63933,32 @@ function WalletConnect({
63588
63933
  userId,
63589
63934
  publishableKey,
63590
63935
  clientSecret,
63936
+ // In-tab flow: poll the single connected deposit wallet.
63591
63937
  depositWalletId: activeDepositWallet?.id ?? "",
63592
- enabled: hasSignedTransaction && !!activeDepositWallet,
63938
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
63939
+ // chain's deposit wallet. Detection still happens via the single /query by
63940
+ // external_user_id, which already spans all chains.
63941
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
63942
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
63593
63943
  onDepositSuccess,
63594
63944
  onDepositError
63595
63945
  });
63596
63946
  React302.useEffect(() => {
63597
63947
  onExecutionsChange?.(depositExecutions);
63598
63948
  }, [depositExecutions, onExecutionsChange]);
63949
+ const latestDepositExecution = React302.useMemo(() => {
63950
+ if (depositExecutions.length === 0) return null;
63951
+ return [...depositExecutions].sort((a, b) => {
63952
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
63953
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
63954
+ return tb - ta;
63955
+ })[0];
63956
+ }, [depositExecutions]);
63957
+ React302.useEffect(() => {
63958
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
63959
+ transitionTo("mobile_deposit_status");
63960
+ }
63961
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
63599
63962
  React302.useEffect(() => {
63600
63963
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
63601
63964
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -63637,7 +64000,7 @@ function WalletConnect({
63637
64000
  let cancelled = false;
63638
64001
  setIsLoading(true);
63639
64002
  setError(null);
63640
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
64003
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
63641
64004
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
63642
64005
  if (cancelled) return;
63643
64006
  const nonZero = response.balances.filter((b) => b.amount !== "0");
@@ -63726,6 +64089,16 @@ function WalletConnect({
63726
64089
  setSelectedWalletDef(null);
63727
64090
  setConnectingNetwork(null);
63728
64091
  break;
64092
+ case "mobile_redirect":
64093
+ transitionTo("select_wallet");
64094
+ setMobileRedirect(null);
64095
+ setAwaitingMobileDeposit(false);
64096
+ break;
64097
+ case "mobile_deposit_status":
64098
+ transitionTo("select_wallet");
64099
+ setMobileRedirect(null);
64100
+ setAwaitingMobileDeposit(false);
64101
+ break;
63729
64102
  case "select_token":
63730
64103
  if (walletProvidedAtMount.current) parentOnBack?.();
63731
64104
  else transitionTo("select_wallet");
@@ -63793,9 +64166,16 @@ function WalletConnect({
63793
64166
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
63794
64167
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
63795
64168
  };
63796
- const sendEthereumTransaction = async (token, amountStr) => {
63797
- if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
63798
- const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
64169
+ const resolveEvmProvider = () => {
64170
+ const walletIdMap = {
64171
+ "phantom-ethereum": "phantom",
64172
+ coinbase: "coinbase",
64173
+ trust: "trust",
64174
+ okx: "okx",
64175
+ rainbow: "rainbow",
64176
+ rabby: "rabby",
64177
+ metamask: "metamask"
64178
+ };
63799
64179
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
63800
64180
  const eip6963Match = findProviderByWalletId(lookupId);
63801
64181
  let provider = eip6963Match?.provider;
@@ -63804,6 +64184,11 @@ function WalletConnect({
63804
64184
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
63805
64185
  else provider = window.ethereum;
63806
64186
  }
64187
+ return provider;
64188
+ };
64189
+ const sendEthereumTransaction = async (token, amountStr) => {
64190
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
64191
+ const provider = resolveEvmProvider();
63807
64192
  if (!provider) throw new Error("Ethereum wallet not found");
63808
64193
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
63809
64194
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -63868,6 +64253,19 @@ function WalletConnect({
63868
64253
  const resp = await sendSolanaTransaction({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
63869
64254
  return resp.signature;
63870
64255
  };
64256
+ const sendHypercoreDeposit = async (token, amountStr) => {
64257
+ const provider = resolveEvmProvider();
64258
+ if (!provider) throw new Error("Ethereum wallet not found");
64259
+ const { signature } = await sendHypercoreEvmTransfer({
64260
+ provider,
64261
+ fromAddress: walletInfo.address,
64262
+ recipientAddress,
64263
+ sourceTokenAddress: token.token_address,
64264
+ amount: amountStr,
64265
+ publishableKey
64266
+ });
64267
+ return signature;
64268
+ };
63871
64269
  const handleConfirm = async () => {
63872
64270
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
63873
64271
  const token = getTokenFromBalance(selectedBalance);
@@ -63887,7 +64285,33 @@ function WalletConnect({
63887
64285
  setIsConfirming(true);
63888
64286
  setError(null);
63889
64287
  try {
63890
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction2(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
64288
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
64289
+ let txHash;
64290
+ if (token.chain_type === "solana") {
64291
+ txHash = await sendSolanaTransaction2(token, tokenAmount.toString());
64292
+ } else if (isHypercoreToken) {
64293
+ let sendAmount = tokenAmount;
64294
+ try {
64295
+ const activation = await checkHypercoreActivation(
64296
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
64297
+ publishableKey
64298
+ );
64299
+ if (!activation.user_exists) {
64300
+ const fee = activation.activation_fee;
64301
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
64302
+ throw new Error(
64303
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
64304
+ );
64305
+ }
64306
+ sendAmount = tokenAmount - fee;
64307
+ }
64308
+ } catch (e) {
64309
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
64310
+ }
64311
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
64312
+ } else {
64313
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
64314
+ }
63891
64315
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
63892
64316
  setHasSignedTransaction(true);
63893
64317
  handleIveDeposited();
@@ -63911,33 +64335,40 @@ function WalletConnect({
63911
64335
  return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63912
64336
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
63913
64337
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-pb-4", children: [
63914
- /* @__PURE__ */ (0, import_jsx_runtime73.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" }),
63915
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
63916
- "button",
63917
- {
63918
- onClick: () => handleWalletClick(wallet),
63919
- disabled: isWalletConnecting,
63920
- 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",
63921
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
63922
- children: [
63923
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
63924
- WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
63925
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
63926
- ] }),
63927
- wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime73.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_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
63928
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
63929
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
63930
- ] })
63931
- ]
63932
- },
63933
- wallet.id
63934
- )) }),
64338
+ /* @__PURE__ */ (0, import_jsx_runtime73.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" }),
64339
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
64340
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
64341
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
64342
+ const isPending = pendingMobileWallet?.id === wallet.id;
64343
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64344
+ "button",
64345
+ {
64346
+ onClick: () => void handleWalletClick(wallet),
64347
+ disabled: isWalletConnecting || !!pendingMobileWallet,
64348
+ 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",
64349
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
64350
+ children: [
64351
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64352
+ WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
64353
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
64354
+ ] }),
64355
+ isPending ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin", style: { color: colors2.primary } }) : wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime73.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_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
64356
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
64357
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
64358
+ ] })
64359
+ ]
64360
+ },
64361
+ wallet.id
64362
+ );
64363
+ }) }),
63935
64364
  walletError && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
63936
64365
  ] })
63937
64366
  ] });
63938
64367
  }
64368
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
64369
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
63939
64370
  if (view === "select_network" && selectedWalletDef) {
63940
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64371
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63941
64372
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
63942
64373
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-pb-4", children: [
63943
64374
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -63967,10 +64398,10 @@ function WalletConnect({
63967
64398
  )) }),
63968
64399
  walletError && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
63969
64400
  ] })
63970
- ] });
64401
+ ] }) });
63971
64402
  }
63972
64403
  if (view === "connecting") {
63973
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64404
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63974
64405
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
63975
64406
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
63976
64407
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(LoaderCircle, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -63981,41 +64412,149 @@ function WalletConnect({
63981
64412
  ] }),
63982
64413
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: "Please approve the connection in your wallet" })
63983
64414
  ] })
63984
- ] });
63985
- }
63986
- if (!hasWallet) return null;
63987
- if (view === "select_token") {
63988
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
63989
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
63990
- }
63991
- if (view === "enter_amount" && selectedToken && selectedBalance) {
63992
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
63993
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
63994
- }
63995
- if (view === "review" && selectedToken) {
63996
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
63997
- }) }) });
63998
- }
63999
- if (view === "confirming") {
64000
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
64001
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
64415
+ ] }) });
64002
64416
  }
64003
- return null;
64004
- }
64005
- function SkeletonButton({
64006
- variant = "default"
64007
- }) {
64008
- return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-animate-pulse", children: [
64009
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64010
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-bg-muted uf-rounded-lg uf-w-9 uf-h-9" }),
64011
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-space-y-1.5", children: [
64012
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-3.5 uf-w-24 uf-bg-muted uf-rounded" }),
64013
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded" })
64014
- ] })
64015
- ] }),
64016
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
64017
- variant === "with-icons" && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-flex uf--space-x-1", children: [1, 2, 3].map((i) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64018
- "div",
64417
+ if (view === "mobile_redirect" && mobileRedirect) {
64418
+ const Icon22 = WALLET_ICONS3[mobileRedirect.walletId];
64419
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64420
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
64421
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-px-6 uf-py-10", children: [
64422
+ Icon22 ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Icon22, { size: 64, className: "uf-rounded-2xl uf-mb-5" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-w-16 uf-h-16 uf-rounded-2xl uf-bg-gray-500 uf-mb-5" }),
64423
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64424
+ "div",
64425
+ {
64426
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
64427
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
64428
+ children: [
64429
+ "Continue in ",
64430
+ mobileRedirect.walletName
64431
+ ]
64432
+ }
64433
+ ),
64434
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64435
+ "div",
64436
+ {
64437
+ className: "uf-text-sm uf-text-center uf-mb-6",
64438
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
64439
+ children: [
64440
+ "Complete your deposit in the ",
64441
+ mobileRedirect.walletName,
64442
+ " app"
64443
+ ]
64444
+ }
64445
+ ),
64446
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64447
+ "button",
64448
+ {
64449
+ type: "button",
64450
+ onClick: () => {
64451
+ window.location.href = mobileRedirect.deeplink;
64452
+ },
64453
+ 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",
64454
+ style: {
64455
+ backgroundColor: components.card.backgroundColor,
64456
+ borderRadius: components.card.borderRadius,
64457
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
64458
+ color: components.card.titleColor,
64459
+ fontFamily: fonts.medium
64460
+ },
64461
+ children: [
64462
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
64463
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("span", { className: "uf-text-sm uf-font-medium", children: [
64464
+ "Open in ",
64465
+ mobileRedirect.walletName
64466
+ ] })
64467
+ ]
64468
+ }
64469
+ ),
64470
+ awaitingMobileDeposit && /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
64471
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64472
+ LoaderCircle,
64473
+ {
64474
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
64475
+ style: { color: colors2.foregroundMuted }
64476
+ }
64477
+ ),
64478
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64479
+ "span",
64480
+ {
64481
+ className: "uf-text-sm",
64482
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
64483
+ children: "Checking for deposit..."
64484
+ }
64485
+ )
64486
+ ] })
64487
+ ] })
64488
+ ] }) });
64489
+ }
64490
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
64491
+ const isComplete = latestDepositExecution.status === ExecutionStatus.SUCCEEDED;
64492
+ const isFailed = latestDepositExecution.status === ExecutionStatus.FAILED;
64493
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
64494
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64495
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64496
+ DepositHeader,
64497
+ {
64498
+ title,
64499
+ showBack: false,
64500
+ onClose: isComplete && onDone ? onDone : onClose
64501
+ }
64502
+ ),
64503
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositDetailContent, { execution: latestDepositExecution }),
64504
+ isComplete && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-4 uf-pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64505
+ "button",
64506
+ {
64507
+ type: "button",
64508
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
64509
+ }),
64510
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
64511
+ style: {
64512
+ backgroundColor: colors2.primary,
64513
+ color: colors2.primaryForeground,
64514
+ fontFamily: fonts.medium,
64515
+ borderRadius: components.button.borderRadius,
64516
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
64517
+ },
64518
+ children: "Done"
64519
+ }
64520
+ ) })
64521
+ ] }) });
64522
+ }
64523
+ if (!hasWallet) return null;
64524
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
64525
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
64526
+ if (view === "select_token") {
64527
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
64528
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
64529
+ }
64530
+ if (view === "enter_amount" && selectedToken && selectedBalance) {
64531
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
64532
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
64533
+ }
64534
+ if (view === "review" && selectedToken) {
64535
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
64536
+ }) }) }) });
64537
+ }
64538
+ if (view === "confirming") {
64539
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
64540
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
64541
+ }
64542
+ return null;
64543
+ }
64544
+ function SkeletonButton({
64545
+ variant = "default"
64546
+ }) {
64547
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-w-full uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-justify-between uf-animate-pulse", children: [
64548
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64549
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-bg-muted uf-rounded-lg uf-w-9 uf-h-9" }),
64550
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-space-y-1.5", children: [
64551
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-3.5 uf-w-24 uf-bg-muted uf-rounded" }),
64552
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded" })
64553
+ ] })
64554
+ ] }),
64555
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
64556
+ variant === "with-icons" && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-flex uf--space-x-1", children: [1, 2, 3].map((i) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64557
+ "div",
64019
64558
  {
64020
64559
  className: "uf-w-5 uf-h-5 uf-rounded-full uf-bg-muted uf-border-2 uf-border-secondary"
64021
64560
  },
@@ -64026,6 +64565,9 @@ function SkeletonButton({
64026
64565
  ] });
64027
64566
  }
64028
64567
  var t7 = i18n2.depositModal;
64568
+ function depositTabForScreen(screen) {
64569
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
64570
+ }
64029
64571
  function DepositModal({
64030
64572
  open,
64031
64573
  onOpenChange,
@@ -64061,6 +64603,7 @@ function DepositModal({
64061
64603
  theme = "dark",
64062
64604
  hideOverlay = false,
64063
64605
  initialScreen = "main",
64606
+ displayMode = "stacked",
64064
64607
  transferCryptoTitle = t7.transferCrypto.title,
64065
64608
  depositWithCardTitle = t7.depositWithCard.title,
64066
64609
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -64095,6 +64638,9 @@ function DepositModal({
64095
64638
  effectiveInitialScreen
64096
64639
  );
64097
64640
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = (0, import_react3.useState)(false);
64641
+ const [depositTab, setDepositTab] = (0, import_react3.useState)(
64642
+ () => depositTabForScreen(effectiveInitialScreen)
64643
+ );
64098
64644
  const resetViewTimeoutRef = (0, import_react3.useRef)(null);
64099
64645
  const [cardView, setCardView] = (0, import_react3.useState)(
64100
64646
  "amount"
@@ -64110,7 +64656,6 @@ function DepositModal({
64110
64656
  const [allExecutions, setAllExecutions] = (0, import_react3.useState)([]);
64111
64657
  const [selectedExecution, setSelectedExecution] = (0, import_react3.useState)(null);
64112
64658
  const [depositExecutions, setDepositExecutions] = (0, import_react3.useState)([]);
64113
- const isMobileView = useIsMobileViewport();
64114
64659
  const { projectConfig } = useProjectConfig({
64115
64660
  publishableKey,
64116
64661
  enabled: open
@@ -64393,6 +64938,7 @@ function DepositModal({
64393
64938
  resetViewTimeoutRef.current = null;
64394
64939
  }
64395
64940
  setView(effectiveInitialScreen);
64941
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
64396
64942
  setCardView("amount");
64397
64943
  setExchangeView("providers");
64398
64944
  setBrowserWalletInfo(null);
@@ -64421,6 +64967,7 @@ function DepositModal({
64421
64967
  } else if (view === "cashapp" && cashAppView !== "amount") {
64422
64968
  setCashAppView("amount");
64423
64969
  } else {
64970
+ setDepositTab(depositTabForScreen(view));
64424
64971
  setView("main");
64425
64972
  setCardView("amount");
64426
64973
  setExchangeView("providers");
@@ -64500,13 +65047,181 @@ function DepositModal({
64500
65047
  className: "uf-flex uf-justify-center uf-shrink-0"
64501
65048
  }
64502
65049
  ) });
65050
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65051
+ TransferCryptoButton,
65052
+ {
65053
+ onClick: () => setView("transfer"),
65054
+ title: transferCryptoTitle,
65055
+ subtitle: t7.transferCrypto.subtitle,
65056
+ featuredTokens: projectConfig?.transfer_crypto.networks
65057
+ },
65058
+ "transfer"
65059
+ ) : null;
65060
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65061
+ BrowserWalletButton,
65062
+ {
65063
+ onClick: handleBrowserWalletClick,
65064
+ onConnectClick: handleWalletConnectClick,
65065
+ onDisconnect: handleWalletDisconnect,
65066
+ chainType: browserWalletChainType,
65067
+ publishableKey,
65068
+ featuredWallets: projectConfig?.connect_wallet?.wallets
65069
+ },
65070
+ "wallet"
65071
+ ) : null;
65072
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65073
+ DepositWithCardButton,
65074
+ {
65075
+ onClick: () => setView("card"),
65076
+ title: depositWithCardTitle,
65077
+ subtitle: t7.depositWithCard.subtitle,
65078
+ paymentNetworks: projectConfig?.payment_networks.networks
65079
+ },
65080
+ "card"
65081
+ ) : null;
65082
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65083
+ PayWithExchangeButton,
65084
+ {
65085
+ onClick: () => setView("exchange"),
65086
+ title: payWithExchangeTitle,
65087
+ subtitle: t7.payWithExchange.subtitle,
65088
+ exchanges,
65089
+ loading: exchangesLoading
65090
+ },
65091
+ "exchange"
65092
+ ) : null;
65093
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65094
+ ConnectExchangeButton,
65095
+ {
65096
+ onClick: () => {
65097
+ setCoinbaseSkipToHoldings(true);
65098
+ setView("coinbase_connect");
65099
+ },
65100
+ onDisconnect: handleExchangeDisconnect,
65101
+ title: i18n2.connectExchange.title,
65102
+ subtitle: i18n2.connectExchange.subtitle,
65103
+ exchanges: integrationExchanges,
65104
+ connectedExchange
65105
+ },
65106
+ "connect-exchange"
65107
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65108
+ ConnectExchangeButton,
65109
+ {
65110
+ onClick: () => {
65111
+ setCoinbaseSkipToHoldings(false);
65112
+ setView("coinbase_connect");
65113
+ },
65114
+ title: i18n2.connectExchange.title,
65115
+ subtitle: i18n2.connectExchange.subtitle,
65116
+ exchanges: integrationExchanges
65117
+ },
65118
+ "connect-exchange"
65119
+ ) : null;
65120
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65121
+ CashAppButton,
65122
+ {
65123
+ onClick: () => setView("cashapp"),
65124
+ title: "Pay with Cash App",
65125
+ subtitle: "Deposit via Cash App",
65126
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
65127
+ },
65128
+ "cashapp"
65129
+ ) : null;
65130
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65131
+ DepositTrackerButton,
65132
+ {
65133
+ onClick: () => {
65134
+ setAllExecutions(depositExecutions);
65135
+ setView("tracker");
65136
+ },
65137
+ title: depositTrackerTitle,
65138
+ subtitle: depositTrackerSubTitle,
65139
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
65140
+ },
65141
+ "tracker"
65142
+ ) : null;
65143
+ const cryptoMenuButtons = [
65144
+ transferCryptoMenuButton,
65145
+ connectWalletMenuButton,
65146
+ payWithExchangeMenuButton,
65147
+ connectExchangeMenuButton
65148
+ ].filter(Boolean);
65149
+ const cashMenuButtons = [
65150
+ depositWithCardMenuButton,
65151
+ cashAppMenuButton
65152
+ ].filter(Boolean);
65153
+ const depositTabs = [
65154
+ { id: "crypto", label: "Use Crypto", buttons: cryptoMenuButtons },
65155
+ { id: "cash", label: "Use Cash", buttons: cashMenuButtons }
65156
+ ].filter((tab) => tab.buttons.length > 0);
65157
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
65158
+ const renderMainMenuBody = () => {
65159
+ if (depositPrerequisiteBody) {
65160
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
65161
+ }
65162
+ if (displayMode === "tabs" && activeDepositTab) {
65163
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { children: [
65164
+ depositTabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65165
+ "div",
65166
+ {
65167
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
65168
+ style: {
65169
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
65170
+ // the control reads as a soft surface rather than a solid bar.
65171
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
65172
+ backdropFilter: "blur(12px)",
65173
+ WebkitBackdropFilter: "blur(12px)"
65174
+ },
65175
+ role: "tablist",
65176
+ children: depositTabs.map((tab) => {
65177
+ const active = activeDepositTab.id === tab.id;
65178
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65179
+ "button",
65180
+ {
65181
+ type: "button",
65182
+ role: "tab",
65183
+ "aria-selected": active,
65184
+ onClick: () => setDepositTab(tab.id),
65185
+ className: "uf-flex-1 uf-py-2 uf-px-3 uf-rounded-lg uf-text-sm uf-transition-all",
65186
+ style: {
65187
+ // Active tab is a soft, blurred glass pill — a faint accent
65188
+ // tint with its own backdrop blur and a subtle border/shadow,
65189
+ // so it looks frosted instead of like a hard solid button.
65190
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
65191
+ backdropFilter: active ? "blur(8px)" : void 0,
65192
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
65193
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
65194
+ color: active ? colors2.foreground : colors2.foregroundMuted,
65195
+ fontFamily: fonts.medium
65196
+ },
65197
+ children: tab.label
65198
+ },
65199
+ tab.id
65200
+ );
65201
+ })
65202
+ }
65203
+ ),
65204
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
65205
+ depositTrackerMenuButton && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
65206
+ ] });
65207
+ }
65208
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-space-y-3", children: [
65209
+ transferCryptoMenuButton,
65210
+ connectWalletMenuButton,
65211
+ depositWithCardMenuButton,
65212
+ payWithExchangeMenuButton,
65213
+ connectExchangeMenuButton,
65214
+ cashAppMenuButton,
65215
+ depositTrackerMenuButton
65216
+ ] });
65217
+ };
64503
65218
  return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64504
65219
  Dialog2,
64505
65220
  {
64506
65221
  open: hideOverlay || open,
64507
65222
  onOpenChange: hideOverlay ? void 0 : handleClose,
64508
65223
  modal: !hideOverlay,
64509
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65224
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
64510
65225
  DialogContent2,
64511
65226
  {
64512
65227
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -64515,386 +65230,302 @@ function DepositModal({
64515
65230
  style: { backgroundColor: colors2.background },
64516
65231
  onPointerDownOutside: (e) => e.preventDefault(),
64517
65232
  onInteractOutside: (e) => e.preventDefault(),
64518
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64519
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64520
- DepositHeader,
64521
- {
64522
- title: modalTitle || "Deposit",
64523
- showClose: !hideOverlay,
64524
- onClose: handleClose,
64525
- showBalance: showBalanceHeader,
64526
- balanceAddress: recipientAddress,
64527
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64528
- balanceChainId: destinationChainId,
64529
- balanceTokenAddress: destinationTokenAddress,
64530
- projectName: projectConfig?.project_name,
64531
- publishableKey
64532
- }
64533
- ),
64534
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64535
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64536
- showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64537
- TransferCryptoButton,
64538
- {
64539
- onClick: () => setView("transfer"),
64540
- title: transferCryptoTitle,
64541
- subtitle: t7.transferCrypto.subtitle,
64542
- featuredTokens: projectConfig?.transfer_crypto.networks
64543
- }
64544
- ),
64545
- showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64546
- BrowserWalletButton,
65233
+ children: [
65234
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(DialogTitle2, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
65235
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65236
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65237
+ DepositHeader,
65238
+ {
65239
+ title: modalTitle || "Deposit",
65240
+ showClose: !hideOverlay,
65241
+ onClose: handleClose,
65242
+ showBalance: showBalanceHeader,
65243
+ balanceAddress: recipientAddress,
65244
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65245
+ balanceChainId: destinationChainId,
65246
+ balanceTokenAddress: destinationTokenAddress,
65247
+ projectName: projectConfig?.project_name,
65248
+ publishableKey
65249
+ }
65250
+ ),
65251
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65252
+ renderMainMenuBody(),
65253
+ depositPoweredByFooter
65254
+ ] })
65255
+ ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65256
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65257
+ DepositHeader,
65258
+ {
65259
+ title: transferCryptoTitle,
65260
+ showBack: showBackTransfer,
65261
+ onBack: handleBack,
65262
+ onClose: handleClose,
65263
+ showBalance: showBalanceHeader,
65264
+ balanceAddress: recipientAddress,
65265
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65266
+ balanceChainId: destinationChainId,
65267
+ balanceTokenAddress: destinationTokenAddress,
65268
+ projectName: projectConfig?.project_name,
65269
+ publishableKey
65270
+ }
65271
+ ),
65272
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65273
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65274
+ TransferCryptoSingleInput,
64547
65275
  {
64548
- onClick: handleBrowserWalletClick,
64549
- onConnectClick: handleWalletConnectClick,
64550
- onDisconnect: handleWalletDisconnect,
64551
- chainType: browserWalletChainType,
65276
+ userId,
64552
65277
  publishableKey,
64553
- featuredWallets: projectConfig?.connect_wallet?.wallets
65278
+ recipientAddress,
65279
+ destinationChainType,
65280
+ destinationChainId,
65281
+ destinationTokenAddress,
65282
+ defaultSourceChainType,
65283
+ defaultSourceChainId,
65284
+ defaultSourceTokenAddress,
65285
+ defaultSourceSymbol,
65286
+ depositConfirmationMode,
65287
+ onExecutionsChange: setDepositExecutions,
65288
+ onDepositSuccess,
65289
+ onDepositError,
65290
+ wallets
64554
65291
  }
64555
- ),
64556
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64557
- DepositWithCardButton,
65292
+ ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65293
+ TransferCryptoDoubleInput,
64558
65294
  {
64559
- onClick: () => setView("card"),
64560
- title: depositWithCardTitle,
64561
- subtitle: t7.depositWithCard.subtitle,
64562
- paymentNetworks: projectConfig?.payment_networks.networks
65295
+ userId,
65296
+ publishableKey,
65297
+ recipientAddress,
65298
+ destinationChainType,
65299
+ destinationChainId,
65300
+ destinationTokenAddress,
65301
+ defaultSourceChainType,
65302
+ defaultSourceChainId,
65303
+ defaultSourceTokenAddress,
65304
+ defaultSourceSymbol,
65305
+ depositConfirmationMode,
65306
+ onExecutionsChange: setDepositExecutions,
65307
+ onDepositSuccess,
65308
+ onDepositError,
65309
+ wallets
64563
65310
  }
64564
65311
  ),
64565
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64566
- PayWithExchangeButton,
65312
+ depositPoweredByFooter
65313
+ ] })
65314
+ ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65315
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65316
+ DepositHeader,
65317
+ {
65318
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
65319
+ showBack: showBackTracker,
65320
+ onBack: handleBack,
65321
+ onClose: handleClose
65322
+ }
65323
+ ),
65324
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65325
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65326
+ "div",
64567
65327
  {
64568
- onClick: () => setView("exchange"),
64569
- title: payWithExchangeTitle,
64570
- subtitle: t7.payWithExchange.subtitle,
64571
- exchanges,
64572
- loading: exchangesLoading
65328
+ className: "uf-text-sm",
65329
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
65330
+ children: "No deposits yet"
64573
65331
  }
64574
- ),
64575
- showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64576
- ConnectExchangeButton,
65332
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65333
+ DepositExecutionItem,
64577
65334
  {
64578
- onClick: () => {
64579
- setCoinbaseSkipToHoldings(true);
64580
- setView("coinbase_connect");
64581
- },
64582
- onDisconnect: handleExchangeDisconnect,
64583
- title: i18n2.connectExchange.title,
64584
- subtitle: i18n2.connectExchange.subtitle,
64585
- exchanges: integrationExchanges,
64586
- connectedExchange
64587
- }
64588
- ),
64589
- showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64590
- ConnectExchangeButton,
65335
+ execution,
65336
+ onClick: () => setSelectedExecution(execution)
65337
+ },
65338
+ execution.id
65339
+ )) }) }),
65340
+ depositPoweredByFooter
65341
+ ] })
65342
+ ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65343
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65344
+ DepositHeader,
65345
+ {
65346
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
65347
+ showBack: showBackCard,
65348
+ onBack: handleBack,
65349
+ onClose: handleClose,
65350
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
65351
+ showBalance: showBalanceHeader,
65352
+ balanceAddress: recipientAddress,
65353
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65354
+ balanceChainId: destinationChainId,
65355
+ balanceTokenAddress: destinationTokenAddress,
65356
+ projectName: projectConfig?.project_name,
65357
+ publishableKey
65358
+ }
65359
+ ),
65360
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65361
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65362
+ BuyWithCard,
64591
65363
  {
64592
- onClick: () => {
64593
- setCoinbaseSkipToHoldings(false);
64594
- setView("coinbase_connect");
64595
- },
64596
- title: i18n2.connectExchange.title,
64597
- subtitle: i18n2.connectExchange.subtitle,
64598
- exchanges: integrationExchanges
65364
+ userId,
65365
+ publishableKey,
65366
+ view: cardView,
65367
+ onViewChange: handleCardViewChange,
65368
+ destinationTokenSymbol,
65369
+ recipientAddress,
65370
+ destinationChainType,
65371
+ destinationChainId,
65372
+ destinationTokenAddress,
65373
+ onDepositSuccess,
65374
+ onDepositError,
65375
+ onEvent,
65376
+ themeClass,
65377
+ wallets,
65378
+ assetCdnUrl: projectConfig?.asset_cdn_url,
65379
+ hideDepositFlowInfo,
65380
+ hideDisplayDescription
64599
65381
  }
64600
65382
  ),
64601
- showCashApp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64602
- CashAppButton,
65383
+ depositPoweredByFooter
65384
+ ] })
65385
+ ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65386
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65387
+ DepositHeader,
65388
+ {
65389
+ title: payWithExchangeTitle,
65390
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
65391
+ onBack: handleBack,
65392
+ onClose: handleClose
65393
+ }
65394
+ ),
65395
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65396
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65397
+ PayWithExchange,
64603
65398
  {
64604
- onClick: () => setView("cashapp"),
64605
- title: "Pay with Cash App",
64606
- subtitle: "Deposit via Cash App",
64607
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
65399
+ userId,
65400
+ publishableKey,
65401
+ exchanges,
65402
+ view: exchangeView,
65403
+ onViewChange: setExchangeView,
65404
+ destinationTokenSymbol,
65405
+ recipientAddress,
65406
+ destinationChainType,
65407
+ destinationChainId,
65408
+ destinationTokenAddress,
65409
+ onDepositSuccess,
65410
+ onDepositError,
65411
+ wallets,
65412
+ defaultToken: defaultToken ?? null
64608
65413
  }
64609
65414
  ),
64610
- showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64611
- DepositTrackerButton,
64612
- {
64613
- onClick: () => {
64614
- setAllExecutions(depositExecutions);
64615
- setView("tracker");
64616
- },
64617
- title: depositTrackerTitle,
64618
- subtitle: depositTrackerSubTitle,
64619
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
64620
- }
64621
- )
64622
- ] }) }),
64623
- depositPoweredByFooter
64624
- ] })
64625
- ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64626
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64627
- DepositHeader,
64628
- {
64629
- title: transferCryptoTitle,
64630
- showBack: showBackTransfer,
64631
- onBack: handleBack,
64632
- onClose: handleClose,
64633
- showBalance: showBalanceHeader,
64634
- balanceAddress: recipientAddress,
64635
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64636
- balanceChainId: destinationChainId,
64637
- balanceTokenAddress: destinationTokenAddress,
64638
- projectName: projectConfig?.project_name,
64639
- publishableKey
64640
- }
64641
- ),
64642
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64643
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64644
- TransferCryptoSingleInput,
65415
+ depositPoweredByFooter
65416
+ ] })
65417
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65418
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65419
+ CoinbaseConnect,
64645
65420
  {
64646
- userId,
64647
65421
  publishableKey,
64648
- recipientAddress,
64649
- destinationChainType,
64650
- destinationChainId,
64651
- destinationTokenAddress,
64652
- defaultSourceChainType,
64653
- defaultSourceChainId,
64654
- defaultSourceTokenAddress,
64655
- defaultSourceSymbol,
64656
- depositConfirmationMode,
64657
- onExecutionsChange: setDepositExecutions,
64658
- onDepositSuccess,
64659
- onDepositError,
64660
- wallets
64661
- }
64662
- ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64663
- TransferCryptoDoubleInput,
64664
- {
64665
65422
  userId,
64666
- publishableKey,
65423
+ wallets,
64667
65424
  recipientAddress,
64668
- destinationChainType,
64669
- destinationChainId,
64670
- destinationTokenAddress,
65425
+ destinationTokenAddress: destinationTokenAddress ?? "",
65426
+ destinationChainId: destinationChainId ?? "",
65427
+ destinationChainType: destinationChainType ?? "",
65428
+ onTransferSuccess: (result) => {
65429
+ onDepositSuccess?.({
65430
+ message: "Transfer completed via Coinbase Connect",
65431
+ transaction: result
65432
+ });
65433
+ },
65434
+ onTransferError: (error) => {
65435
+ onDepositError?.({
65436
+ message: error.message,
65437
+ error
65438
+ });
65439
+ },
65440
+ onBack: handleBack,
65441
+ onClose: handleClose,
65442
+ onDisconnect: handleExchangeDisconnect,
65443
+ skipToHoldings: coinbaseSkipToHoldings,
65444
+ canGoBack: sessionOpenedFromMenu,
65445
+ onExecutionsChange: setDepositExecutions,
64671
65446
  defaultSourceChainType,
64672
65447
  defaultSourceChainId,
64673
65448
  defaultSourceTokenAddress,
64674
- defaultSourceSymbol,
64675
- depositConfirmationMode,
64676
- onExecutionsChange: setDepositExecutions,
64677
- onDepositSuccess,
64678
- onDepositError,
64679
- wallets
64680
- }
64681
- ),
64682
- depositPoweredByFooter
64683
- ] })
64684
- ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64685
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64686
- DepositHeader,
64687
- {
64688
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
64689
- showBack: showBackTracker,
64690
- onBack: handleBack,
64691
- onClose: handleClose
64692
- }
64693
- ),
64694
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64695
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64696
- "div",
64697
- {
64698
- className: "uf-text-sm",
64699
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
64700
- children: "No deposits yet"
64701
- }
64702
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64703
- DepositExecutionItem,
64704
- {
64705
- execution,
64706
- onClick: () => setSelectedExecution(execution)
64707
- },
64708
- execution.id
64709
- )) }) }),
64710
- depositPoweredByFooter
64711
- ] })
64712
- ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64713
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64714
- DepositHeader,
64715
- {
64716
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
64717
- showBack: showBackCard,
64718
- onBack: handleBack,
64719
- onClose: handleClose,
64720
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
64721
- showBalance: showBalanceHeader,
64722
- balanceAddress: recipientAddress,
64723
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64724
- balanceChainId: destinationChainId,
64725
- balanceTokenAddress: destinationTokenAddress,
64726
- projectName: projectConfig?.project_name,
64727
- publishableKey
64728
- }
64729
- ),
64730
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64731
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64732
- BuyWithCard,
64733
- {
64734
- userId,
64735
- publishableKey,
64736
- view: cardView,
64737
- onViewChange: handleCardViewChange,
64738
- destinationTokenSymbol,
64739
- recipientAddress,
64740
- destinationChainType,
64741
- destinationChainId,
64742
- destinationTokenAddress,
64743
- onDepositSuccess,
64744
- onDepositError,
64745
- onEvent,
64746
- themeClass,
64747
- wallets,
64748
- assetCdnUrl: projectConfig?.asset_cdn_url,
64749
- hideDepositFlowInfo,
64750
- hideDisplayDescription
65449
+ defaultSourceSymbol
64751
65450
  }
64752
65451
  ),
64753
65452
  depositPoweredByFooter
64754
- ] })
64755
- ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64756
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64757
- DepositHeader,
64758
- {
64759
- title: payWithExchangeTitle,
64760
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
64761
- onBack: handleBack,
64762
- onClose: handleClose
64763
- }
64764
- ),
64765
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65453
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64766
65454
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64767
- PayWithExchange,
65455
+ WalletConnect,
64768
65456
  {
65457
+ walletInfo: browserWalletInfo ?? void 0,
65458
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
65459
+ wallets,
64769
65460
  userId,
64770
65461
  publishableKey,
64771
- exchanges,
64772
- view: exchangeView,
64773
- onViewChange: setExchangeView,
64774
- destinationTokenSymbol,
64775
- recipientAddress,
64776
- destinationChainType,
64777
- destinationChainId,
64778
- destinationTokenAddress,
65462
+ assetCdnUrl: projectConfig?.asset_cdn_url,
65463
+ projectName: projectConfig?.project_name,
65464
+ onSuccess: (txHash) => {
65465
+ onDepositSuccess?.({
65466
+ message: "Transaction sent successfully",
65467
+ transaction: { txHash }
65468
+ });
65469
+ },
65470
+ onError: (error) => {
65471
+ onDepositError?.({
65472
+ message: error.message,
65473
+ error
65474
+ });
65475
+ },
64779
65476
  onDepositSuccess,
64780
65477
  onDepositError,
64781
- wallets,
64782
- defaultToken: defaultToken ?? null
65478
+ amountQuickSelect: browserWalletAmountQuickSelect,
65479
+ onWalletDisconnect: handleWalletDisconnect,
65480
+ onWalletConnected: (info, dw) => {
65481
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
65482
+ setStoredWalletState(info.type);
65483
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
65484
+ },
65485
+ onBack: handleBack,
65486
+ onClose: handleClose,
65487
+ defaultSourceChainType,
65488
+ defaultSourceChainId,
65489
+ defaultSourceTokenAddress,
65490
+ defaultSourceSymbol,
65491
+ canGoBack: sessionOpenedFromMenu,
65492
+ depositWalletsLoading: walletsLoading
64783
65493
  }
64784
65494
  ),
64785
65495
  depositPoweredByFooter
64786
- ] })
64787
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64788
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64789
- CoinbaseConnect,
64790
- {
64791
- publishableKey,
64792
- userId,
64793
- wallets,
64794
- recipientAddress,
64795
- destinationTokenAddress: destinationTokenAddress ?? "",
64796
- destinationChainId: destinationChainId ?? "",
64797
- destinationChainType: destinationChainType ?? "",
64798
- onTransferSuccess: (result) => {
64799
- onDepositSuccess?.({
64800
- message: "Transfer completed via Coinbase Connect",
64801
- transaction: result
64802
- });
64803
- },
64804
- onTransferError: (error) => {
64805
- onDepositError?.({
64806
- message: error.message,
64807
- error
64808
- });
64809
- },
64810
- onBack: handleBack,
64811
- onClose: handleClose,
64812
- onDisconnect: handleExchangeDisconnect,
64813
- skipToHoldings: coinbaseSkipToHoldings,
64814
- canGoBack: sessionOpenedFromMenu,
64815
- onExecutionsChange: setDepositExecutions,
64816
- defaultSourceChainType,
64817
- defaultSourceChainId,
64818
- defaultSourceTokenAddress,
64819
- defaultSourceSymbol
64820
- }
64821
- ),
64822
- depositPoweredByFooter
64823
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64824
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64825
- WalletConnect,
64826
- {
64827
- walletInfo: browserWalletInfo ?? void 0,
64828
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
64829
- wallets,
64830
- userId,
64831
- publishableKey,
64832
- assetCdnUrl: projectConfig?.asset_cdn_url,
64833
- projectName: projectConfig?.project_name,
64834
- onSuccess: (txHash) => {
64835
- onDepositSuccess?.({
64836
- message: "Transaction sent successfully",
64837
- transaction: { txHash }
64838
- });
64839
- },
64840
- onError: (error) => {
64841
- onDepositError?.({
64842
- message: error.message,
64843
- error
64844
- });
64845
- },
64846
- onDepositSuccess,
64847
- onDepositError,
64848
- amountQuickSelect: browserWalletAmountQuickSelect,
64849
- onWalletDisconnect: handleWalletDisconnect,
64850
- onWalletConnected: (info, dw) => {
64851
- setBrowserWalletInfo({ ...info, depositWallet: dw });
64852
- setStoredWalletState(info.type);
64853
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
64854
- },
64855
- onBack: handleBack,
64856
- onClose: handleClose,
64857
- defaultSourceChainType,
64858
- defaultSourceChainId,
64859
- defaultSourceTokenAddress,
64860
- defaultSourceSymbol,
64861
- canGoBack: sessionOpenedFromMenu,
64862
- depositWalletsLoading: walletsLoading
64863
- }
64864
- ),
64865
- depositPoweredByFooter
64866
- ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64867
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64868
- DepositHeader,
64869
- {
64870
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
64871
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
64872
- onBack: handleBack,
64873
- onClose: handleClose
64874
- }
64875
- ),
64876
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65496
+ ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64877
65497
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64878
- PayWithCashApp,
65498
+ DepositHeader,
64879
65499
  {
64880
- userId,
64881
- publishableKey,
64882
- recipientAddress,
64883
- destinationChainType,
64884
- destinationChainId,
64885
- destinationTokenAddress,
64886
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
64887
- view: cashAppView,
64888
- onViewChange: setCashAppView,
64889
- onAmountChange: setCashAppAmount,
64890
- onEvent,
64891
- onDepositSuccess,
64892
- onDepositError
65500
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
65501
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
65502
+ onBack: handleBack,
65503
+ onClose: handleClose
64893
65504
  }
64894
65505
  ),
64895
- depositPoweredByFooter
64896
- ] })
64897
- ] }) : null })
65506
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65507
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65508
+ PayWithCashApp,
65509
+ {
65510
+ userId,
65511
+ publishableKey,
65512
+ recipientAddress,
65513
+ destinationChainType,
65514
+ destinationChainId,
65515
+ destinationTokenAddress,
65516
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
65517
+ view: cashAppView,
65518
+ onViewChange: setCashAppView,
65519
+ onAmountChange: setCashAppAmount,
65520
+ onEvent,
65521
+ onDepositSuccess,
65522
+ onDepositError
65523
+ }
65524
+ ),
65525
+ depositPoweredByFooter
65526
+ ] })
65527
+ ] }) : null })
65528
+ ]
64898
65529
  }
64899
65530
  )
64900
65531
  }
@@ -64979,7 +65610,6 @@ function CheckoutModal({
64979
65610
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react29.useState)(null);
64980
65611
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react29.useState)(false);
64981
65612
  const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react29.useState)(() => getStoredWalletState()?.chainType);
64982
- const isMobileView = useIsMobileViewport();
64983
65613
  const [resolvedTheme, setResolvedTheme] = (0, import_react29.useState)(
64984
65614
  theme === "auto" ? "dark" : theme
64985
65615
  );
@@ -65405,7 +66035,7 @@ function CheckoutModal({
65405
66035
  featuredTokens: projectConfig?.transfer_crypto.networks
65406
66036
  }
65407
66037
  ),
65408
- showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
66038
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65409
66039
  BrowserWalletButton,
65410
66040
  {
65411
66041
  onClick: handleBrowserWalletClick,
@@ -66016,9 +66646,6 @@ function useVerifyRecipientAddress(params) {
66016
66646
  refetchOnWindowFocus: false
66017
66647
  });
66018
66648
  }
66019
- function isHypercoreChain(chainId) {
66020
- return chainId === HYPERCORE_CHAIN_ID;
66021
- }
66022
66649
  function useGetDepositAddress(params) {
66023
66650
  const {
66024
66651
  userId,
@@ -66945,8 +67572,6 @@ function WithdrawConfirmingView({
66945
67572
  className: "uf-text-sm uf-text-center",
66946
67573
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
66947
67574
  children: [
66948
- txInfo.amount,
66949
- " ",
66950
67575
  txInfo.sourceTokenSymbol,
66951
67576
  " to",
66952
67577
  " ",
@@ -67311,6 +67936,16 @@ function UnifoldProvider2({
67311
67936
  });
67312
67937
  promise.catch(() => {
67313
67938
  });
67939
+ if (!config2.recipientAddress) {
67940
+ const error = {
67941
+ message: "beginDeposit requires a `recipientAddress`.",
67942
+ code: "MISSING_RECIPIENT"
67943
+ };
67944
+ console.error(`[UnifoldProvider] ${error.message}`);
67945
+ depositPromiseRef.current.reject(error);
67946
+ depositPromiseRef.current = null;
67947
+ return promise;
67948
+ }
67314
67949
  setDepositConfig(config2);
67315
67950
  setIsOpen(true);
67316
67951
  return promise;
@@ -67577,6 +68212,7 @@ function UnifoldProvider2({
67577
68212
  hideDepositTracker: config?.hideDepositTracker,
67578
68213
  showBalanceHeader: config?.showBalanceHeader,
67579
68214
  transferInputVariant: config?.transferInputVariant,
68215
+ displayMode: config?.displayMode,
67580
68216
  enableTransferCrypto: config?.enableTransferCrypto,
67581
68217
  enableConnectWallet: config?.enableConnectWallet,
67582
68218
  enablePayWithExchange: config?.enablePayWithExchange,