@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.js CHANGED
@@ -43579,6 +43579,40 @@ async function getAddressBalances(address, chainType, publishableKey) {
43579
43579
  const data = await response.json();
43580
43580
  return data;
43581
43581
  }
43582
+ async function getExternalWallets(publishableKey) {
43583
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43584
+ validatePublishableKey(pk);
43585
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets`, {
43586
+ method: "GET",
43587
+ headers: {
43588
+ accept: "application/json",
43589
+ "x-publishable-key": pk
43590
+ }
43591
+ });
43592
+ if (!response.ok) {
43593
+ throw new Error(`Failed to fetch external wallets: ${response.statusText}`);
43594
+ }
43595
+ const data = await response.json();
43596
+ return data;
43597
+ }
43598
+ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey) {
43599
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43600
+ validatePublishableKey(pk);
43601
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets/mobile_deeplink`, {
43602
+ method: "POST",
43603
+ headers: {
43604
+ "Content-Type": "application/json",
43605
+ accept: "application/json",
43606
+ "x-publishable-key": pk
43607
+ },
43608
+ body: JSON.stringify({ wallet, deposit_addresses: depositAddresses })
43609
+ });
43610
+ if (!response.ok) {
43611
+ throw new Error(`Failed to generate wallet deep link: ${response.statusText}`);
43612
+ }
43613
+ const data = await response.json();
43614
+ return data;
43615
+ }
43582
43616
  async function getAddressBalance(address, chainType, chainId, tokenAddress, publishableKey) {
43583
43617
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43584
43618
  validatePublishableKey(pk);
@@ -43952,6 +43986,29 @@ async function getDepositQuote(request, publishableKey) {
43952
43986
  const json = await response.json();
43953
43987
  return json.data;
43954
43988
  }
43989
+ async function buildHypercoreTransaction(request, publishableKey) {
43990
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43991
+ validatePublishableKey(pk);
43992
+ const response = await fetch(
43993
+ `${API_BASE_URL}/v1/public/transactions/hypercore/build`,
43994
+ {
43995
+ method: "POST",
43996
+ headers: {
43997
+ accept: "application/json",
43998
+ "x-publishable-key": pk,
43999
+ "Content-Type": "application/json"
44000
+ },
44001
+ body: JSON.stringify(request)
44002
+ }
44003
+ );
44004
+ if (!response.ok) {
44005
+ const error = await response.json().catch(() => ({ message: response.statusText }));
44006
+ throw new Error(
44007
+ `Failed to build HyperCore transaction: ${error.message || response.statusText}`
44008
+ );
44009
+ }
44010
+ return response.json();
44011
+ }
43955
44012
  async function getCashAppLimits(currency = "usd", publishableKey) {
43956
44013
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43957
44014
  validatePublishableKey(pk);
@@ -44017,6 +44074,29 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
44017
44074
  }
44018
44075
  return response.json();
44019
44076
  }
44077
+ async function sendHypercoreTransaction(request, publishableKey) {
44078
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
44079
+ validatePublishableKey(pk);
44080
+ const response = await fetch(
44081
+ `${API_BASE_URL}/v1/public/transactions/hypercore/send`,
44082
+ {
44083
+ method: "POST",
44084
+ headers: {
44085
+ accept: "application/json",
44086
+ "x-publishable-key": pk,
44087
+ "Content-Type": "application/json"
44088
+ },
44089
+ body: JSON.stringify(request)
44090
+ }
44091
+ );
44092
+ if (!response.ok) {
44093
+ const error = await response.json().catch(() => ({ message: response.statusText }));
44094
+ throw new Error(
44095
+ `Failed to send HyperCore transaction: ${error.message || response.statusText}`
44096
+ );
44097
+ }
44098
+ return response.json();
44099
+ }
44020
44100
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
44021
44101
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
44022
44102
  return DepositEventType2;
@@ -50193,6 +50273,22 @@ function clearStoredWalletState() {
50193
50273
  } catch {
50194
50274
  }
50195
50275
  }
50276
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
50277
+ function getLastOpenedWallet() {
50278
+ if (typeof window === "undefined") return void 0;
50279
+ try {
50280
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
50281
+ } catch {
50282
+ return void 0;
50283
+ }
50284
+ }
50285
+ function setLastOpenedWallet(walletId) {
50286
+ if (typeof window === "undefined") return;
50287
+ try {
50288
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
50289
+ } catch {
50290
+ }
50291
+ }
50196
50292
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
50197
50293
  function isMobileViewport() {
50198
50294
  if (typeof window === "undefined") return false;
@@ -50549,6 +50645,36 @@ function ThemeProvider({
50549
50645
  );
50550
50646
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThemeContext.Provider, { value: contextValue, children });
50551
50647
  }
