@unifold/connect-react 0.1.64 → 0.1.66

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
@@ -1353,6 +1353,17 @@ var ArrowUpDown = createLucideIcon("ArrowUpDown", [
1353
1353
  ["path", { d: "M7 4v16", key: "1glfcx" }]
1354
1354
  ]);
1355
1355
 
1356
+ // ../../node_modules/.pnpm/lucide-react@0.454.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/bitcoin.js
1357
+ var Bitcoin = createLucideIcon("Bitcoin", [
1358
+ [
1359
+ "path",
1360
+ {
1361
+ d: "M11.767 19.089c4.924.868 6.14-6.025 1.216-6.894m-1.216 6.894L5.86 18.047m5.908 1.042-.347 1.97m1.563-8.864c4.924.869 6.14-6.025 1.215-6.893m-1.215 6.893-3.94-.694m5.155-6.2L8.29 4.26m5.908 1.042.348-1.97M7.48 20.364l3.126-17.727",
1362
+ key: "yr8idg"
1363
+ }
1364
+ ]
1365
+ ]);
1366
+
1356
1367
  // ../../node_modules/.pnpm/lucide-react@0.454.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/check.js
1357
1368
  var Check = createLucideIcon("Check", [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]]);
1358
1369
 
@@ -7031,6 +7042,29 @@ async function getDepositQuote(request, publishableKey) {
7031
7042
  const json = await response.json();
7032
7043
  return json.data;
7033
7044
  }
7045
+ async function buildHypercoreTransaction(request, publishableKey) {
7046
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
7047
+ validatePublishableKey(pk);
7048
+ const response = await fetch(
7049
+ `${API_BASE_URL}/v1/public/transactions/hypercore/build`,
7050
+ {
7051
+ method: "POST",
7052
+ headers: {
7053
+ accept: "application/json",
7054
+ "x-publishable-key": pk,
7055
+ "Content-Type": "application/json"
7056
+ },
7057
+ body: JSON.stringify(request)
7058
+ }
7059
+ );
7060
+ if (!response.ok) {
7061
+ const error = await response.json().catch(() => ({ message: response.statusText }));
7062
+ throw new Error(
7063
+ `Failed to build HyperCore transaction: ${error.message || response.statusText}`
7064
+ );
7065
+ }
7066
+ return response.json();
7067
+ }
7034
7068
  async function getCashAppLimits(currency = "usd", publishableKey) {
7035
7069
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
7036
7070
  validatePublishableKey(pk);
@@ -7096,6 +7130,29 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
7096
7130
  }
7097
7131
  return response.json();
7098
7132
  }
7133
+ async function sendHypercoreTransaction(request, publishableKey) {
7134
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
7135
+ validatePublishableKey(pk);
7136
+ const response = await fetch(
7137
+ `${API_BASE_URL}/v1/public/transactions/hypercore/send`,
7138
+ {
7139
+ method: "POST",
7140
+ headers: {
7141
+ accept: "application/json",
7142
+ "x-publishable-key": pk,
7143
+ "Content-Type": "application/json"
7144
+ },
7145
+ body: JSON.stringify(request)
7146
+ }
7147
+ );
7148
+ if (!response.ok) {
7149
+ const error = await response.json().catch(() => ({ message: response.statusText }));
7150
+ throw new Error(
7151
+ `Failed to send HyperCore transaction: ${error.message || response.statusText}`
7152
+ );
7153
+ }
7154
+ return response.json();
7155
+ }
7099
7156
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
7100
7157
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
7101
7158
  return DepositEventType2;
@@ -13610,6 +13667,22 @@ function clearStoredWalletState() {
13610
13667
  } catch {
13611
13668
  }
13612
13669
  }
