@unifold/connect-react 0.1.64 → 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
@@ -7031,6 +7031,29 @@ async function getDepositQuote(request, publishableKey) {
7031
7031
  const json = await response.json();
7032
7032
  return json.data;
7033
7033
  }
7034
+ async function buildHypercoreTransaction(request, publishableKey) {
7035
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
7036
+ validatePublishableKey(pk);
7037
+ const response = await fetch(
7038
+ `${API_BASE_URL}/v1/public/transactions/hypercore/build`,
7039
+ {
7040
+ method: "POST",
7041
+ headers: {
7042
+ accept: "application/json",
7043
+ "x-publishable-key": pk,
7044
+ "Content-Type": "application/json"
7045
+ },
7046
+ body: JSON.stringify(request)
7047
+ }
7048
+ );
7049
+ if (!response.ok) {
7050
+ const error = await response.json().catch(() => ({ message: response.statusText }));
7051
+ throw new Error(
7052
+ `Failed to build HyperCore transaction: ${error.message || response.statusText}`
7053
+ );
7054
+ }
7055
+ return response.json();
7056
+ }
7034
7057
  async function getCashAppLimits(currency = "usd", publishableKey) {
7035
7058
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
7036
7059
  validatePublishableKey(pk);
@@ -7096,6 +7119,29 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
7096
7119
  }
7097
7120
  return response.json();
7098
7121
  }
7122
+ async function sendHypercoreTransaction(request, publishableKey) {
7123
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
7124
+ validatePublishableKey(pk);
7125
+ const response = await fetch(
7126
+ `${API_BASE_URL}/v1/public/transactions/hypercore/send`,
7127
+ {
7128
+ method: "POST",
7129
+ headers: {
7130
+ accept: "application/json",
7131
+ "x-publishable-key": pk,
7132
+ "Content-Type": "application/json"
7133
+ },
7134
+ body: JSON.stringify(request)
7135
+ }
7136
+ );
7137
+ if (!response.ok) {
7138
+ const error = await response.json().catch(() => ({ message: response.statusText }));
7139
+ throw new Error(
7140
+ `Failed to send HyperCore transaction: ${error.message || response.statusText}`
7141
+ );
7142
+ }
7143
+ return response.json();
7144
+ }
7099
7145
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
7100
7146
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
7101
7147
  return DepositEventType2;
@@ -13610,6 +13656,22 @@ function clearStoredWalletState() {
13610
13656
  } catch {
13611
13657
  }
13612
13658
  }
13659
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
13660
+ function getLastOpenedWallet() {
13661
+ if (typeof window === "undefined") return void 0;
13662
+ try {
13663
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
13664
+ } catch {
13665
+ return void 0;
13666
+ }
13667
+ }
13668
+ function setLastOpenedWallet(walletId) {
13669
+ if (typeof window === "undefined") return;
13670
+ try {
13671
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
13672
+ } catch {
13673
+ }
13674
+ }
13613
13675
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
13614
13676
  function isMobileViewport() {
13615
13677
  if (typeof window === "undefined") return false;
@@ -14415,7 +14477,7 @@ function DepositHeader({
14415
14477
  setShowBalanceSkeleton(false);
14416
14478
  return;
14417
14479
  }
14418
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
14480
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
14419
14481
  if (!supportedChainTypes.includes(
14420
14482
  balanceChainType
14421
14483
  )) {
@@ -24433,7 +24495,7 @@ function useHypercoreActivation(params) {
24433
24495
  publishableKey,
24434
24496
  enabled = true
24435
24497
  } = params;
24436
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
24498
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
24437
24499
  const recipient = recipientAddress?.trim() ?? "";
24438
24500
  const source = sourceAddress?.trim() ?? "";
24439
24501
  const hasAddresses = !!recipient && !!source;
@@ -25579,6 +25641,46 @@ function TransferCryptoDoubleInput({
25579
25641
  }
25580
25642
  ) });
25581
25643
  }
25644
+ function isHypercoreChain(chainId) {
25645
+ return chainId === HYPERCORE_CHAIN_ID;
25646
+ }
25647
+ async function sendHypercoreEvmTransfer(params) {
25648
+ const {
25649
+ provider,
25650
+ fromAddress,
25651
+ recipientAddress,
25652
+ sourceTokenAddress,
25653
+ amount,
25654
+ publishableKey
25655
+ } = params;
25656
+ const currentChainHex = await provider.request({
25657
+ method: "eth_chainId",
25658
+ params: []
25659
+ });
25660
+ const activeChainId = String(parseInt(currentChainHex, 16));
25661
+ const buildResult = await buildHypercoreTransaction(
25662
+ {
25663
+ signature_chain_id: activeChainId,
25664
+ recipient_address: recipientAddress,
25665
+ token_address: sourceTokenAddress,
25666
+ amount
25667
+ },
25668
+ publishableKey
25669
+ );
25670
+ const signature = await provider.request({
25671
+ method: "eth_signTypedData_v4",
25672
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
25673
+ });
25674
+ await sendHypercoreTransaction(
25675
+ {
25676
+ action_payload: buildResult.action_payload,
25677
+ signature,
25678
+ nonce: buildResult.nonce
25679
+ },
25680
+ publishableKey
25681
+ );
25682
+ return { signature };
25683
+ }
25582
25684
  function useDepositQuote(params) {
25583
25685
  const {
25584
25686
  publishableKey,
@@ -25986,7 +26088,8 @@ function EnterAmountView({
25986
26088
  onClose,
25987
26089
  quickSelectMode,
25988
26090
  checkoutAmountUsd,
25989
- checkoutReceivedUsd
26091
+ checkoutReceivedUsd,
26092
+ footer
25990
26093
  }) {
25991
26094
  const { colors: colors2, fonts, components } = useTheme();
25992
26095
  const isCheckout = !!checkoutAmountUsd;
@@ -26242,6 +26345,7 @@ function EnterAmountView({
26242
26345
  )
26243
26346
  ] })
26244
26347
  ] }),
26348
+ footer && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
26245
26349
  /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
26246
26350
  "button",
26247
26351
  {
@@ -26691,7 +26795,7 @@ var WALLET_ICONS3 = {
26691
26795
  };
26692
26796
  var FALLBACK_WALLET_DEFINITIONS = [
26693
26797
  { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
26694
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
26798
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
26695
26799
  { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
26696
26800
  { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
26697
26801
  { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
@@ -26751,7 +26855,7 @@ function getLegacyEvmProviders() {
26751
26855
  okxEthereum: win.okxwallet
26752
26856
  };
26753
26857
  }
26754
- function detectAvailableWallets(definitions, filterChainType) {
26858
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
26755
26859
  const solProviders = getSolanaProviders();
26756
26860
  const legacyEvm = getLegacyEvmProviders();
26757
26861
  const eip6963List = getEip6963Providers();
@@ -26777,7 +26881,7 @@ function detectAvailableWallets(definitions, filterChainType) {
26777
26881
  return false;
26778
26882
  }
26779
26883
  });
26780
- return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26884
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26781
26885
  let isInstalled = false;
26782
26886
  const detectedNetworks = [];
26783
26887
  switch (wallet.id) {
@@ -26800,8 +26904,6 @@ function detectAvailableWallets(definitions, filterChainType) {
26800
26904
  isInstalled = true;
26801
26905
  detectedNetworks.push("ethereum");
26802
26906
  }
26803
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
26804
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
26805
26907
  break;
26806
26908
  case "trust":
26807
26909
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -26838,11 +26940,17 @@ function detectAvailableWallets(definitions, filterChainType) {
26838
26940
  }
26839
26941
  return { ...wallet, isInstalled, detectedNetworks };
26840
26942
  }).sort((a, b) => {
26943
+ if (recentWalletId) {
26944
+ const aRecent = a.id === recentWalletId ? 1 : 0;
26945
+ const bRecent = b.id === recentWalletId ? 1 : 0;
26946
+ if (aRecent !== bRecent) return bRecent - aRecent;
26947
+ }
26841
26948
  if (a.isInstalled && !b.isInstalled) return -1;
26842
26949
  if (!a.isInstalled && b.isInstalled) return 1;
26843
26950
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
26844
26951
  return 0;
26845
26952
  });
26953
+ return sorted;
26846
26954
  }
26847
26955
  function WalletConnect({
26848
26956
  walletInfo: initialWalletInfo,
@@ -26917,9 +27025,15 @@ function WalletConnect({
26917
27025
  })) : FALLBACK_WALLET_DEFINITIONS,
26918
27026
  [backendWallets]
26919
27027
  );
27028
+ const [recentWalletId, setRecentWalletIdState] = React302.useState(getLastOpenedWallet);
27029
+ React302.useEffect(() => {
27030
+ if (view === "select_wallet") {
27031
+ setRecentWalletIdState(getLastOpenedWallet());
27032
+ }
27033
+ }, [view]);
26920
27034
  const availableWallets = React302.useMemo(
26921
- () => detectAvailableWallets(walletDefinitions),
26922
- [walletDefinitions, eip6963ProviderCount]
27035
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
27036
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
26923
27037
  );
26924
27038
  const [isMobile, setIsMobile] = React302.useState(false);
26925
27039
  React302.useEffect(() => {
@@ -26979,7 +27093,7 @@ function WalletConnect({
26979
27093
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
26980
27094
  const recipientAddress = activeDepositWallet?.address ?? "";
26981
27095
  const isCheckoutMode = !!checkoutAmountUsd;
26982
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
27096
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
26983
27097
  const transitionTo = React302.useCallback((nextView) => {
26984
27098
  if (nextView === viewRef.current) return;
26985
27099
  setIsTransitioning(true);
@@ -27003,6 +27117,8 @@ function WalletConnect({
27003
27117
  );
27004
27118
  if (res.deeplink) {
27005
27119
  setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
27120
+ setLastOpenedWallet(wallet.id);
27121
+ setRecentWalletIdState(wallet.id);
27006
27122
  setAwaitingMobileDeposit(true);
27007
27123
  transitionTo("mobile_redirect");
27008
27124
  window.location.href = res.deeplink;
@@ -27063,6 +27179,8 @@ function WalletConnect({
27063
27179
  const handleConnectWallet = async (wallet, network) => {
27064
27180
  setConnectingNetwork(network);
27065
27181
  transitionTo("connecting");
27182
+ setLastOpenedWallet(wallet.id);
27183
+ setRecentWalletIdState(wallet.id);
27066
27184
  setWalletError(null);
27067
27185
  setIsWalletConnecting(true);
27068
27186
  try {
@@ -27167,6 +27285,13 @@ function WalletConnect({
27167
27285
  }
27168
27286
  };
27169
27287
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
27288
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
27289
+ recipientAddress,
27290
+ sourceAddress: activeWalletInfo?.address,
27291
+ destinationChainId: selectedToken?.chain_id,
27292
+ publishableKey,
27293
+ enabled: !!activeWalletInfo && !!recipientAddress
27294
+ });
27170
27295
  const effectiveDestinationAmount = React302.useMemo(() => {
27171
27296
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
27172
27297
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -27271,7 +27396,7 @@ function WalletConnect({
27271
27396
  let cancelled = false;
27272
27397
  setIsLoading(true);
27273
27398
  setError(null);
27274
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
27399
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
27275
27400
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
27276
27401
  if (cancelled) return;
27277
27402
  const nonZero = response.balances.filter((b) => b.amount !== "0");
@@ -27437,9 +27562,16 @@ function WalletConnect({
27437
27562
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
27438
27563
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
27439
27564
  };
27440
- const sendEthereumTransaction = async (token, amountStr) => {
27441
- if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
27442
- const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
27565
+ const resolveEvmProvider = () => {
27566
+ const walletIdMap = {
27567
+ "phantom-ethereum": "phantom",
27568
+ coinbase: "coinbase",
27569
+ trust: "trust",
27570
+ okx: "okx",
27571
+ rainbow: "rainbow",
27572
+ rabby: "rabby",
27573
+ metamask: "metamask"
27574
+ };
27443
27575
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
27444
27576
  const eip6963Match = findProviderByWalletId(lookupId);
27445
27577
  let provider = eip6963Match?.provider;
@@ -27448,6 +27580,11 @@ function WalletConnect({
27448
27580
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
27449
27581
  else provider = window.ethereum;
27450
27582
  }
27583
+ return provider;
27584
+ };
27585
+ const sendEthereumTransaction = async (token, amountStr) => {
27586
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
27587
+ const provider = resolveEvmProvider();
27451
27588
  if (!provider) throw new Error("Ethereum wallet not found");
27452
27589
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
27453
27590
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -27512,6 +27649,19 @@ function WalletConnect({
27512
27649
  const resp = await sendSolanaTransaction({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
27513
27650
  return resp.signature;
27514
27651
  };
27652
+ const sendHypercoreDeposit = async (token, amountStr) => {
27653
+ const provider = resolveEvmProvider();
27654
+ if (!provider) throw new Error("Ethereum wallet not found");
27655
+ const { signature } = await sendHypercoreEvmTransfer({
27656
+ provider,
27657
+ fromAddress: walletInfo.address,
27658
+ recipientAddress,
27659
+ sourceTokenAddress: token.token_address,
27660
+ amount: amountStr,
27661
+ publishableKey
27662
+ });
27663
+ return signature;
27664
+ };
27515
27665
  const handleConfirm = async () => {
27516
27666
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
27517
27667
  const token = getTokenFromBalance(selectedBalance);
@@ -27531,7 +27681,33 @@ function WalletConnect({
27531
27681
  setIsConfirming(true);
27532
27682
  setError(null);
27533
27683
  try {
27534
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction2(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
27684
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
27685
+ let txHash;
27686
+ if (token.chain_type === "solana") {
27687
+ txHash = await sendSolanaTransaction2(token, tokenAmount.toString());
27688
+ } else if (isHypercoreToken) {
27689
+ let sendAmount = tokenAmount;
27690
+ try {
27691
+ const activation = await checkHypercoreActivation(
27692
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
27693
+ publishableKey
27694
+ );
27695
+ if (!activation.user_exists) {
27696
+ const fee = activation.activation_fee;
27697
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
27698
+ throw new Error(
27699
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
27700
+ );
27701
+ }
27702
+ sendAmount = tokenAmount - fee;
27703
+ }
27704
+ } catch (e) {
27705
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
27706
+ }
27707
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
27708
+ } else {
27709
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
27710
+ }
27535
27711
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
27536
27712
  setHasSignedTransaction(true);
27537
27713
  handleIveDeposited();
@@ -27749,7 +27925,7 @@ function WalletConnect({
27749
27925
  }
27750
27926
  if (view === "enter_amount" && selectedToken && selectedBalance) {
27751
27927
  return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
27752
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
27928
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
27753
27929
  }
27754
27930
  if (view === "review" && selectedToken) {
27755
27931
  return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
@@ -27785,6 +27961,9 @@ function SkeletonButton({
27785
27961
  ] });
27786
27962
  }
27787
27963
  var t7 = i18n2.depositModal;
27964
+ function depositTabForScreen(screen) {
27965
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
27966
+ }
27788
27967
  function DepositModal({
27789
27968
  open,
27790
27969
  onOpenChange,
@@ -27820,6 +27999,7 @@ function DepositModal({
27820
27999
  theme = "dark",
27821
28000
  hideOverlay = false,
27822
28001
  initialScreen = "main",
28002
+ displayMode = "stacked",
27823
28003
  transferCryptoTitle = t7.transferCrypto.title,
27824
28004
  depositWithCardTitle = t7.depositWithCard.title,
27825
28005
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -27854,6 +28034,9 @@ function DepositModal({
27854
28034
  effectiveInitialScreen
27855
28035
  );
27856
28036
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = (0, import_react8.useState)(false);
28037
+ const [depositTab, setDepositTab] = (0, import_react8.useState)(
28038
+ () => depositTabForScreen(effectiveInitialScreen)
28039
+ );
27857
28040
  const resetViewTimeoutRef = (0, import_react8.useRef)(null);
27858
28041
  const [cardView, setCardView] = (0, import_react8.useState)(
27859
28042
  "amount"
@@ -28151,6 +28334,7 @@ function DepositModal({
28151
28334
  resetViewTimeoutRef.current = null;
28152
28335
  }
28153
28336
  setView(effectiveInitialScreen);
28337
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
28154
28338
  setCardView("amount");
28155
28339
  setExchangeView("providers");
28156
28340
  setBrowserWalletInfo(null);
@@ -28179,6 +28363,7 @@ function DepositModal({
28179
28363
  } else if (view === "cashapp" && cashAppView !== "amount") {
28180
28364
  setCashAppView("amount");
28181
28365
  } else {
28366
+ setDepositTab(depositTabForScreen(view));
28182
28367
  setView("main");
28183
28368
  setCardView("amount");
28184
28369
  setExchangeView("providers");
@@ -28258,6 +28443,174 @@ function DepositModal({
28258
28443
  className: "uf-flex uf-justify-center uf-shrink-0"
28259
28444
  }
28260
28445
  ) });
28446
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28447
+ TransferCryptoButton,
28448
+ {
28449
+ onClick: () => setView("transfer"),
28450
+ title: transferCryptoTitle,
28451
+ subtitle: t7.transferCrypto.subtitle,
28452
+ featuredTokens: projectConfig?.transfer_crypto.networks
28453
+ },
28454
+ "transfer"
28455
+ ) : null;
28456
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28457
+ BrowserWalletButton,
28458
+ {
28459
+ onClick: handleBrowserWalletClick,
28460
+ onConnectClick: handleWalletConnectClick,
28461
+ onDisconnect: handleWalletDisconnect,
28462
+ chainType: browserWalletChainType,
28463
+ publishableKey,
28464
+ featuredWallets: projectConfig?.connect_wallet?.wallets
28465
+ },
28466
+ "wallet"
28467
+ ) : null;
28468
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28469
+ DepositWithCardButton,
28470
+ {
28471
+ onClick: () => setView("card"),
28472
+ title: depositWithCardTitle,
28473
+ subtitle: t7.depositWithCard.subtitle,
28474
+ paymentNetworks: projectConfig?.payment_networks.networks
28475
+ },
28476
+ "card"
28477
+ ) : null;
28478
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28479
+ PayWithExchangeButton,
28480
+ {
28481
+ onClick: () => setView("exchange"),
28482
+ title: payWithExchangeTitle,
28483
+ subtitle: t7.payWithExchange.subtitle,
28484
+ exchanges,
28485
+ loading: exchangesLoading
28486
+ },
28487
+ "exchange"
28488
+ ) : null;
28489
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28490
+ ConnectExchangeButton,
28491
+ {
28492
+ onClick: () => {
28493
+ setCoinbaseSkipToHoldings(true);
28494
+ setView("coinbase_connect");
28495
+ },
28496
+ onDisconnect: handleExchangeDisconnect,
28497
+ title: i18n2.connectExchange.title,
28498
+ subtitle: i18n2.connectExchange.subtitle,
28499
+ exchanges: integrationExchanges,
28500
+ connectedExchange
28501
+ },
28502
+ "connect-exchange"
28503
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28504
+ ConnectExchangeButton,
28505
+ {
28506
+ onClick: () => {
28507
+ setCoinbaseSkipToHoldings(false);
28508
+ setView("coinbase_connect");
28509
+ },
28510
+ title: i18n2.connectExchange.title,
28511
+ subtitle: i18n2.connectExchange.subtitle,
28512
+ exchanges: integrationExchanges
28513
+ },
28514
+ "connect-exchange"
28515
+ ) : null;
28516
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28517
+ CashAppButton,
28518
+ {
28519
+ onClick: () => setView("cashapp"),
28520
+ title: "Pay with Cash App",
28521
+ subtitle: "Deposit via Cash App",
28522
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28523
+ },
28524
+ "cashapp"
28525
+ ) : null;
28526
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28527
+ DepositTrackerButton,
28528
+ {
28529
+ onClick: () => {
28530
+ setAllExecutions(depositExecutions);
28531
+ setView("tracker");
28532
+ },
28533
+ title: depositTrackerTitle,
28534
+ subtitle: depositTrackerSubTitle,
28535
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
28536
+ },
28537
+ "tracker"
28538
+ ) : null;
28539
+ const cryptoMenuButtons = [
28540
+ transferCryptoMenuButton,
28541
+ connectWalletMenuButton,
28542
+ payWithExchangeMenuButton,
28543
+ connectExchangeMenuButton
28544
+ ].filter(Boolean);
28545
+ const cashMenuButtons = [
28546
+ depositWithCardMenuButton,
28547
+ cashAppMenuButton
28548
+ ].filter(Boolean);
28549
+ const depositTabs = [
28550
+ { id: "crypto", label: "Use Crypto", buttons: cryptoMenuButtons },
28551
+ { id: "cash", label: "Use Cash", buttons: cashMenuButtons }
28552
+ ].filter((tab) => tab.buttons.length > 0);
28553
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
28554
+ const renderMainMenuBody = () => {
28555
+ if (depositPrerequisiteBody) {
28556
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
28557
+ }
28558
+ if (displayMode === "tabs" && activeDepositTab) {
28559
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { children: [
28560
+ depositTabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28561
+ "div",
28562
+ {
28563
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
28564
+ style: {
28565
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
28566
+ // the control reads as a soft surface rather than a solid bar.
28567
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
28568
+ backdropFilter: "blur(12px)",
28569
+ WebkitBackdropFilter: "blur(12px)"
28570
+ },
28571
+ role: "tablist",
28572
+ children: depositTabs.map((tab) => {
28573
+ const active = activeDepositTab.id === tab.id;
28574
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28575
+ "button",
28576
+ {
28577
+ type: "button",
28578
+ role: "tab",
28579
+ "aria-selected": active,
28580
+ onClick: () => setDepositTab(tab.id),
28581
+ className: "uf-flex-1 uf-py-2 uf-px-3 uf-rounded-lg uf-text-sm uf-transition-all",
28582
+ style: {
28583
+ // Active tab is a soft, blurred glass pill — a faint accent
28584
+ // tint with its own backdrop blur and a subtle border/shadow,
28585
+ // so it looks frosted instead of like a hard solid button.
28586
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
28587
+ backdropFilter: active ? "blur(8px)" : void 0,
28588
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
28589
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
28590
+ color: active ? colors2.foreground : colors2.foregroundMuted,
28591
+ fontFamily: fonts.medium
28592
+ },
28593
+ children: tab.label
28594
+ },
28595
+ tab.id
28596
+ );
28597
+ })
28598
+ }
28599
+ ),
28600
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
28601
+ depositTrackerMenuButton && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
28602
+ ] });
28603
+ }
28604
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-space-y-3", children: [
28605
+ transferCryptoMenuButton,
28606
+ connectWalletMenuButton,
28607
+ depositWithCardMenuButton,
28608
+ payWithExchangeMenuButton,
28609
+ connectExchangeMenuButton,
28610
+ cashAppMenuButton,
28611
+ depositTrackerMenuButton
28612
+ ] });
28613
+ };
28261
28614
  return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28262
28615
  Dialog2,
28263
28616
  {
@@ -28284,7 +28637,7 @@ function DepositModal({
28284
28637
  onClose: handleClose,
28285
28638
  showBalance: showBalanceHeader,
28286
28639
  balanceAddress: recipientAddress,
28287
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28640
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
28288
28641
  balanceChainId: destinationChainId,
28289
28642
  balanceTokenAddress: destinationTokenAddress,
28290
28643
  projectName: projectConfig?.project_name,
@@ -28292,94 +28645,7 @@ function DepositModal({
28292
28645
  }
28293
28646
  ),
28294
28647
  /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28295
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
28296
- showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28297
- TransferCryptoButton,
28298
- {
28299
- onClick: () => setView("transfer"),
28300
- title: transferCryptoTitle,
28301
- subtitle: t7.transferCrypto.subtitle,
28302
- featuredTokens: projectConfig?.transfer_crypto.networks
28303
- }
28304
- ),
28305
- showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28306
- BrowserWalletButton,
28307
- {
28308
- onClick: handleBrowserWalletClick,
28309
- onConnectClick: handleWalletConnectClick,
28310
- onDisconnect: handleWalletDisconnect,
28311
- chainType: browserWalletChainType,
28312
- publishableKey,
28313
- featuredWallets: projectConfig?.connect_wallet?.wallets
28314
- }
28315
- ),
28316
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28317
- DepositWithCardButton,
28318
- {
28319
- onClick: () => setView("card"),
28320
- title: depositWithCardTitle,
28321
- subtitle: t7.depositWithCard.subtitle,
28322
- paymentNetworks: projectConfig?.payment_networks.networks
28323
- }
28324
- ),
28325
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28326
- PayWithExchangeButton,
28327
- {
28328
- onClick: () => setView("exchange"),
28329
- title: payWithExchangeTitle,
28330
- subtitle: t7.payWithExchange.subtitle,
28331
- exchanges,
28332
- loading: exchangesLoading
28333
- }
28334
- ),
28335
- showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28336
- ConnectExchangeButton,
28337
- {
28338
- onClick: () => {
28339
- setCoinbaseSkipToHoldings(true);
28340
- setView("coinbase_connect");
28341
- },
28342
- onDisconnect: handleExchangeDisconnect,
28343
- title: i18n2.connectExchange.title,
28344
- subtitle: i18n2.connectExchange.subtitle,
28345
- exchanges: integrationExchanges,
28346
- connectedExchange
28347
- }
28348
- ),
28349
- showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28350
- ConnectExchangeButton,
28351
- {
28352
- onClick: () => {
28353
- setCoinbaseSkipToHoldings(false);
28354
- setView("coinbase_connect");
28355
- },
28356
- title: i18n2.connectExchange.title,
28357
- subtitle: i18n2.connectExchange.subtitle,
28358
- exchanges: integrationExchanges
28359
- }
28360
- ),
28361
- showCashApp && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28362
- CashAppButton,
28363
- {
28364
- onClick: () => setView("cashapp"),
28365
- title: "Pay with Cash App",
28366
- subtitle: "Deposit via Cash App",
28367
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28368
- }
28369
- ),
28370
- showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28371
- DepositTrackerButton,
28372
- {
28373
- onClick: () => {
28374
- setAllExecutions(depositExecutions);
28375
- setView("tracker");
28376
- },
28377
- title: depositTrackerTitle,
28378
- subtitle: depositTrackerSubTitle,
28379
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
28380
- }
28381
- )
28382
- ] }) }),
28648
+ renderMainMenuBody(),
28383
28649
  depositPoweredByFooter
28384
28650
  ] })
28385
28651
  ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
@@ -28392,7 +28658,7 @@ function DepositModal({
28392
28658
  onClose: handleClose,
28393
28659
  showBalance: showBalanceHeader,
28394
28660
  balanceAddress: recipientAddress,
28395
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28661
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
28396
28662
  balanceChainId: destinationChainId,
28397
28663
  balanceTokenAddress: destinationTokenAddress,
28398
28664
  projectName: projectConfig?.project_name,
@@ -28480,7 +28746,7 @@ function DepositModal({
28480
28746
  badge: cardView === "quotes" ? { count: quotesCount } : void 0,
28481
28747
  showBalance: showBalanceHeader,
28482
28748
  balanceAddress: recipientAddress,
28483
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28749
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
28484
28750
  balanceChainId: destinationChainId,
28485
28751
  balanceTokenAddress: destinationTokenAddress,
28486
28752
  projectName: projectConfig?.project_name,
@@ -29776,9 +30042,6 @@ function useVerifyRecipientAddress(params) {
29776
30042
  refetchOnWindowFocus: false
29777
30043
  });
29778
30044
  }
29779
- function isHypercoreChain(chainId) {
29780
- return chainId === HYPERCORE_CHAIN_ID;
29781
- }
29782
30045
  function useGetDepositAddress(params) {
29783
30046
  const {
29784
30047
  userId,
@@ -30705,8 +30968,6 @@ function WithdrawConfirmingView({
30705
30968
  className: "uf-text-sm uf-text-center",
30706
30969
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
30707
30970
  children: [
30708
- txInfo.amount,
30709
- " ",
30710
30971
  txInfo.sourceTokenSymbol,
30711
30972
  " to",
30712
30973
  " ",
@@ -31350,6 +31611,7 @@ function UnifoldProvider2({
31350
31611
  hideDepositTracker: config?.hideDepositTracker,
31351
31612
  showBalanceHeader: config?.showBalanceHeader,
31352
31613
  transferInputVariant: config?.transferInputVariant,
31614
+ displayMode: config?.displayMode,
31353
31615
  enableTransferCrypto: config?.enableTransferCrypto,
31354
31616
  enableConnectWallet: config?.enableConnectWallet,
31355
31617
  enablePayWithExchange: config?.enablePayWithExchange,