50648
+ function AccentColorOverride({
50649
+ accentColor,
50650
+ accentForeground,
50651
+ children
50652
+ }) {
50653
+ const parent = useTheme();
50654
+ const value = React37.useMemo(() => {
50655
+ if (!accentColor) return parent;
50656
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
50657
+ const nextColors = {
50658
+ ...parent.colors,
50659
+ primary: accentColor,
50660
+ primaryForeground: foreground
50661
+ };
50662
+ const nextComponents = {
50663
+ ...parent.components,
50664
+ button: {
50665
+ ...parent.components.button,
50666
+ primaryBackground: accentColor,
50667
+ primaryText: foreground
50668
+ },
50669
+ card: {
50670
+ ...parent.components.card,
50671
+ iconBackgroundColor: `${accentColor}26`
50672
+ }
50673
+ };
50674
+ return { ...parent, colors: nextColors, components: nextComponents };
50675
+ }, [parent, accentColor, accentForeground]);
50676
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThemeContext.Provider, { value, children });
50677
+ }
50552
50678
  function useTheme() {
50553
50679
  const context = React37.useContext(ThemeContext);
50554
50680
  if (!context) {
@@ -50968,7 +51094,7 @@ function DepositHeader({
50968
51094
  setShowBalanceSkeleton(false);
50969
51095
  return;
50970
51096
  }
50971
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
51097
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
50972
51098
  if (!supportedChainTypes.includes(
50973
51099
  balanceChainType
50974
51100
  )) {
@@ -51600,6 +51726,7 @@ function useDepositPolling({
51600
51726
  clientSecret,
51601
51727
  depositConfirmationMode = "auto_ui",
51602
51728
  depositWalletId,
51729
+ depositWalletIds,
51603
51730
  enabled = true,
51604
51731
  immediateDirectPolling = false,
51605
51732
  onDepositSuccess,
@@ -51745,21 +51872,25 @@ function useDepositPolling({
51745
51872
  setIsPolling(false);
51746
51873
  };
51747
51874
  }, [userId, publishableKey, clientSecret, enabled]);
51875
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
51748
51876
  (0, import_react10.useEffect)(() => {
51749
- if (!pollingEnabled || !depositWalletId) return;
51877
+ if (!pollingEnabled || !pollWalletIdsKey) return;
51878
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
51750
51879
  const triggerPoll = async () => {
51751
- try {
51752
- await pollDirectExecutions(
51753
- { deposit_wallet_id: depositWalletId },
51754
- publishableKey
51755
- );
51756
- } catch {
51757
- }
51880
+ await Promise.all(
51881
+ ids.map(
51882
+ (id) => pollDirectExecutions(
51883
+ { deposit_wallet_id: id },
51884
+ publishableKey
51885
+ ).catch(() => {
51886
+ })
51887
+ )
51888
+ );
51758
51889
  };
51759
51890
  triggerPoll();
51760
51891
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
51761
51892
  return () => clearInterval(interval);
51762
- }, [pollingEnabled, depositWalletId, publishableKey]);
51893
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
51763
51894
  const handleIveDeposited = () => {
51764
51895
  setPollingEnabled(true);
51765
51896
  setShowWaitingUi(true);
@@ -52948,6 +53079,7 @@ function BuyWithCard({
52948
53079
  if (!selectedProvider) return "0.000000";
52949
53080
  return selectedProvider.destination_amount.toFixed(6);
52950
53081
  };
53082
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
52951
53083
  const selectedCurrencyData = fiatCurrencies.find(
52952
53084
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
52953
53085
  );
@@ -53133,9 +53265,12 @@ function BuyWithCard({
53133
53265
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53134
53266
  "button",
53135
53267
  {
53136
- onClick: () => handleViewChange("quotes"),
53268
+ onClick: () => {
53269
+ if (canOpenProviderSelector) handleViewChange("quotes");
53270
+ },
53137
53271
  disabled: quotesLoading || quotes.length === 0,
53138
- 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",
53272
+ "aria-disabled": !canOpenProviderSelector,
53273
+ 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"}`,
53139
53274
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
53140
53275
  children: quotesLoading ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
53141
53276
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
@@ -53162,7 +53297,7 @@ function BuyWithCard({
53162
53297
  )
53163
53298
  ] })
53164
53299
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "uf-w-full uf-text-left", children: [
53165
- isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53300
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53166
53301
  "div",
53167
53302
  {
53168
53303
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -53198,7 +53333,7 @@ function BuyWithCard({
53198
53333
  ),
53199
53334
  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" }) })
53200
53335
  ] }),
53201
- quotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53336
+ canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53202
53337
  ChevronRight,
53203
53338
  {
53204
53339
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -60977,7 +61112,7 @@ function useHypercoreActivation(params) {
60977
61112
  publishableKey,
60978
61113
  enabled = true
60979
61114
  } = params;
60980
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
61115
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
60981
61116
  const recipient = recipientAddress?.trim() ?? "";
60982
61117
  const source = sourceAddress?.trim() ?? "";
60983
61118
  const hasAddresses = !!recipient && !!source;
@@ -62123,6 +62258,46 @@ function TransferCryptoDoubleInput({
62123
62258
  }
62124
62259
  ) });
62125
62260
  }
62261
+ function isHypercoreChain(chainId) {
62262
+ return chainId === HYPERCORE_CHAIN_ID;
62263
+ }
62264
+ async function sendHypercoreEvmTransfer(params) {
62265
+ const {
62266
+ provider,
62267
+ fromAddress,
62268
+ recipientAddress,
62269
+ sourceTokenAddress,
62270
+ amount,
62271
+ publishableKey
62272
+ } = params;
62273
+ const currentChainHex = await provider.request({
62274
+ method: "eth_chainId",
62275
+ params: []
62276
+ });
62277
+ const activeChainId = String(parseInt(currentChainHex, 16));
62278
+ const buildResult = await buildHypercoreTransaction(
62279
+ {
62280
+ signature_chain_id: activeChainId,
62281
+ recipient_address: recipientAddress,
62282
+ token_address: sourceTokenAddress,
62283
+ amount
62284
+ },
62285
+ publishableKey
62286
+ );
62287
+ const signature = await provider.request({
62288
+ method: "eth_signTypedData_v4",
62289
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
62290
+ });
62291
+ await sendHypercoreTransaction(
62292
+ {
62293
+ action_payload: buildResult.action_payload,
62294
+ signature,
62295
+ nonce: buildResult.nonce
62296
+ },
62297
+ publishableKey
62298
+ );
62299
+ return { signature };
62300
+ }
62126
62301
  function useDepositQuote(params) {
62127
62302
  const {
62128
62303
  publishableKey,
@@ -62174,6 +62349,60 @@ function useDepositQuote(params) {
62174
62349
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 5e3)
62175
62350
  });
62176
62351
  }
62352
+ function useExternalWallets({
62353
+ publishableKey,
62354
+ enabled = true
62355
+ }) {
62356
+ const { data: wallets = [], isLoading } = useQuery({
62357
+ queryKey: ["unifold", "external-wallets", publishableKey],
62358
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
62359
+ enabled: enabled && !!publishableKey,
62360
+ staleTime: 1e3 * 60 * 30,
62361
+ refetchOnMount: false,
62362
+ refetchOnWindowFocus: false
62363
+ });
62364
+ return { wallets, isLoading };
62365
+ }
62366
+ var WALLET_BRAND_COLORS = {
62367
+ phantom: "#AB9FF2",
62368
+ metamask: "#F6851B",
62369
+ coinbase: "#0052FF",
62370
+ trust: "#3375BB",
62371
+ rainbow: "#5B6CFF",
62372
+ rabby: "#7084FF",
62373
+ okx: "#000000"
62374
+ };
62375
+ function normalizeWalletId(type) {
62376
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
62377
+ }
62378
+ function getWalletBrandColor(type, mode = "dark") {
62379
+ if (!type) return void 0;
62380
+ const id = normalizeWalletId(type);
62381
+ const color = WALLET_BRAND_COLORS[id];
62382
+ if (!color) return void 0;
62383
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
62384
+ return color;
62385
+ }
62386
+ function getContrastingTextColor(hex) {
62387
+ const c = hex.replace("#", "");
62388
+ if (c.length !== 6) return "#FFFFFF";
62389
+ const r2 = parseInt(c.slice(0, 2), 16);
62390
+ const g = parseInt(c.slice(2, 4), 16);
62391
+ const b = parseInt(c.slice(4, 6), 16);
62392
+ const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
62393
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
62394
+ }
62395
+ function isMobileDevice() {
62396
+ if (typeof navigator === "undefined") return false;
62397
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
62398
+ }
62399
+ function getMobilePlatform() {
62400
+ if (typeof navigator === "undefined") return null;
62401
+ const ua = navigator.userAgent;
62402
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
62403
+ if (/android/i.test(ua)) return "android";
62404
+ return null;
62405
+ }
62177
62406
  var WALLET_ICONS = {
62178
62407
  metamask: MetamaskIcon,
62179
62408
  phantom: PhantomIcon,
@@ -62476,7 +62705,8 @@ function EnterAmountView({
62476
62705
  onClose,
62477
62706
  quickSelectMode,
62478
62707
  checkoutAmountUsd,
62479
- checkoutReceivedUsd
62708
+ checkoutReceivedUsd,
62709
+ footer
62480
62710
  }) {
62481
62711
  const { colors: colors2, fonts, components } = useTheme();
62482
62712
  const isCheckout = !!checkoutAmountUsd;
@@ -62732,6 +62962,7 @@ function EnterAmountView({
62732
62962
  )
62733
62963
  ] })
62734
62964
  ] }),
62965
+ footer && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
62735
62966
  /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
62736
62967
  "button",
62737
62968
  {
@@ -63179,18 +63410,33 @@ var WALLET_ICONS3 = {
63179
63410
  backpack: BackpackIcon,
63180
63411
  glow: GlowIcon
63181
63412
  };
63182
- var WALLET_DEFINITIONS = [
63183
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
63184
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
63185
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
63186
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
63187
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
63188
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
63189
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
63190
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
63191
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
63192
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
63413
+ var FALLBACK_WALLET_DEFINITIONS = [
63414
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
63415
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
63416
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
63417
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
63418
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
63419
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
63420
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
63193
63421
  ];
63422
+ function getMobileInstallUrl(walletId, defaultUrl) {
63423
+ if (!isMobileDevice()) return defaultUrl;
63424
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
63425
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
63426
+ const stores = {
63427
+ rabby: {
63428
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
63429
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
63430
+ },
63431
+ glow: {
63432
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
63433
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
63434
+ }
63435
+ };
63436
+ const entry = stores[walletId];
63437
+ if (!entry) return defaultUrl;
63438
+ return isIOS ? entry.ios : entry.android;
63439
+ }
63194
63440
  function normalizeTokenAddress(address) {
63195
63441
  const normalized = (address ?? "").toLowerCase();
63196
63442
  if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
@@ -63226,7 +63472,7 @@ function getLegacyEvmProviders() {
63226
63472
  okxEthereum: win.okxwallet
63227
63473
  };
63228
63474
  }
63229
- function detectAvailableWallets(filterChainType) {
63475
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
63230
63476
  const solProviders = getSolanaProviders();
63231
63477
  const legacyEvm = getLegacyEvmProviders();
63232
63478
  const eip6963List = getEip6963Providers();
@@ -63252,7 +63498,7 @@ function detectAvailableWallets(filterChainType) {
63252
63498
  return false;
63253
63499
  }
63254
63500
  });
63255
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63501
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63256
63502
  let isInstalled = false;
63257
63503
  const detectedNetworks = [];
63258
63504
  switch (wallet.id) {
@@ -63275,8 +63521,6 @@ function detectAvailableWallets(filterChainType) {
63275
63521
  isInstalled = true;
63276
63522
  detectedNetworks.push("ethereum");
63277
63523
  }
63278
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
63279
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
63280
63524
  break;
63281
63525
  case "trust":
63282
63526
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -63313,11 +63557,17 @@ function detectAvailableWallets(filterChainType) {
63313
63557
  }
63314
63558
  return { ...wallet, isInstalled, detectedNetworks };
63315
63559
  }).sort((a, b) => {
63560
+ if (recentWalletId) {
63561
+ const aRecent = a.id === recentWalletId ? 1 : 0;
63562
+ const bRecent = b.id === recentWalletId ? 1 : 0;
63563
+ if (aRecent !== bRecent) return bRecent - aRecent;
63564
+ }
63316
63565
  if (a.isInstalled && !b.isInstalled) return -1;
63317
63566
  if (!a.isInstalled && b.isInstalled) return 1;
63318
63567
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
63319
63568
  return 0;
63320
63569
  });
63570
+ return sorted;
63321
63571
  }
63322
63572
  function WalletConnect({
63323
63573
  walletInfo: initialWalletInfo,
@@ -63356,7 +63606,7 @@ function WalletConnect({
63356
63606
  depositWalletsLoading = false,
63357
63607
  onExecutionsChange
63358
63608
  }) {
63359
- const { colors: colors2, fonts, components } = useTheme();
63609
+ const { colors: colors2, fonts, components, mode } = useTheme();
63360
63610
  const walletProvidedAtMount = React302.useRef(!!initialWalletInfo && !!initialDepositWallet);
63361
63611
  const [activeWalletInfo, setActiveWalletInfo] = React302.useState(initialWalletInfo ?? null);
63362
63612
  const [activeDepositWallet, setActiveDepositWallet] = React302.useState(initialDepositWallet ?? null);
@@ -63380,7 +63630,43 @@ function WalletConnect({
63380
63630
  setEip6963ProviderCount(providers.length);
63381
63631
  });
63382
63632
  }, []);
63383
- const availableWallets = React302.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
63633
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
63634
+ const walletDefinitions = React302.useMemo(
63635
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
63636
+ id: w.id,
63637
+ name: w.name,
63638
+ networks: w.chain_types,
63639
+ installUrl: w.install_url,
63640
+ supportsMobileBrowse: w.supports_mobile_browse,
63641
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
63642
+ })) : FALLBACK_WALLET_DEFINITIONS,
63643
+ [backendWallets]
63644
+ );
63645
+ const [recentWalletId, setRecentWalletIdState] = React302.useState(getLastOpenedWallet);
63646
+ React302.useEffect(() => {
63647
+ if (view === "select_wallet") {
63648
+ setRecentWalletIdState(getLastOpenedWallet());
63649
+ }
63650
+ }, [view]);
63651
+ const availableWallets = React302.useMemo(
63652
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
63653
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
63654
+ );
63655
+ const [isMobile, setIsMobile] = React302.useState(false);
63656
+ React302.useEffect(() => {
63657
+ setIsMobile(isMobileDevice());
63658
+ }, []);
63659
+ const mobileDepositAddresses = React302.useMemo(
63660
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
63661
+ [depositWallets]
63662
+ );
63663
+ const mobileDepositWalletIds = React302.useMemo(
63664
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
63665
+ [depositWallets]
63666
+ );
63667
+ const [mobileRedirect, setMobileRedirect] = React302.useState(null);
63668
+ const [pendingMobileWallet, setPendingMobileWallet] = React302.useState(null);
63669
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React302.useState(false);
63384
63670
  React302.useEffect(() => {
63385
63671
  if (!standalone || autoResolved || detectingWallet) return;
63386
63672
  if (!detectedWallet) {
@@ -63424,7 +63710,7 @@ function WalletConnect({
63424
63710
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
63425
63711
  const recipientAddress = activeDepositWallet?.address ?? "";
63426
63712
  const isCheckoutMode = !!checkoutAmountUsd;
63427
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
63713
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
63428
63714
  const transitionTo = React302.useCallback((nextView) => {
63429
63715
  if (nextView === viewRef.current) return;
63430
63716
  setIsTransitioning(true);
@@ -63439,9 +63725,38 @@ function WalletConnect({
63439
63725
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
63440
63726
  transition: "opacity 150ms ease, transform 150ms ease"
63441
63727
  };
63442
- const handleWalletClick = (wallet) => {
63728
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
63729
+ try {
63730
+ const res = await getWalletMobileDeepLink(
63731
+ wallet.id,
63732
+ depositAddresses,
63733
+ publishableKey
63734
+ );
63735
+ if (res.deeplink) {
63736
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
63737
+ setLastOpenedWallet(wallet.id);
63738
+ setRecentWalletIdState(wallet.id);
63739
+ setAwaitingMobileDeposit(true);
63740
+ transitionTo("mobile_redirect");
63741
+ window.location.href = res.deeplink;
63742
+ return true;
63743
+ }
63744
+ } catch {
63745
+ }
63746
+ return false;
63747
+ };
63748
+ const handleWalletClick = async (wallet) => {
63443
63749
  if (!wallet.isInstalled) {
63444
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
63750
+ const platform2 = getMobilePlatform();
63751
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform2 ?? "");
63752
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
63753
+ if (mobileDepositAddresses.length === 0) {
63754
+ setPendingMobileWallet(wallet);
63755
+ return;
63756
+ }
63757
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
63758
+ }
63759
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
63445
63760
  return;
63446
63761
  }
63447
63762
  setSelectedWalletDef(wallet);
@@ -63457,9 +63772,32 @@ function WalletConnect({
63457
63772
  if (!selectedWalletDef) return;
63458
63773
  handleConnectWallet(selectedWalletDef, network);
63459
63774
  };
63775
+ React302.useEffect(() => {
63776
+ if (!pendingMobileWallet) return;
63777
+ if (mobileDepositAddresses.length > 0) {
63778
+ const wallet = pendingMobileWallet;
63779
+ setPendingMobileWallet(null);
63780
+ void (async () => {
63781
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
63782
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
63783
+ }
63784
+ })();
63785
+ return;
63786
+ }
63787
+ const timeout = setTimeout(() => {
63788
+ setPendingMobileWallet((current) => {
63789
+ if (!current) return null;
63790
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
63791
+ return null;
63792
+ });
63793
+ }, 8e3);
63794
+ return () => clearTimeout(timeout);
63795
+ }, [pendingMobileWallet, mobileDepositAddresses]);
63460
63796
  const handleConnectWallet = async (wallet, network) => {
63461
63797
  setConnectingNetwork(network);
63462
63798
  transitionTo("connecting");
63799
+ setLastOpenedWallet(wallet.id);
63800
+ setRecentWalletIdState(wallet.id);
63463
63801
  setWalletError(null);
63464
63802
  setIsWalletConnecting(true);
63465
63803
  try {
@@ -63564,6 +63902,13 @@ function WalletConnect({
63564
63902
  }
63565
63903
  };
63566
63904
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
63905
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
63906
+ recipientAddress,
63907
+ sourceAddress: activeWalletInfo?.address,
63908
+ destinationChainId: selectedToken?.chain_id,
63909
+ publishableKey,
63910
+ enabled: !!activeWalletInfo && !!recipientAddress
63911
+ });
63567
63912
  const effectiveDestinationAmount = React302.useMemo(() => {
63568
63913
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
63569
63914
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -63601,14 +63946,32 @@ function WalletConnect({
63601
63946
  userId,
63602
63947
  publishableKey,
63603
63948
  clientSecret,
63949
+ // In-tab flow: poll the single connected deposit wallet.
63604
63950
  depositWalletId: activeDepositWallet?.id ?? "",
63605
- enabled: hasSignedTransaction && !!activeDepositWallet,
63951
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
63952
+ // chain's deposit wallet. Detection still happens via the single /query by
63953
+ // external_user_id, which already spans all chains.
63954
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
63955
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
63606
63956
  onDepositSuccess,
63607
63957
  onDepositError
63608
63958
  });
63609
63959
  React302.useEffect(() => {
63610
63960
  onExecutionsChange?.(depositExecutions);
63611
63961
  }, [depositExecutions, onExecutionsChange]);
63962
+ const latestDepositExecution = React302.useMemo(() => {
63963
+ if (depositExecutions.length === 0) return null;
63964
+ return [...depositExecutions].sort((a, b) => {
63965
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
63966
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
63967
+ return tb - ta;
63968
+ })[0];
63969
+ }, [depositExecutions]);
63970
+ React302.useEffect(() => {
63971
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
63972
+ transitionTo("mobile_deposit_status");
63973
+ }
63974
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
63612
63975
  React302.useEffect(() => {
63613
63976
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
63614
63977
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -63650,7 +64013,7 @@ function WalletConnect({
63650
64013
  let cancelled = false;
63651
64014
  setIsLoading(true);
63652
64015
  setError(null);
63653
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
64016
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
63654
64017
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
63655
64018
  if (cancelled) return;
63656
64019
  const nonZero = response.balances.filter((b) => b.amount !== "0");
@@ -63739,6 +64102,16 @@ function WalletConnect({
63739
64102
  setSelectedWalletDef(null);
63740
64103
  setConnectingNetwork(null);
63741
64104
  break;
64105
+ case "mobile_redirect":
64106
+ transitionTo("select_wallet");
64107
+ setMobileRedirect(null);
64108
+ setAwaitingMobileDeposit(false);
64109
+ break;
64110
+ case "mobile_deposit_status":
64111
+ transitionTo("select_wallet");
64112
+ setMobileRedirect(null);
64113
+ setAwaitingMobileDeposit(false);
64114
+ break;
63742
64115
  case "select_token":
63743
64116
  if (walletProvidedAtMount.current) parentOnBack?.();
63744
64117
  else transitionTo("select_wallet");
@@ -63806,9 +64179,16 @@ function WalletConnect({
63806
64179
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
63807
64180
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
63808
64181
  };
63809
- const sendEthereumTransaction = async (token, amountStr) => {
63810
- if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
63811
- const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
64182
+ const resolveEvmProvider = () => {
64183
+ const walletIdMap = {
64184
+ "phantom-ethereum": "phantom",
64185
+ coinbase: "coinbase",
64186
+ trust: "trust",
64187
+ okx: "okx",
64188
+ rainbow: "rainbow",
64189
+ rabby: "rabby",
64190
+ metamask: "metamask"
64191
+ };
63812
64192
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
63813
64193
  const eip6963Match = findProviderByWalletId(lookupId);
63814
64194
  let provider = eip6963Match?.provider;
@@ -63817,6 +64197,11 @@ function WalletConnect({
63817
64197
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
63818
64198
  else provider = window.ethereum;
63819
64199
  }
64200
+ return provider;
64201
+ };
64202
+ const sendEthereumTransaction = async (token, amountStr) => {
64203
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
64204
+ const provider = resolveEvmProvider();
63820
64205
  if (!provider) throw new Error("Ethereum wallet not found");
63821
64206
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
63822
64207
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -63881,6 +64266,19 @@ function WalletConnect({
63881
64266
  const resp = await sendSolanaTransaction({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
63882
64267
  return resp.signature;
63883
64268
  };
64269
+ const sendHypercoreDeposit = async (token, amountStr) => {
64270
+ const provider = resolveEvmProvider();
64271
+ if (!provider) throw new Error("Ethereum wallet not found");
64272
+ const { signature } = await sendHypercoreEvmTransfer({
64273
+ provider,
64274
+ fromAddress: walletInfo.address,
64275
+ recipientAddress,
64276
+ sourceTokenAddress: token.token_address,
64277
+ amount: amountStr,
64278
+ publishableKey
64279
+ });
64280
+ return signature;
64281
+ };
63884
64282
  const handleConfirm = async () => {
63885
64283
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
63886
64284
  const token = getTokenFromBalance(selectedBalance);
@@ -63900,7 +64298,33 @@ function WalletConnect({
63900
64298
  setIsConfirming(true);
63901
64299
  setError(null);
63902
64300
  try {
63903
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction2(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
64301
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
64302
+ let txHash;
64303
+ if (token.chain_type === "solana") {
64304
+ txHash = await sendSolanaTransaction2(token, tokenAmount.toString());
64305
+ } else if (isHypercoreToken) {
64306
+ let sendAmount = tokenAmount;
64307
+ try {
64308
+ const activation = await checkHypercoreActivation(
64309
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
64310
+ publishableKey
64311
+ );
64312
+ if (!activation.user_exists) {
64313
+ const fee = activation.activation_fee;
64314
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
64315
+ throw new Error(
64316
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
64317
+ );
64318
+ }
64319
+ sendAmount = tokenAmount - fee;
64320
+ }
64321
+ } catch (e) {
64322
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
64323
+ }
64324
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
64325
+ } else {
64326
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
64327
+ }
63904
64328
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
63905
64329
  setHasSignedTransaction(true);
63906
64330
  handleIveDeposited();
@@ -63924,33 +64348,40 @@ function WalletConnect({
63924
64348
  return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63925
64349
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
63926
64350
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-pb-4", children: [
63927
- /* @__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" }),
63928
- /* @__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)(
63929
- "button",
63930
- {
63931
- onClick: () => handleWalletClick(wallet),
63932
- disabled: isWalletConnecting,
63933
- 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",
63934
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
63935
- children: [
63936
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
63937
- 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" }),
63938
- /* @__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 })
63939
- ] }),
63940
- 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: [
63941
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
63942
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
63943
- ] })
63944
- ]
63945
- },
63946
- wallet.id
63947
- )) }),
64351
+ /* @__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" }),
64352
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
64353
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
64354
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
64355
+ const isPending = pendingMobileWallet?.id === wallet.id;
64356
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64357
+ "button",
64358
+ {
64359
+ onClick: () => void handleWalletClick(wallet),
64360
+ disabled: isWalletConnecting || !!pendingMobileWallet,
64361
+ 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",
64362
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
64363
+ children: [
64364
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64365
+ 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" }),
64366
+ /* @__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 })
64367
+ ] }),
64368
+ 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: [
64369
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
64370
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
64371
+ ] })
64372
+ ]
64373
+ },
64374
+ wallet.id
64375
+ );
64376
+ }) }),
63948
64377
  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 })
63949
64378
  ] })
63950
64379
  ] });
63951
64380
  }
64381
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
64382
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
63952
64383
  if (view === "select_network" && selectedWalletDef) {
63953
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64384
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63954
64385
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
63955
64386
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-pb-4", children: [
63956
64387
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -63980,10 +64411,10 @@ function WalletConnect({
63980
64411
  )) }),
63981
64412
  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 })
63982
64413
  ] })
63983
- ] });
64414
+ ] }) });
63984
64415
  }
63985
64416
  if (view === "connecting") {
63986
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64417
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63987
64418
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
63988
64419
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
63989
64420
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(LoaderCircle, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -63994,41 +64425,149 @@ function WalletConnect({
63994
64425
  ] }),
63995
64426
  /* @__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" })
63996
64427
  ] })
63997
- ] });
63998
- }
63999
- if (!hasWallet) return null;
64000
- if (view === "select_token") {
64001
- 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 ?? (() => {
64002
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
64003
- }
64004
- if (view === "enter_amount" && selectedToken && selectedBalance) {
64005
- 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 ?? (() => {
64006
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
64007
- }
64008
- if (view === "review" && selectedToken) {
64009
- 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 ?? (() => {
64010
- }) }) });
64011
- }
64012
- if (view === "confirming") {
64013
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
64014
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
64428
+ ] }) });
64015
64429
  }
64016
- return null;
64017
- }
64018
- function SkeletonButton({
64019
- variant = "default"
64020
- }) {
64021
- 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: [
64022
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64023
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-bg-muted uf-rounded-lg uf-w-9 uf-h-9" }),
64024
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-space-y-1.5", children: [
64025
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-3.5 uf-w-24 uf-bg-muted uf-rounded" }),
64026
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded" })
64027
- ] })
64028
- ] }),
64029
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
64030
- 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)(
64031
- "div",
64430
+ if (view === "mobile_redirect" && mobileRedirect) {
64431
+ const Icon22 = WALLET_ICONS3[mobileRedirect.walletId];
64432
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64433
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
64434
+ /* @__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: [
64435
+ 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" }),
64436
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64437
+ "div",
64438
+ {
64439
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
64440
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
64441
+ children: [
64442
+ "Continue in ",
64443
+ mobileRedirect.walletName
64444
+ ]
64445
+ }
64446
+ ),
64447
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64448
+ "div",
64449
+ {
64450
+ className: "uf-text-sm uf-text-center uf-mb-6",
64451
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
64452
+ children: [
64453
+ "Complete your deposit in the ",
64454
+ mobileRedirect.walletName,
64455
+ " app"
64456
+ ]
64457
+ }
64458
+ ),
64459
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64460
+ "button",
64461
+ {
64462
+ type: "button",
64463
+ onClick: () => {
64464
+ window.location.href = mobileRedirect.deeplink;
64465
+ },
64466
+ 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",
64467
+ style: {
64468
+ backgroundColor: components.card.backgroundColor,
64469
+ borderRadius: components.card.borderRadius,
64470
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
64471
+ color: components.card.titleColor,
64472
+ fontFamily: fonts.medium
64473
+ },
64474
+ children: [
64475
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
64476
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("span", { className: "uf-text-sm uf-font-medium", children: [
64477
+ "Open in ",
64478
+ mobileRedirect.walletName
64479
+ ] })
64480
+ ]
64481
+ }
64482
+ ),
64483
+ awaitingMobileDeposit && /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
64484
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64485
+ LoaderCircle,
64486
+ {
64487
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
64488
+ style: { color: colors2.foregroundMuted }
64489
+ }
64490
+ ),
64491
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64492
+ "span",
64493
+ {
64494
+ className: "uf-text-sm",
64495
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
64496
+ children: "Checking for deposit..."
64497
+ }
64498
+ )
64499
+ ] })
64500
+ ] })
64501
+ ] }) });
64502
+ }
64503
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
64504
+ const isComplete = latestDepositExecution.status === ExecutionStatus.SUCCEEDED;
64505
+ const isFailed = latestDepositExecution.status === ExecutionStatus.FAILED;
64506
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
64507
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64508
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64509
+ DepositHeader,
64510
+ {
64511
+ title,
64512
+ showBack: false,
64513
+ onClose: isComplete && onDone ? onDone : onClose
64514
+ }
64515
+ ),
64516
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositDetailContent, { execution: latestDepositExecution }),
64517
+ 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)(
64518
+ "button",
64519
+ {
64520
+ type: "button",
64521
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
64522
+ }),
64523
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
64524
+ style: {
64525
+ backgroundColor: colors2.primary,
64526
+ color: colors2.primaryForeground,
64527
+ fontFamily: fonts.medium,
64528
+ borderRadius: components.button.borderRadius,
64529
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
64530
+ },
64531
+ children: "Done"
64532
+ }
64533
+ ) })
64534
+ ] }) });
64535
+ }
64536
+ if (!hasWallet) return null;
64537
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
64538
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
64539
+ if (view === "select_token") {
64540
+ 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 ?? (() => {
64541
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
64542
+ }
64543
+ if (view === "enter_amount" && selectedToken && selectedBalance) {
64544
+ 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 ?? (() => {
64545
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
64546
+ }
64547
+ if (view === "review" && selectedToken) {
64548
+ 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 ?? (() => {
64549
+ }) }) }) });
64550
+ }
64551
+ if (view === "confirming") {
64552
+ 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 ?? (() => {
64553
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
64554
+ }
64555
+ return null;
64556
+ }
64557
+ function SkeletonButton({
64558
+ variant = "default"
64559
+ }) {
64560
+ 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: [
64561
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64562
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-bg-muted uf-rounded-lg uf-w-9 uf-h-9" }),
64563
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-space-y-1.5", children: [
64564
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-3.5 uf-w-24 uf-bg-muted uf-rounded" }),
64565
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded" })
64566
+ ] })
64567
+ ] }),
64568
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
64569
+ 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)(
64570
+ "div",
64032
64571
  {
64033
64572
  className: "uf-w-5 uf-h-5 uf-rounded-full uf-bg-muted uf-border-2 uf-border-secondary"
64034
64573
  },
@@ -64039,6 +64578,9 @@ function SkeletonButton({
64039
64578
  ] });
64040
64579
  }
64041
64580
  var t7 = i18n2.depositModal;
64581
+ function depositTabForScreen(screen) {
64582
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
64583
+ }
64042
64584
  function DepositModal({
64043
64585
  open,
64044
64586
  onOpenChange,
@@ -64074,6 +64616,7 @@ function DepositModal({
64074
64616
  theme = "dark",
64075
64617
  hideOverlay = false,
64076
64618
  initialScreen = "main",
64619
+ displayMode = "stacked",
64077
64620
  transferCryptoTitle = t7.transferCrypto.title,
64078
64621
  depositWithCardTitle = t7.depositWithCard.title,
64079
64622
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -64108,6 +64651,9 @@ function DepositModal({
64108
64651
  effectiveInitialScreen
64109
64652
  );
64110
64653
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = (0, import_react3.useState)(false);
64654
+ const [depositTab, setDepositTab] = (0, import_react3.useState)(
64655
+ () => depositTabForScreen(effectiveInitialScreen)
64656
+ );
64111
64657
  const resetViewTimeoutRef = (0, import_react3.useRef)(null);
64112
64658
  const [cardView, setCardView] = (0, import_react3.useState)(
64113
64659
  "amount"
@@ -64123,7 +64669,6 @@ function DepositModal({
64123
64669
  const [allExecutions, setAllExecutions] = (0, import_react3.useState)([]);
64124
64670
  const [selectedExecution, setSelectedExecution] = (0, import_react3.useState)(null);
64125
64671
  const [depositExecutions, setDepositExecutions] = (0, import_react3.useState)([]);
64126
- const isMobileView = useIsMobileViewport();
64127
64672
  const { projectConfig } = useProjectConfig({
64128
64673
  publishableKey,
64129
64674
  enabled: open
@@ -64406,6 +64951,7 @@ function DepositModal({
64406
64951
  resetViewTimeoutRef.current = null;
64407
64952
  }
64408
64953
  setView(effectiveInitialScreen);
64954
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
64409
64955
  setCardView("amount");
64410
64956
  setExchangeView("providers");
64411
64957
  setBrowserWalletInfo(null);
@@ -64434,6 +64980,7 @@ function DepositModal({
64434
64980
  } else if (view === "cashapp" && cashAppView !== "amount") {
64435
64981
  setCashAppView("amount");
64436
64982
  } else {
64983
+ setDepositTab(depositTabForScreen(view));
64437
64984
  setView("main");
64438
64985
  setCardView("amount");
64439
64986
  setExchangeView("providers");
@@ -64513,13 +65060,181 @@ function DepositModal({
64513
65060
  className: "uf-flex uf-justify-center uf-shrink-0"
64514
65061
  }
64515
65062
  ) });
65063
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65064
+ TransferCryptoButton,
65065
+ {
65066
+ onClick: () => setView("transfer"),
65067
+ title: transferCryptoTitle,
65068
+ subtitle: t7.transferCrypto.subtitle,
65069
+ featuredTokens: projectConfig?.transfer_crypto.networks
65070
+ },
65071
+ "transfer"
65072
+ ) : null;
65073
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65074
+ BrowserWalletButton,
65075
+ {
65076
+ onClick: handleBrowserWalletClick,
65077
+ onConnectClick: handleWalletConnectClick,
65078
+ onDisconnect: handleWalletDisconnect,
65079
+ chainType: browserWalletChainType,
65080
+ publishableKey,
65081
+ featuredWallets: projectConfig?.connect_wallet?.wallets
65082
+ },
65083
+ "wallet"
65084
+ ) : null;
65085
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65086
+ DepositWithCardButton,
65087
+ {
65088
+ onClick: () => setView("card"),
65089
+ title: depositWithCardTitle,
65090
+ subtitle: t7.depositWithCard.subtitle,
65091
+ paymentNetworks: projectConfig?.payment_networks.networks
65092
+ },
65093
+ "card"
65094
+ ) : null;
65095
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65096
+ PayWithExchangeButton,
65097
+ {
65098
+ onClick: () => setView("exchange"),
65099
+ title: payWithExchangeTitle,
65100
+ subtitle: t7.payWithExchange.subtitle,
65101
+ exchanges,
65102
+ loading: exchangesLoading
65103
+ },
65104
+ "exchange"
65105
+ ) : null;
65106
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65107
+ ConnectExchangeButton,
65108
+ {
65109
+ onClick: () => {
65110
+ setCoinbaseSkipToHoldings(true);
65111
+ setView("coinbase_connect");
65112
+ },
65113
+ onDisconnect: handleExchangeDisconnect,
65114
+ title: i18n2.connectExchange.title,
65115
+ subtitle: i18n2.connectExchange.subtitle,
65116
+ exchanges: integrationExchanges,
65117
+ connectedExchange
65118
+ },
65119
+ "connect-exchange"
65120
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65121
+ ConnectExchangeButton,
65122
+ {
65123
+ onClick: () => {
65124
+ setCoinbaseSkipToHoldings(false);
65125
+ setView("coinbase_connect");
65126
+ },
65127
+ title: i18n2.connectExchange.title,
65128
+ subtitle: i18n2.connectExchange.subtitle,
65129
+ exchanges: integrationExchanges
65130
+ },
65131
+ "connect-exchange"
65132
+ ) : null;
65133
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65134
+ CashAppButton,
65135
+ {
65136
+ onClick: () => setView("cashapp"),
65137
+ title: "Pay with Cash App",
65138
+ subtitle: "Deposit via Cash App",
65139
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
65140
+ },
65141
+ "cashapp"
65142
+ ) : null;
65143
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65144
+ DepositTrackerButton,
65145
+ {
65146
+ onClick: () => {
65147
+ setAllExecutions(depositExecutions);
65148
+ setView("tracker");
65149
+ },
65150
+ title: depositTrackerTitle,
65151
+ subtitle: depositTrackerSubTitle,
65152
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
65153
+ },
65154
+ "tracker"
65155
+ ) : null;
65156
+ const cryptoMenuButtons = [
65157
+ transferCryptoMenuButton,
65158
+ connectWalletMenuButton,
65159
+ payWithExchangeMenuButton,
65160
+ connectExchangeMenuButton
65161
+ ].filter(Boolean);
65162
+ const cashMenuButtons = [
65163
+ depositWithCardMenuButton,
65164
+ cashAppMenuButton
65165
+ ].filter(Boolean);
65166
+ const depositTabs = [
65167
+ { id: "crypto", label: "Use Crypto", buttons: cryptoMenuButtons },
65168
+ { id: "cash", label: "Use Cash", buttons: cashMenuButtons }
65169
+ ].filter((tab) => tab.buttons.length > 0);
65170
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
65171
+ const renderMainMenuBody = () => {
65172
+ if (depositPrerequisiteBody) {
65173
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
65174
+ }
65175
+ if (displayMode === "tabs" && activeDepositTab) {
65176
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { children: [
65177
+ depositTabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65178
+ "div",
65179
+ {
65180
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
65181
+ style: {
65182
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
65183
+ // the control reads as a soft surface rather than a solid bar.
65184
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
65185
+ backdropFilter: "blur(12px)",
65186
+ WebkitBackdropFilter: "blur(12px)"
65187
+ },
65188
+ role: "tablist",
65189
+ children: depositTabs.map((tab) => {
65190
+ const active = activeDepositTab.id === tab.id;
65191
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65192
+ "button",
65193
+ {
65194
+ type: "button",
65195
+ role: "tab",
65196
+ "aria-selected": active,
65197
+ onClick: () => setDepositTab(tab.id),
65198
+ className: "uf-flex-1 uf-py-2 uf-px-3 uf-rounded-lg uf-text-sm uf-transition-all",
65199
+ style: {
65200
+ // Active tab is a soft, blurred glass pill — a faint accent
65201
+ // tint with its own backdrop blur and a subtle border/shadow,
65202
+ // so it looks frosted instead of like a hard solid button.
65203
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
65204
+ backdropFilter: active ? "blur(8px)" : void 0,
65205
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
65206
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
65207
+ color: active ? colors2.foreground : colors2.foregroundMuted,
65208
+ fontFamily: fonts.medium
65209
+ },
65210
+ children: tab.label
65211
+ },
65212
+ tab.id
65213
+ );
65214
+ })
65215
+ }
65216
+ ),
65217
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
65218
+ depositTrackerMenuButton && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
65219
+ ] });
65220
+ }
65221
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-space-y-3", children: [
65222
+ transferCryptoMenuButton,
65223
+ connectWalletMenuButton,
65224
+ depositWithCardMenuButton,
65225
+ payWithExchangeMenuButton,
65226
+ connectExchangeMenuButton,
65227
+ cashAppMenuButton,
65228
+ depositTrackerMenuButton
65229
+ ] });
65230
+ };
64516
65231
  return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64517
65232
  Dialog2,
64518
65233
  {
64519
65234
  open: hideOverlay || open,
64520
65235
  onOpenChange: hideOverlay ? void 0 : handleClose,
64521
65236
  modal: !hideOverlay,
64522
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65237
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
64523
65238
  DialogContent2,
64524
65239
  {
64525
65240
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -64528,386 +65243,302 @@ function DepositModal({
64528
65243
  style: { backgroundColor: colors2.background },
64529
65244
  onPointerDownOutside: (e) => e.preventDefault(),
64530
65245
  onInteractOutside: (e) => e.preventDefault(),
64531
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64532
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64533
- DepositHeader,
64534
- {
64535
- title: modalTitle || "Deposit",
64536
- showClose: !hideOverlay,
64537
- onClose: handleClose,
64538
- showBalance: showBalanceHeader,
64539
- balanceAddress: recipientAddress,
64540
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64541
- balanceChainId: destinationChainId,
64542
- balanceTokenAddress: destinationTokenAddress,
64543
- projectName: projectConfig?.project_name,
64544
- publishableKey
64545
- }
64546
- ),
64547
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64548
- /* @__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: [
64549
- showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64550
- TransferCryptoButton,
64551
- {
64552
- onClick: () => setView("transfer"),
64553
- title: transferCryptoTitle,
64554
- subtitle: t7.transferCrypto.subtitle,
64555
- featuredTokens: projectConfig?.transfer_crypto.networks
64556
- }
64557
- ),
64558
- showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64559
- BrowserWalletButton,
65246
+ children: [
65247
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(DialogTitle2, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
65248
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65249
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65250
+ DepositHeader,
65251
+ {
65252
+ title: modalTitle || "Deposit",
65253
+ showClose: !hideOverlay,
65254
+ onClose: handleClose,
65255
+ showBalance: showBalanceHeader,
65256
+ balanceAddress: recipientAddress,
65257
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65258
+ balanceChainId: destinationChainId,
65259
+ balanceTokenAddress: destinationTokenAddress,
65260
+ projectName: projectConfig?.project_name,
65261
+ publishableKey
65262
+ }
65263
+ ),
65264
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65265
+ renderMainMenuBody(),
65266
+ depositPoweredByFooter
65267
+ ] })
65268
+ ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65269
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65270
+ DepositHeader,
65271
+ {
65272
+ title: transferCryptoTitle,
65273
+ showBack: showBackTransfer,
65274
+ onBack: handleBack,
65275
+ onClose: handleClose,
65276
+ showBalance: showBalanceHeader,
65277
+ balanceAddress: recipientAddress,
65278
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65279
+ balanceChainId: destinationChainId,
65280
+ balanceTokenAddress: destinationTokenAddress,
65281
+ projectName: projectConfig?.project_name,
65282
+ publishableKey
65283
+ }
65284
+ ),
65285
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65286
+ 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)(
65287
+ TransferCryptoSingleInput,
64560
65288
  {
64561
- onClick: handleBrowserWalletClick,
64562
- onConnectClick: handleWalletConnectClick,
64563
- onDisconnect: handleWalletDisconnect,
64564
- chainType: browserWalletChainType,
65289
+ userId,
64565
65290
  publishableKey,
64566
- featuredWallets: projectConfig?.connect_wallet?.wallets
65291
+ recipientAddress,
65292
+ destinationChainType,
65293
+ destinationChainId,
65294
+ destinationTokenAddress,
65295
+ defaultSourceChainType,
65296
+ defaultSourceChainId,
65297
+ defaultSourceTokenAddress,
65298
+ defaultSourceSymbol,
65299
+ depositConfirmationMode,
65300
+ onExecutionsChange: setDepositExecutions,
65301
+ onDepositSuccess,
65302
+ onDepositError,
65303
+ wallets
64567
65304
  }
64568
- ),
64569
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64570
- DepositWithCardButton,
65305
+ ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65306
+ TransferCryptoDoubleInput,
64571
65307
  {
64572
- onClick: () => setView("card"),
64573
- title: depositWithCardTitle,
64574
- subtitle: t7.depositWithCard.subtitle,
64575
- paymentNetworks: projectConfig?.payment_networks.networks
65308
+ userId,
65309
+ publishableKey,
65310
+ recipientAddress,
65311
+ destinationChainType,
65312
+ destinationChainId,
65313
+ destinationTokenAddress,
65314
+ defaultSourceChainType,
65315
+ defaultSourceChainId,
65316
+ defaultSourceTokenAddress,
65317
+ defaultSourceSymbol,
65318
+ depositConfirmationMode,
65319
+ onExecutionsChange: setDepositExecutions,
65320
+ onDepositSuccess,
65321
+ onDepositError,
65322
+ wallets
64576
65323
  }
64577
65324
  ),
64578
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64579
- PayWithExchangeButton,
65325
+ depositPoweredByFooter
65326
+ ] })
65327
+ ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65328
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65329
+ DepositHeader,
65330
+ {
65331
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
65332
+ showBack: showBackTracker,
65333
+ onBack: handleBack,
65334
+ onClose: handleClose
65335
+ }
65336
+ ),
65337
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65338
+ /* @__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)(
65339
+ "div",
64580
65340
  {
64581
- onClick: () => setView("exchange"),
64582
- title: payWithExchangeTitle,
64583
- subtitle: t7.payWithExchange.subtitle,
64584
- exchanges,
64585
- loading: exchangesLoading
65341
+ className: "uf-text-sm",
65342
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
65343
+ children: "No deposits yet"
64586
65344
  }
64587
- ),
64588
- showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64589
- ConnectExchangeButton,
65345
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65346
+ DepositExecutionItem,
64590
65347
  {
64591
- onClick: () => {
64592
- setCoinbaseSkipToHoldings(true);
64593
- setView("coinbase_connect");
64594
- },
64595
- onDisconnect: handleExchangeDisconnect,
64596
- title: i18n2.connectExchange.title,
64597
- subtitle: i18n2.connectExchange.subtitle,
64598
- exchanges: integrationExchanges,
64599
- connectedExchange
64600
- }
64601
- ),
64602
- showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64603
- ConnectExchangeButton,
65348
+ execution,
65349
+ onClick: () => setSelectedExecution(execution)
65350
+ },
65351
+ execution.id
65352
+ )) }) }),
65353
+ depositPoweredByFooter
65354
+ ] })
65355
+ ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65356
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65357
+ DepositHeader,
65358
+ {
65359
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
65360
+ showBack: showBackCard,
65361
+ onBack: handleBack,
65362
+ onClose: handleClose,
65363
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
65364
+ showBalance: showBalanceHeader,
65365
+ balanceAddress: recipientAddress,
65366
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65367
+ balanceChainId: destinationChainId,
65368
+ balanceTokenAddress: destinationTokenAddress,
65369
+ projectName: projectConfig?.project_name,
65370
+ publishableKey
65371
+ }
65372
+ ),
65373
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65374
+ 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)(
65375
+ BuyWithCard,
64604
65376
  {
64605
- onClick: () => {
64606
- setCoinbaseSkipToHoldings(false);
64607
- setView("coinbase_connect");
64608
- },
64609
- title: i18n2.connectExchange.title,
64610
- subtitle: i18n2.connectExchange.subtitle,
64611
- exchanges: integrationExchanges
65377
+ userId,
65378
+ publishableKey,
65379
+ view: cardView,
65380
+ onViewChange: handleCardViewChange,
65381
+ destinationTokenSymbol,
65382
+ recipientAddress,
65383
+ destinationChainType,
65384
+ destinationChainId,
65385
+ destinationTokenAddress,
65386
+ onDepositSuccess,
65387
+ onDepositError,
65388
+ onEvent,
65389
+ themeClass,
65390
+ wallets,
65391
+ assetCdnUrl: projectConfig?.asset_cdn_url,
65392
+ hideDepositFlowInfo,
65393
+ hideDisplayDescription
64612
65394
  }
64613
65395
  ),
64614
- showCashApp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64615
- CashAppButton,
65396
+ depositPoweredByFooter
65397
+ ] })
65398
+ ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65399
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65400
+ DepositHeader,
65401
+ {
65402
+ title: payWithExchangeTitle,
65403
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
65404
+ onBack: handleBack,
65405
+ onClose: handleClose
65406
+ }
65407
+ ),
65408
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65409
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65410
+ PayWithExchange,
64616
65411
  {
64617
- onClick: () => setView("cashapp"),
64618
- title: "Pay with Cash App",
64619
- subtitle: "Deposit via Cash App",
64620
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
65412
+ userId,
65413
+ publishableKey,
65414
+ exchanges,
65415
+ view: exchangeView,
65416
+ onViewChange: setExchangeView,
65417
+ destinationTokenSymbol,
65418
+ recipientAddress,
65419
+ destinationChainType,
65420
+ destinationChainId,
65421
+ destinationTokenAddress,
65422
+ onDepositSuccess,
65423
+ onDepositError,
65424
+ wallets,
65425
+ defaultToken: defaultToken ?? null
64621
65426
  }
64622
65427
  ),
64623
- showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64624
- DepositTrackerButton,
64625
- {
64626
- onClick: () => {
64627
- setAllExecutions(depositExecutions);
64628
- setView("tracker");
64629
- },
64630
- title: depositTrackerTitle,
64631
- subtitle: depositTrackerSubTitle,
64632
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
64633
- }
64634
- )
64635
- ] }) }),
64636
- depositPoweredByFooter
64637
- ] })
64638
- ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64639
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64640
- DepositHeader,
64641
- {
64642
- title: transferCryptoTitle,
64643
- showBack: showBackTransfer,
64644
- onBack: handleBack,
64645
- onClose: handleClose,
64646
- showBalance: showBalanceHeader,
64647
- balanceAddress: recipientAddress,
64648
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64649
- balanceChainId: destinationChainId,
64650
- balanceTokenAddress: destinationTokenAddress,
64651
- projectName: projectConfig?.project_name,
64652
- publishableKey
64653
- }
64654
- ),
64655
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64656
- 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)(
64657
- TransferCryptoSingleInput,
65428
+ depositPoweredByFooter
65429
+ ] })
65430
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65431
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65432
+ CoinbaseConnect,
64658
65433
  {
64659
- userId,
64660
65434
  publishableKey,
64661
- recipientAddress,
64662
- destinationChainType,
64663
- destinationChainId,
64664
- destinationTokenAddress,
64665
- defaultSourceChainType,
64666
- defaultSourceChainId,
64667
- defaultSourceTokenAddress,
64668
- defaultSourceSymbol,
64669
- depositConfirmationMode,
64670
- onExecutionsChange: setDepositExecutions,
64671
- onDepositSuccess,
64672
- onDepositError,
64673
- wallets
64674
- }
64675
- ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64676
- TransferCryptoDoubleInput,
64677
- {
64678
65435
  userId,
64679
- publishableKey,
65436
+ wallets,
64680
65437
  recipientAddress,
64681
- destinationChainType,
64682
- destinationChainId,
64683
- destinationTokenAddress,
65438
+ destinationTokenAddress: destinationTokenAddress ?? "",
65439
+ destinationChainId: destinationChainId ?? "",
65440
+ destinationChainType: destinationChainType ?? "",
65441
+ onTransferSuccess: (result) => {
65442
+ onDepositSuccess?.({
65443
+ message: "Transfer completed via Coinbase Connect",
65444
+ transaction: result
65445
+ });
65446
+ },
65447
+ onTransferError: (error) => {
65448
+ onDepositError?.({
65449
+ message: error.message,
65450
+ error
65451
+ });
65452
+ },
65453
+ onBack: handleBack,
65454
+ onClose: handleClose,
65455
+ onDisconnect: handleExchangeDisconnect,
65456
+ skipToHoldings: coinbaseSkipToHoldings,
65457
+ canGoBack: sessionOpenedFromMenu,
65458
+ onExecutionsChange: setDepositExecutions,
64684
65459
  defaultSourceChainType,
64685
65460
  defaultSourceChainId,
64686
65461
  defaultSourceTokenAddress,
64687
- defaultSourceSymbol,
64688
- depositConfirmationMode,
64689
- onExecutionsChange: setDepositExecutions,
64690
- onDepositSuccess,
64691
- onDepositError,
64692
- wallets
64693
- }
64694
- ),
64695
- depositPoweredByFooter
64696
- ] })
64697
- ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64698
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64699
- DepositHeader,
64700
- {
64701
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
64702
- showBack: showBackTracker,
64703
- onBack: handleBack,
64704
- onClose: handleClose
64705
- }
64706
- ),
64707
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64708
- /* @__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)(
64709
- "div",
64710
- {
64711
- className: "uf-text-sm",
64712
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
64713
- children: "No deposits yet"
64714
- }
64715
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64716
- DepositExecutionItem,
64717
- {
64718
- execution,
64719
- onClick: () => setSelectedExecution(execution)
64720
- },
64721
- execution.id
64722
- )) }) }),
64723
- depositPoweredByFooter
64724
- ] })
64725
- ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64726
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64727
- DepositHeader,
64728
- {
64729
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
64730
- showBack: showBackCard,
64731
- onBack: handleBack,
64732
- onClose: handleClose,
64733
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
64734
- showBalance: showBalanceHeader,
64735
- balanceAddress: recipientAddress,
64736
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64737
- balanceChainId: destinationChainId,
64738
- balanceTokenAddress: destinationTokenAddress,
64739
- projectName: projectConfig?.project_name,
64740
- publishableKey
64741
- }
64742
- ),
64743
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64744
- 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)(
64745
- BuyWithCard,
64746
- {
64747
- userId,
64748
- publishableKey,
64749
- view: cardView,
64750
- onViewChange: handleCardViewChange,
64751
- destinationTokenSymbol,
64752
- recipientAddress,
64753
- destinationChainType,
64754
- destinationChainId,
64755
- destinationTokenAddress,
64756
- onDepositSuccess,
64757
- onDepositError,
64758
- onEvent,
64759
- themeClass,
64760
- wallets,
64761
- assetCdnUrl: projectConfig?.asset_cdn_url,
64762
- hideDepositFlowInfo,
64763
- hideDisplayDescription
65462
+ defaultSourceSymbol
64764
65463
  }
64765
65464
  ),
64766
65465
  depositPoweredByFooter
64767
- ] })
64768
- ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64769
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64770
- DepositHeader,
64771
- {
64772
- title: payWithExchangeTitle,
64773
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
64774
- onBack: handleBack,
64775
- onClose: handleClose
64776
- }
64777
- ),
64778
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65466
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64779
65467
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64780
- PayWithExchange,
65468
+ WalletConnect,
64781
65469
  {
65470
+ walletInfo: browserWalletInfo ?? void 0,
65471
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
65472
+ wallets,
64782
65473
  userId,
64783
65474
  publishableKey,
64784
- exchanges,
64785
- view: exchangeView,
64786
- onViewChange: setExchangeView,
64787
- destinationTokenSymbol,
64788
- recipientAddress,
64789
- destinationChainType,
64790
- destinationChainId,
64791
- destinationTokenAddress,
65475
+ assetCdnUrl: projectConfig?.asset_cdn_url,
65476
+ projectName: projectConfig?.project_name,
65477
+ onSuccess: (txHash) => {
65478
+ onDepositSuccess?.({
65479
+ message: "Transaction sent successfully",
65480
+ transaction: { txHash }
65481
+ });
65482
+ },
65483
+ onError: (error) => {
65484
+ onDepositError?.({
65485
+ message: error.message,
65486
+ error
65487
+ });
65488
+ },
64792
65489
  onDepositSuccess,
64793
65490
  onDepositError,
64794
- wallets,
64795
- defaultToken: defaultToken ?? null
65491
+ amountQuickSelect: browserWalletAmountQuickSelect,
65492
+ onWalletDisconnect: handleWalletDisconnect,
65493
+ onWalletConnected: (info, dw) => {
65494
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
65495
+ setStoredWalletState(info.type);
65496
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
65497
+ },
65498
+ onBack: handleBack,
65499
+ onClose: handleClose,
65500
+ defaultSourceChainType,
65501
+ defaultSourceChainId,
65502
+ defaultSourceTokenAddress,
65503
+ defaultSourceSymbol,
65504
+ canGoBack: sessionOpenedFromMenu,
65505
+ depositWalletsLoading: walletsLoading
64796
65506
  }
64797
65507
  ),
64798
65508
  depositPoweredByFooter
64799
- ] })
64800
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64801
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64802
- CoinbaseConnect,
64803
- {
64804
- publishableKey,
64805
- userId,
64806
- wallets,
64807
- recipientAddress,
64808
- destinationTokenAddress: destinationTokenAddress ?? "",
64809
- destinationChainId: destinationChainId ?? "",
64810
- destinationChainType: destinationChainType ?? "",
64811
- onTransferSuccess: (result) => {
64812
- onDepositSuccess?.({
64813
- message: "Transfer completed via Coinbase Connect",
64814
- transaction: result
64815
- });
64816
- },
64817
- onTransferError: (error) => {
64818
- onDepositError?.({
64819
- message: error.message,
64820
- error
64821
- });
64822
- },
64823
- onBack: handleBack,
64824
- onClose: handleClose,
64825
- onDisconnect: handleExchangeDisconnect,
64826
- skipToHoldings: coinbaseSkipToHoldings,
64827
- canGoBack: sessionOpenedFromMenu,
64828
- onExecutionsChange: setDepositExecutions,
64829
- defaultSourceChainType,
64830
- defaultSourceChainId,
64831
- defaultSourceTokenAddress,
64832
- defaultSourceSymbol
64833
- }
64834
- ),
64835
- depositPoweredByFooter
64836
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64837
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64838
- WalletConnect,
64839
- {
64840
- walletInfo: browserWalletInfo ?? void 0,
64841
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
64842
- wallets,
64843
- userId,
64844
- publishableKey,
64845
- assetCdnUrl: projectConfig?.asset_cdn_url,
64846
- projectName: projectConfig?.project_name,
64847
- onSuccess: (txHash) => {
64848
- onDepositSuccess?.({
64849
- message: "Transaction sent successfully",
64850
- transaction: { txHash }
64851
- });
64852
- },
64853
- onError: (error) => {
64854
- onDepositError?.({
64855
- message: error.message,
64856
- error
64857
- });
64858
- },
64859
- onDepositSuccess,
64860
- onDepositError,
64861
- amountQuickSelect: browserWalletAmountQuickSelect,
64862
- onWalletDisconnect: handleWalletDisconnect,
64863
- onWalletConnected: (info, dw) => {
64864
- setBrowserWalletInfo({ ...info, depositWallet: dw });
64865
- setStoredWalletState(info.type);
64866
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
64867
- },
64868
- onBack: handleBack,
64869
- onClose: handleClose,
64870
- defaultSourceChainType,
64871
- defaultSourceChainId,
64872
- defaultSourceTokenAddress,
64873
- defaultSourceSymbol,
64874
- canGoBack: sessionOpenedFromMenu,
64875
- depositWalletsLoading: walletsLoading
64876
- }
64877
- ),
64878
- depositPoweredByFooter
64879
- ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64880
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64881
- DepositHeader,
64882
- {
64883
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
64884
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
64885
- onBack: handleBack,
64886
- onClose: handleClose
64887
- }
64888
- ),
64889
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65509
+ ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64890
65510
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64891
- PayWithCashApp,
65511
+ DepositHeader,
64892
65512
  {
64893
- userId,
64894
- publishableKey,
64895
- recipientAddress,
64896
- destinationChainType,
64897
- destinationChainId,
64898
- destinationTokenAddress,
64899
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
64900
- view: cashAppView,
64901
- onViewChange: setCashAppView,
64902
- onAmountChange: setCashAppAmount,
64903
- onEvent,
64904
- onDepositSuccess,
64905
- onDepositError
65513
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
65514
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
65515
+ onBack: handleBack,
65516
+ onClose: handleClose
64906
65517
  }
64907
65518
  ),
64908
- depositPoweredByFooter
64909
- ] })
64910
- ] }) : null })
65519
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65520
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65521
+ PayWithCashApp,
65522
+ {
65523
+ userId,
65524
+ publishableKey,
65525
+ recipientAddress,
65526
+ destinationChainType,
65527
+ destinationChainId,
65528
+ destinationTokenAddress,
65529
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
65530
+ view: cashAppView,
65531
+ onViewChange: setCashAppView,
65532
+ onAmountChange: setCashAppAmount,
65533
+ onEvent,
65534
+ onDepositSuccess,
65535
+ onDepositError
65536
+ }
65537
+ ),
65538
+ depositPoweredByFooter
65539
+ ] })
65540
+ ] }) : null })
65541
+ ]
64911
65542
  }
64912
65543
  )
64913
65544
  }
@@ -64992,7 +65623,6 @@ function CheckoutModal({
64992
65623
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react29.useState)(null);
64993
65624
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react29.useState)(false);
64994
65625
  const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react29.useState)(() => getStoredWalletState()?.chainType);
64995
- const isMobileView = useIsMobileViewport();
64996
65626
  const [resolvedTheme, setResolvedTheme] = (0, import_react29.useState)(
64997
65627
  theme === "auto" ? "dark" : theme
64998
65628
  );
@@ -65418,7 +66048,7 @@ function CheckoutModal({
65418
66048
  featuredTokens: projectConfig?.transfer_crypto.networks
65419
66049
  }
65420
66050
  ),
65421
- showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
66051
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65422
66052
  BrowserWalletButton,
65423
66053
  {
65424
66054
  onClick: handleBrowserWalletClick,
@@ -66029,9 +66659,6 @@ function useVerifyRecipientAddress(params) {
66029
66659
  refetchOnWindowFocus: false
66030
66660
  });
66031
66661
  }
66032
- function isHypercoreChain(chainId) {
66033
- return chainId === HYPERCORE_CHAIN_ID;
66034
- }
66035
66662
  function useGetDepositAddress(params) {
66036
66663
  const {
66037
66664
  userId,
@@ -66958,8 +67585,6 @@ function WithdrawConfirmingView({
66958
67585
  className: "uf-text-sm uf-text-center",
66959
67586
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
66960
67587
  children: [
66961
- txInfo.amount,
66962
- " ",
66963
67588
  txInfo.sourceTokenSymbol,
66964
67589
  " to",
66965
67590
  " ",
@@ -67324,6 +67949,16 @@ function UnifoldProvider2({
67324
67949
  });
67325
67950
  promise.catch(() => {
67326
67951
  });
67952
+ if (!config2.recipientAddress) {
67953
+ const error = {
67954
+ message: "beginDeposit requires a `recipientAddress`.",
67955
+ code: "MISSING_RECIPIENT"
67956
+ };
67957
+ console.error(`[UnifoldProvider] ${error.message}`);
67958
+ depositPromiseRef.current.reject(error);
67959
+ depositPromiseRef.current = null;
67960
+ return promise;
67961
+ }
67327
67962
  setDepositConfig(config2);
67328
67963
  setIsOpen(true);
67329
67964
  return promise;
@@ -67590,6 +68225,7 @@ function UnifoldProvider2({
67590
68225
  hideDepositTracker: config?.hideDepositTracker,
67591
68226
  showBalanceHeader: config?.showBalanceHeader,
67592
68227
  transferInputVariant: config?.transferInputVariant,
68228
+ displayMode: config?.displayMode,
67593
68229
  enableTransferCrypto: config?.enableTransferCrypto,
67594
68230
  enableConnectWallet: config?.enableConnectWallet,
67595
68231
  enablePayWithExchange: config?.enablePayWithExchange,