@unifold/ui-web 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.
Files changed (3) hide show
  1. package/dist/index.js +399 -114
  2. package/dist/index.mjs +399 -114
  3. package/package.json +5 -5
package/dist/index.mjs CHANGED
@@ -38511,6 +38511,15 @@ var ArrowUpDown = createLucideIcon("ArrowUpDown", [
38511
38511
  ["path", { d: "m3 8 4-4 4 4", key: "11wl7u" }],
38512
38512
  ["path", { d: "M7 4v16", key: "1glfcx" }]
38513
38513
  ]);
38514
+ var Bitcoin = createLucideIcon("Bitcoin", [
38515
+ [
38516
+ "path",
38517
+ {
38518
+ 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",
38519
+ key: "yr8idg"
38520
+ }
38521
+ ]
38522
+ ]);
38514
38523
  var Check = createLucideIcon("Check", [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]]);
38515
38524
  var ChevronDown = createLucideIcon("ChevronDown", [
38516
38525
  ["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]
@@ -43973,6 +43982,29 @@ async function getDepositQuote(request, publishableKey) {
43973
43982
  const json = await response.json();
43974
43983
  return json.data;
43975
43984
  }
43985
+ async function buildHypercoreTransaction(request, publishableKey) {
43986
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43987
+ validatePublishableKey(pk);
43988
+ const response = await fetch(
43989
+ `${API_BASE_URL}/v1/public/transactions/hypercore/build`,
43990
+ {
43991
+ method: "POST",
43992
+ headers: {
43993
+ accept: "application/json",
43994
+ "x-publishable-key": pk,
43995
+ "Content-Type": "application/json"
43996
+ },
43997
+ body: JSON.stringify(request)
43998
+ }
43999
+ );
44000
+ if (!response.ok) {
44001
+ const error = await response.json().catch(() => ({ message: response.statusText }));
44002
+ throw new Error(
44003
+ `Failed to build HyperCore transaction: ${error.message || response.statusText}`
44004
+ );
44005
+ }
44006
+ return response.json();
44007
+ }
43976
44008
  async function getCashAppLimits(currency = "usd", publishableKey) {
43977
44009
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43978
44010
  validatePublishableKey(pk);
@@ -44038,6 +44070,29 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
44038
44070
  }
44039
44071
  return response.json();
44040
44072
  }
44073
+ async function sendHypercoreTransaction(request, publishableKey) {
44074
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
44075
+ validatePublishableKey(pk);
44076
+ const response = await fetch(
44077
+ `${API_BASE_URL}/v1/public/transactions/hypercore/send`,
44078
+ {
44079
+ method: "POST",
44080
+ headers: {
44081
+ accept: "application/json",
44082
+ "x-publishable-key": pk,
44083
+ "Content-Type": "application/json"
44084
+ },
44085
+ body: JSON.stringify(request)
44086
+ }
44087
+ );
44088
+ if (!response.ok) {
44089
+ const error = await response.json().catch(() => ({ message: response.statusText }));
44090
+ throw new Error(
44091
+ `Failed to send HyperCore transaction: ${error.message || response.statusText}`
44092
+ );
44093
+ }
44094
+ return response.json();
44095
+ }
44041
44096
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
44042
44097
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
44043
44098
  return DepositEventType2;
@@ -50214,6 +50269,22 @@ function clearStoredWalletState() {
50214
50269
  } catch {
50215
50270
  }
50216
50271
  }
50272
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
50273
+ function getLastOpenedWallet() {
50274
+ if (typeof window === "undefined") return void 0;
50275
+ try {
50276
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
50277
+ } catch {
50278
+ return void 0;
50279
+ }
50280
+ }
50281
+ function setLastOpenedWallet(walletId) {
50282
+ if (typeof window === "undefined") return;
50283
+ try {
50284
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
50285
+ } catch {
50286
+ }
50287
+ }
50217
50288
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
50218
50289
  function isMobileViewport() {
50219
50290
  if (typeof window === "undefined") return false;
@@ -51019,7 +51090,7 @@ function DepositHeader({
51019
51090
  setShowBalanceSkeleton(false);
51020
51091
  return;
51021
51092
  }
51022
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
51093
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
51023
51094
  if (!supportedChainTypes.includes(
51024
51095
  balanceChainType
51025
51096
  )) {
@@ -61037,7 +61108,7 @@ function useHypercoreActivation(params) {
61037
61108
  publishableKey,
61038
61109
  enabled = true
61039
61110
  } = params;
61040
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
61111
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
61041
61112
  const recipient = recipientAddress?.trim() ?? "";
61042
61113
  const source = sourceAddress?.trim() ?? "";
61043
61114
  const hasAddresses = !!recipient && !!source;
@@ -62183,6 +62254,46 @@ function TransferCryptoDoubleInput({
62183
62254
  }
62184
62255
  ) });
62185
62256
  }
62257
+ function isHypercoreChain(chainId) {
62258
+ return chainId === HYPERCORE_CHAIN_ID;
62259
+ }
62260
+ async function sendHypercoreEvmTransfer(params) {
62261
+ const {
62262
+ provider,
62263
+ fromAddress,
62264
+ recipientAddress,
62265
+ sourceTokenAddress,
62266
+ amount,
62267
+ publishableKey
62268
+ } = params;
62269
+ const currentChainHex = await provider.request({
62270
+ method: "eth_chainId",
62271
+ params: []
62272
+ });
62273
+ const activeChainId = String(parseInt(currentChainHex, 16));
62274
+ const buildResult = await buildHypercoreTransaction(
62275
+ {
62276
+ signature_chain_id: activeChainId,
62277
+ recipient_address: recipientAddress,
62278
+ token_address: sourceTokenAddress,
62279
+ amount
62280
+ },
62281
+ publishableKey
62282
+ );
62283
+ const signature = await provider.request({
62284
+ method: "eth_signTypedData_v4",
62285
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
62286
+ });
62287
+ await sendHypercoreTransaction(
62288
+ {
62289
+ action_payload: buildResult.action_payload,
62290
+ signature,
62291
+ nonce: buildResult.nonce
62292
+ },
62293
+ publishableKey
62294
+ );
62295
+ return { signature };
62296
+ }
62186
62297
  function useDepositQuote(params) {
62187
62298
  const {
62188
62299
  publishableKey,
@@ -62590,7 +62701,8 @@ function EnterAmountView({
62590
62701
  onClose,
62591
62702
  quickSelectMode,
62592
62703
  checkoutAmountUsd,
62593
- checkoutReceivedUsd
62704
+ checkoutReceivedUsd,
62705
+ footer
62594
62706
  }) {
62595
62707
  const { colors: colors2, fonts, components } = useTheme();
62596
62708
  const isCheckout = !!checkoutAmountUsd;
@@ -62846,6 +62958,7 @@ function EnterAmountView({
62846
62958
  )
62847
62959
  ] })
62848
62960
  ] }),
62961
+ footer && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
62849
62962
  /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
62850
62963
  "button",
62851
62964
  {
@@ -63295,7 +63408,7 @@ var WALLET_ICONS3 = {
63295
63408
  };
63296
63409
  var FALLBACK_WALLET_DEFINITIONS = [
63297
63410
  { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
63298
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
63411
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
63299
63412
  { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
63300
63413
  { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
63301
63414
  { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
@@ -63355,7 +63468,7 @@ function getLegacyEvmProviders() {
63355
63468
  okxEthereum: win.okxwallet
63356
63469
  };
63357
63470
  }
63358
- function detectAvailableWallets(definitions, filterChainType) {
63471
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
63359
63472
  const solProviders = getSolanaProviders();
63360
63473
  const legacyEvm = getLegacyEvmProviders();
63361
63474
  const eip6963List = getEip6963Providers();
@@ -63381,7 +63494,7 @@ function detectAvailableWallets(definitions, filterChainType) {
63381
63494
  return false;
63382
63495
  }
63383
63496
  });
63384
- return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63497
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63385
63498
  let isInstalled = false;
63386
63499
  const detectedNetworks = [];
63387
63500
  switch (wallet.id) {
@@ -63404,8 +63517,6 @@ function detectAvailableWallets(definitions, filterChainType) {
63404
63517
  isInstalled = true;
63405
63518
  detectedNetworks.push("ethereum");
63406
63519
  }
63407
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
63408
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
63409
63520
  break;
63410
63521
  case "trust":
63411
63522
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -63442,11 +63553,17 @@ function detectAvailableWallets(definitions, filterChainType) {
63442
63553
  }
63443
63554
  return { ...wallet, isInstalled, detectedNetworks };
63444
63555
  }).sort((a, b) => {
63556
+ if (recentWalletId) {
63557
+ const aRecent = a.id === recentWalletId ? 1 : 0;
63558
+ const bRecent = b.id === recentWalletId ? 1 : 0;
63559
+ if (aRecent !== bRecent) return bRecent - aRecent;
63560
+ }
63445
63561
  if (a.isInstalled && !b.isInstalled) return -1;
63446
63562
  if (!a.isInstalled && b.isInstalled) return 1;
63447
63563
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
63448
63564
  return 0;
63449
63565
  });
63566
+ return sorted;
63450
63567
  }
63451
63568
  function WalletConnect({
63452
63569
  walletInfo: initialWalletInfo,
@@ -63521,9 +63638,15 @@ function WalletConnect({
63521
63638
  })) : FALLBACK_WALLET_DEFINITIONS,
63522
63639
  [backendWallets]
63523
63640
  );
63641
+ const [recentWalletId, setRecentWalletIdState] = React302.useState(getLastOpenedWallet);
63642
+ React302.useEffect(() => {
63643
+ if (view === "select_wallet") {
63644
+ setRecentWalletIdState(getLastOpenedWallet());
63645
+ }
63646
+ }, [view]);
63524
63647
  const availableWallets = React302.useMemo(
63525
- () => detectAvailableWallets(walletDefinitions),
63526
- [walletDefinitions, eip6963ProviderCount]
63648
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
63649
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
63527
63650
  );
63528
63651
  const [isMobile, setIsMobile] = React302.useState(false);
63529
63652
  React302.useEffect(() => {
@@ -63583,7 +63706,7 @@ function WalletConnect({
63583
63706
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
63584
63707
  const recipientAddress = activeDepositWallet?.address ?? "";
63585
63708
  const isCheckoutMode = !!checkoutAmountUsd;
63586
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
63709
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
63587
63710
  const transitionTo = React302.useCallback((nextView) => {
63588
63711
  if (nextView === viewRef.current) return;
63589
63712
  setIsTransitioning(true);
@@ -63607,6 +63730,8 @@ function WalletConnect({
63607
63730
  );
63608
63731
  if (res.deeplink) {
63609
63732
  setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
63733
+ setLastOpenedWallet(wallet.id);
63734
+ setRecentWalletIdState(wallet.id);
63610
63735
  setAwaitingMobileDeposit(true);
63611
63736
  transitionTo("mobile_redirect");
63612
63737
  window.location.href = res.deeplink;
@@ -63667,6 +63792,8 @@ function WalletConnect({
63667
63792
  const handleConnectWallet = async (wallet, network) => {
63668
63793
  setConnectingNetwork(network);
63669
63794
  transitionTo("connecting");
63795
+ setLastOpenedWallet(wallet.id);
63796
+ setRecentWalletIdState(wallet.id);
63670
63797
  setWalletError(null);
63671
63798
  setIsWalletConnecting(true);
63672
63799
  try {
@@ -63771,6 +63898,13 @@ function WalletConnect({
63771
63898
  }
63772
63899
  };
63773
63900
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
63901
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
63902
+ recipientAddress,
63903
+ sourceAddress: activeWalletInfo?.address,
63904
+ destinationChainId: selectedToken?.chain_id,
63905
+ publishableKey,
63906
+ enabled: !!activeWalletInfo && !!recipientAddress
63907
+ });
63774
63908
  const effectiveDestinationAmount = React302.useMemo(() => {
63775
63909
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
63776
63910
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -63875,7 +64009,7 @@ function WalletConnect({
63875
64009
  let cancelled = false;
63876
64010
  setIsLoading(true);
63877
64011
  setError(null);
63878
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
64012
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
63879
64013
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
63880
64014
  if (cancelled) return;
63881
64015
  const nonZero = response.balances.filter((b) => b.amount !== "0");
@@ -64041,9 +64175,16 @@ function WalletConnect({
64041
64175
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
64042
64176
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
64043
64177
  };
64044
- const sendEthereumTransaction = async (token, amountStr) => {
64045
- if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
64046
- const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
64178
+ const resolveEvmProvider = () => {
64179
+ const walletIdMap = {
64180
+ "phantom-ethereum": "phantom",
64181
+ coinbase: "coinbase",
64182
+ trust: "trust",
64183
+ okx: "okx",
64184
+ rainbow: "rainbow",
64185
+ rabby: "rabby",
64186
+ metamask: "metamask"
64187
+ };
64047
64188
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
64048
64189
  const eip6963Match = findProviderByWalletId(lookupId);
64049
64190
  let provider = eip6963Match?.provider;
@@ -64052,6 +64193,11 @@ function WalletConnect({
64052
64193
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
64053
64194
  else provider = window.ethereum;
64054
64195
  }
64196
+ return provider;
64197
+ };
64198
+ const sendEthereumTransaction = async (token, amountStr) => {
64199
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
64200
+ const provider = resolveEvmProvider();
64055
64201
  if (!provider) throw new Error("Ethereum wallet not found");
64056
64202
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
64057
64203
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -64116,6 +64262,19 @@ function WalletConnect({
64116
64262
  const resp = await sendSolanaTransaction({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
64117
64263
  return resp.signature;
64118
64264
  };
64265
+ const sendHypercoreDeposit = async (token, amountStr) => {
64266
+ const provider = resolveEvmProvider();
64267
+ if (!provider) throw new Error("Ethereum wallet not found");
64268
+ const { signature } = await sendHypercoreEvmTransfer({
64269
+ provider,
64270
+ fromAddress: walletInfo.address,
64271
+ recipientAddress,
64272
+ sourceTokenAddress: token.token_address,
64273
+ amount: amountStr,
64274
+ publishableKey
64275
+ });
64276
+ return signature;
64277
+ };
64119
64278
  const handleConfirm = async () => {
64120
64279
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
64121
64280
  const token = getTokenFromBalance(selectedBalance);
@@ -64135,7 +64294,33 @@ function WalletConnect({
64135
64294
  setIsConfirming(true);
64136
64295
  setError(null);
64137
64296
  try {
64138
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction2(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
64297
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
64298
+ let txHash;
64299
+ if (token.chain_type === "solana") {
64300
+ txHash = await sendSolanaTransaction2(token, tokenAmount.toString());
64301
+ } else if (isHypercoreToken) {
64302
+ let sendAmount = tokenAmount;
64303
+ try {
64304
+ const activation = await checkHypercoreActivation(
64305
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
64306
+ publishableKey
64307
+ );
64308
+ if (!activation.user_exists) {
64309
+ const fee = activation.activation_fee;
64310
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
64311
+ throw new Error(
64312
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
64313
+ );
64314
+ }
64315
+ sendAmount = tokenAmount - fee;
64316
+ }
64317
+ } catch (e) {
64318
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
64319
+ }
64320
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
64321
+ } else {
64322
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
64323
+ }
64139
64324
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
64140
64325
  setHasSignedTransaction(true);
64141
64326
  handleIveDeposited();
@@ -64174,7 +64359,10 @@ function WalletConnect({
64174
64359
  children: [
64175
64360
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64176
64361
  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" }),
64177
- /* @__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 })
64362
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
64363
+ /* @__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 }),
64364
+ wallet.id === recentWalletId && /* @__PURE__ */ (0, import_jsx_runtime73.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" })
64365
+ ] })
64178
64366
  ] }),
64179
64367
  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: [
64180
64368
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
@@ -64353,7 +64541,7 @@ function WalletConnect({
64353
64541
  }
64354
64542
  if (view === "enter_amount" && selectedToken && selectedBalance) {
64355
64543
  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 ?? (() => {
64356
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
64544
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
64357
64545
  }
64358
64546
  if (view === "review" && selectedToken) {
64359
64547
  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 ?? (() => {
@@ -64389,6 +64577,9 @@ function SkeletonButton({
64389
64577
  ] });
64390
64578
  }
64391
64579
  var t7 = i18n2.depositModal;
64580
+ function depositTabForScreen(screen) {
64581
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
64582
+ }
64392
64583
  function DepositModal({
64393
64584
  open,
64394
64585
  onOpenChange,
@@ -64424,6 +64615,7 @@ function DepositModal({
64424
64615
  theme = "dark",
64425
64616
  hideOverlay = false,
64426
64617
  initialScreen = "main",
64618
+ displayMode = "stacked",
64427
64619
  transferCryptoTitle = t7.transferCrypto.title,
64428
64620
  depositWithCardTitle = t7.depositWithCard.title,
64429
64621
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -64458,6 +64650,9 @@ function DepositModal({
64458
64650
  effectiveInitialScreen
64459
64651
  );
64460
64652
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = (0, import_react3.useState)(false);
64653
+ const [depositTab, setDepositTab] = (0, import_react3.useState)(
64654
+ () => depositTabForScreen(effectiveInitialScreen)
64655
+ );
64461
64656
  const resetViewTimeoutRef = (0, import_react3.useRef)(null);
64462
64657
  const [cardView, setCardView] = (0, import_react3.useState)(
64463
64658
  "amount"
@@ -64755,6 +64950,7 @@ function DepositModal({
64755
64950
  resetViewTimeoutRef.current = null;
64756
64951
  }
64757
64952
  setView(effectiveInitialScreen);
64953
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
64758
64954
  setCardView("amount");
64759
64955
  setExchangeView("providers");
64760
64956
  setBrowserWalletInfo(null);
@@ -64783,6 +64979,7 @@ function DepositModal({
64783
64979
  } else if (view === "cashapp" && cashAppView !== "amount") {
64784
64980
  setCashAppView("amount");
64785
64981
  } else {
64982
+ setDepositTab(depositTabForScreen(view));
64786
64983
  setView("main");
64787
64984
  setCardView("amount");
64788
64985
  setExchangeView("providers");
@@ -64862,6 +65059,184 @@ function DepositModal({
64862
65059
  className: "uf-flex uf-justify-center uf-shrink-0"
64863
65060
  }
64864
65061
  ) });
65062
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65063
+ TransferCryptoButton,
65064
+ {
65065
+ onClick: () => setView("transfer"),
65066
+ title: transferCryptoTitle,
65067
+ subtitle: t7.transferCrypto.subtitle,
65068
+ featuredTokens: projectConfig?.transfer_crypto.networks
65069
+ },
65070
+ "transfer"
65071
+ ) : null;
65072
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65073
+ BrowserWalletButton,
65074
+ {
65075
+ onClick: handleBrowserWalletClick,
65076
+ onConnectClick: handleWalletConnectClick,
65077
+ onDisconnect: handleWalletDisconnect,
65078
+ chainType: browserWalletChainType,
65079
+ publishableKey,
65080
+ featuredWallets: projectConfig?.connect_wallet?.wallets
65081
+ },
65082
+ "wallet"
65083
+ ) : null;
65084
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65085
+ DepositWithCardButton,
65086
+ {
65087
+ onClick: () => setView("card"),
65088
+ title: depositWithCardTitle,
65089
+ subtitle: t7.depositWithCard.subtitle,
65090
+ paymentNetworks: projectConfig?.payment_networks.networks
65091
+ },
65092
+ "card"
65093
+ ) : null;
65094
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65095
+ PayWithExchangeButton,
65096
+ {
65097
+ onClick: () => setView("exchange"),
65098
+ title: payWithExchangeTitle,
65099
+ subtitle: t7.payWithExchange.subtitle,
65100
+ exchanges,
65101
+ loading: exchangesLoading
65102
+ },
65103
+ "exchange"
65104
+ ) : null;
65105
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65106
+ ConnectExchangeButton,
65107
+ {
65108
+ onClick: () => {
65109
+ setCoinbaseSkipToHoldings(true);
65110
+ setView("coinbase_connect");
65111
+ },
65112
+ onDisconnect: handleExchangeDisconnect,
65113
+ title: i18n2.connectExchange.title,
65114
+ subtitle: i18n2.connectExchange.subtitle,
65115
+ exchanges: integrationExchanges,
65116
+ connectedExchange
65117
+ },
65118
+ "connect-exchange"
65119
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65120
+ ConnectExchangeButton,
65121
+ {
65122
+ onClick: () => {
65123
+ setCoinbaseSkipToHoldings(false);
65124
+ setView("coinbase_connect");
65125
+ },
65126
+ title: i18n2.connectExchange.title,
65127
+ subtitle: i18n2.connectExchange.subtitle,
65128
+ exchanges: integrationExchanges
65129
+ },
65130
+ "connect-exchange"
65131
+ ) : null;
65132
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65133
+ CashAppButton,
65134
+ {
65135
+ onClick: () => setView("cashapp"),
65136
+ title: "Pay with Cash App",
65137
+ subtitle: "Deposit via Cash App",
65138
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
65139
+ },
65140
+ "cashapp"
65141
+ ) : null;
65142
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65143
+ DepositTrackerButton,
65144
+ {
65145
+ onClick: () => {
65146
+ setAllExecutions(depositExecutions);
65147
+ setView("tracker");
65148
+ },
65149
+ title: depositTrackerTitle,
65150
+ subtitle: depositTrackerSubTitle,
65151
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
65152
+ },
65153
+ "tracker"
65154
+ ) : null;
65155
+ const cryptoMenuButtons = [
65156
+ transferCryptoMenuButton,
65157
+ connectWalletMenuButton,
65158
+ payWithExchangeMenuButton,
65159
+ connectExchangeMenuButton
65160
+ ].filter(Boolean);
65161
+ const cashMenuButtons = [
65162
+ depositWithCardMenuButton,
65163
+ cashAppMenuButton
65164
+ ].filter(Boolean);
65165
+ const depositTabs = [
65166
+ { id: "crypto", label: "Use Crypto", icon: Bitcoin, buttons: cryptoMenuButtons },
65167
+ { id: "cash", label: "Use Cash", icon: DollarSign, buttons: cashMenuButtons }
65168
+ ].filter((tab) => tab.buttons.length > 0);
65169
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
65170
+ const renderMainMenuBody = () => {
65171
+ if (depositPrerequisiteBody) {
65172
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
65173
+ }
65174
+ if (displayMode === "tabs" && activeDepositTab) {
65175
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { children: [
65176
+ depositTabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65177
+ "div",
65178
+ {
65179
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
65180
+ style: {
65181
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
65182
+ // the control reads as a soft surface rather than a solid bar.
65183
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
65184
+ backdropFilter: "blur(12px)",
65185
+ WebkitBackdropFilter: "blur(12px)"
65186
+ },
65187
+ role: "tablist",
65188
+ children: depositTabs.map((tab) => {
65189
+ const active = activeDepositTab.id === tab.id;
65190
+ const TabIcon = tab.icon;
65191
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
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 uf-flex uf-items-center uf-justify-center uf-gap-1.5",
65199
+ style: {
65200
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
65201
+ backdropFilter: active ? "blur(8px)" : void 0,
65202
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
65203
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
65204
+ color: active ? colors2.foreground : colors2.foregroundMuted,
65205
+ fontFamily: fonts.medium
65206
+ },
65207
+ children: [
65208
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65209
+ "span",
65210
+ {
65211
+ className: "uf-inline-flex uf-items-center uf-justify-center uf-rounded-full uf-w-5 uf-h-5 uf-flex-shrink-0",
65212
+ style: {
65213
+ backgroundColor: active ? colors2.foreground : colors2.foregroundMuted
65214
+ },
65215
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(TabIcon, { size: 12, style: { color: active ? colors2.background : colors2.background }, strokeWidth: 2.5 })
65216
+ }
65217
+ ),
65218
+ tab.label
65219
+ ]
65220
+ },
65221
+ tab.id
65222
+ );
65223
+ })
65224
+ }
65225
+ ),
65226
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
65227
+ depositTrackerMenuButton && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
65228
+ ] });
65229
+ }
65230
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-space-y-3", children: [
65231
+ transferCryptoMenuButton,
65232
+ connectWalletMenuButton,
65233
+ depositWithCardMenuButton,
65234
+ payWithExchangeMenuButton,
65235
+ connectExchangeMenuButton,
65236
+ cashAppMenuButton,
65237
+ depositTrackerMenuButton
65238
+ ] });
65239
+ };
64865
65240
  return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64866
65241
  Dialog2,
64867
65242
  {
@@ -64888,7 +65263,7 @@ function DepositModal({
64888
65263
  onClose: handleClose,
64889
65264
  showBalance: showBalanceHeader,
64890
65265
  balanceAddress: recipientAddress,
64891
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65266
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
64892
65267
  balanceChainId: destinationChainId,
64893
65268
  balanceTokenAddress: destinationTokenAddress,
64894
65269
  projectName: projectConfig?.project_name,
@@ -64896,94 +65271,7 @@ function DepositModal({
64896
65271
  }
64897
65272
  ),
64898
65273
  /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64899
- /* @__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: [
64900
- showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64901
- TransferCryptoButton,
64902
- {
64903
- onClick: () => setView("transfer"),
64904
- title: transferCryptoTitle,
64905
- subtitle: t7.transferCrypto.subtitle,
64906
- featuredTokens: projectConfig?.transfer_crypto.networks
64907
- }
64908
- ),
64909
- showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64910
- BrowserWalletButton,
64911
- {
64912
- onClick: handleBrowserWalletClick,
64913
- onConnectClick: handleWalletConnectClick,
64914
- onDisconnect: handleWalletDisconnect,
64915
- chainType: browserWalletChainType,
64916
- publishableKey,
64917
- featuredWallets: projectConfig?.connect_wallet?.wallets
64918
- }
64919
- ),
64920
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64921
- DepositWithCardButton,
64922
- {
64923
- onClick: () => setView("card"),
64924
- title: depositWithCardTitle,
64925
- subtitle: t7.depositWithCard.subtitle,
64926
- paymentNetworks: projectConfig?.payment_networks.networks
64927
- }
64928
- ),
64929
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64930
- PayWithExchangeButton,
64931
- {
64932
- onClick: () => setView("exchange"),
64933
- title: payWithExchangeTitle,
64934
- subtitle: t7.payWithExchange.subtitle,
64935
- exchanges,
64936
- loading: exchangesLoading
64937
- }
64938
- ),
64939
- showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64940
- ConnectExchangeButton,
64941
- {
64942
- onClick: () => {
64943
- setCoinbaseSkipToHoldings(true);
64944
- setView("coinbase_connect");
64945
- },
64946
- onDisconnect: handleExchangeDisconnect,
64947
- title: i18n2.connectExchange.title,
64948
- subtitle: i18n2.connectExchange.subtitle,
64949
- exchanges: integrationExchanges,
64950
- connectedExchange
64951
- }
64952
- ),
64953
- showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64954
- ConnectExchangeButton,
64955
- {
64956
- onClick: () => {
64957
- setCoinbaseSkipToHoldings(false);
64958
- setView("coinbase_connect");
64959
- },
64960
- title: i18n2.connectExchange.title,
64961
- subtitle: i18n2.connectExchange.subtitle,
64962
- exchanges: integrationExchanges
64963
- }
64964
- ),
64965
- showCashApp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64966
- CashAppButton,
64967
- {
64968
- onClick: () => setView("cashapp"),
64969
- title: "Pay with Cash App",
64970
- subtitle: "Deposit via Cash App",
64971
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
64972
- }
64973
- ),
64974
- showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64975
- DepositTrackerButton,
64976
- {
64977
- onClick: () => {
64978
- setAllExecutions(depositExecutions);
64979
- setView("tracker");
64980
- },
64981
- title: depositTrackerTitle,
64982
- subtitle: depositTrackerSubTitle,
64983
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
64984
- }
64985
- )
64986
- ] }) }),
65274
+ renderMainMenuBody(),
64987
65275
  depositPoweredByFooter
64988
65276
  ] })
64989
65277
  ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
@@ -64996,7 +65284,7 @@ function DepositModal({
64996
65284
  onClose: handleClose,
64997
65285
  showBalance: showBalanceHeader,
64998
65286
  balanceAddress: recipientAddress,
64999
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65287
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65000
65288
  balanceChainId: destinationChainId,
65001
65289
  balanceTokenAddress: destinationTokenAddress,
65002
65290
  projectName: projectConfig?.project_name,
@@ -65084,7 +65372,7 @@ function DepositModal({
65084
65372
  badge: cardView === "quotes" ? { count: quotesCount } : void 0,
65085
65373
  showBalance: showBalanceHeader,
65086
65374
  balanceAddress: recipientAddress,
65087
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65375
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65088
65376
  balanceChainId: destinationChainId,
65089
65377
  balanceTokenAddress: destinationTokenAddress,
65090
65378
  projectName: projectConfig?.project_name,
@@ -66380,9 +66668,6 @@ function useVerifyRecipientAddress(params) {
66380
66668
  refetchOnWindowFocus: false
66381
66669
  });
66382
66670
  }
66383
- function isHypercoreChain(chainId) {
66384
- return chainId === HYPERCORE_CHAIN_ID;
66385
- }
66386
66671
  function useGetDepositAddress(params) {
66387
66672
  const {
66388
66673
  userId,
@@ -67309,8 +67594,6 @@ function WithdrawConfirmingView({
67309
67594
  className: "uf-text-sm uf-text-center",
67310
67595
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
67311
67596
  children: [
67312
- txInfo.amount,
67313
- " ",
67314
67597
  txInfo.sourceTokenSymbol,
67315
67598
  " to",
67316
67599
  " ",
@@ -67951,6 +68234,7 @@ function UnifoldProvider2({
67951
68234
  hideDepositTracker: config?.hideDepositTracker,
67952
68235
  showBalanceHeader: config?.showBalanceHeader,
67953
68236
  transferInputVariant: config?.transferInputVariant,
68237
+ displayMode: config?.displayMode,
67954
68238
  enableTransferCrypto: config?.enableTransferCrypto,
67955
68239
  enableConnectWallet: config?.enableConnectWallet,
67956
68240
  enablePayWithExchange: config?.enablePayWithExchange,
@@ -68129,6 +68413,7 @@ lucide-react/dist/esm/createLucideIcon.js:
68129
68413
  lucide-react/dist/esm/icons/arrow-left-right.js:
68130
68414
  lucide-react/dist/esm/icons/arrow-left.js:
68131
68415
  lucide-react/dist/esm/icons/arrow-up-down.js:
68416
+ lucide-react/dist/esm/icons/bitcoin.js:
68132
68417
  lucide-react/dist/esm/icons/check.js:
68133
68418
  lucide-react/dist/esm/icons/chevron-down.js:
68134
68419
  lucide-react/dist/esm/icons/chevron-right.js: