@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.js CHANGED
@@ -38524,6 +38524,15 @@ var ArrowUpDown = createLucideIcon("ArrowUpDown", [
38524
38524
  ["path", { d: "m3 8 4-4 4 4", key: "11wl7u" }],
38525
38525
  ["path", { d: "M7 4v16", key: "1glfcx" }]
38526
38526
  ]);
38527
+ var Bitcoin = createLucideIcon("Bitcoin", [
38528
+ [
38529
+ "path",
38530
+ {
38531
+ 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",
38532
+ key: "yr8idg"
38533
+ }
38534
+ ]
38535
+ ]);
38527
38536
  var Check = createLucideIcon("Check", [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]]);
38528
38537
  var ChevronDown = createLucideIcon("ChevronDown", [
38529
38538
  ["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]
@@ -43986,6 +43995,29 @@ async function getDepositQuote(request, publishableKey) {
43986
43995
  const json = await response.json();
43987
43996
  return json.data;
43988
43997
  }
43998
+ async function buildHypercoreTransaction(request, publishableKey) {
43999
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
44000
+ validatePublishableKey(pk);
44001
+ const response = await fetch(
44002
+ `${API_BASE_URL}/v1/public/transactions/hypercore/build`,
44003
+ {
44004
+ method: "POST",
44005
+ headers: {
44006
+ accept: "application/json",
44007
+ "x-publishable-key": pk,
44008
+ "Content-Type": "application/json"
44009
+ },
44010
+ body: JSON.stringify(request)
44011
+ }
44012
+ );
44013
+ if (!response.ok) {
44014
+ const error = await response.json().catch(() => ({ message: response.statusText }));
44015
+ throw new Error(
44016
+ `Failed to build HyperCore transaction: ${error.message || response.statusText}`
44017
+ );
44018
+ }
44019
+ return response.json();
44020
+ }
43989
44021
  async function getCashAppLimits(currency = "usd", publishableKey) {
43990
44022
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43991
44023
  validatePublishableKey(pk);
@@ -44051,6 +44083,29 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
44051
44083
  }
44052
44084
  return response.json();
44053
44085
  }
44086
+ async function sendHypercoreTransaction(request, publishableKey) {
44087
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
44088
+ validatePublishableKey(pk);
44089
+ const response = await fetch(
44090
+ `${API_BASE_URL}/v1/public/transactions/hypercore/send`,
44091
+ {
44092
+ method: "POST",
44093
+ headers: {
44094
+ accept: "application/json",
44095
+ "x-publishable-key": pk,
44096
+ "Content-Type": "application/json"
44097
+ },
44098
+ body: JSON.stringify(request)
44099
+ }
44100
+ );
44101
+ if (!response.ok) {
44102
+ const error = await response.json().catch(() => ({ message: response.statusText }));
44103
+ throw new Error(
44104
+ `Failed to send HyperCore transaction: ${error.message || response.statusText}`
44105
+ );
44106
+ }
44107
+ return response.json();
44108
+ }
44054
44109
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
44055
44110
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
44056
44111
  return DepositEventType2;
@@ -50227,6 +50282,22 @@ function clearStoredWalletState() {
50227
50282
  } catch {
50228
50283
  }
50229
50284
  }
50285
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
50286
+ function getLastOpenedWallet() {
50287
+ if (typeof window === "undefined") return void 0;
50288
+ try {
50289
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
50290
+ } catch {
50291
+ return void 0;
50292
+ }
50293
+ }
50294
+ function setLastOpenedWallet(walletId) {
50295
+ if (typeof window === "undefined") return;
50296
+ try {
50297
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
50298
+ } catch {
50299
+ }
50300
+ }
50230
50301
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
50231
50302
  function isMobileViewport() {
50232
50303
  if (typeof window === "undefined") return false;
@@ -51032,7 +51103,7 @@ function DepositHeader({
51032
51103
  setShowBalanceSkeleton(false);
51033
51104
  return;
51034
51105
  }
51035
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
51106
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
51036
51107
  if (!supportedChainTypes.includes(
51037
51108
  balanceChainType
51038
51109
  )) {
@@ -61050,7 +61121,7 @@ function useHypercoreActivation(params) {
61050
61121
  publishableKey,
61051
61122
  enabled = true
61052
61123
  } = params;
61053
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
61124
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
61054
61125
  const recipient = recipientAddress?.trim() ?? "";
61055
61126
  const source = sourceAddress?.trim() ?? "";
61056
61127
  const hasAddresses = !!recipient && !!source;
@@ -62196,6 +62267,46 @@ function TransferCryptoDoubleInput({
62196
62267
  }
62197
62268
  ) });
62198
62269
  }
62270
+ function isHypercoreChain(chainId) {
62271
+ return chainId === HYPERCORE_CHAIN_ID;
62272
+ }
62273
+ async function sendHypercoreEvmTransfer(params) {
62274
+ const {
62275
+ provider,
62276
+ fromAddress,
62277
+ recipientAddress,
62278
+ sourceTokenAddress,
62279
+ amount,
62280
+ publishableKey
62281
+ } = params;
62282
+ const currentChainHex = await provider.request({
62283
+ method: "eth_chainId",
62284
+ params: []
62285
+ });
62286
+ const activeChainId = String(parseInt(currentChainHex, 16));
62287
+ const buildResult = await buildHypercoreTransaction(
62288
+ {
62289
+ signature_chain_id: activeChainId,
62290
+ recipient_address: recipientAddress,
62291
+ token_address: sourceTokenAddress,
62292
+ amount
62293
+ },
62294
+ publishableKey
62295
+ );
62296
+ const signature = await provider.request({
62297
+ method: "eth_signTypedData_v4",
62298
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
62299
+ });
62300
+ await sendHypercoreTransaction(
62301
+ {
62302
+ action_payload: buildResult.action_payload,
62303
+ signature,
62304
+ nonce: buildResult.nonce
62305
+ },
62306
+ publishableKey
62307
+ );
62308
+ return { signature };
62309
+ }
62199
62310
  function useDepositQuote(params) {
62200
62311
  const {
62201
62312
  publishableKey,
@@ -62603,7 +62714,8 @@ function EnterAmountView({
62603
62714
  onClose,
62604
62715
  quickSelectMode,
62605
62716
  checkoutAmountUsd,
62606
- checkoutReceivedUsd
62717
+ checkoutReceivedUsd,
62718
+ footer
62607
62719
  }) {
62608
62720
  const { colors: colors2, fonts, components } = useTheme();
62609
62721
  const isCheckout = !!checkoutAmountUsd;
@@ -62859,6 +62971,7 @@ function EnterAmountView({
62859
62971
  )
62860
62972
  ] })
62861
62973
  ] }),
62974
+ footer && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
62862
62975
  /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
62863
62976
  "button",
62864
62977
  {
@@ -63308,7 +63421,7 @@ var WALLET_ICONS3 = {
63308
63421
  };
63309
63422
  var FALLBACK_WALLET_DEFINITIONS = [
63310
63423
  { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
63311
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
63424
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
63312
63425
  { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
63313
63426
  { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
63314
63427
  { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
@@ -63368,7 +63481,7 @@ function getLegacyEvmProviders() {
63368
63481
  okxEthereum: win.okxwallet
63369
63482
  };
63370
63483
  }
63371
- function detectAvailableWallets(definitions, filterChainType) {
63484
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
63372
63485
  const solProviders = getSolanaProviders();
63373
63486
  const legacyEvm = getLegacyEvmProviders();
63374
63487
  const eip6963List = getEip6963Providers();
@@ -63394,7 +63507,7 @@ function detectAvailableWallets(definitions, filterChainType) {
63394
63507
  return false;
63395
63508
  }
63396
63509
  });
63397
- return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63510
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63398
63511
  let isInstalled = false;
63399
63512
  const detectedNetworks = [];
63400
63513
  switch (wallet.id) {
@@ -63417,8 +63530,6 @@ function detectAvailableWallets(definitions, filterChainType) {
63417
63530
  isInstalled = true;
63418
63531
  detectedNetworks.push("ethereum");
63419
63532
  }
63420
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
63421
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
63422
63533
  break;
63423
63534
  case "trust":
63424
63535
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -63455,11 +63566,17 @@ function detectAvailableWallets(definitions, filterChainType) {
63455
63566
  }
63456
63567
  return { ...wallet, isInstalled, detectedNetworks };
63457
63568
  }).sort((a, b) => {
63569
+ if (recentWalletId) {
63570
+ const aRecent = a.id === recentWalletId ? 1 : 0;
63571
+ const bRecent = b.id === recentWalletId ? 1 : 0;
63572
+ if (aRecent !== bRecent) return bRecent - aRecent;
63573
+ }
63458
63574
  if (a.isInstalled && !b.isInstalled) return -1;
63459
63575
  if (!a.isInstalled && b.isInstalled) return 1;
63460
63576
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
63461
63577
  return 0;
63462
63578
  });
63579
+ return sorted;
63463
63580
  }
63464
63581
  function WalletConnect({
63465
63582
  walletInfo: initialWalletInfo,
@@ -63534,9 +63651,15 @@ function WalletConnect({
63534
63651
  })) : FALLBACK_WALLET_DEFINITIONS,
63535
63652
  [backendWallets]
63536
63653
  );
63654
+ const [recentWalletId, setRecentWalletIdState] = React302.useState(getLastOpenedWallet);
63655
+ React302.useEffect(() => {
63656
+ if (view === "select_wallet") {
63657
+ setRecentWalletIdState(getLastOpenedWallet());
63658
+ }
63659
+ }, [view]);
63537
63660
  const availableWallets = React302.useMemo(
63538
- () => detectAvailableWallets(walletDefinitions),
63539
- [walletDefinitions, eip6963ProviderCount]
63661
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
63662
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
63540
63663
  );
63541
63664
  const [isMobile, setIsMobile] = React302.useState(false);
63542
63665
  React302.useEffect(() => {
@@ -63596,7 +63719,7 @@ function WalletConnect({
63596
63719
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
63597
63720
  const recipientAddress = activeDepositWallet?.address ?? "";
63598
63721
  const isCheckoutMode = !!checkoutAmountUsd;
63599
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
63722
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
63600
63723
  const transitionTo = React302.useCallback((nextView) => {
63601
63724
  if (nextView === viewRef.current) return;
63602
63725
  setIsTransitioning(true);
@@ -63620,6 +63743,8 @@ function WalletConnect({
63620
63743
  );
63621
63744
  if (res.deeplink) {
63622
63745
  setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
63746
+ setLastOpenedWallet(wallet.id);
63747
+ setRecentWalletIdState(wallet.id);
63623
63748
  setAwaitingMobileDeposit(true);
63624
63749
  transitionTo("mobile_redirect");
63625
63750
  window.location.href = res.deeplink;
@@ -63680,6 +63805,8 @@ function WalletConnect({
63680
63805
  const handleConnectWallet = async (wallet, network) => {
63681
63806
  setConnectingNetwork(network);
63682
63807
  transitionTo("connecting");
63808
+ setLastOpenedWallet(wallet.id);
63809
+ setRecentWalletIdState(wallet.id);
63683
63810
  setWalletError(null);
63684
63811
  setIsWalletConnecting(true);
63685
63812
  try {
@@ -63784,6 +63911,13 @@ function WalletConnect({
63784
63911
  }
63785
63912
  };
63786
63913
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
63914
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
63915
+ recipientAddress,
63916
+ sourceAddress: activeWalletInfo?.address,
63917
+ destinationChainId: selectedToken?.chain_id,
63918
+ publishableKey,
63919
+ enabled: !!activeWalletInfo && !!recipientAddress
63920
+ });
63787
63921
  const effectiveDestinationAmount = React302.useMemo(() => {
63788
63922
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
63789
63923
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -63888,7 +64022,7 @@ function WalletConnect({
63888
64022
  let cancelled = false;
63889
64023
  setIsLoading(true);
63890
64024
  setError(null);
63891
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
64025
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
63892
64026
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
63893
64027
  if (cancelled) return;
63894
64028
  const nonZero = response.balances.filter((b) => b.amount !== "0");
@@ -64054,9 +64188,16 @@ function WalletConnect({
64054
64188
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
64055
64189
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
64056
64190
  };
64057
- const sendEthereumTransaction = async (token, amountStr) => {
64058
- if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
64059
- const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
64191
+ const resolveEvmProvider = () => {
64192
+ const walletIdMap = {
64193
+ "phantom-ethereum": "phantom",
64194
+ coinbase: "coinbase",
64195
+ trust: "trust",
64196
+ okx: "okx",
64197
+ rainbow: "rainbow",
64198
+ rabby: "rabby",
64199
+ metamask: "metamask"
64200
+ };
64060
64201
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
64061
64202
  const eip6963Match = findProviderByWalletId(lookupId);
64062
64203
  let provider = eip6963Match?.provider;
@@ -64065,6 +64206,11 @@ function WalletConnect({
64065
64206
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
64066
64207
  else provider = window.ethereum;
64067
64208
  }
64209
+ return provider;
64210
+ };
64211
+ const sendEthereumTransaction = async (token, amountStr) => {
64212
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
64213
+ const provider = resolveEvmProvider();
64068
64214
  if (!provider) throw new Error("Ethereum wallet not found");
64069
64215
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
64070
64216
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -64129,6 +64275,19 @@ function WalletConnect({
64129
64275
  const resp = await sendSolanaTransaction({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
64130
64276
  return resp.signature;
64131
64277
  };
64278
+ const sendHypercoreDeposit = async (token, amountStr) => {
64279
+ const provider = resolveEvmProvider();
64280
+ if (!provider) throw new Error("Ethereum wallet not found");
64281
+ const { signature } = await sendHypercoreEvmTransfer({
64282
+ provider,
64283
+ fromAddress: walletInfo.address,
64284
+ recipientAddress,
64285
+ sourceTokenAddress: token.token_address,
64286
+ amount: amountStr,
64287
+ publishableKey
64288
+ });
64289
+ return signature;
64290
+ };
64132
64291
  const handleConfirm = async () => {
64133
64292
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
64134
64293
  const token = getTokenFromBalance(selectedBalance);
@@ -64148,7 +64307,33 @@ function WalletConnect({
64148
64307
  setIsConfirming(true);
64149
64308
  setError(null);
64150
64309
  try {
64151
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction2(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
64310
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
64311
+ let txHash;
64312
+ if (token.chain_type === "solana") {
64313
+ txHash = await sendSolanaTransaction2(token, tokenAmount.toString());
64314
+ } else if (isHypercoreToken) {
64315
+ let sendAmount = tokenAmount;
64316
+ try {
64317
+ const activation = await checkHypercoreActivation(
64318
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
64319
+ publishableKey
64320
+ );
64321
+ if (!activation.user_exists) {
64322
+ const fee = activation.activation_fee;
64323
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
64324
+ throw new Error(
64325
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
64326
+ );
64327
+ }
64328
+ sendAmount = tokenAmount - fee;
64329
+ }
64330
+ } catch (e) {
64331
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
64332
+ }
64333
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
64334
+ } else {
64335
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
64336
+ }
64152
64337
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
64153
64338
  setHasSignedTransaction(true);
64154
64339
  handleIveDeposited();
@@ -64187,7 +64372,10 @@ function WalletConnect({
64187
64372
  children: [
64188
64373
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64189
64374
  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" }),
64190
- /* @__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 })
64375
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
64376
+ /* @__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 }),
64377
+ 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" })
64378
+ ] })
64191
64379
  ] }),
64192
64380
  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: [
64193
64381
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
@@ -64366,7 +64554,7 @@ function WalletConnect({
64366
64554
  }
64367
64555
  if (view === "enter_amount" && selectedToken && selectedBalance) {
64368
64556
  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 ?? (() => {
64369
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
64557
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
64370
64558
  }
64371
64559
  if (view === "review" && selectedToken) {
64372
64560
  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 ?? (() => {
@@ -64402,6 +64590,9 @@ function SkeletonButton({
64402
64590
  ] });
64403
64591
  }
64404
64592
  var t7 = i18n2.depositModal;
64593
+ function depositTabForScreen(screen) {
64594
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
64595
+ }
64405
64596
  function DepositModal({
64406
64597
  open,
64407
64598
  onOpenChange,
@@ -64437,6 +64628,7 @@ function DepositModal({
64437
64628
  theme = "dark",
64438
64629
  hideOverlay = false,
64439
64630
  initialScreen = "main",
64631
+ displayMode = "stacked",
64440
64632
  transferCryptoTitle = t7.transferCrypto.title,
64441
64633
  depositWithCardTitle = t7.depositWithCard.title,
64442
64634
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -64471,6 +64663,9 @@ function DepositModal({
64471
64663
  effectiveInitialScreen
64472
64664
  );
64473
64665
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = (0, import_react3.useState)(false);
64666
+ const [depositTab, setDepositTab] = (0, import_react3.useState)(
64667
+ () => depositTabForScreen(effectiveInitialScreen)
64668
+ );
64474
64669
  const resetViewTimeoutRef = (0, import_react3.useRef)(null);
64475
64670
  const [cardView, setCardView] = (0, import_react3.useState)(
64476
64671
  "amount"
@@ -64768,6 +64963,7 @@ function DepositModal({
64768
64963
  resetViewTimeoutRef.current = null;
64769
64964
  }
64770
64965
  setView(effectiveInitialScreen);
64966
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
64771
64967
  setCardView("amount");
64772
64968
  setExchangeView("providers");
64773
64969
  setBrowserWalletInfo(null);
@@ -64796,6 +64992,7 @@ function DepositModal({
64796
64992
  } else if (view === "cashapp" && cashAppView !== "amount") {
64797
64993
  setCashAppView("amount");
64798
64994
  } else {
64995
+ setDepositTab(depositTabForScreen(view));
64799
64996
  setView("main");
64800
64997
  setCardView("amount");
64801
64998
  setExchangeView("providers");
@@ -64875,6 +65072,184 @@ function DepositModal({
64875
65072
  className: "uf-flex uf-justify-center uf-shrink-0"
64876
65073
  }
64877
65074
  ) });
65075
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65076
+ TransferCryptoButton,
65077
+ {
65078
+ onClick: () => setView("transfer"),
65079
+ title: transferCryptoTitle,
65080
+ subtitle: t7.transferCrypto.subtitle,
65081
+ featuredTokens: projectConfig?.transfer_crypto.networks
65082
+ },
65083
+ "transfer"
65084
+ ) : null;
65085
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65086
+ BrowserWalletButton,
65087
+ {
65088
+ onClick: handleBrowserWalletClick,
65089
+ onConnectClick: handleWalletConnectClick,
65090
+ onDisconnect: handleWalletDisconnect,
65091
+ chainType: browserWalletChainType,
65092
+ publishableKey,
65093
+ featuredWallets: projectConfig?.connect_wallet?.wallets
65094
+ },
65095
+ "wallet"
65096
+ ) : null;
65097
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65098
+ DepositWithCardButton,
65099
+ {
65100
+ onClick: () => setView("card"),
65101
+ title: depositWithCardTitle,
65102
+ subtitle: t7.depositWithCard.subtitle,
65103
+ paymentNetworks: projectConfig?.payment_networks.networks
65104
+ },
65105
+ "card"
65106
+ ) : null;
65107
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65108
+ PayWithExchangeButton,
65109
+ {
65110
+ onClick: () => setView("exchange"),
65111
+ title: payWithExchangeTitle,
65112
+ subtitle: t7.payWithExchange.subtitle,
65113
+ exchanges,
65114
+ loading: exchangesLoading
65115
+ },
65116
+ "exchange"
65117
+ ) : null;
65118
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65119
+ ConnectExchangeButton,
65120
+ {
65121
+ onClick: () => {
65122
+ setCoinbaseSkipToHoldings(true);
65123
+ setView("coinbase_connect");
65124
+ },
65125
+ onDisconnect: handleExchangeDisconnect,
65126
+ title: i18n2.connectExchange.title,
65127
+ subtitle: i18n2.connectExchange.subtitle,
65128
+ exchanges: integrationExchanges,
65129
+ connectedExchange
65130
+ },
65131
+ "connect-exchange"
65132
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65133
+ ConnectExchangeButton,
65134
+ {
65135
+ onClick: () => {
65136
+ setCoinbaseSkipToHoldings(false);
65137
+ setView("coinbase_connect");
65138
+ },
65139
+ title: i18n2.connectExchange.title,
65140
+ subtitle: i18n2.connectExchange.subtitle,
65141
+ exchanges: integrationExchanges
65142
+ },
65143
+ "connect-exchange"
65144
+ ) : null;
65145
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65146
+ CashAppButton,
65147
+ {
65148
+ onClick: () => setView("cashapp"),
65149
+ title: "Pay with Cash App",
65150
+ subtitle: "Deposit via Cash App",
65151
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
65152
+ },
65153
+ "cashapp"
65154
+ ) : null;
65155
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65156
+ DepositTrackerButton,
65157
+ {
65158
+ onClick: () => {
65159
+ setAllExecutions(depositExecutions);
65160
+ setView("tracker");
65161
+ },
65162
+ title: depositTrackerTitle,
65163
+ subtitle: depositTrackerSubTitle,
65164
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
65165
+ },
65166
+ "tracker"
65167
+ ) : null;
65168
+ const cryptoMenuButtons = [
65169
+ transferCryptoMenuButton,
65170
+ connectWalletMenuButton,
65171
+ payWithExchangeMenuButton,
65172
+ connectExchangeMenuButton
65173
+ ].filter(Boolean);
65174
+ const cashMenuButtons = [
65175
+ depositWithCardMenuButton,
65176
+ cashAppMenuButton
65177
+ ].filter(Boolean);
65178
+ const depositTabs = [
65179
+ { id: "crypto", label: "Use Crypto", icon: Bitcoin, buttons: cryptoMenuButtons },
65180
+ { id: "cash", label: "Use Cash", icon: DollarSign, buttons: cashMenuButtons }
65181
+ ].filter((tab) => tab.buttons.length > 0);
65182
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
65183
+ const renderMainMenuBody = () => {
65184
+ if (depositPrerequisiteBody) {
65185
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
65186
+ }
65187
+ if (displayMode === "tabs" && activeDepositTab) {
65188
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { children: [
65189
+ depositTabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65190
+ "div",
65191
+ {
65192
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
65193
+ style: {
65194
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
65195
+ // the control reads as a soft surface rather than a solid bar.
65196
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
65197
+ backdropFilter: "blur(12px)",
65198
+ WebkitBackdropFilter: "blur(12px)"
65199
+ },
65200
+ role: "tablist",
65201
+ children: depositTabs.map((tab) => {
65202
+ const active = activeDepositTab.id === tab.id;
65203
+ const TabIcon = tab.icon;
65204
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
65205
+ "button",
65206
+ {
65207
+ type: "button",
65208
+ role: "tab",
65209
+ "aria-selected": active,
65210
+ onClick: () => setDepositTab(tab.id),
65211
+ 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",
65212
+ style: {
65213
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
65214
+ backdropFilter: active ? "blur(8px)" : void 0,
65215
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
65216
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
65217
+ color: active ? colors2.foreground : colors2.foregroundMuted,
65218
+ fontFamily: fonts.medium
65219
+ },
65220
+ children: [
65221
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65222
+ "span",
65223
+ {
65224
+ className: "uf-inline-flex uf-items-center uf-justify-center uf-rounded-full uf-w-5 uf-h-5 uf-flex-shrink-0",
65225
+ style: {
65226
+ backgroundColor: active ? colors2.foreground : colors2.foregroundMuted
65227
+ },
65228
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(TabIcon, { size: 12, style: { color: active ? colors2.background : colors2.background }, strokeWidth: 2.5 })
65229
+ }
65230
+ ),
65231
+ tab.label
65232
+ ]
65233
+ },
65234
+ tab.id
65235
+ );
65236
+ })
65237
+ }
65238
+ ),
65239
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
65240
+ depositTrackerMenuButton && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
65241
+ ] });
65242
+ }
65243
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-space-y-3", children: [
65244
+ transferCryptoMenuButton,
65245
+ connectWalletMenuButton,
65246
+ depositWithCardMenuButton,
65247
+ payWithExchangeMenuButton,
65248
+ connectExchangeMenuButton,
65249
+ cashAppMenuButton,
65250
+ depositTrackerMenuButton
65251
+ ] });
65252
+ };
64878
65253
  return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64879
65254
  Dialog2,
64880
65255
  {
@@ -64901,7 +65276,7 @@ function DepositModal({
64901
65276
  onClose: handleClose,
64902
65277
  showBalance: showBalanceHeader,
64903
65278
  balanceAddress: recipientAddress,
64904
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65279
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
64905
65280
  balanceChainId: destinationChainId,
64906
65281
  balanceTokenAddress: destinationTokenAddress,
64907
65282
  projectName: projectConfig?.project_name,
@@ -64909,94 +65284,7 @@ function DepositModal({
64909
65284
  }
64910
65285
  ),
64911
65286
  /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64912
- /* @__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: [
64913
- showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64914
- TransferCryptoButton,
64915
- {
64916
- onClick: () => setView("transfer"),
64917
- title: transferCryptoTitle,
64918
- subtitle: t7.transferCrypto.subtitle,
64919
- featuredTokens: projectConfig?.transfer_crypto.networks
64920
- }
64921
- ),
64922
- showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64923
- BrowserWalletButton,
64924
- {
64925
- onClick: handleBrowserWalletClick,
64926
- onConnectClick: handleWalletConnectClick,
64927
- onDisconnect: handleWalletDisconnect,
64928
- chainType: browserWalletChainType,
64929
- publishableKey,
64930
- featuredWallets: projectConfig?.connect_wallet?.wallets
64931
- }
64932
- ),
64933
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64934
- DepositWithCardButton,
64935
- {
64936
- onClick: () => setView("card"),
64937
- title: depositWithCardTitle,
64938
- subtitle: t7.depositWithCard.subtitle,
64939
- paymentNetworks: projectConfig?.payment_networks.networks
64940
- }
64941
- ),
64942
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64943
- PayWithExchangeButton,
64944
- {
64945
- onClick: () => setView("exchange"),
64946
- title: payWithExchangeTitle,
64947
- subtitle: t7.payWithExchange.subtitle,
64948
- exchanges,
64949
- loading: exchangesLoading
64950
- }
64951
- ),
64952
- showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64953
- ConnectExchangeButton,
64954
- {
64955
- onClick: () => {
64956
- setCoinbaseSkipToHoldings(true);
64957
- setView("coinbase_connect");
64958
- },
64959
- onDisconnect: handleExchangeDisconnect,
64960
- title: i18n2.connectExchange.title,
64961
- subtitle: i18n2.connectExchange.subtitle,
64962
- exchanges: integrationExchanges,
64963
- connectedExchange
64964
- }
64965
- ),
64966
- showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64967
- ConnectExchangeButton,
64968
- {
64969
- onClick: () => {
64970
- setCoinbaseSkipToHoldings(false);
64971
- setView("coinbase_connect");
64972
- },
64973
- title: i18n2.connectExchange.title,
64974
- subtitle: i18n2.connectExchange.subtitle,
64975
- exchanges: integrationExchanges
64976
- }
64977
- ),
64978
- showCashApp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64979
- CashAppButton,
64980
- {
64981
- onClick: () => setView("cashapp"),
64982
- title: "Pay with Cash App",
64983
- subtitle: "Deposit via Cash App",
64984
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
64985
- }
64986
- ),
64987
- showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64988
- DepositTrackerButton,
64989
- {
64990
- onClick: () => {
64991
- setAllExecutions(depositExecutions);
64992
- setView("tracker");
64993
- },
64994
- title: depositTrackerTitle,
64995
- subtitle: depositTrackerSubTitle,
64996
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
64997
- }
64998
- )
64999
- ] }) }),
65287
+ renderMainMenuBody(),
65000
65288
  depositPoweredByFooter
65001
65289
  ] })
65002
65290
  ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
@@ -65009,7 +65297,7 @@ function DepositModal({
65009
65297
  onClose: handleClose,
65010
65298
  showBalance: showBalanceHeader,
65011
65299
  balanceAddress: recipientAddress,
65012
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65300
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65013
65301
  balanceChainId: destinationChainId,
65014
65302
  balanceTokenAddress: destinationTokenAddress,
65015
65303
  projectName: projectConfig?.project_name,
@@ -65097,7 +65385,7 @@ function DepositModal({
65097
65385
  badge: cardView === "quotes" ? { count: quotesCount } : void 0,
65098
65386
  showBalance: showBalanceHeader,
65099
65387
  balanceAddress: recipientAddress,
65100
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65388
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
65101
65389
  balanceChainId: destinationChainId,
65102
65390
  balanceTokenAddress: destinationTokenAddress,
65103
65391
  projectName: projectConfig?.project_name,
@@ -66393,9 +66681,6 @@ function useVerifyRecipientAddress(params) {
66393
66681
  refetchOnWindowFocus: false
66394
66682
  });
66395
66683
  }
66396
- function isHypercoreChain(chainId) {
66397
- return chainId === HYPERCORE_CHAIN_ID;
66398
- }
66399
66684
  function useGetDepositAddress(params) {
66400
66685
  const {
66401
66686
  userId,
@@ -67322,8 +67607,6 @@ function WithdrawConfirmingView({
67322
67607
  className: "uf-text-sm uf-text-center",
67323
67608
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
67324
67609
  children: [
67325
- txInfo.amount,
67326
- " ",
67327
67610
  txInfo.sourceTokenSymbol,
67328
67611
  " to",
67329
67612
  " ",
@@ -67964,6 +68247,7 @@ function UnifoldProvider2({
67964
68247
  hideDepositTracker: config?.hideDepositTracker,
67965
68248
  showBalanceHeader: config?.showBalanceHeader,
67966
68249
  transferInputVariant: config?.transferInputVariant,
68250
+ displayMode: config?.displayMode,
67967
68251
  enableTransferCrypto: config?.enableTransferCrypto,
67968
68252
  enableConnectWallet: config?.enableConnectWallet,
67969
68253
  enablePayWithExchange: config?.enablePayWithExchange,
@@ -68143,6 +68427,7 @@ lucide-react/dist/esm/createLucideIcon.js:
68143
68427
  lucide-react/dist/esm/icons/arrow-left-right.js:
68144
68428
  lucide-react/dist/esm/icons/arrow-left.js:
68145
68429
  lucide-react/dist/esm/icons/arrow-up-down.js:
68430
+ lucide-react/dist/esm/icons/bitcoin.js:
68146
68431
  lucide-react/dist/esm/icons/check.js:
68147
68432
  lucide-react/dist/esm/icons/chevron-down.js:
68148
68433
  lucide-react/dist/esm/icons/chevron-right.js: