@unifold/ui-react 0.1.64 → 0.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -205,6 +205,22 @@ function clearStoredWalletState() {
205
205
  } catch {
206
206
  }
207
207
  }
208
+ var LAST_OPENED_WALLET_KEY = "unifold_last_opened_wallet";
209
+ function getLastOpenedWallet() {
210
+ if (typeof window === "undefined") return void 0;
211
+ try {
212
+ return localStorage.getItem(LAST_OPENED_WALLET_KEY) ?? void 0;
213
+ } catch {
214
+ return void 0;
215
+ }
216
+ }
217
+ function setLastOpenedWallet(walletId) {
218
+ if (typeof window === "undefined") return;
219
+ try {
220
+ localStorage.setItem(LAST_OPENED_WALLET_KEY, walletId);
221
+ } catch {
222
+ }
223
+ }
208
224
  var MOBILE_VIEWPORT_MEDIA_QUERY = "(max-width: 768px)";
209
225
  function isMobileViewport() {
210
226
  if (typeof window === "undefined") return false;
@@ -1052,7 +1068,7 @@ function DepositHeader({
1052
1068
  setShowBalanceSkeleton(false);
1053
1069
  return;
1054
1070
  }
1055
- const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
1071
+ const supportedChainTypes = ["ethereum", "solana", "bitcoin", "n1"];
1056
1072
  if (!supportedChainTypes.includes(
1057
1073
  balanceChainType
1058
1074
  )) {
@@ -10110,7 +10126,7 @@ function useDefaultOnrampToken({
10110
10126
  }
10111
10127
 
10112
10128
  // src/components/deposits/DepositModal.tsx
10113
- var import_core30 = require("@unifold/core");
10129
+ var import_core31 = require("@unifold/core");
10114
10130
 
10115
10131
  // src/hooks/use-allowed-country.ts
10116
10132
  var import_react_query9 = require("@tanstack/react-query");
@@ -11381,7 +11397,7 @@ function useHypercoreActivation(params) {
11381
11397
  publishableKey,
11382
11398
  enabled = true
11383
11399
  } = params;
11384
- const isHypercore2 = destinationChainId === HYPERCORE_CHAIN_ID;
11400
+ const isHypercore2 = String(destinationChainId) === HYPERCORE_CHAIN_ID;
11385
11401
  const recipient = recipientAddress?.trim() ?? "";
11386
11402
  const source = sourceAddress?.trim() ?? "";
11387
11403
  const hasAddresses = !!recipient && !!source;
@@ -12553,11 +12569,54 @@ function TransferCryptoDoubleInput({
12553
12569
  // src/components/deposits/WalletConnect.tsx
12554
12570
  var React30 = __toESM(require("react"));
12555
12571
  var import_lucide_react28 = require("lucide-react");
12556
- var import_core29 = require("@unifold/core");
12572
+ var import_core30 = require("@unifold/core");
12573
+
12574
+ // src/lib/send-hypercore.ts
12575
+ var import_core27 = require("@unifold/core");
12576
+ function isHypercoreChain(chainId) {
12577
+ return chainId === HYPERCORE_CHAIN_ID;
12578
+ }
12579
+ async function sendHypercoreEvmTransfer(params) {
12580
+ const {
12581
+ provider,
12582
+ fromAddress,
12583
+ recipientAddress,
12584
+ sourceTokenAddress,
12585
+ amount,
12586
+ publishableKey
12587
+ } = params;
12588
+ const currentChainHex = await provider.request({
12589
+ method: "eth_chainId",
12590
+ params: []
12591
+ });
12592
+ const activeChainId = String(parseInt(currentChainHex, 16));
12593
+ const buildResult = await (0, import_core27.buildHypercoreTransaction)(
12594
+ {
12595
+ signature_chain_id: activeChainId,
12596
+ recipient_address: recipientAddress,
12597
+ token_address: sourceTokenAddress,
12598
+ amount
12599
+ },
12600
+ publishableKey
12601
+ );
12602
+ const signature = await provider.request({
12603
+ method: "eth_signTypedData_v4",
12604
+ params: [fromAddress, JSON.stringify(buildResult.typed_data)]
12605
+ });
12606
+ await (0, import_core27.sendHypercoreTransaction)(
12607
+ {
12608
+ action_payload: buildResult.action_payload,
12609
+ signature,
12610
+ nonce: buildResult.nonce
12611
+ },
12612
+ publishableKey
12613
+ );
12614
+ return { signature };
12615
+ }
12557
12616
 
12558
12617
  // src/hooks/use-deposit-quote.ts
12559
12618
  var import_react_query12 = require("@tanstack/react-query");
12560
- var import_core27 = require("@unifold/core");
12619
+ var import_core28 = require("@unifold/core");
12561
12620
  function useDepositQuote(params) {
12562
12621
  const {
12563
12622
  publishableKey,
@@ -12598,7 +12657,7 @@ function useDepositQuote(params) {
12598
12657
  stablecoinParity,
12599
12658
  publishableKey
12600
12659
  ],
12601
- queryFn: () => (0, import_core27.getDepositQuote)(request, publishableKey),
12660
+ queryFn: () => (0, import_core28.getDepositQuote)(request, publishableKey),
12602
12661
  enabled: enabled && !!publishableKey && !!sourceChainType && !!sourceChainId && !!sourceTokenAddress && !!destinationAmount && destinationAmount !== "0" && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress,
12603
12662
  staleTime: 3e4,
12604
12663
  gcTime: 5 * 6e4,
@@ -12612,14 +12671,14 @@ function useDepositQuote(params) {
12612
12671
 
12613
12672
  // src/hooks/use-external-wallets.ts
12614
12673
  var import_react_query13 = require("@tanstack/react-query");
12615
- var import_core28 = require("@unifold/core");
12674
+ var import_core29 = require("@unifold/core");
12616
12675
  function useExternalWallets({
12617
12676
  publishableKey,
12618
12677
  enabled = true
12619
12678
  }) {
12620
12679
  const { data: wallets = [], isLoading } = (0, import_react_query13.useQuery)({
12621
12680
  queryKey: ["unifold", "external-wallets", publishableKey],
12622
- queryFn: () => (0, import_core28.getExternalWallets)(publishableKey).then((res) => res.data),
12681
+ queryFn: () => (0, import_core29.getExternalWallets)(publishableKey).then((res) => res.data),
12623
12682
  enabled: enabled && !!publishableKey,
12624
12683
  staleTime: 1e3 * 60 * 30,
12625
12684
  refetchOnMount: false,
@@ -12985,7 +13044,8 @@ function EnterAmountView({
12985
13044
  onClose,
12986
13045
  quickSelectMode,
12987
13046
  checkoutAmountUsd,
12988
- checkoutReceivedUsd
13047
+ checkoutReceivedUsd,
13048
+ footer
12989
13049
  }) {
12990
13050
  const { colors: colors2, fonts, components } = useTheme();
12991
13051
  const isCheckout = !!checkoutAmountUsd;
@@ -13241,6 +13301,7 @@ function EnterAmountView({
13241
13301
  )
13242
13302
  ] })
13243
13303
  ] }),
13304
+ footer && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: footer }),
13244
13305
  /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uf-shrink-0 uf-pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
13245
13306
  "button",
13246
13307
  {
@@ -13702,7 +13763,7 @@ var WALLET_ICONS3 = {
13702
13763
  };
13703
13764
  var FALLBACK_WALLET_DEFINITIONS = [
13704
13765
  { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
13705
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
13766
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
13706
13767
  { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
13707
13768
  { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
13708
13769
  { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
@@ -13762,7 +13823,7 @@ function getLegacyEvmProviders() {
13762
13823
  okxEthereum: win.okxwallet
13763
13824
  };
13764
13825
  }
13765
- function detectAvailableWallets(definitions, filterChainType) {
13826
+ function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
13766
13827
  const solProviders = getSolanaProviders();
13767
13828
  const legacyEvm = getLegacyEvmProviders();
13768
13829
  const eip6963List = getEip6963Providers();
@@ -13788,7 +13849,7 @@ function detectAvailableWallets(definitions, filterChainType) {
13788
13849
  return false;
13789
13850
  }
13790
13851
  });
13791
- return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13852
+ const sorted = definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13792
13853
  let isInstalled = false;
13793
13854
  const detectedNetworks = [];
13794
13855
  switch (wallet.id) {
@@ -13811,8 +13872,6 @@ function detectAvailableWallets(definitions, filterChainType) {
13811
13872
  isInstalled = true;
13812
13873
  detectedNetworks.push("ethereum");
13813
13874
  }
13814
- if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
13815
- if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
13816
13875
  break;
13817
13876
  case "trust":
13818
13877
  if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
@@ -13849,11 +13908,17 @@ function detectAvailableWallets(definitions, filterChainType) {
13849
13908
  }
13850
13909
  return { ...wallet, isInstalled, detectedNetworks };
13851
13910
  }).sort((a, b) => {
13911
+ if (recentWalletId) {
13912
+ const aRecent = a.id === recentWalletId ? 1 : 0;
13913
+ const bRecent = b.id === recentWalletId ? 1 : 0;
13914
+ if (aRecent !== bRecent) return bRecent - aRecent;
13915
+ }
13852
13916
  if (a.isInstalled && !b.isInstalled) return -1;
13853
13917
  if (!a.isInstalled && b.isInstalled) return 1;
13854
13918
  if (a.isInstalled && b.isInstalled) return b.networks.length - a.networks.length;
13855
13919
  return 0;
13856
13920
  });
13921
+ return sorted;
13857
13922
  }
13858
13923
  function WalletConnect({
13859
13924
  walletInfo: initialWalletInfo,
@@ -13928,9 +13993,15 @@ function WalletConnect({
13928
13993
  })) : FALLBACK_WALLET_DEFINITIONS,
13929
13994
  [backendWallets]
13930
13995
  );
13996
+ const [recentWalletId, setRecentWalletIdState] = React30.useState(getLastOpenedWallet);
13997
+ React30.useEffect(() => {
13998
+ if (view === "select_wallet") {
13999
+ setRecentWalletIdState(getLastOpenedWallet());
14000
+ }
14001
+ }, [view]);
13931
14002
  const availableWallets = React30.useMemo(
13932
- () => detectAvailableWallets(walletDefinitions),
13933
- [walletDefinitions, eip6963ProviderCount]
14003
+ () => detectAvailableWallets(walletDefinitions, recentWalletId),
14004
+ [walletDefinitions, eip6963ProviderCount, recentWalletId]
13934
14005
  );
13935
14006
  const [isMobile, setIsMobile] = React30.useState(false);
13936
14007
  React30.useEffect(() => {
@@ -13990,7 +14061,7 @@ function WalletConnect({
13990
14061
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
13991
14062
  const recipientAddress = activeDepositWallet?.address ?? "";
13992
14063
  const isCheckoutMode = !!checkoutAmountUsd;
13993
- const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
14064
+ const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
13994
14065
  const transitionTo = React30.useCallback((nextView) => {
13995
14066
  if (nextView === viewRef.current) return;
13996
14067
  setIsTransitioning(true);
@@ -14007,13 +14078,15 @@ function WalletConnect({
14007
14078
  };
14008
14079
  const openMobileWalletBrowse = async (wallet, depositAddresses) => {
14009
14080
  try {
14010
- const res = await (0, import_core29.getWalletMobileDeepLink)(
14081
+ const res = await (0, import_core30.getWalletMobileDeepLink)(
14011
14082
  wallet.id,
14012
14083
  depositAddresses,
14013
14084
  publishableKey
14014
14085
  );
14015
14086
  if (res.deeplink) {
14016
14087
  setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
14088
+ setLastOpenedWallet(wallet.id);
14089
+ setRecentWalletIdState(wallet.id);
14017
14090
  setAwaitingMobileDeposit(true);
14018
14091
  transitionTo("mobile_redirect");
14019
14092
  window.location.href = res.deeplink;
@@ -14074,6 +14147,8 @@ function WalletConnect({
14074
14147
  const handleConnectWallet = async (wallet, network) => {
14075
14148
  setConnectingNetwork(network);
14076
14149
  transitionTo("connecting");
14150
+ setLastOpenedWallet(wallet.id);
14151
+ setRecentWalletIdState(wallet.id);
14077
14152
  setWalletError(null);
14078
14153
  setIsWalletConnecting(true);
14079
14154
  try {
@@ -14178,6 +14253,13 @@ function WalletConnect({
14178
14253
  }
14179
14254
  };
14180
14255
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
14256
+ const { needsActivation: hypercoreNeedsActivation, activationFee: hypercoreActivationFee, sponsored: hypercoreActivationSponsored } = useHypercoreActivation({
14257
+ recipientAddress,
14258
+ sourceAddress: activeWalletInfo?.address,
14259
+ destinationChainId: selectedToken?.chain_id,
14260
+ publishableKey,
14261
+ enabled: !!activeWalletInfo && !!recipientAddress
14262
+ });
14181
14263
  const effectiveDestinationAmount = React30.useMemo(() => {
14182
14264
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
14183
14265
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
@@ -14259,7 +14341,7 @@ function WalletConnect({
14259
14341
  const token = getTokenFromBalance(selectedBalance);
14260
14342
  if (!token) return;
14261
14343
  const options = { destination_token_address: activeDepositWallet.destination_token_address, destination_chain_id: activeDepositWallet.destination_chain_id, destination_chain_type: activeDepositWallet.destination_chain_type, ...productType ? { product_type: productType } : {} };
14262
- const response = await (0, import_core29.getSupportedDepositTokens)(publishableKey, options);
14344
+ const response = await (0, import_core30.getSupportedDepositTokens)(publishableKey, options);
14263
14345
  if (cancelled) return;
14264
14346
  const supportedToken = response.data.find((t12) => t12.symbol.toLowerCase() === token.symbol.toLowerCase());
14265
14347
  if (supportedToken) {
@@ -14282,8 +14364,8 @@ function WalletConnect({
14282
14364
  let cancelled = false;
14283
14365
  setIsLoading(true);
14284
14366
  setError(null);
14285
- const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" ? "ethereum" : activeDepositWallet.chain_type;
14286
- (0, import_core29.getAddressBalances)(activeWalletInfo.address, sct, publishableKey).then((response) => {
14367
+ const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
14368
+ (0, import_core30.getAddressBalances)(activeWalletInfo.address, sct, publishableKey).then((response) => {
14287
14369
  if (cancelled) return;
14288
14370
  const nonZero = response.balances.filter((b) => b.amount !== "0");
14289
14371
  const defaultSource = {
@@ -14448,9 +14530,16 @@ function WalletConnect({
14448
14530
  const [integerPart = "0", decimalPart = ""] = amountStr.trim().split(".");
14449
14531
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
14450
14532
  };
14451
- const sendEthereumTransaction = async (token, amountStr) => {
14452
- if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
14453
- const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
14533
+ const resolveEvmProvider = () => {
14534
+ const walletIdMap = {
14535
+ "phantom-ethereum": "phantom",
14536
+ coinbase: "coinbase",
14537
+ trust: "trust",
14538
+ okx: "okx",
14539
+ rainbow: "rainbow",
14540
+ rabby: "rabby",
14541
+ metamask: "metamask"
14542
+ };
14454
14543
  const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
14455
14544
  const eip6963Match = findProviderByWalletId(lookupId);
14456
14545
  let provider = eip6963Match?.provider;
@@ -14459,6 +14548,11 @@ function WalletConnect({
14459
14548
  else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
14460
14549
  else provider = window.ethereum;
14461
14550
  }
14551
+ return provider;
14552
+ };
14553
+ const sendEthereumTransaction = async (token, amountStr) => {
14554
+ if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
14555
+ const provider = resolveEvmProvider();
14462
14556
  if (!provider) throw new Error("Ethereum wallet not found");
14463
14557
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
14464
14558
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -14507,7 +14601,7 @@ function WalletConnect({
14507
14601
  if (!provider.publicKey) await provider.connect();
14508
14602
  const isNative = token.token_address === "native" || token.token_address === "So11111111111111111111111111111111111111112" || token.token_address === "";
14509
14603
  const smallestUnit = isNative ? decimalToSmallestUnit(amountStr, 9) : decimalToSmallestUnit(amountStr, token.decimals);
14510
- const buildResp = await (0, import_core29.buildSolanaTransaction)({ chain_id: "mainnet", token_address: token.token_address === "" ? "native" : token.token_address, source_address: walletInfo.address, destination_address: recipientAddress, amount: smallestUnit }, publishableKey);
14604
+ const buildResp = await (0, import_core30.buildSolanaTransaction)({ chain_id: "mainnet", token_address: token.token_address === "" ? "native" : token.token_address, source_address: walletInfo.address, destination_address: recipientAddress, amount: smallestUnit }, publishableKey);
14511
14605
  const { VersionedTransaction } = await import(
14512
14606
  /* @vite-ignore */
14513
14607
  "@solana/web3.js"
@@ -14520,9 +14614,22 @@ function WalletConnect({
14520
14614
  const ser = signed.serialize();
14521
14615
  let bs = "";
14522
14616
  for (let i = 0; i < ser.length; i++) bs += String.fromCharCode(ser[i]);
14523
- const resp = await (0, import_core29.sendSolanaTransaction)({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
14617
+ const resp = await (0, import_core30.sendSolanaTransaction)({ chain_id: "mainnet", signed_transaction: btoa(bs) }, publishableKey);
14524
14618
  return resp.signature;
14525
14619
  };
14620
+ const sendHypercoreDeposit = async (token, amountStr) => {
14621
+ const provider = resolveEvmProvider();
14622
+ if (!provider) throw new Error("Ethereum wallet not found");
14623
+ const { signature } = await sendHypercoreEvmTransfer({
14624
+ provider,
14625
+ fromAddress: walletInfo.address,
14626
+ recipientAddress,
14627
+ sourceTokenAddress: token.token_address,
14628
+ amount: amountStr,
14629
+ publishableKey
14630
+ });
14631
+ return signature;
14632
+ };
14526
14633
  const handleConfirm = async () => {
14527
14634
  if (!hasWallet || !selectedBalance || !amountUsd || tokenAmount === 0 || !recipientAddress) return;
14528
14635
  const token = getTokenFromBalance(selectedBalance);
@@ -14542,7 +14649,33 @@ function WalletConnect({
14542
14649
  setIsConfirming(true);
14543
14650
  setError(null);
14544
14651
  try {
14545
- const txHash = token.chain_type === "solana" ? await sendSolanaTransaction(token, tokenAmount.toString()) : await sendEthereumTransaction(token, tokenAmount.toString());
14652
+ const isHypercoreToken = String(token.chain_id) === HYPERCORE_CHAIN_ID;
14653
+ let txHash;
14654
+ if (token.chain_type === "solana") {
14655
+ txHash = await sendSolanaTransaction(token, tokenAmount.toString());
14656
+ } else if (isHypercoreToken) {
14657
+ let sendAmount = tokenAmount;
14658
+ try {
14659
+ const activation = await (0, import_core30.checkHypercoreActivation)(
14660
+ { source_address: walletInfo.address, recipient_address: recipientAddress },
14661
+ publishableKey
14662
+ );
14663
+ if (!activation.user_exists) {
14664
+ const fee = activation.activation_fee;
14665
+ if (!Number.isFinite(tokenAmount) || tokenAmount <= fee) {
14666
+ throw new Error(
14667
+ `Insufficient amount. A ${fee} USDC activation fee is required for the first transfer to this address.`
14668
+ );
14669
+ }
14670
+ sendAmount = tokenAmount - fee;
14671
+ }
14672
+ } catch (e) {
14673
+ if (e instanceof Error && e.message.includes("activation fee")) throw e;
14674
+ }
14675
+ txHash = await sendHypercoreDeposit(token, sendAmount.toString());
14676
+ } else {
14677
+ txHash = await sendEthereumTransaction(token, tokenAmount.toString());
14678
+ }
14546
14679
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
14547
14680
  setHasSignedTransaction(true);
14548
14681
  handleIveDeposited();
@@ -14719,8 +14852,8 @@ function WalletConnect({
14719
14852
  ] }) });
14720
14853
  }
14721
14854
  if (view === "mobile_deposit_status" && latestDepositExecution) {
14722
- const isComplete = latestDepositExecution.status === import_core29.ExecutionStatus.SUCCEEDED;
14723
- const isFailed = latestDepositExecution.status === import_core29.ExecutionStatus.FAILED;
14855
+ const isComplete = latestDepositExecution.status === import_core30.ExecutionStatus.SUCCEEDED;
14856
+ const isFailed = latestDepositExecution.status === import_core30.ExecutionStatus.FAILED;
14724
14857
  const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
14725
14858
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14726
14859
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
@@ -14760,7 +14893,7 @@ function WalletConnect({
14760
14893
  }
14761
14894
  if (view === "enter_amount" && selectedToken && selectedBalance) {
14762
14895
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
14763
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
14896
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd, footer: hypercoreNeedsActivation && !hypercoreActivationSponsored ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(HypercoreActivationWarning, { activationFee: hypercoreActivationFee }) : void 0 }) }) });
14764
14897
  }
14765
14898
  if (view === "review" && selectedToken) {
14766
14899
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
@@ -14799,6 +14932,9 @@ function SkeletonButton({
14799
14932
  ] });
14800
14933
  }
14801
14934
  var t7 = i18n.depositModal;
14935
+ function depositTabForScreen(screen) {
14936
+ return screen === "card" || screen === "cashapp" ? "cash" : "crypto";
14937
+ }
14802
14938
  function DepositModal({
14803
14939
  open,
14804
14940
  onOpenChange,
@@ -14834,6 +14970,7 @@ function DepositModal({
14834
14970
  theme = "dark",
14835
14971
  hideOverlay = false,
14836
14972
  initialScreen = "main",
14973
+ displayMode = "stacked",
14837
14974
  transferCryptoTitle = t7.transferCrypto.title,
14838
14975
  depositWithCardTitle = t7.depositWithCard.title,
14839
14976
  payWithExchangeTitle = t7.payWithExchange.title,
@@ -14868,6 +15005,9 @@ function DepositModal({
14868
15005
  effectiveInitialScreen
14869
15006
  );
14870
15007
  const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = (0, import_react20.useState)(false);
15008
+ const [depositTab, setDepositTab] = (0, import_react20.useState)(
15009
+ () => depositTabForScreen(effectiveInitialScreen)
15010
+ );
14871
15011
  const resetViewTimeoutRef = (0, import_react20.useRef)(null);
14872
15012
  const [cardView, setCardView] = (0, import_react20.useState)(
14873
15013
  "amount"
@@ -14897,18 +15037,18 @@ function DepositModal({
14897
15037
  const [integrationExchanges, setIntegrationExchanges] = (0, import_react20.useState)([]);
14898
15038
  (0, import_react20.useEffect)(() => {
14899
15039
  if (!showConnectExchange || !open) return;
14900
- (0, import_core30.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
15040
+ (0, import_core31.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
14901
15041
  });
14902
15042
  }, [showConnectExchange, open, publishableKey]);
14903
15043
  const [connectedExchange, setConnectedExchange] = (0, import_react20.useState)(() => {
14904
15044
  if (!showConnectExchange) return null;
14905
- const stored = getStoredIntegrationToken(import_core30.IntegrationProvider.COINBASE);
15045
+ const stored = getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
14906
15046
  if (!stored) return null;
14907
15047
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
14908
15048
  });
14909
15049
  (0, import_react20.useEffect)(() => {
14910
15050
  if (!showConnectExchange || !open || view !== "main") return;
14911
- const stored = getStoredIntegrationToken(import_core30.IntegrationProvider.COINBASE);
15051
+ const stored = getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
14912
15052
  if (!stored) {
14913
15053
  setConnectedExchange(null);
14914
15054
  return;
@@ -14925,20 +15065,20 @@ function DepositModal({
14925
15065
  const balanceUsd = totalUsd > 0 ? totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : null;
14926
15066
  setConnectedExchange((prev) => prev ? { ...prev, balanceUsd, isLoading: false } : null);
14927
15067
  };
14928
- (0, import_core30.getIntegrationHoldings)(import_core30.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
15068
+ (0, import_core31.getIntegrationHoldings)(import_core31.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
14929
15069
  try {
14930
- const refreshResult = await (0, import_core30.refreshIntegrationToken)(stored.access_token, publishableKey);
14931
- if (!getStoredIntegrationToken(import_core30.IntegrationProvider.COINBASE)) return;
15070
+ const refreshResult = await (0, import_core31.refreshIntegrationToken)(stored.access_token, publishableKey);
15071
+ if (!getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE)) return;
14932
15072
  setStoredIntegrationToken({
14933
- integration_provider: import_core30.IntegrationProvider.COINBASE,
15073
+ integration_provider: import_core31.IntegrationProvider.COINBASE,
14934
15074
  access_token: refreshResult.access_token,
14935
15075
  expires_at: refreshResult.expires_at
14936
15076
  });
14937
- const retryResult = await (0, import_core30.getIntegrationHoldings)(import_core30.IntegrationProvider.COINBASE, refreshResult.access_token, publishableKey);
15077
+ const retryResult = await (0, import_core31.getIntegrationHoldings)(import_core31.IntegrationProvider.COINBASE, refreshResult.access_token, publishableKey);
14938
15078
  processHoldings(retryResult);
14939
15079
  } catch {
14940
- if (!getStoredIntegrationToken(import_core30.IntegrationProvider.COINBASE)) return;
14941
- clearStoredIntegrationToken(import_core30.IntegrationProvider.COINBASE);
15080
+ if (!getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE)) return;
15081
+ clearStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
14942
15082
  setConnectedExchange(null);
14943
15083
  }
14944
15084
  });
@@ -14946,7 +15086,7 @@ function DepositModal({
14946
15086
  (0, import_react20.useEffect)(() => {
14947
15087
  if (!connectedExchange || integrationExchanges.length === 0) return;
14948
15088
  const cbExchange = integrationExchanges.find(
14949
- (e) => e.service_provider === import_core30.IntegrationProvider.COINBASE
15089
+ (e) => e.service_provider === import_core31.IntegrationProvider.COINBASE
14950
15090
  );
14951
15091
  const iconUrl = cbExchange?.icon_urls?.find((u) => u.format === "svg")?.url || cbExchange?.icon_urls?.find((u) => u.format === "png")?.url || cbExchange?.icon_url;
14952
15092
  if (iconUrl && iconUrl !== connectedExchange.iconUrl) {
@@ -15032,7 +15172,7 @@ function DepositModal({
15032
15172
  if (view !== "tracker" || !userId) return;
15033
15173
  const fetchExecutions = async () => {
15034
15174
  try {
15035
- const response = await (0, import_core30.queryExecutions)(userId, publishableKey, import_core30.ActionType.Deposit);
15175
+ const response = await (0, import_core31.queryExecutions)(userId, publishableKey, import_core31.ActionType.Deposit);
15036
15176
  const sorted = [...response.data].sort((a, b) => {
15037
15177
  const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
15038
15178
  const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
@@ -15136,11 +15276,11 @@ function DepositModal({
15136
15276
  if (view === "wallet_connect" && sessionOpenedFromMenu) setView("main");
15137
15277
  };
15138
15278
  const handleExchangeDisconnect = () => {
15139
- const stored = getStoredIntegrationToken(import_core30.IntegrationProvider.COINBASE);
15279
+ const stored = getStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
15140
15280
  if (stored) {
15141
- (0, import_core30.revokeIntegrationToken)(stored.access_token, publishableKey);
15281
+ (0, import_core31.revokeIntegrationToken)(stored.access_token, publishableKey);
15142
15282
  }
15143
- clearStoredIntegrationToken(import_core30.IntegrationProvider.COINBASE);
15283
+ clearStoredIntegrationToken(import_core31.IntegrationProvider.COINBASE);
15144
15284
  setConnectedExchange(null);
15145
15285
  if (view === "coinbase_connect" && sessionOpenedFromMenu) setView("main");
15146
15286
  };
@@ -15165,6 +15305,7 @@ function DepositModal({
15165
15305
  resetViewTimeoutRef.current = null;
15166
15306
  }
15167
15307
  setView(effectiveInitialScreen);
15308
+ setDepositTab(depositTabForScreen(effectiveInitialScreen));
15168
15309
  setCardView("amount");
15169
15310
  setExchangeView("providers");
15170
15311
  setBrowserWalletInfo(null);
@@ -15193,6 +15334,7 @@ function DepositModal({
15193
15334
  } else if (view === "cashapp" && cashAppView !== "amount") {
15194
15335
  setCashAppView("amount");
15195
15336
  } else {
15337
+ setDepositTab(depositTabForScreen(view));
15196
15338
  setView("main");
15197
15339
  setCardView("amount");
15198
15340
  setExchangeView("providers");
@@ -15272,6 +15414,174 @@ function DepositModal({
15272
15414
  className: "uf-flex uf-justify-center uf-shrink-0"
15273
15415
  }
15274
15416
  ) });
15417
+ const transferCryptoMenuButton = showTransferCrypto ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15418
+ TransferCryptoButton,
15419
+ {
15420
+ onClick: () => setView("transfer"),
15421
+ title: transferCryptoTitle,
15422
+ subtitle: t7.transferCrypto.subtitle,
15423
+ featuredTokens: projectConfig?.transfer_crypto.networks
15424
+ },
15425
+ "transfer"
15426
+ ) : null;
15427
+ const connectWalletMenuButton = showConnectWallet ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15428
+ BrowserWalletButton,
15429
+ {
15430
+ onClick: handleBrowserWalletClick,
15431
+ onConnectClick: handleWalletConnectClick,
15432
+ onDisconnect: handleWalletDisconnect,
15433
+ chainType: browserWalletChainType,
15434
+ publishableKey,
15435
+ featuredWallets: projectConfig?.connect_wallet?.wallets
15436
+ },
15437
+ "wallet"
15438
+ ) : null;
15439
+ const depositWithCardMenuButton = showFiatOnramp ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15440
+ DepositWithCardButton,
15441
+ {
15442
+ onClick: () => setView("card"),
15443
+ title: depositWithCardTitle,
15444
+ subtitle: t7.depositWithCard.subtitle,
15445
+ paymentNetworks: projectConfig?.payment_networks.networks
15446
+ },
15447
+ "card"
15448
+ ) : null;
15449
+ const payWithExchangeMenuButton = showPayWithExchange ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15450
+ PayWithExchangeButton,
15451
+ {
15452
+ onClick: () => setView("exchange"),
15453
+ title: payWithExchangeTitle,
15454
+ subtitle: t7.payWithExchange.subtitle,
15455
+ exchanges,
15456
+ loading: exchangesLoading
15457
+ },
15458
+ "exchange"
15459
+ ) : null;
15460
+ const connectExchangeMenuButton = showConnectExchange && connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15461
+ ConnectExchangeButton,
15462
+ {
15463
+ onClick: () => {
15464
+ setCoinbaseSkipToHoldings(true);
15465
+ setView("coinbase_connect");
15466
+ },
15467
+ onDisconnect: handleExchangeDisconnect,
15468
+ title: i18n.connectExchange.title,
15469
+ subtitle: i18n.connectExchange.subtitle,
15470
+ exchanges: integrationExchanges,
15471
+ connectedExchange
15472
+ },
15473
+ "connect-exchange"
15474
+ ) : showConnectExchange && !connectedExchange ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15475
+ ConnectExchangeButton,
15476
+ {
15477
+ onClick: () => {
15478
+ setCoinbaseSkipToHoldings(false);
15479
+ setView("coinbase_connect");
15480
+ },
15481
+ title: i18n.connectExchange.title,
15482
+ subtitle: i18n.connectExchange.subtitle,
15483
+ exchanges: integrationExchanges
15484
+ },
15485
+ "connect-exchange"
15486
+ ) : null;
15487
+ const cashAppMenuButton = showCashApp ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15488
+ CashAppButton,
15489
+ {
15490
+ onClick: () => setView("cashapp"),
15491
+ title: "Pay with Cash App",
15492
+ subtitle: "Deposit via Cash App",
15493
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
15494
+ },
15495
+ "cashapp"
15496
+ ) : null;
15497
+ const depositTrackerMenuButton = showDepositTracker ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15498
+ DepositTrackerButton,
15499
+ {
15500
+ onClick: () => {
15501
+ setAllExecutions(depositExecutions);
15502
+ setView("tracker");
15503
+ },
15504
+ title: depositTrackerTitle,
15505
+ subtitle: depositTrackerSubTitle,
15506
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
15507
+ },
15508
+ "tracker"
15509
+ ) : null;
15510
+ const cryptoMenuButtons = [
15511
+ transferCryptoMenuButton,
15512
+ connectWalletMenuButton,
15513
+ payWithExchangeMenuButton,
15514
+ connectExchangeMenuButton
15515
+ ].filter(Boolean);
15516
+ const cashMenuButtons = [
15517
+ depositWithCardMenuButton,
15518
+ cashAppMenuButton
15519
+ ].filter(Boolean);
15520
+ const depositTabs = [
15521
+ { id: "crypto", label: "Use Crypto", buttons: cryptoMenuButtons },
15522
+ { id: "cash", label: "Use Cash", buttons: cashMenuButtons }
15523
+ ].filter((tab) => tab.buttons.length > 0);
15524
+ const activeDepositTab = depositTabs.find((tab) => tab.id === depositTab) ?? depositTabs[0];
15525
+ const renderMainMenuBody = () => {
15526
+ if (depositPrerequisiteBody) {
15527
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody });
15528
+ }
15529
+ if (displayMode === "tabs" && activeDepositTab) {
15530
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { children: [
15531
+ depositTabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15532
+ "div",
15533
+ {
15534
+ className: "uf-flex uf-gap-1 uf-p-1 uf-rounded-xl uf-mb-3",
15535
+ style: {
15536
+ // Frosted-glass track: a translucent fill plus a backdrop blur so
15537
+ // the control reads as a soft surface rather than a solid bar.
15538
+ backgroundColor: `color-mix(in srgb, ${colors2.card} 55%, transparent)`,
15539
+ backdropFilter: "blur(12px)",
15540
+ WebkitBackdropFilter: "blur(12px)"
15541
+ },
15542
+ role: "tablist",
15543
+ children: depositTabs.map((tab) => {
15544
+ const active = activeDepositTab.id === tab.id;
15545
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15546
+ "button",
15547
+ {
15548
+ type: "button",
15549
+ role: "tab",
15550
+ "aria-selected": active,
15551
+ onClick: () => setDepositTab(tab.id),
15552
+ className: "uf-flex-1 uf-py-2 uf-px-3 uf-rounded-lg uf-text-sm uf-transition-all",
15553
+ style: {
15554
+ // Active tab is a soft, blurred glass pill — a faint accent
15555
+ // tint with its own backdrop blur and a subtle border/shadow,
15556
+ // so it looks frosted instead of like a hard solid button.
15557
+ backgroundColor: active ? `color-mix(in srgb, ${colors2.primary} 22%, transparent)` : "transparent",
15558
+ backdropFilter: active ? "blur(8px)" : void 0,
15559
+ WebkitBackdropFilter: active ? "blur(8px)" : void 0,
15560
+ boxShadow: active ? `0 1px 8px color-mix(in srgb, ${colors2.primary} 25%, transparent)` : void 0,
15561
+ color: active ? colors2.foreground : colors2.foregroundMuted,
15562
+ fontFamily: fonts.medium
15563
+ },
15564
+ children: tab.label
15565
+ },
15566
+ tab.id
15567
+ );
15568
+ })
15569
+ }
15570
+ ),
15571
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-space-y-3", children: activeDepositTab.buttons }),
15572
+ depositTrackerMenuButton && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-mt-3", children: depositTrackerMenuButton })
15573
+ ] });
15574
+ }
15575
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-space-y-3", children: [
15576
+ transferCryptoMenuButton,
15577
+ connectWalletMenuButton,
15578
+ depositWithCardMenuButton,
15579
+ payWithExchangeMenuButton,
15580
+ connectExchangeMenuButton,
15581
+ cashAppMenuButton,
15582
+ depositTrackerMenuButton
15583
+ ] });
15584
+ };
15275
15585
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15276
15586
  Dialog,
15277
15587
  {
@@ -15298,7 +15608,7 @@ function DepositModal({
15298
15608
  onClose: handleClose,
15299
15609
  showBalance: showBalanceHeader,
15300
15610
  balanceAddress: recipientAddress,
15301
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15611
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
15302
15612
  balanceChainId: destinationChainId,
15303
15613
  balanceTokenAddress: destinationTokenAddress,
15304
15614
  projectName: projectConfig?.project_name,
@@ -15306,94 +15616,7 @@ function DepositModal({
15306
15616
  }
15307
15617
  ),
15308
15618
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
15309
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
15310
- showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15311
- TransferCryptoButton,
15312
- {
15313
- onClick: () => setView("transfer"),
15314
- title: transferCryptoTitle,
15315
- subtitle: t7.transferCrypto.subtitle,
15316
- featuredTokens: projectConfig?.transfer_crypto.networks
15317
- }
15318
- ),
15319
- showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15320
- BrowserWalletButton,
15321
- {
15322
- onClick: handleBrowserWalletClick,
15323
- onConnectClick: handleWalletConnectClick,
15324
- onDisconnect: handleWalletDisconnect,
15325
- chainType: browserWalletChainType,
15326
- publishableKey,
15327
- featuredWallets: projectConfig?.connect_wallet?.wallets
15328
- }
15329
- ),
15330
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15331
- DepositWithCardButton,
15332
- {
15333
- onClick: () => setView("card"),
15334
- title: depositWithCardTitle,
15335
- subtitle: t7.depositWithCard.subtitle,
15336
- paymentNetworks: projectConfig?.payment_networks.networks
15337
- }
15338
- ),
15339
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15340
- PayWithExchangeButton,
15341
- {
15342
- onClick: () => setView("exchange"),
15343
- title: payWithExchangeTitle,
15344
- subtitle: t7.payWithExchange.subtitle,
15345
- exchanges,
15346
- loading: exchangesLoading
15347
- }
15348
- ),
15349
- showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15350
- ConnectExchangeButton,
15351
- {
15352
- onClick: () => {
15353
- setCoinbaseSkipToHoldings(true);
15354
- setView("coinbase_connect");
15355
- },
15356
- onDisconnect: handleExchangeDisconnect,
15357
- title: i18n.connectExchange.title,
15358
- subtitle: i18n.connectExchange.subtitle,
15359
- exchanges: integrationExchanges,
15360
- connectedExchange
15361
- }
15362
- ),
15363
- showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15364
- ConnectExchangeButton,
15365
- {
15366
- onClick: () => {
15367
- setCoinbaseSkipToHoldings(false);
15368
- setView("coinbase_connect");
15369
- },
15370
- title: i18n.connectExchange.title,
15371
- subtitle: i18n.connectExchange.subtitle,
15372
- exchanges: integrationExchanges
15373
- }
15374
- ),
15375
- showCashApp && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15376
- CashAppButton,
15377
- {
15378
- onClick: () => setView("cashapp"),
15379
- title: "Pay with Cash App",
15380
- subtitle: "Deposit via Cash App",
15381
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
15382
- }
15383
- ),
15384
- showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15385
- DepositTrackerButton,
15386
- {
15387
- onClick: () => {
15388
- setAllExecutions(depositExecutions);
15389
- setView("tracker");
15390
- },
15391
- title: depositTrackerTitle,
15392
- subtitle: depositTrackerSubTitle,
15393
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
15394
- }
15395
- )
15396
- ] }) }),
15619
+ renderMainMenuBody(),
15397
15620
  depositPoweredByFooter
15398
15621
  ] })
15399
15622
  ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
@@ -15406,7 +15629,7 @@ function DepositModal({
15406
15629
  onClose: handleClose,
15407
15630
  showBalance: showBalanceHeader,
15408
15631
  balanceAddress: recipientAddress,
15409
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15632
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
15410
15633
  balanceChainId: destinationChainId,
15411
15634
  balanceTokenAddress: destinationTokenAddress,
15412
15635
  projectName: projectConfig?.project_name,
@@ -15494,7 +15717,7 @@ function DepositModal({
15494
15717
  badge: cardView === "quotes" ? { count: quotesCount } : void 0,
15495
15718
  showBalance: showBalanceHeader,
15496
15719
  balanceAddress: recipientAddress,
15497
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
15720
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
15498
15721
  balanceChainId: destinationChainId,
15499
15722
  balanceTokenAddress: destinationTokenAddress,
15500
15723
  projectName: projectConfig?.project_name,
@@ -15682,7 +15905,7 @@ var import_lucide_react30 = require("lucide-react");
15682
15905
 
15683
15906
  // src/hooks/use-payment-intent.ts
15684
15907
  var import_react_query14 = require("@tanstack/react-query");
15685
- var import_core31 = require("@unifold/core");
15908
+ var import_core32 = require("@unifold/core");
15686
15909
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
15687
15910
  "succeeded",
15688
15911
  "expired",
@@ -15698,7 +15921,7 @@ function usePaymentIntent(params) {
15698
15921
  } = params;
15699
15922
  return (0, import_react_query14.useQuery)({
15700
15923
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
15701
- queryFn: () => (0, import_core31.retrievePaymentIntent)(clientSecret, publishableKey),
15924
+ queryFn: () => (0, import_core32.retrievePaymentIntent)(clientSecret, publishableKey),
15702
15925
  enabled: enabled && !!clientSecret && !!publishableKey,
15703
15926
  staleTime: 0,
15704
15927
  refetchInterval: (query) => {
@@ -16357,11 +16580,11 @@ var import_lucide_react33 = require("lucide-react");
16357
16580
 
16358
16581
  // src/hooks/use-supported-destination-tokens.ts
16359
16582
  var import_react_query15 = require("@tanstack/react-query");
16360
- var import_core32 = require("@unifold/core");
16583
+ var import_core33 = require("@unifold/core");
16361
16584
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
16362
16585
  return (0, import_react_query15.useQuery)({
16363
16586
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
16364
- queryFn: () => (0, import_core32.getSupportedDestinationTokens)(publishableKey),
16587
+ queryFn: () => (0, import_core33.getSupportedDestinationTokens)(publishableKey),
16365
16588
  staleTime: 1e3 * 60 * 5,
16366
16589
  gcTime: 1e3 * 60 * 30,
16367
16590
  refetchOnMount: false,
@@ -16389,7 +16612,7 @@ function useDefaultDestinationToken({
16389
16612
 
16390
16613
  // src/hooks/use-source-token-validation.ts
16391
16614
  var import_react_query16 = require("@tanstack/react-query");
16392
- var import_core33 = require("@unifold/core");
16615
+ var import_core34 = require("@unifold/core");
16393
16616
  function useSourceTokenValidation(params) {
16394
16617
  const {
16395
16618
  sourceChainType,
@@ -16410,7 +16633,7 @@ function useSourceTokenValidation(params) {
16410
16633
  publishableKey
16411
16634
  ],
16412
16635
  queryFn: async () => {
16413
- const res = await (0, import_core33.getSupportedDepositTokens)(publishableKey);
16636
+ const res = await (0, import_core34.getSupportedDepositTokens)(publishableKey);
16414
16637
  let matchedMinUsd = null;
16415
16638
  let matchedProcessingTime = null;
16416
16639
  let matchedSlippage = null;
@@ -16449,7 +16672,7 @@ function useSourceTokenValidation(params) {
16449
16672
 
16450
16673
  // src/hooks/use-address-balance.ts
16451
16674
  var import_react_query17 = require("@tanstack/react-query");
16452
- var import_core34 = require("@unifold/core");
16675
+ var import_core35 = require("@unifold/core");
16453
16676
  function useAddressBalance(params) {
16454
16677
  const {
16455
16678
  address,
@@ -16471,7 +16694,7 @@ function useAddressBalance(params) {
16471
16694
  publishableKey
16472
16695
  ],
16473
16696
  queryFn: async () => {
16474
- const res = await (0, import_core34.getAddressBalance)(
16697
+ const res = await (0, import_core35.getAddressBalance)(
16475
16698
  address,
16476
16699
  chainType,
16477
16700
  chainId,
@@ -16510,12 +16733,12 @@ function useAddressBalance(params) {
16510
16733
 
16511
16734
  // src/hooks/use-executions.ts
16512
16735
  var import_react_query18 = require("@tanstack/react-query");
16513
- var import_core35 = require("@unifold/core");
16736
+ var import_core36 = require("@unifold/core");
16514
16737
  function useExecutions(userId, publishableKey, options) {
16515
- const actionType = options?.actionType ?? import_core35.ActionType.Deposit;
16738
+ const actionType = options?.actionType ?? import_core36.ActionType.Deposit;
16516
16739
  return (0, import_react_query18.useQuery)({
16517
16740
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
16518
- queryFn: () => (0, import_core35.queryExecutions)(userId, publishableKey, actionType),
16741
+ queryFn: () => (0, import_core36.queryExecutions)(userId, publishableKey, actionType),
16519
16742
  enabled: (options?.enabled ?? true) && !!userId,
16520
16743
  refetchInterval: options?.refetchInterval ?? 3e3,
16521
16744
  staleTime: 0,
@@ -16526,7 +16749,7 @@ function useExecutions(userId, publishableKey, options) {
16526
16749
 
16527
16750
  // src/hooks/use-withdraw-polling.ts
16528
16751
  var import_react22 = require("react");
16529
- var import_core36 = require("@unifold/core");
16752
+ var import_core37 = require("@unifold/core");
16530
16753
  var POLL_INTERVAL_MS3 = 2500;
16531
16754
  var POLL_ENDPOINT_INTERVAL_MS2 = 5e3;
16532
16755
  var CUTOFF_BUFFER_MS2 = 6e4;
@@ -16566,15 +16789,15 @@ function useWithdrawPolling({
16566
16789
  const enabledAt = enabledAtRef.current;
16567
16790
  const poll = async () => {
16568
16791
  try {
16569
- const response = await (0, import_core36.queryExecutions)(userId, publishableKey, import_core36.ActionType.Withdraw);
16792
+ const response = await (0, import_core37.queryExecutions)(userId, publishableKey, import_core37.ActionType.Withdraw);
16570
16793
  const cutoff = new Date(enabledAt.getTime() - CUTOFF_BUFFER_MS2);
16571
16794
  const sorted = [...response.data].sort((a, b) => {
16572
16795
  const tA = a.created_at ? new Date(a.created_at).getTime() : 0;
16573
16796
  const tB = b.created_at ? new Date(b.created_at).getTime() : 0;
16574
16797
  return tB - tA;
16575
16798
  });
16576
- const inProgress = [import_core36.ExecutionStatus.PENDING, import_core36.ExecutionStatus.WAITING, import_core36.ExecutionStatus.DELAYED];
16577
- const terminal = [import_core36.ExecutionStatus.SUCCEEDED, import_core36.ExecutionStatus.FAILED];
16799
+ const inProgress = [import_core37.ExecutionStatus.PENDING, import_core37.ExecutionStatus.WAITING, import_core37.ExecutionStatus.DELAYED];
16800
+ const terminal = [import_core37.ExecutionStatus.SUCCEEDED, import_core37.ExecutionStatus.FAILED];
16578
16801
  let target = null;
16579
16802
  for (const ex of sorted) {
16580
16803
  const t12 = ex.created_at ? new Date(ex.created_at) : null;
@@ -16604,9 +16827,9 @@ function useWithdrawPolling({
16604
16827
  }
16605
16828
  return [...list, ex];
16606
16829
  });
16607
- if (ex.status === import_core36.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16830
+ if (ex.status === import_core37.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
16608
16831
  onSuccessRef.current?.({ message: "Withdrawal completed successfully", executionId: ex.id, transaction: ex });
16609
- } else if (ex.status === import_core36.ExecutionStatus.FAILED && prev !== import_core36.ExecutionStatus.FAILED) {
16832
+ } else if (ex.status === import_core37.ExecutionStatus.FAILED && prev !== import_core37.ExecutionStatus.FAILED) {
16610
16833
  onErrorRef.current?.({ message: "Withdrawal failed", code: "WITHDRAW_FAILED", error: ex });
16611
16834
  }
16612
16835
  }
@@ -16627,7 +16850,7 @@ function useWithdrawPolling({
16627
16850
  if (!enabled || !depositWalletId) return;
16628
16851
  const trigger = async () => {
16629
16852
  try {
16630
- await (0, import_core36.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
16853
+ await (0, import_core37.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
16631
16854
  } catch {
16632
16855
  }
16633
16856
  };
@@ -16796,11 +17019,11 @@ function WithdrawDoubleInput({
16796
17019
  // src/components/withdrawals/WithdrawForm.tsx
16797
17020
  var import_react24 = require("react");
16798
17021
  var import_lucide_react31 = require("lucide-react");
16799
- var import_core41 = require("@unifold/core");
17022
+ var import_core42 = require("@unifold/core");
16800
17023
 
16801
17024
  // src/hooks/use-verify-recipient-address.ts
16802
17025
  var import_react_query19 = require("@tanstack/react-query");
16803
- var import_core37 = require("@unifold/core");
17026
+ var import_core38 = require("@unifold/core");
16804
17027
  function useVerifyRecipientAddress(params) {
16805
17028
  const {
16806
17029
  chainType,
@@ -16822,7 +17045,7 @@ function useVerifyRecipientAddress(params) {
16822
17045
  trimmedAddress,
16823
17046
  publishableKey
16824
17047
  ],
16825
- queryFn: () => (0, import_core37.verifyRecipientAddress)(
17048
+ queryFn: () => (0, import_core38.verifyRecipientAddress)(
16826
17049
  {
16827
17050
  chain_type: chainType,
16828
17051
  chain_id: chainId,
@@ -16841,7 +17064,7 @@ function useVerifyRecipientAddress(params) {
16841
17064
  }
16842
17065
 
16843
17066
  // src/components/withdrawals/send-withdraw.ts
16844
- var import_core38 = require("@unifold/core");
17067
+ var import_core39 = require("@unifold/core");
16845
17068
  async function sendEvmWithdraw(params) {
16846
17069
  const {
16847
17070
  provider,
@@ -16919,7 +17142,7 @@ async function sendSolanaWithdraw(params) {
16919
17142
  if (!provider.publicKey) {
16920
17143
  await provider.connect();
16921
17144
  }
16922
- const buildResponse = await (0, import_core38.buildSolanaTransaction)(
17145
+ const buildResponse = await (0, import_core39.buildSolanaTransaction)(
16923
17146
  {
16924
17147
  chain_id: "mainnet",
16925
17148
  token_address: sourceTokenAddress === "" ? "native" : sourceTokenAddress,
@@ -16945,56 +17168,21 @@ async function sendSolanaWithdraw(params) {
16945
17168
  for (let i = 0; i < serialized.length; i++) {
16946
17169
  binaryStr += String.fromCharCode(serialized[i]);
16947
17170
  }
16948
- const sendResponse = await (0, import_core38.sendSolanaTransaction)(
17171
+ const sendResponse = await (0, import_core39.sendSolanaTransaction)(
16949
17172
  { chain_id: "mainnet", signed_transaction: btoa(binaryStr) },
16950
17173
  publishableKey
16951
17174
  );
16952
17175
  return sendResponse.signature;
16953
17176
  }
16954
- var HYPERCORE_SPOT_USDC_ADDRESS = "0x6d1e7cde53ba9467b783cb7c530ce054";
16955
- function isHypercoreChain(chainId) {
16956
- return chainId === HYPERCORE_CHAIN_ID;
16957
- }
16958
17177
  async function sendHypercoreWithdraw(params) {
16959
- const {
16960
- provider,
16961
- fromAddress,
16962
- depositWalletAddress,
16963
- sourceTokenAddress,
16964
- amount,
16965
- tokenSymbol,
16966
- publishableKey
16967
- } = params;
16968
- const isSpot = sourceTokenAddress.toLowerCase() === HYPERCORE_SPOT_USDC_ADDRESS;
16969
- const currentChainHex = await provider.request({
16970
- method: "eth_chainId",
16971
- params: []
17178
+ await sendHypercoreEvmTransfer({
17179
+ provider: params.provider,
17180
+ fromAddress: params.fromAddress,
17181
+ recipientAddress: params.depositWalletAddress,
17182
+ sourceTokenAddress: params.sourceTokenAddress,
17183
+ amount: params.amount,
17184
+ publishableKey: params.publishableKey
16972
17185
  });
16973
- const activeChainId = String(parseInt(currentChainHex, 16));
16974
- const buildResult = await (0, import_core38.buildHypercoreTransaction)(
16975
- {
16976
- action_type: isSpot ? "spot_send" : "usd_send",
16977
- signature_chain_type: "ethereum",
16978
- signature_chain_id: activeChainId,
16979
- recipient_address: depositWalletAddress,
16980
- token_address: sourceTokenAddress,
16981
- token_symbol: tokenSymbol || void 0,
16982
- amount
16983
- },
16984
- publishableKey
16985
- );
16986
- const signature = await provider.request({
16987
- method: "eth_signTypedData_v4",
16988
- params: [fromAddress, JSON.stringify(buildResult.typed_data)]
16989
- });
16990
- await (0, import_core38.sendHypercoreTransaction)(
16991
- {
16992
- action_payload: buildResult.action_payload,
16993
- signature,
16994
- nonce: buildResult.nonce
16995
- },
16996
- publishableKey
16997
- );
16998
17186
  }
16999
17187
  async function detectBrowserWallet(chainType, senderAddress) {
17000
17188
  const win = typeof window !== "undefined" ? window : null;
@@ -17076,11 +17264,11 @@ async function detectBrowserWallet(chainType, senderAddress) {
17076
17264
 
17077
17265
  // src/hooks/use-hypercore-withdraw-activation.ts
17078
17266
  var import_react23 = require("react");
17079
- var import_core40 = require("@unifold/core");
17267
+ var import_core41 = require("@unifold/core");
17080
17268
 
17081
17269
  // src/hooks/use-get-deposit-address.ts
17082
17270
  var import_react_query20 = require("@tanstack/react-query");
17083
- var import_core39 = require("@unifold/core");
17271
+ var import_core40 = require("@unifold/core");
17084
17272
  function useGetDepositAddress(params) {
17085
17273
  const {
17086
17274
  userId,
@@ -17105,7 +17293,7 @@ function useGetDepositAddress(params) {
17105
17293
  actionType ?? null,
17106
17294
  publishableKey
17107
17295
  ],
17108
- queryFn: () => (0, import_core39.getDepositAddress)(
17296
+ queryFn: () => (0, import_core40.getDepositAddress)(
17109
17297
  {
17110
17298
  external_user_id: userId,
17111
17299
  recipient_address: recipientAddress,
@@ -17159,7 +17347,7 @@ function useHypercoreWithdrawActivation(params) {
17159
17347
  destinationChainType,
17160
17348
  destinationChainId,
17161
17349
  destinationTokenAddress,
17162
- actionType: import_core40.ActionType.Withdraw,
17350
+ actionType: import_core41.ActionType.Withdraw,
17163
17351
  enabled: enabled && isHypercore(sourceChainId)
17164
17352
  });
17165
17353
  const depositWalletAddress = (0, import_react23.useMemo)(() => {
@@ -17428,7 +17616,7 @@ function WithdrawForm({
17428
17616
  let humanAmount = isMaxed ? balanceData.balanceHuman : toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
17429
17617
  if (isHypercoreChain(sourceChainId)) {
17430
17618
  try {
17431
- const check = await (0, import_core41.checkHypercoreActivation)(
17619
+ const check = await (0, import_core42.checkHypercoreActivation)(
17432
17620
  {
17433
17621
  source_address: senderAddress,
17434
17622
  recipient_address: depositWallet.address
@@ -17745,14 +17933,14 @@ function WithdrawForm({
17745
17933
 
17746
17934
  // src/components/withdrawals/WithdrawExecutionItem.tsx
17747
17935
  var import_lucide_react32 = require("lucide-react");
17748
- var import_core42 = require("@unifold/core");
17936
+ var import_core43 = require("@unifold/core");
17749
17937
  var import_jsx_runtime59 = require("react/jsx-runtime");
17750
17938
  function WithdrawExecutionItem({
17751
17939
  execution,
17752
17940
  onClick
17753
17941
  }) {
17754
17942
  const { colors: colors2, fonts, components } = useTheme();
17755
- const isPending = execution.status === import_core42.ExecutionStatus.PENDING || execution.status === import_core42.ExecutionStatus.WAITING || execution.status === import_core42.ExecutionStatus.DELAYED;
17943
+ const isPending = execution.status === import_core43.ExecutionStatus.PENDING || execution.status === import_core43.ExecutionStatus.WAITING || execution.status === import_core43.ExecutionStatus.DELAYED;
17756
17944
  const formatDateTime = (timestamp) => {
17757
17945
  try {
17758
17946
  const date = new Date(timestamp);
@@ -17799,7 +17987,7 @@ function WithdrawExecutionItem({
17799
17987
  /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
17800
17988
  "img",
17801
17989
  {
17802
- src: execution.destination_token_metadata?.icon_url || (0, import_core42.getIconUrl)("/icons/tokens/svg/usdc.svg"),
17990
+ src: execution.destination_token_metadata?.icon_url || (0, import_core43.getIconUrl)("/icons/tokens/svg/usdc.svg"),
17803
17991
  alt: "Token",
17804
17992
  width: 36,
17805
17993
  height: 36,
@@ -18021,8 +18209,6 @@ function WithdrawConfirmingView({
18021
18209
  className: "uf-text-sm uf-text-center",
18022
18210
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
18023
18211
  children: [
18024
- txInfo.amount,
18025
- " ",
18026
18212
  txInfo.sourceTokenSymbol,
18027
18213
  " to",
18028
18214
  " ",
@@ -18058,7 +18244,7 @@ function WithdrawConfirmingView({
18058
18244
  }
18059
18245
 
18060
18246
  // src/components/withdrawals/WithdrawModal.tsx
18061
- var import_core43 = require("@unifold/core");
18247
+ var import_core44 = require("@unifold/core");
18062
18248
  var import_jsx_runtime61 = require("react/jsx-runtime");
18063
18249
  var t10 = i18n.withdrawModal;
18064
18250
  var getChainKey5 = (chainId, chainType) => `${chainType}:${chainId}`;
@@ -18149,25 +18335,25 @@ function WithdrawModal({
18149
18335
  onWithdrawError
18150
18336
  });
18151
18337
  const { data: allWithdrawalsData } = useExecutions(externalUserId, publishableKey, {
18152
- actionType: import_core43.ActionType.Withdraw,
18338
+ actionType: import_core44.ActionType.Withdraw,
18153
18339
  enabled: open,
18154
18340
  refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
18155
18341
  });
18156
18342
  const allWithdrawals = allWithdrawalsData?.data ?? [];
18157
18343
  const handleDepositWalletCreation = (0, import_react26.useCallback)(async (params) => {
18158
- const { data: wallets } = await (0, import_core43.createDepositAddress)(
18344
+ const { data: wallets } = await (0, import_core44.createDepositAddress)(
18159
18345
  {
18160
18346
  external_user_id: externalUserId,
18161
18347
  destination_chain_type: params.destinationChainType,
18162
18348
  destination_chain_id: params.destinationChainId,
18163
18349
  destination_token_address: params.destinationTokenAddress,
18164
18350
  recipient_address: params.recipientAddress,
18165
- action_type: import_core43.ActionType.Withdraw,
18351
+ action_type: import_core44.ActionType.Withdraw,
18166
18352
  source_chain_type: sourceChainType
18167
18353
  },
18168
18354
  publishableKey
18169
18355
  );
18170
- const depositWallet = (0, import_core43.getWalletByChainType)(wallets, sourceChainType);
18356
+ const depositWallet = (0, import_core44.getWalletByChainType)(wallets, sourceChainType);
18171
18357
  if (!depositWallet) {
18172
18358
  throw new Error(`No deposit wallet available for ${sourceChainType}`);
18173
18359
  }