13670
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
13671
+ function getLastOpenedWallet() {
13672
+ if (typeof window === "undefined") return void 0;
13673
+ try {
13674
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
13675
+ } catch {
13676
+ return void 0;
13677
+ }
13678
+ }
13679
+ function setLastOpenedWallet(walletId) {
13680
+ if (typeof window === "undefined") return;
13681
+ try {
13682
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
13683
+ } catch {
13684
+ }
13685
+ }
13613
13686
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
13614
13687
  function isMobileViewport() {
13615
13688
  if (typeof window === "undefined") return false;
@@ -14415,7 +14488,7 @@ function DepositHeader({
14415
14488
  setShowBalanceSkeleton(false);
14416
14489
  return;
14417
14490
  }
14418
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
14491
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
14419
14492
  if (!supportedChainTypes.includes(
14420
14493
  balanceChainType
14421
14494
  )) {
@@ -24433,7 +24506,7 @@ function useHypercoreActivation(params) {
24433
24506
  publishableKey,
24434
24507
  enabled = true
24435
24508
  } = params;
24436
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
24509
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
24437
24510
  const recipient = recipientAddress?.trim() ?? "";
24438
24511
  const source = sourceAddress?.trim() ?? "";
24439
24512
  const hasAddresses = !!recipient && !!source;
@@ -25579,6 +25652,46 @@ function TransferCryptoDoubleInput({
25579
25652
  }
25580
25653
  ) });
25581
25654
  }
25655
+ function isHypercoreChain(chainId) {
25656
+ return chainId === HYPERCORE_CHAIN_ID;
25657
+ }
25658
+ async function sendHypercoreEvmTransfer(params) {
25659
+ const {
25660
+ provider,
25661
+ fromAddress,
25662
+ recipientAddress,
25663
+ sourceTokenAddress,
25664
+ amount,
25665
+ publishableKey
25666
+ } = params;
25667
+ const currentChainHex = await provider.request({
25668
+ method: "eth_chainId",
25669
+ params: []
25670
+ });
25671
+ const activeChainId = String(parseInt(currentChainHex, 16));
25672
+ const buildResult = await buildHypercoreTransaction(
25673
+ {
25674
+ signature_chain_id: activeChainId,
25675
+ recipient_address: recipientAddress,
25676
+ token_address: sourceTokenAddress,
25677
+ amount
25678
+ },
25679
+ publishableKey
25680
+ );
25681
+ const signature = await provider.request({
25682
+ method: "eth_signTypedData_v4",
25683
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
25684
+ });
25685
+ await sendHypercoreTransaction(
25686
+ {
25687
+ action_payload: buildResult.action_payload,
25688
+ signature,
25689
+ nonce: buildResult.nonce
25690
+ },
25691
+ publishableKey
25692
+ );
25693
+ return { signature };
25694
+ }
25582
25695
  function useDepositQuote(params) {
25583
25696
  const {
25584
25697
  publishableKey,
@@ -25986,7 +26099,8 @@ function EnterAmountView({
25986
26099
  onClose,
25987
26100
  quickSelectMode,
25988
26101
  checkoutAmountUsd,
25989
- checkoutReceivedUsd
26102
+ checkoutReceivedUsd,
26103
+ footer
25990
26104
  }) {
25991
26105
  const { colors: colors2, fonts, components } = useTheme();
25992
26106
  const isCheckout = !!checkoutAmountUsd;
@@ -26242,6 +26356,7 @@ function EnterAmountView({
26242
26356
  )
26243
26357
  ] })
26244
26358
  ] }),
26359
+ footer && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
26245
26360
  /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
26246
26361
  "button",
26247
26362
  {
@@ -26691,7 +26806,7 @@ var WALLET_ICONS3 = {
26691
26806
  };
26692
26807
  var FALLBACK_WALLET_DEFINITIONS = [
26693
26808
  { 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 },
26809
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
26695
26810
  { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
26696
26811
  { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
26697
26812
  { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
@@ -26751,7 +26866,7 @@ function getLegacyEvmProviders() {
26751
26866
  okxEthereum: win.okxwallet
26752
26867
  };
26753
26868
  }
26754
- function detectAvailableWallets(definitions, filterChainType) {
26869
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
26755
26870
  const solProviders = getSolanaProviders();
26756
26871
  const legacyEvm = getLegacyEvmProviders();
26757
26872
  const eip6963List = getEip6963Providers();
@@ -26777,7 +26892,7 @@ function detectAvailableWallets(definitions, filterChainType) {
26777
26892
  return false;
26778
26893
  }
26779
26894
  });
26780
- return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26895
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26781
26896
  let isInstalled = false;
26782
26897
  const detectedNetworks = [];
26783
26898
  switch (wallet.id) {
@@ -26800,8 +26915,6 @@ function detectAvailableWallets(definitions, filterChainType) {
26800
26915
  isInstalled = true;
26801
26916
  detectedNetworks.push("ethereum");
26802
26917
  }
26803
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
26804
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
26805
26918
  break;
26806
26919
  case "trust":
26807
26920
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -26838,11 +26951,17 @@ function detectAvailableWallets(definitions, filterChainType) {
26838
26951
  }
26839
26952
  return { ...wallet, isInstalled, detectedNetworks };
26840
26953
  }).sort((a, b) => {
26954
+ if (recentWalletId) {
26955
+ const aRecent = a.id === recentWalletId ? 1 : 0;
26956
+ const bRecent = b.id === recentWalletId ? 1 : 0;
26957
+ if (aRecent !== bRecent) return bRecent - aRecent;
26958
+ }
26841
26959
  if (a.isInstalled && !b.isInstalled) return -1;
26842
26960
  if (!a.isInstalled && b.isInstalled) return 1;
26843
26961
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
26844
26962
  return 0;
26845
26963
  });
26964
+ return sorted;
26846
26965
  }
26847
26966
  function WalletConnect({
26848
26967
  walletInfo: initialWalletInfo,
@@ -26917,9 +27036,15 @@ function WalletConnect({
26917
27036
  })) : FALLBACK_WALLET_DEFINITIONS,
26918
27037
  [backendWallets]
26919
27038
  );
27039
+ const [recentWalletId, setRecentWalletIdState] = React302.useState(getLastOpenedWallet);
27040
+ React302.useEffect(() => {
27041
+ if (view === "select_wallet") {
27042
+ setRecentWalletIdState(getLastOpenedWallet());
27043
+ }
27044
+ }, [view]);
26920
27045
  const availableWallets = React302.useMemo(
26921
- () => detectAvailableWallets(walletDefinitions),
26922
- [walletDefinitions, eip6963ProviderCount]
27046
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
27047
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
26923
27048
  );
26924
27049
  const [isMobile, setIsMobile] = React302.useState(false);
26925
27050
  React302.useEffect(() => {
@@ -26979,7 +27104,7 @@ function WalletConnect({
26979
27104
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
26980
27105
  const recipientAddress = activeDepositWallet?.address ?? "";
26981
27106
  const isCheckoutMode = !!checkoutAmountUsd;
26982
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
27107
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
26983
27108
  const transitionTo = React302.useCallback((nextView) => {
26984
27109
  if (nextView === viewRef.current) return;
26985
27110
  setIsTransitioning(true);
@@ -27003,6 +27128,8 @@ function WalletConnect({
27003
27128
  );
27004
27129
  if (res.deeplink) {
27005
27130
  setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
27131
+ setLastOpenedWallet(wallet.id);
27132
+ setRecentWalletIdState(wallet.id);
27006
27133
  setAwaitingMobileDeposit(true);
27007
27134
  transitionTo("mobile_redirect");
27008
27135
  window.location.href = res.deeplink;
@@ -27063,6 +27190,8 @@ function WalletConnect({
27063
27190
  const handleConnectWallet = async (wallet, network) => {
27064
27191
  setConnectingNetwork(network);
27065
27192
  transitionTo("connecting");
27193
+ setLastOpenedWallet(wallet.id);
27194
+ setRecentWalletIdState(wallet.id);
27066
27195
  setWalletError(null);
27067
27196
  setIsWalletConnecting(true);
27068
27197
  try {
@@ -27167,6 +27296,13 @@ function WalletConnect({
27167
27296
  }
27168
27297
  };
27169
27298
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
27299
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
27300
+ recipientAddress,
27301
+ sourceAddress: activeWalletInfo?.address,
27302
+ destinationChainId: selectedToken?.chain_id,
27303
+ publishableKey,
27304
+ enabled: !!activeWalletInfo && !!recipientAddress
27305
+ });
27170
27306
  const effectiveDestinationAmount = React302.useMemo(() => {
27171
27307
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
27172
27308
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -27271,7 +27407,7 @@ function WalletConnect({
27271
27407
  let cancelled = false;
27272
27408
  setIsLoading(true);
27273
27409
  setError(null);
27274
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
27410
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
27275
27411
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
27276
27412
  if (cancelled) return;
27277
27413
  const nonZero = response.balances.filter((b) => b.amount !== "0");
@@ -27437,9 +27573,16 @@ function WalletConnect({
27437
27573
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
27438
27574
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
27439
27575
  };
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" };
27576
+ const resolveEvmProvider = () => {
27577
+ const walletIdMap = {
27578
+ "phantom-ethereum": "phantom",
27579
+ coinbase: "coinbase",
27580
+ trust: "trust",
27581
+ okx: "okx",
27582
+ rainbow: "rainbow",
27583
+ rabby: "rabby",
27584
+ metamask: "metamask"
27585
+ };
27443
27586
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
27444
27587
  const eip6963Match = findProviderByWalletId(lookupId);
27445
27588
  let provider = eip6963Match?.provider;
@@ -27448,6 +27591,11 @@ function WalletConnect({
27448
27591
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
27449
27592
  else provider = window.ethereum;
27450
27593
  }
27594
+ return provider;
27595
+ };
27596
+ const sendEthereumTransaction = async (token, amountStr) => {
27597
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
27598
+ const provider = resolveEvmProvider();
27451
27599
  if (!provider) throw new Error("Ethereum wallet not found");
27452
27600
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
27453
27601
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -27512,6 +27660,19 @@ function WalletConnect({
27512
27660
  const resp = await sendSolanaTransaction({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
27513
27661
  return resp.signature;
27514
27662
  };
27663
+ const sendHypercoreDeposit = async (token, amountStr) => {
27664
+ const provider = resolveEvmProvider();
27665
+ if (!provider) throw new Error("Ethereum wallet not found");
27666
+ const { signature } = await sendHypercoreEvmTransfer({
27667
+ provider,
27668
+ fromAddress: walletInfo.address,
27669
+ recipientAddress,
27670
+ sourceTokenAddress: token.token_address,
27671
+ amount: amountStr,
27672
+ publishableKey
27673
+ });
27674
+ return signature;
27675
+ };
27515
27676
  const handleConfirm = async () => {
27516
27677
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
27517
27678
  const token = getTokenFromBalance(selectedBalance);
@@ -27531,7 +27692,33 @@ function WalletConnect({
27531
27692
  setIsConfirming(true);
27532
27693
  setError(null);
27533
27694
  try {
27534
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction2(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
27695
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
27696
+ let txHash;
27697
+ if (token.chain_type === "solana") {
27698
+ txHash = await sendSolanaTransaction2(token, tokenAmount.toString());
27699
+ } else if (isHypercoreToken) {
27700
+ let sendAmount = tokenAmount;
27701
+ try {
27702
+ const activation = await checkHypercoreActivation(
27703
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
27704
+ publishableKey
27705
+ );
27706
+ if (!activation.user_exists) {
27707
+ const fee = activation.activation_fee;
27708
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
27709
+ throw new Error(
27710
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
27711
+ );
27712
+ }
27713
+ sendAmount = tokenAmount - fee;
27714
+ }
27715
+ } catch (e) {
27716
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
27717
+ }
27718
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
27719
+ } else {
27720
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
27721
+ }
27535
27722
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
27536
27723
  setHasSignedTransaction(true);
27537
27724
  handleIveDeposited();
@@ -27570,7 +27757,10 @@ function WalletConnect({
27570
27757
  children: [
27571
27758
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27572
27759
  WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
27573
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
27760
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
27761
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name }),
27762
+ wallet.id === recentWalletId && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "uf-text-xs uf-px-2 uf-py-0.5 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Last used" })
27763
+ ] })
27574
27764
  ] }),
27575
27765
  isPending ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin", style: { color: colors2.primary } }) : wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Detected" }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
27576
27766
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
@@ -27749,7 +27939,7 @@ function WalletConnect({
27749
27939
  }
27750
27940
  if (view === "enter_amount" && selectedToken && selectedBalance) {
27751
27941
  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 }) }) });
27942
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
27753
27943
  }
27754
27944
  if (view === "review" && selectedToken) {
27755
27945
  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 +27975,9 @@ function SkeletonButton({
27785
27975
  ] });
27786
27976
  }
27787
27977
  var t7 = i18n2.depositModal;
27978
+ function depositTabForScreen(screen) {
27979
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
27980
+ }
27788
27981
  function DepositModal({
27789
27982
  open,
27790
27983
  onOpenChange,
@@ -27820,6 +28013,7 @@ function DepositModal({
27820
28013
  theme = "dark",
27821
28014
  hideOverlay = false,
27822
28015
  initialScreen = "main",
28016
+ displayMode = "stacked",
27823
28017
  transferCryptoTitle = t7.transferCrypto.title,
27824
28018
  depositWithCardTitle = t7.depositWithCard.title,
27825
28019
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -27854,6 +28048,9 @@ function DepositModal({
27854
28048
  effectiveInitialScreen
27855
28049
  );
27856
28050
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = (0, import_react8.useState)(false);
28051
+ const [depositTab, setDepositTab] = (0, import_react8.useState)(
28052
+ () => depositTabForScreen(effectiveInitialScreen)
28053
+ );
27857
28054
  const resetViewTimeoutRef = (0, import_react8.useRef)(null);
27858
28055
  const [cardView, setCardView] = (0, import_react8.useState)(
27859
28056
  "amount"
@@ -28151,6 +28348,7 @@ function DepositModal({
28151
28348
  resetViewTimeoutRef.current = null;
28152
28349
  }
28153
28350
  setView(effectiveInitialScreen);
28351
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
28154
28352
  setCardView("amount");
28155
28353
  setExchangeView("providers");
28156
28354
  setBrowserWalletInfo(null);
@@ -28179,6 +28377,7 @@ function DepositModal({
28179
28377
  } else if (view === "cashapp" && cashAppView !== "amount") {
28180
28378
  setCashAppView("amount");
28181
28379
  } else {
28380
+ setDepositTab(depositTabForScreen(view));
28182
28381
  setView("main");
28183
28382
  setCardView("amount");
28184
28383
  setExchangeView("providers");
@@ -28258,6 +28457,184 @@ function DepositModal({
28258
28457
  className: "uf-flex uf-justify-center uf-shrink-0"
28259
28458
  }
28260
28459
  ) });
28460
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28461
+ TransferCryptoButton,
28462
+ {
28463
+ onClick: () => setView("transfer"),
28464
+ title: transferCryptoTitle,
28465
+ subtitle: t7.transferCrypto.subtitle,
28466
+ featuredTokens: projectConfig?.transfer_crypto.networks
28467
+ },
28468
+ "transfer"
28469
+ ) : null;
28470
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28471
+ BrowserWalletButton,
28472
+ {
28473
+ onClick: handleBrowserWalletClick,
28474
+ onConnectClick: handleWalletConnectClick,
28475
+ onDisconnect: handleWalletDisconnect,
28476
+ chainType: browserWalletChainType,
28477
+ publishableKey,
28478
+ featuredWallets: projectConfig?.connect_wallet?.wallets
28479
+ },
28480
+ "wallet"
28481
+ ) : null;
28482
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28483
+ DepositWithCardButton,
28484
+ {
28485
+ onClick: () => setView("card"),
28486
+ title: depositWithCardTitle,
28487
+ subtitle: t7.depositWithCard.subtitle,
28488
+ paymentNetworks: projectConfig?.payment_networks.networks
28489
+ },
28490
+ "card"
28491
+ ) : null;
28492
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28493
+ PayWithExchangeButton,
28494
+ {
28495
+ onClick: () => setView("exchange"),
28496
+ title: payWithExchangeTitle,
28497
+ subtitle: t7.payWithExchange.subtitle,
28498
+ exchanges,
28499
+ loading: exchangesLoading
28500
+ },
28501
+ "exchange"
28502
+ ) : null;
28503
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28504
+ ConnectExchangeButton,
28505
+ {
28506
+ onClick: () => {
28507
+ setCoinbaseSkipToHoldings(true);
28508
+ setView("coinbase_connect");
28509
+ },
28510
+ onDisconnect: handleExchangeDisconnect,
28511
+ title: i18n2.connectExchange.title,
28512
+ subtitle: i18n2.connectExchange.subtitle,
28513
+ exchanges: integrationExchanges,
28514
+ connectedExchange
28515
+ },
28516
+ "connect-exchange"
28517
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28518
+ ConnectExchangeButton,
28519
+ {
28520
+ onClick: () => {
28521
+ setCoinbaseSkipToHoldings(false);
28522
+ setView("coinbase_connect");
28523
+ },
28524
+ title: i18n2.connectExchange.title,
28525
+ subtitle: i18n2.connectExchange.subtitle,
28526
+ exchanges: integrationExchanges
28527
+ },
28528
+ "connect-exchange"
28529
+ ) : null;
28530
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28531
+ CashAppButton,
28532
+ {
28533
+ onClick: () => setView("cashapp"),
28534
+ title: "Pay with Cash App",
28535
+ subtitle: "Deposit via Cash App",
28536
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28537
+ },
28538
+ "cashapp"
28539
+ ) : null;
28540
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28541
+ DepositTrackerButton,
28542
+ {
28543
+ onClick: () => {
28544
+ setAllExecutions(depositExecutions);
28545
+ setView("tracker");
28546
+ },
28547
+ title: depositTrackerTitle,
28548
+ subtitle: depositTrackerSubTitle,
28549
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
28550
+ },
28551
+ "tracker"
28552
+ ) : null;
28553
+ const cryptoMenuButtons = [
28554
+ transferCryptoMenuButton,
28555
+ connectWalletMenuButton,
28556
+ payWithExchangeMenuButton,
28557
+ connectExchangeMenuButton
28558
+ ].filter(Boolean);
28559
+ const cashMenuButtons = [
28560
+ depositWithCardMenuButton,
28561
+ cashAppMenuButton
28562
+ ].filter(Boolean);
28563
+ const depositTabs = [
28564
+ { id: "crypto", label: "Use Crypto", icon: Bitcoin, buttons: cryptoMenuButtons },
28565
+ { id: "cash", label: "Use Cash", icon: DollarSign, buttons: cashMenuButtons }
28566
+ ].filter((tab) => tab.buttons.length > 0);
28567
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
28568
+ const renderMainMenuBody = () => {
28569
+ if (depositPrerequisiteBody) {
28570
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
28571
+ }
28572
+ if (displayMode === "tabs" && activeDepositTab) {
28573
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { children: [
28574
+ depositTabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28575
+ "div",
28576
+ {
28577
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
28578
+ style: {
28579
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
28580
+ // the control reads as a soft surface rather than a solid bar.
28581
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
28582
+ backdropFilter: "blur(12px)",
28583
+ WebkitBackdropFilter: "blur(12px)"
28584
+ },
28585
+ role: "tablist",
28586
+ children: depositTabs.map((tab) => {
28587
+ const active = activeDepositTab.id === tab.id;
28588
+ const TabIcon = tab.icon;
28589
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
28590
+ "button",
28591
+ {
28592
+ type: "button",
28593
+ role: "tab",
28594
+ "aria-selected": active,
28595
+ onClick: () => setDepositTab(tab.id),
28596
+ className: "uf-flex-1 uf-py-2 uf-px-3 uf-rounded-lg uf-text-sm uf-transition-all uf-flex uf-items-center uf-justify-center uf-gap-1.5",
28597
+ style: {
28598
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
28599
+ backdropFilter: active ? "blur(8px)" : void 0,
28600
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
28601
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
28602
+ color: active ? colors2.foreground : colors2.foregroundMuted,
28603
+ fontFamily: fonts.medium
28604
+ },
28605
+ children: [
28606
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28607
+ "span",
28608
+ {
28609
+ className: "uf-inline-flex uf-items-center uf-justify-center uf-rounded-full uf-w-5 uf-h-5 uf-flex-shrink-0",
28610
+ style: {
28611
+ backgroundColor: active ? colors2.foreground : colors2.foregroundMuted
28612
+ },
28613
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(TabIcon, { size: 12, style: { color: active ? colors2.background : colors2.background }, strokeWidth: 2.5 })
28614
+ }
28615
+ ),
28616
+ tab.label
28617
+ ]
28618
+ },
28619
+ tab.id
28620
+ );
28621
+ })
28622
+ }
28623
+ ),
28624
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
28625
+ depositTrackerMenuButton && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
28626
+ ] });
28627
+ }
28628
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "uf-space-y-3", children: [
28629
+ transferCryptoMenuButton,
28630
+ connectWalletMenuButton,
28631
+ depositWithCardMenuButton,
28632
+ payWithExchangeMenuButton,
28633
+ connectExchangeMenuButton,
28634
+ cashAppMenuButton,
28635
+ depositTrackerMenuButton
28636
+ ] });
28637
+ };
28261
28638
  return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
28262
28639
  Dialog2,
28263
28640
  {
@@ -28284,7 +28661,7 @@ function DepositModal({
28284
28661
  onClose: handleClose,
28285
28662
  showBalance: showBalanceHeader,
28286
28663
  balanceAddress: recipientAddress,
28287
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28664
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
28288
28665
  balanceChainId: destinationChainId,
28289
28666
  balanceTokenAddress: destinationTokenAddress,
28290
28667
  projectName: projectConfig?.project_name,
@@ -28292,94 +28669,7 @@ function DepositModal({
28292
28669
  }
28293
28670
  ),
28294
28671
  /* @__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
- ] }) }),
28672
+ renderMainMenuBody(),
28383
28673
  depositPoweredByFooter
28384
28674
  ] })
28385
28675
  ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
@@ -28392,7 +28682,7 @@ function DepositModal({
28392
28682
  onClose: handleClose,
28393
28683
  showBalance: showBalanceHeader,
28394
28684
  balanceAddress: recipientAddress,
28395
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28685
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
28396
28686
  balanceChainId: destinationChainId,
28397
28687
  balanceTokenAddress: destinationTokenAddress,
28398
28688
  projectName: projectConfig?.project_name,
@@ -28480,7 +28770,7 @@ function DepositModal({
28480
28770
  badge: cardView === "quotes" ? { count: quotesCount } : void 0,
28481
28771
  showBalance: showBalanceHeader,
28482
28772
  balanceAddress: recipientAddress,
28483
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28773
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
28484
28774
  balanceChainId: destinationChainId,
28485
28775
  balanceTokenAddress: destinationTokenAddress,
28486
28776
  projectName: projectConfig?.project_name,
@@ -29776,9 +30066,6 @@ function useVerifyRecipientAddress(params) {
29776
30066
  refetchOnWindowFocus: false
29777
30067
  });
29778
30068
  }
29779
- function isHypercoreChain(chainId) {
29780
- return chainId === HYPERCORE_CHAIN_ID;
29781
- }
29782
30069
  function useGetDepositAddress(params) {
29783
30070
  const {
29784
30071
  userId,
@@ -30705,8 +30992,6 @@ function WithdrawConfirmingView({
30705
30992
  className: "uf-text-sm uf-text-center",
30706
30993
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
30707
30994
  children: [
30708
- txInfo.amount,
30709
- " ",
30710
30995
  txInfo.sourceTokenSymbol,
30711
30996
  " to",
30712
30997
  " ",
@@ -31350,6 +31635,7 @@ function UnifoldProvider2({
31350
31635
  hideDepositTracker: config?.hideDepositTracker,
31351
31636
  showBalanceHeader: config?.showBalanceHeader,
31352
31637
  transferInputVariant: config?.transferInputVariant,
31638
+ displayMode: config?.displayMode,
31353
31639
  enableTransferCrypto: config?.enableTransferCrypto,
31354
31640
  enableConnectWallet: config?.enableConnectWallet,
31355
31641
  enablePayWithExchange: config?.enablePayWithExchange,
@@ -31456,6 +31742,7 @@ lucide-react/dist/esm/createLucideIcon.js:
31456
31742
  lucide-react/dist/esm/icons/arrow-left-right.js:
31457
31743
  lucide-react/dist/esm/icons/arrow-left.js:
31458
31744
  lucide-react/dist/esm/icons/arrow-up-down.js:
31745
+ lucide-react/dist/esm/icons/bitcoin.js:
31459
31746
  lucide-react/dist/esm/icons/check.js:
31460
31747
  lucide-react/dist/esm/icons/chevron-down.js:
31461
31748
  lucide-react/dist/esm/icons/chevron-right.js: