@unifold/ui-react 0.1.68-beta.2 → 0.1.69

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
@@ -583,6 +583,7 @@ var DialogContent = React3.forwardRef(({ className, style, children, omitOverlay
583
583
  className: cn(
584
584
  portalContainer ? "uf-absolute" : "uf-fixed",
585
585
  "uf-bottom-0 uf-left-0 uf-right-0 uf-top-0 uf-z-50 uf-grid uf-w-full uf-max-w-full uf-h-full",
586
+ "focus:uf-outline-none focus-visible:uf-outline-none",
586
587
  !portalContainer && "sm:uf-left-[50%] sm:uf-top-[50%] sm:uf-bottom-auto sm:uf-right-auto sm:uf-translate-x-[-50%] sm:uf-translate-y-[-50%] sm:uf-h-auto",
587
588
  "uf-border uf-bg-background",
588
589
  omitOverlayEmbed ? "uf-gap-0 uf-p-0" : "uf-gap-4 uf-p-6 uf-shadow-lg uf-duration-200",
@@ -598,6 +599,14 @@ var DialogContent = React3.forwardRef(({ className, style, children, omitOverlay
598
599
  ),
599
600
  style: {
600
601
  "--uf-container-radius": `${components.container.borderRadius}px`,
602
+ // Radix traps focus and, when the focused control unmounts during an
603
+ // in-modal screen transition, moves focus onto this container. Modern
604
+ // browsers paint the default focus ring via `:focus-visible`, which
605
+ // flashes a highlight around the whole modal until focus settles on
606
+ // the next screen. Suppress it inline so it works regardless of the
607
+ // Tailwind build (the container is a programmatic focus target, not an
608
+ // interactive control, so it should never show a focus ring).
609
+ outline: "none",
601
610
  ...portalContainer ? { display: "flex", flexDirection: "column" } : {},
602
611
  ...style
603
612
  },
@@ -688,7 +697,9 @@ function GeoRestrictionScreen({ methodName, message }) {
688
697
  }
689
698
 
690
699
  // src/components/deposits/BuyWithCard.tsx
700
+ var React5 = __toESM(require("react"));
691
701
  var import_react8 = require("react");
702
+ var import_react_query3 = require("@tanstack/react-query");
692
703
  var import_lucide_react8 = require("lucide-react");
693
704
  var import_core9 = require("@unifold/core");
694
705
 
@@ -2676,13 +2687,25 @@ function BuyWithCard({
2676
2687
  wallets: externalWallets,
2677
2688
  assetCdnUrl,
2678
2689
  hideDepositFlowInfo = false,
2679
- hideDisplayDescription = false
2690
+ hideDisplayDescription = false,
2691
+ prefilledAmountUsd
2680
2692
  }) {
2681
2693
  const { colors: colors2, fonts, components } = useTheme();
2682
- const [amount, setAmount] = (0, import_react8.useState)("");
2694
+ const cleanedPrefilledAmountUsd = React5.useMemo(() => {
2695
+ if (!prefilledAmountUsd) return "";
2696
+ return prefilledAmountUsd.replace(/[^0-9.]/g, "");
2697
+ }, [prefilledAmountUsd]);
2698
+ const parsedPrefilledAmountUsd = React5.useMemo(() => {
2699
+ const parsed = parseFloat(cleanedPrefilledAmountUsd);
2700
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
2701
+ }, [cleanedPrefilledAmountUsd]);
2702
+ const shouldAutoConvertPrefilledRef = (0, import_react8.useRef)(!!cleanedPrefilledAmountUsd);
2703
+ const [amount, setAmount] = (0, import_react8.useState)(() => cleanedPrefilledAmountUsd);
2683
2704
  const [currency, setCurrency] = (0, import_react8.useState)("usd");
2684
2705
  const [hasManualCurrencySelection, setHasManualCurrencySelection] = (0, import_react8.useState)(false);
2685
- const [hasManualAmountEntry, setHasManualAmountEntry] = (0, import_react8.useState)(false);
2706
+ const [hasManualAmountEntry, setHasManualAmountEntry] = (0, import_react8.useState)(
2707
+ () => !!cleanedPrefilledAmountUsd
2708
+ );
2686
2709
  const [showCurrencyModal, setShowCurrencyModal] = (0, import_react8.useState)(false);
2687
2710
  const [quotes, setQuotes] = (0, import_react8.useState)([]);
2688
2711
  const [quotesLoading, setQuotesLoading] = (0, import_react8.useState)(false);
@@ -2739,6 +2762,71 @@ function BuyWithCard({
2739
2762
  const [preferredCurrencyCodes, setPreferredCurrencyCodes] = (0, import_react8.useState)([]);
2740
2763
  const [currenciesLoading, setCurrenciesLoading] = (0, import_react8.useState)(true);
2741
2764
  const [destinationToken, setDestinationToken] = (0, import_react8.useState)(null);
2765
+ (0, import_react8.useEffect)(() => {
2766
+ const hasPrefilledAmount = !!cleanedPrefilledAmountUsd;
2767
+ shouldAutoConvertPrefilledRef.current = hasPrefilledAmount;
2768
+ if (!hasPrefilledAmount) return;
2769
+ setAmount(cleanedPrefilledAmountUsd);
2770
+ setHasManualAmountEntry(true);
2771
+ }, [cleanedPrefilledAmountUsd]);
2772
+ const { data: fiatExchangeRatesResponse, isLoading: isFiatExchangeRatesLoading } = (0, import_react_query3.useQuery)({
2773
+ queryKey: ["fiat-exchange-rates", publishableKey],
2774
+ staleTime: 3e4,
2775
+ refetchInterval: 3e4,
2776
+ queryFn: async () => {
2777
+ try {
2778
+ return await (0, import_core9.getFiatExchangeRates)({}, publishableKey);
2779
+ } catch (error) {
2780
+ console.error("Error fetching fiat exchange rates:", error);
2781
+ return { base_currency: "usd", rates: {} };
2782
+ }
2783
+ }
2784
+ });
2785
+ const fiatExchangeRates = fiatExchangeRatesResponse?.rates ?? {};
2786
+ const convertAmountBetweenCurrencies = React5.useCallback(
2787
+ (rawAmount, fromCurrencyCode, toCurrencyCode) => {
2788
+ const parsedAmount = parseFloat(rawAmount);
2789
+ if (!Number.isFinite(parsedAmount) || parsedAmount <= 0) return null;
2790
+ const fromCode = fromCurrencyCode.toLowerCase();
2791
+ const toCode = toCurrencyCode.toLowerCase();
2792
+ const fromRate = fromCode === "usd" ? 1 : fiatExchangeRates[fromCode];
2793
+ const toRate = toCode === "usd" ? 1 : fiatExchangeRates[toCode];
2794
+ if (!Number.isFinite(fromRate) || fromRate <= 0) return null;
2795
+ if (!Number.isFinite(toRate) || toRate <= 0) return null;
2796
+ const usdAmount = parsedAmount / fromRate;
2797
+ return parseFloat((usdAmount * toRate).toFixed(2)).toString();
2798
+ },
2799
+ [fiatExchangeRates]
2800
+ );
2801
+ const getConvertedPrefilledAmount = React5.useCallback(
2802
+ (targetCurrencyCode) => {
2803
+ if (!parsedPrefilledAmountUsd) return null;
2804
+ const normalizedTargetCurrency = targetCurrencyCode.toLowerCase();
2805
+ const rate = normalizedTargetCurrency === "usd" ? 1 : fiatExchangeRates[normalizedTargetCurrency];
2806
+ if (!Number.isFinite(rate) || rate <= 0) return null;
2807
+ return parseFloat((parsedPrefilledAmountUsd * rate).toFixed(2)).toString();
2808
+ },
2809
+ [parsedPrefilledAmountUsd, fiatExchangeRates]
2810
+ );
2811
+ (0, import_react8.useEffect)(() => {
2812
+ if (!cleanedPrefilledAmountUsd || !shouldAutoConvertPrefilledRef.current) return;
2813
+ const convertedAmount = getConvertedPrefilledAmount(currency);
2814
+ if (!convertedAmount) {
2815
+ if (isFiatExchangeRatesLoading) return;
2816
+ const targetCurrency = currency.toLowerCase();
2817
+ if (targetCurrency !== "usd") {
2818
+ setCurrency("usd");
2819
+ }
2820
+ return;
2821
+ }
2822
+ setAmount(convertedAmount);
2823
+ setHasManualAmountEntry(true);
2824
+ }, [
2825
+ cleanedPrefilledAmountUsd,
2826
+ currency,
2827
+ getConvertedPrefilledAmount,
2828
+ isFiatExchangeRatesLoading
2829
+ ]);
2742
2830
  const depositWalletId = defaultToken ? (0, import_core9.getWalletByChainType)(wallets, defaultToken.destination_token_metadata.chain_type)?.id : void 0;
2743
2831
  const { executions, isPolling, showWaitingUi } = useDepositPolling({
2744
2832
  userId,
@@ -2769,6 +2857,7 @@ function BuyWithCard({
2769
2857
  }, [publishableKey]);
2770
2858
  (0, import_react8.useEffect)(() => {
2771
2859
  if (hasManualCurrencySelection) return;
2860
+ if (hasManualAmountEntry && !shouldAutoConvertPrefilledRef.current) return;
2772
2861
  if (fiatCurrencies.length === 0 || !userIpInfo?.alpha2) return;
2773
2862
  const userCountryCode = userIpInfo.alpha2;
2774
2863
  const matchingCurrency = fiatCurrencies.find((c) => c.country_codes.includes(userCountryCode));
@@ -2787,7 +2876,15 @@ function BuyWithCard({
2787
2876
  const prevCurrencyRef = (0, import_react8.useRef)(null);
2788
2877
  (0, import_react8.useEffect)(() => {
2789
2878
  if (fiatCurrencies.length === 0) return;
2879
+ if (shouldAutoConvertPrefilledRef.current) {
2880
+ prevCurrencyRef.current = currency;
2881
+ return;
2882
+ }
2790
2883
  if (prevCurrencyRef.current !== null && prevCurrencyRef.current !== currency) {
2884
+ if (hasManualAmountEntry) {
2885
+ prevCurrencyRef.current = currency;
2886
+ return;
2887
+ }
2791
2888
  const currentCurrency = fiatCurrencies.find(
2792
2889
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
2793
2890
  );
@@ -2796,7 +2893,7 @@ function BuyWithCard({
2796
2893
  }
2797
2894
  }
2798
2895
  prevCurrencyRef.current = currency;
2799
- }, [currency]);
2896
+ }, [currency, fiatCurrencies, hasManualAmountEntry]);
2800
2897
  (0, import_react8.useEffect)(() => {
2801
2898
  async function fetchDestinationToken() {
2802
2899
  try {
@@ -2973,6 +3070,7 @@ function BuyWithCard({
2973
3070
  return () => clearInterval(timer);
2974
3071
  }, [quotes.length, amount]);
2975
3072
  const handleAmountChange = (value) => {
3073
+ shouldAutoConvertPrefilledRef.current = false;
2976
3074
  if (value === "") {
2977
3075
  setAmount(value);
2978
3076
  setHasManualAmountEntry(true);
@@ -2986,6 +3084,7 @@ function BuyWithCard({
2986
3084
  }
2987
3085
  };
2988
3086
  const handleQuickAmount = (quickAmount) => {
3087
+ shouldAutoConvertPrefilledRef.current = false;
2989
3088
  setAmount(quickAmount.toString());
2990
3089
  setHasManualAmountEntry(true);
2991
3090
  };
@@ -3589,8 +3688,43 @@ function BuyWithCard({
3589
3688
  preferredCurrencyCodes,
3590
3689
  selectedCurrency: currency,
3591
3690
  onSelectCurrency: (currencyCode) => {
3592
- setCurrency(currencyCode.toLowerCase());
3691
+ const nextCurrency = currencyCode.toLowerCase();
3692
+ if (nextCurrency === currency.toLowerCase()) {
3693
+ setHasManualCurrencySelection(true);
3694
+ return;
3695
+ }
3696
+ const currentCurrency = currency;
3593
3697
  setHasManualCurrencySelection(true);
3698
+ if (shouldAutoConvertPrefilledRef.current) {
3699
+ const convertedAmount = getConvertedPrefilledAmount(nextCurrency);
3700
+ if (convertedAmount) {
3701
+ setCurrency(nextCurrency);
3702
+ setAmount(convertedAmount);
3703
+ setHasManualAmountEntry(true);
3704
+ } else {
3705
+ if (isFiatExchangeRatesLoading) return;
3706
+ const fallbackUsdAmount = getConvertedPrefilledAmount("usd");
3707
+ setCurrency("usd");
3708
+ if (fallbackUsdAmount) {
3709
+ setAmount(fallbackUsdAmount);
3710
+ setHasManualAmountEntry(true);
3711
+ }
3712
+ }
3713
+ return;
3714
+ }
3715
+ if (hasManualAmountEntry && amount) {
3716
+ const convertedAmount = convertAmountBetweenCurrencies(
3717
+ amount,
3718
+ currentCurrency,
3719
+ nextCurrency
3720
+ );
3721
+ if (convertedAmount) {
3722
+ setCurrency(nextCurrency);
3723
+ setAmount(convertedAmount);
3724
+ }
3725
+ return;
3726
+ }
3727
+ setCurrency(nextCurrency);
3594
3728
  },
3595
3729
  themeClass
3596
3730
  }
@@ -3609,7 +3743,7 @@ function BuyWithCard({
3609
3743
  }
3610
3744
 
3611
3745
  // src/components/deposits/BuyWithApplePay.tsx
3612
- var React5 = __toESM(require("react"));
3746
+ var React6 = __toESM(require("react"));
3613
3747
  var import_react10 = require("react");
3614
3748
  var import_lucide_react9 = require("lucide-react");
3615
3749
  var import_core13 = require("@unifold/core");
@@ -3656,13 +3790,13 @@ function isOnrampTokenFresh(contact) {
3656
3790
  }
3657
3791
 
3658
3792
  // src/hooks/use-coinbase-legal-agreements.ts
3659
- var import_react_query3 = require("@tanstack/react-query");
3793
+ var import_react_query4 = require("@tanstack/react-query");
3660
3794
  var import_core10 = require("@unifold/core");
3661
3795
  function useCoinbaseLegalAgreements({
3662
3796
  publishableKey,
3663
3797
  enabled = true
3664
3798
  }) {
3665
- return (0, import_react_query3.useQuery)({
3799
+ return (0, import_react_query4.useQuery)({
3666
3800
  queryKey: ["unifold", "coinbaseLegalAgreements", publishableKey],
3667
3801
  queryFn: () => (0, import_core10.getCoinbaseLegalAgreements)(publishableKey),
3668
3802
  enabled: enabled && !!publishableKey,
@@ -3678,7 +3812,7 @@ function useCoinbaseLegalAgreements({
3678
3812
  var import_react9 = require("react");
3679
3813
 
3680
3814
  // src/hooks/use-apple-pay-limits.ts
3681
- var import_react_query4 = require("@tanstack/react-query");
3815
+ var import_react_query5 = require("@tanstack/react-query");
3682
3816
  var import_core11 = require("@unifold/core");
3683
3817
  var US_E164_REGEX = /^\+1\d{10}$/;
3684
3818
  function useApplePayLimits({
@@ -3687,7 +3821,7 @@ function useApplePayLimits({
3687
3821
  enabled = true
3688
3822
  }) {
3689
3823
  const phoneValid = US_E164_REGEX.test(phone);
3690
- return (0, import_react_query4.useQuery)({
3824
+ return (0, import_react_query5.useQuery)({
3691
3825
  queryKey: ["unifold", "applePayLimits", phone, publishableKey],
3692
3826
  queryFn: ({ signal }) => (0, import_core11.getCoinbaseApplePayLimits)(phone, publishableKey, signal),
3693
3827
  enabled: enabled && phoneValid && !!publishableKey,
@@ -3777,7 +3911,7 @@ function useApplePayInitialScreen({
3777
3911
  }
3778
3912
 
3779
3913
  // src/hooks/use-default-onramp-token.ts
3780
- var import_react_query5 = require("@tanstack/react-query");
3914
+ var import_react_query6 = require("@tanstack/react-query");
3781
3915
  var import_core12 = require("@unifold/core");
3782
3916
  function useDefaultOnrampToken({
3783
3917
  publishableKey,
@@ -3793,7 +3927,7 @@ function useDefaultOnrampToken({
3793
3927
  isLoading,
3794
3928
  isError,
3795
3929
  error
3796
- } = (0, import_react_query5.useQuery)({
3930
+ } = (0, import_react_query6.useQuery)({
3797
3931
  queryKey: [
3798
3932
  "unifold",
3799
3933
  "defaultOnrampToken",
@@ -3870,7 +4004,7 @@ function parseCoinbasePostMessage(raw) {
3870
4004
  } : void 0
3871
4005
  };
3872
4006
  }
3873
- var BuyWithApplePay = React5.forwardRef(
4007
+ var BuyWithApplePay = React6.forwardRef(
3874
4008
  function BuyWithApplePay2({
3875
4009
  userId,
3876
4010
  publishableKey,
@@ -4029,7 +4163,7 @@ var BuyWithApplePay = React5.forwardRef(
4029
4163
  popupRef.current = null;
4030
4164
  };
4031
4165
  }, []);
4032
- React5.useImperativeHandle(
4166
+ React6.useImperativeHandle(
4033
4167
  ref,
4034
4168
  () => ({
4035
4169
  requestBack: () => {
@@ -5339,7 +5473,7 @@ function LegalDisclaimer({ legalAgreements, loading }) {
5339
5473
  children: [
5340
5474
  "By continuing, you agree to Coinbase's",
5341
5475
  " ",
5342
- agreements.map((a, idx, arr) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(React5.Fragment, { children: [
5476
+ agreements.map((a, idx, arr) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(React6.Fragment, { children: [
5343
5477
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5344
5478
  "a",
5345
5479
  {
@@ -5775,10 +5909,10 @@ function useIsMobileViewport() {
5775
5909
  }
5776
5910
 
5777
5911
  // src/hooks/use-cashapp-limits.ts
5778
- var import_react_query6 = require("@tanstack/react-query");
5912
+ var import_react_query7 = require("@tanstack/react-query");
5779
5913
  var import_core15 = require("@unifold/core");
5780
5914
  function useCashAppLimits({ publishableKey, currency = "usd" }) {
5781
- return (0, import_react_query6.useQuery)({
5915
+ return (0, import_react_query7.useQuery)({
5782
5916
  queryKey: ["unifold", "cashAppLimits", currency, publishableKey],
5783
5917
  queryFn: () => (0, import_core15.getCashAppLimits)(currency, publishableKey),
5784
5918
  enabled: !!publishableKey,
@@ -5794,6 +5928,7 @@ var POLL_INTERVAL_MS2 = 5e3;
5794
5928
  var FALLBACK_MIN_USD = 5;
5795
5929
  var SUGGESTED_AMOUNTS = [25, 50, 100];
5796
5930
  var t3 = i18n.depositModal.cashApp;
5931
+ var sanitizePrefilledUsd = (value) => value?.replace(/[^0-9.]/g, "") ?? "";
5797
5932
  function PayWithCashApp({
5798
5933
  userId,
5799
5934
  publishableKey,
@@ -5808,6 +5943,7 @@ function PayWithCashApp({
5808
5943
  onEvent,
5809
5944
  onDepositSuccess,
5810
5945
  onDepositError,
5946
+ prefilledAmountUsd,
5811
5947
  wallets = []
5812
5948
  }) {
5813
5949
  const { colors: colors2, fonts, components } = useTheme();
@@ -5823,7 +5959,7 @@ function PayWithCashApp({
5823
5959
  const { data: limits, isLoading: limitsLoading } = useCashAppLimits({ publishableKey });
5824
5960
  const minUsd = limits?.minimum_amount ?? FALLBACK_MIN_USD;
5825
5961
  const maxUsd = limits?.maximum_amount ?? null;
5826
- const [amount, setAmount] = (0, import_react14.useState)("");
5962
+ const [amount, setAmount] = (0, import_react14.useState)(() => sanitizePrefilledUsd(prefilledAmountUsd));
5827
5963
  const [loading, setLoading] = (0, import_react14.useState)(false);
5828
5964
  const [session, setSession] = (0, import_react14.useState)(null);
5829
5965
  const [status, setStatus] = (0, import_react14.useState)("pending");
@@ -5946,6 +6082,13 @@ function PayWithCashApp({
5946
6082
  return () => clearInterval(interval);
5947
6083
  }, [session, view, status, publishableKey, onDepositSuccess, onDepositError]);
5948
6084
  const [softExpired, setSoftExpired] = (0, import_react14.useState)(false);
6085
+ (0, import_react14.useEffect)(() => {
6086
+ if (!prefilledAmountUsd) return;
6087
+ const cleaned = sanitizePrefilledUsd(prefilledAmountUsd);
6088
+ if (!cleaned) return;
6089
+ setAmount(cleaned);
6090
+ onAmountChange?.(cleaned);
6091
+ }, [prefilledAmountUsd, onAmountChange]);
5949
6092
  (0, import_react14.useEffect)(() => {
5950
6093
  if (!session?.expires_at || view !== "payment") return;
5951
6094
  const expiresMs = new Date(session.expires_at).getTime();
@@ -6301,7 +6444,7 @@ var import_lucide_react12 = require("lucide-react");
6301
6444
  var import_core18 = require("@unifold/core");
6302
6445
 
6303
6446
  // src/hooks/use-bank-transfer-providers.ts
6304
- var import_react_query7 = require("@tanstack/react-query");
6447
+ var import_react_query8 = require("@tanstack/react-query");
6305
6448
  var import_core17 = require("@unifold/core");
6306
6449
  function useBankTransferProviders({
6307
6450
  publishableKey,
@@ -6309,7 +6452,7 @@ function useBankTransferProviders({
6309
6452
  countryCode
6310
6453
  }) {
6311
6454
  const normalizedCountry = countryCode?.toUpperCase();
6312
- const { data: providers, isLoading } = (0, import_react_query7.useQuery)({
6455
+ const { data: providers, isLoading } = (0, import_react_query8.useQuery)({
6313
6456
  queryKey: ["unifold", "bankTransferProviders", publishableKey, normalizedCountry ?? null],
6314
6457
  queryFn: () => (0, import_core17.getBankTransferProviders)(publishableKey, { countryCode: normalizedCountry }),
6315
6458
  enabled,
@@ -6350,7 +6493,8 @@ function BankTransfer({
6350
6493
  assetCdnUrl,
6351
6494
  onDepositSuccess,
6352
6495
  onEvent,
6353
- onDepositError
6496
+ onDepositError,
6497
+ prefilledAmountUsd
6354
6498
  }) {
6355
6499
  const { colors: colors2, fonts, components } = useTheme();
6356
6500
  const [internalView, setInternalView] = (0, import_react15.useState)("providers");
@@ -6360,6 +6504,10 @@ function BankTransfer({
6360
6504
  const [requestBase, setRequestBase] = (0, import_react15.useState)(null);
6361
6505
  const [activeRequest, setActiveRequest] = (0, import_react15.useState)(null);
6362
6506
  const [amount, setAmount] = (0, import_react15.useState)("");
6507
+ const [fiatExchangeRates, setFiatExchangeRates] = (0, import_react15.useState)({
6508
+ usd: 1
6509
+ });
6510
+ const providerSelectionRequestIdRef = (0, import_react15.useRef)(0);
6363
6511
  const currentView = externalView ?? internalView;
6364
6512
  const setView = (v) => {
6365
6513
  setInternalView(v);
@@ -6409,7 +6557,38 @@ function BankTransfer({
6409
6557
  () => destinationTokenSymbol?.toUpperCase() ?? defaultToken?.destination_token_metadata?.symbol?.toUpperCase() ?? defaultToken?.destination_currency?.toUpperCase() ?? "USDC",
6410
6558
  [destinationTokenSymbol, defaultToken]
6411
6559
  );
6412
- const handleProviderClick = (provider) => {
6560
+ const resolvePrefilledSourceAmount = (0, import_react15.useCallback)(
6561
+ async (sourceCurrencyCode) => {
6562
+ const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
6563
+ if (!cleanedPrefilled) return "";
6564
+ const prefilledUsd = parseFloat(cleanedPrefilled);
6565
+ if (!Number.isFinite(prefilledUsd) || prefilledUsd <= 0) return "";
6566
+ const sourceCurrency2 = sourceCurrencyCode.toLowerCase();
6567
+ let rate = sourceCurrency2 === "usd" ? 1 : fiatExchangeRates[sourceCurrency2];
6568
+ if ((!rate || rate <= 0) && sourceCurrency2 !== "usd") {
6569
+ try {
6570
+ const response = await (0, import_core18.getFiatExchangeRates)({}, publishableKey);
6571
+ if (response?.rates) {
6572
+ setFiatExchangeRates((prev) => ({
6573
+ ...prev,
6574
+ ...response.rates,
6575
+ usd: 1
6576
+ }));
6577
+ }
6578
+ const fetchedRate = response.rates?.[sourceCurrency2];
6579
+ if (Number.isFinite(fetchedRate) && fetchedRate > 0) {
6580
+ rate = fetchedRate;
6581
+ }
6582
+ } catch (error) {
6583
+ console.error("Error fetching fiat exchange rates for bank transfer:", error);
6584
+ }
6585
+ }
6586
+ if (!rate || rate <= 0) return sourceCurrency2 === "usd" ? cleanedPrefilled : "";
6587
+ return parseFloat((prefilledUsd * rate).toFixed(2)).toString();
6588
+ },
6589
+ [fiatExchangeRates, prefilledAmountUsd, publishableKey]
6590
+ );
6591
+ const handleProviderClick = async (provider) => {
6413
6592
  if (!provider.enabled) return;
6414
6593
  setSessionError(null);
6415
6594
  if (!defaultToken) {
@@ -6428,6 +6607,7 @@ function BankTransfer({
6428
6607
  });
6429
6608
  return;
6430
6609
  }
6610
+ const requestId = ++providerSelectionRequestIdRef.current;
6431
6611
  setRequestBase({
6432
6612
  service_provider: provider.service_provider,
6433
6613
  country_code: (userIpInfo?.alpha2 || "DE").toUpperCase(),
@@ -6441,7 +6621,10 @@ function BankTransfer({
6441
6621
  payment_method: provider.payment_methods[0]
6442
6622
  });
6443
6623
  setActiveProvider(provider);
6444
- setAmount("100");
6624
+ const convertedPrefilled = await resolvePrefilledSourceAmount(provider.source_currency);
6625
+ if (requestId !== providerSelectionRequestIdRef.current) return;
6626
+ const hasPrefilledAmount = !!prefilledAmountUsd?.replace(/[^0-9.]/g, "");
6627
+ setAmount(hasPrefilledAmount ? convertedPrefilled : "100");
6445
6628
  setView("amount");
6446
6629
  };
6447
6630
  const handleAmountChange = (value) => {
@@ -6539,7 +6722,7 @@ function BankTransfer({
6539
6722
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
6540
6723
  "button",
6541
6724
  {
6542
- onClick: () => handleProviderClick(provider),
6725
+ onClick: () => void handleProviderClick(provider),
6543
6726
  onMouseEnter: () => !disabled && setHoveredId(provider.service_provider),
6544
6727
  onMouseLeave: () => setHoveredId(null),
6545
6728
  disabled,
@@ -7108,7 +7291,7 @@ function DepositExecutionItem({ execution, onClick }) {
7108
7291
  }
7109
7292
 
7110
7293
  // src/components/deposits/buttons/TransferCryptoButton.tsx
7111
- var React6 = __toESM(require("react"));
7294
+ var React7 = __toESM(require("react"));
7112
7295
  var import_lucide_react14 = require("lucide-react");
7113
7296
  var import_jsx_runtime19 = require("react/jsx-runtime");
7114
7297
  function TransferCryptoButton({
@@ -7118,9 +7301,9 @@ function TransferCryptoButton({
7118
7301
  featuredTokens
7119
7302
  }) {
7120
7303
  const { colors: colors2, fonts, components } = useTheme();
7121
- const [isHovered, setIsHovered] = React6.useState(false);
7122
- const [isTouchDevice, setIsTouchDevice] = React6.useState(false);
7123
- React6.useEffect(() => {
7304
+ const [isHovered, setIsHovered] = React7.useState(false);
7305
+ const [isTouchDevice, setIsTouchDevice] = React7.useState(false);
7306
+ React7.useEffect(() => {
7124
7307
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7125
7308
  }, []);
7126
7309
  const sortedTokens = featuredTokens ? [...featuredTokens].sort((a, b) => a.position - b.position) : [];
@@ -7195,7 +7378,7 @@ function TransferCryptoButton({
7195
7378
  }
7196
7379
 
7197
7380
  // src/components/deposits/buttons/DepositWithCardButton.tsx
7198
- var React7 = __toESM(require("react"));
7381
+ var React8 = __toESM(require("react"));
7199
7382
  var import_lucide_react15 = require("lucide-react");
7200
7383
  var import_jsx_runtime20 = require("react/jsx-runtime");
7201
7384
  function DepositWithCardButton({
@@ -7205,9 +7388,9 @@ function DepositWithCardButton({
7205
7388
  paymentNetworks
7206
7389
  }) {
7207
7390
  const { colors: colors2, fonts, components } = useTheme();
7208
- const [isHovered, setIsHovered] = React7.useState(false);
7209
- const [isTouchDevice, setIsTouchDevice] = React7.useState(false);
7210
- React7.useEffect(() => {
7391
+ const [isHovered, setIsHovered] = React8.useState(false);
7392
+ const [isTouchDevice, setIsTouchDevice] = React8.useState(false);
7393
+ React8.useEffect(() => {
7211
7394
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7212
7395
  }, []);
7213
7396
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
@@ -7280,7 +7463,7 @@ function DepositWithCardButton({
7280
7463
  }
7281
7464
 
7282
7465
  // src/components/deposits/buttons/PayWithExchangeButton.tsx
7283
- var React8 = __toESM(require("react"));
7466
+ var React9 = __toESM(require("react"));
7284
7467
  var import_lucide_react16 = require("lucide-react");
7285
7468
  var import_jsx_runtime21 = require("react/jsx-runtime");
7286
7469
  function PayWithExchangeButton({
@@ -7291,9 +7474,9 @@ function PayWithExchangeButton({
7291
7474
  loading = false
7292
7475
  }) {
7293
7476
  const { colors: colors2, fonts, components } = useTheme();
7294
- const [isHovered, setIsHovered] = React8.useState(false);
7295
- const [isTouchDevice, setIsTouchDevice] = React8.useState(false);
7296
- React8.useEffect(() => {
7477
+ const [isHovered, setIsHovered] = React9.useState(false);
7478
+ const [isTouchDevice, setIsTouchDevice] = React9.useState(false);
7479
+ React9.useEffect(() => {
7297
7480
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7298
7481
  }, []);
7299
7482
  if (loading) {
@@ -7372,11 +7555,11 @@ function PayWithExchangeButton({
7372
7555
  }
7373
7556
 
7374
7557
  // src/components/deposits/buttons/ConnectExchangeButton.tsx
7375
- var React10 = __toESM(require("react"));
7558
+ var React11 = __toESM(require("react"));
7376
7559
  var import_lucide_react17 = require("lucide-react");
7377
7560
 
7378
7561
  // src/components/shared/button.tsx
7379
- var React9 = __toESM(require("react"));
7562
+ var React10 = __toESM(require("react"));
7380
7563
  var import_react_slot = require("@radix-ui/react-slot");
7381
7564
  var import_class_variance_authority = require("class-variance-authority");
7382
7565
  var import_jsx_runtime22 = require("react/jsx-runtime");
@@ -7405,11 +7588,11 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
7405
7588
  }
7406
7589
  }
7407
7590
  );
7408
- var Button = React9.forwardRef(
7591
+ var Button = React10.forwardRef(
7409
7592
  ({ className, variant, size, asChild = false, style, ...props }, ref) => {
7410
7593
  const Comp = asChild ? import_react_slot.Slot : "button";
7411
7594
  const { components, fonts } = useTheme();
7412
- const themeStyle = React9.useMemo(() => {
7595
+ const themeStyle = React10.useMemo(() => {
7413
7596
  const baseStyle = { ...style };
7414
7597
  if (variant === "default" || !variant) {
7415
7598
  baseStyle.backgroundColor = components.button.primaryBackground;
@@ -7447,9 +7630,9 @@ function ConnectExchangeButton({
7447
7630
  connectedExchange
7448
7631
  }) {
7449
7632
  const { colors: colors2, fonts, components } = useTheme();
7450
- const [isHovered, setIsHovered] = React10.useState(false);
7451
- const [isTouchDevice, setIsTouchDevice] = React10.useState(false);
7452
- React10.useEffect(() => {
7633
+ const [isHovered, setIsHovered] = React11.useState(false);
7634
+ const [isTouchDevice, setIsTouchDevice] = React11.useState(false);
7635
+ React11.useEffect(() => {
7453
7636
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7454
7637
  }, []);
7455
7638
  const isConnected = connectedExchange != null;
@@ -7589,7 +7772,7 @@ function ConnectExchangeButton({
7589
7772
  }
7590
7773
 
7591
7774
  // src/components/deposits/buttons/DepositTrackerButton.tsx
7592
- var React11 = __toESM(require("react"));
7775
+ var React12 = __toESM(require("react"));
7593
7776
  var import_lucide_react18 = require("lucide-react");
7594
7777
  var import_jsx_runtime24 = require("react/jsx-runtime");
7595
7778
  function DepositTrackerButton({
@@ -7599,9 +7782,9 @@ function DepositTrackerButton({
7599
7782
  badge
7600
7783
  }) {
7601
7784
  const { colors: colors2, fonts, components } = useTheme();
7602
- const [isHovered, setIsHovered] = React11.useState(false);
7603
- const [isTouchDevice, setIsTouchDevice] = React11.useState(false);
7604
- React11.useEffect(() => {
7785
+ const [isHovered, setIsHovered] = React12.useState(false);
7786
+ const [isTouchDevice, setIsTouchDevice] = React12.useState(false);
7787
+ React12.useEffect(() => {
7605
7788
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7606
7789
  }, []);
7607
7790
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
@@ -7672,14 +7855,14 @@ function DepositTrackerButton({
7672
7855
  }
7673
7856
 
7674
7857
  // src/components/deposits/buttons/CashAppButton.tsx
7675
- var React12 = __toESM(require("react"));
7858
+ var React13 = __toESM(require("react"));
7676
7859
  var import_lucide_react19 = require("lucide-react");
7677
7860
  var import_jsx_runtime25 = require("react/jsx-runtime");
7678
7861
  function CashAppButton({ onClick, title, subtitle, iconUrl }) {
7679
7862
  const { colors: colors2, fonts, components } = useTheme();
7680
- const [isHovered, setIsHovered] = React12.useState(false);
7681
- const [isTouchDevice, setIsTouchDevice] = React12.useState(false);
7682
- React12.useEffect(() => {
7863
+ const [isHovered, setIsHovered] = React13.useState(false);
7864
+ const [isTouchDevice, setIsTouchDevice] = React13.useState(false);
7865
+ React13.useEffect(() => {
7683
7866
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7684
7867
  }, []);
7685
7868
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
@@ -7743,7 +7926,7 @@ function CashAppButton({ onClick, title, subtitle, iconUrl }) {
7743
7926
  }
7744
7927
 
7745
7928
  // src/components/deposits/buttons/ApplePayButton.tsx
7746
- var React13 = __toESM(require("react"));
7929
+ var React14 = __toESM(require("react"));
7747
7930
  var import_lucide_react20 = require("lucide-react");
7748
7931
  var import_jsx_runtime26 = require("react/jsx-runtime");
7749
7932
  function AppleLogo({ className, style }) {
@@ -7768,9 +7951,9 @@ function AppleLogo({ className, style }) {
7768
7951
  }
7769
7952
  function ApplePayButton({ onClick, title, subtitle }) {
7770
7953
  const { colors: colors2, fonts, components } = useTheme();
7771
- const [isHovered, setIsHovered] = React13.useState(false);
7772
- const [isTouchDevice, setIsTouchDevice] = React13.useState(false);
7773
- React13.useEffect(() => {
7954
+ const [isHovered, setIsHovered] = React14.useState(false);
7955
+ const [isTouchDevice, setIsTouchDevice] = React14.useState(false);
7956
+ React14.useEffect(() => {
7774
7957
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7775
7958
  }, []);
7776
7959
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
@@ -7827,7 +8010,7 @@ function ApplePayButton({ onClick, title, subtitle }) {
7827
8010
  }
7828
8011
 
7829
8012
  // src/components/deposits/buttons/BankTransferButton.tsx
7830
- var React14 = __toESM(require("react"));
8013
+ var React15 = __toESM(require("react"));
7831
8014
  var import_lucide_react21 = require("lucide-react");
7832
8015
  var import_jsx_runtime27 = require("react/jsx-runtime");
7833
8016
  function BankTransferButton({
@@ -7837,9 +8020,9 @@ function BankTransferButton({
7837
8020
  comingSoon = false
7838
8021
  }) {
7839
8022
  const { colors: colors2, fonts, components } = useTheme();
7840
- const [isHovered, setIsHovered] = React14.useState(false);
7841
- const [isTouchDevice, setIsTouchDevice] = React14.useState(false);
7842
- React14.useEffect(() => {
8023
+ const [isHovered, setIsHovered] = React15.useState(false);
8024
+ const [isTouchDevice, setIsTouchDevice] = React15.useState(false);
8025
+ React15.useEffect(() => {
7843
8026
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7844
8027
  }, []);
7845
8028
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
@@ -7897,7 +8080,7 @@ function BankTransferButton({
7897
8080
  }
7898
8081
 
7899
8082
  // src/components/deposits/buttons/BrowserWalletButton.tsx
7900
- var React28 = __toESM(require("react"));
8083
+ var React29 = __toESM(require("react"));
7901
8084
  var import_lucide_react22 = require("lucide-react");
7902
8085
  var import_core20 = require("@unifold/core");
7903
8086
 
@@ -7952,7 +8135,7 @@ function collectAllEip6963EthProviders() {
7952
8135
  }
7953
8136
 
7954
8137
  // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
7955
- var React15 = __toESM(require("react"));
8138
+ var React16 = __toESM(require("react"));
7956
8139
 
7957
8140
  // src/components/deposits/browser-wallets/detectConnectedWallet.ts
7958
8141
  function identifyEthWallet(provider, hint) {
@@ -8103,18 +8286,18 @@ async function detectConnectedBrowserWallet(chainType) {
8103
8286
  // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
8104
8287
  function useDetectedBrowserWallet(opts = {}) {
8105
8288
  const { chainType, enabled = true, onDisconnect } = opts;
8106
- const [wallet, setWallet] = React15.useState(null);
8107
- const [isLoading, setIsLoading] = React15.useState(enabled);
8108
- const [eip6963ProviderCount, setEip6963ProviderCount] = React15.useState(0);
8109
- const onDisconnectRef = React15.useRef(onDisconnect);
8289
+ const [wallet, setWallet] = React16.useState(null);
8290
+ const [isLoading, setIsLoading] = React16.useState(enabled);
8291
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React16.useState(0);
8292
+ const onDisconnectRef = React16.useRef(onDisconnect);
8110
8293
  onDisconnectRef.current = onDisconnect;
8111
- React15.useEffect(() => {
8294
+ React16.useEffect(() => {
8112
8295
  const store = getEip6963Store();
8113
8296
  if (!store) return;
8114
8297
  setEip6963ProviderCount(store.getProviders().length);
8115
8298
  return store.subscribe((providers) => setEip6963ProviderCount(providers.length));
8116
8299
  }, []);
8117
- React15.useEffect(() => {
8300
+ React16.useEffect(() => {
8118
8301
  if (!enabled) {
8119
8302
  setWallet(null);
8120
8303
  setIsLoading(false);
@@ -8258,10 +8441,10 @@ async function disconnectInjectedBrowserWallet(wallet) {
8258
8441
  }
8259
8442
 
8260
8443
  // src/resources/icons/MetamaskIcon.tsx
8261
- var React16 = __toESM(require("react"));
8444
+ var React17 = __toESM(require("react"));
8262
8445
  var import_jsx_runtime28 = require("react/jsx-runtime");
8263
8446
  function MetamaskIcon({ size = 24, className, variant = "color" }) {
8264
- const id = React16.useId();
8447
+ const id = React17.useId();
8265
8448
  if (variant === "light" || variant === "dark") {
8266
8449
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
8267
8450
  "svg",
@@ -8383,10 +8566,10 @@ function MetamaskIcon({ size = 24, className, variant = "color" }) {
8383
8566
  }
8384
8567
 
8385
8568
  // src/resources/icons/PhantomIcon.tsx
8386
- var React17 = __toESM(require("react"));
8569
+ var React18 = __toESM(require("react"));
8387
8570
  var import_jsx_runtime29 = require("react/jsx-runtime");
8388
8571
  function PhantomIcon({ size = 24, className, variant = "color" }) {
8389
- const id = React17.useId();
8572
+ const id = React18.useId();
8390
8573
  if (variant === "light") {
8391
8574
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
8392
8575
  "svg",
@@ -8454,10 +8637,10 @@ function PhantomIcon({ size = 24, className, variant = "color" }) {
8454
8637
  }
8455
8638
 
8456
8639
  // src/resources/icons/CoinbaseIcon.tsx
8457
- var React18 = __toESM(require("react"));
8640
+ var React19 = __toESM(require("react"));
8458
8641
  var import_jsx_runtime30 = require("react/jsx-runtime");
8459
8642
  function CoinbaseIcon({ size = 24, className, variant = "color" }) {
8460
- const id = React18.useId();
8643
+ const id = React19.useId();
8461
8644
  if (variant === "light") {
8462
8645
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
8463
8646
  "svg",
@@ -8538,10 +8721,10 @@ function CoinbaseIcon({ size = 24, className, variant = "color" }) {
8538
8721
  }
8539
8722
 
8540
8723
  // src/resources/icons/RabbyIcon.tsx
8541
- var React19 = __toESM(require("react"));
8724
+ var React20 = __toESM(require("react"));
8542
8725
  var import_jsx_runtime31 = require("react/jsx-runtime");
8543
8726
  function RabbyIcon({ size = 24, className, variant = "color" }) {
8544
- const id = React19.useId();
8727
+ const id = React20.useId();
8545
8728
  if (variant === "light") {
8546
8729
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
8547
8730
  "svg",
@@ -8889,10 +9072,10 @@ function RabbyIcon({ size = 24, className, variant = "color" }) {
8889
9072
  }
8890
9073
 
8891
9074
  // src/resources/icons/RainbowIcon.tsx
8892
- var React20 = __toESM(require("react"));
9075
+ var React21 = __toESM(require("react"));
8893
9076
  var import_jsx_runtime32 = require("react/jsx-runtime");
8894
9077
  function RainbowIcon({ size = 24, className, variant = "color" }) {
8895
- const id = React20.useId();
9078
+ const id = React21.useId();
8896
9079
  if (variant === "light") {
8897
9080
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
8898
9081
  "svg",
@@ -9307,10 +9490,10 @@ function RainbowIcon({ size = 24, className, variant = "color" }) {
9307
9490
  }
9308
9491
 
9309
9492
  // src/resources/icons/TrustIcon.tsx
9310
- var React21 = __toESM(require("react"));
9493
+ var React22 = __toESM(require("react"));
9311
9494
  var import_jsx_runtime33 = require("react/jsx-runtime");
9312
9495
  function TrustIcon({ size = 24, className, variant = "color" }) {
9313
- const id = React21.useId();
9496
+ const id = React22.useId();
9314
9497
  if (variant === "light") {
9315
9498
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
9316
9499
  "svg",
@@ -9394,10 +9577,10 @@ function TrustIcon({ size = 24, className, variant = "color" }) {
9394
9577
  }
9395
9578
 
9396
9579
  // src/resources/icons/OkxIcon.tsx
9397
- var React22 = __toESM(require("react"));
9580
+ var React23 = __toESM(require("react"));
9398
9581
  var import_jsx_runtime34 = require("react/jsx-runtime");
9399
9582
  function OkxIcon({ size = 24, className, variant = "color" }) {
9400
- const id = React22.useId();
9583
+ const id = React23.useId();
9401
9584
  if (variant === "light") {
9402
9585
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
9403
9586
  "svg",
@@ -9453,10 +9636,10 @@ function OkxIcon({ size = 24, className, variant = "color" }) {
9453
9636
  }
9454
9637
 
9455
9638
  // src/resources/icons/GlowIcon.tsx
9456
- var React23 = __toESM(require("react"));
9639
+ var React24 = __toESM(require("react"));
9457
9640
  var import_jsx_runtime35 = require("react/jsx-runtime");
9458
9641
  function GlowIcon({ size = 24, className, variant = "color" }) {
9459
- const id = React23.useId();
9642
+ const id = React24.useId();
9460
9643
  if (variant === "light") {
9461
9644
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
9462
9645
  "svg",
@@ -9558,10 +9741,10 @@ function GlowIcon({ size = 24, className, variant = "color" }) {
9558
9741
  }
9559
9742
 
9560
9743
  // src/resources/icons/BackpackIcon.tsx
9561
- var React24 = __toESM(require("react"));
9744
+ var React25 = __toESM(require("react"));
9562
9745
  var import_jsx_runtime36 = require("react/jsx-runtime");
9563
9746
  function BackpackIcon({ size = 24, className, variant = "color" }) {
9564
- const id = React24.useId();
9747
+ const id = React25.useId();
9565
9748
  if (variant === "light") {
9566
9749
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
9567
9750
  "svg",
@@ -9635,10 +9818,10 @@ function BackpackIcon({ size = 24, className, variant = "color" }) {
9635
9818
  }
9636
9819
 
9637
9820
  // src/resources/icons/SolflareIcon.tsx
9638
- var React25 = __toESM(require("react"));
9821
+ var React26 = __toESM(require("react"));
9639
9822
  var import_jsx_runtime37 = require("react/jsx-runtime");
9640
9823
  function SolflareIcon({ size = 24, className, variant = "color" }) {
9641
- const id = React25.useId();
9824
+ const id = React26.useId();
9642
9825
  if (variant === "light") {
9643
9826
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
9644
9827
  "svg",
@@ -9706,10 +9889,10 @@ function SolflareIcon({ size = 24, className, variant = "color" }) {
9706
9889
  }
9707
9890
 
9708
9891
  // src/resources/icons/EthereumIcon.tsx
9709
- var React26 = __toESM(require("react"));
9892
+ var React27 = __toESM(require("react"));
9710
9893
  var import_jsx_runtime38 = require("react/jsx-runtime");
9711
9894
  function EthereumIcon({ size = 24, className, variant = "color" }) {
9712
- const id = React26.useId();
9895
+ const id = React27.useId();
9713
9896
  if (variant === "light") {
9714
9897
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
9715
9898
  "svg",
@@ -9834,10 +10017,10 @@ function EthereumIcon({ size = 24, className, variant = "color" }) {
9834
10017
  }
9835
10018
 
9836
10019
  // src/resources/icons/SolanaIcon.tsx
9837
- var React27 = __toESM(require("react"));
10020
+ var React28 = __toESM(require("react"));
9838
10021
  var import_jsx_runtime39 = require("react/jsx-runtime");
9839
10022
  function SolanaIcon({ size = 24, className, variant = "color" }) {
9840
- const id = React27.useId();
10023
+ const id = React28.useId();
9841
10024
  if (variant === "light") {
9842
10025
  return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
9843
10026
  "svg",
@@ -10088,19 +10271,19 @@ function BrowserWalletButton({
10088
10271
  subtitle = i18n.depositModal.browserWallet.subtitle
10089
10272
  }) {
10090
10273
  const { colors: colors2, fonts, components } = useTheme();
10091
- const [isHovered, setIsHovered] = React28.useState(false);
10092
- const [isTouchDevice, setIsTouchDevice] = React28.useState(false);
10274
+ const [isHovered, setIsHovered] = React29.useState(false);
10275
+ const [isTouchDevice, setIsTouchDevice] = React29.useState(false);
10093
10276
  const { wallet, isLoading, setWallet } = useDetectedBrowserWallet({ chainType, onDisconnect });
10094
- const [isConnecting, setIsConnecting] = React28.useState(false);
10095
- const [balanceText, setBalanceText] = React28.useState(null);
10096
- const [isLoadingBalance, setIsLoadingBalance] = React28.useState(false);
10097
- const [isDisconnecting, setIsDisconnecting] = React28.useState(false);
10098
- const onDisconnectRef = React28.useRef(onDisconnect);
10277
+ const [isConnecting, setIsConnecting] = React29.useState(false);
10278
+ const [balanceText, setBalanceText] = React29.useState(null);
10279
+ const [isLoadingBalance, setIsLoadingBalance] = React29.useState(false);
10280
+ const [isDisconnecting, setIsDisconnecting] = React29.useState(false);
10281
+ const onDisconnectRef = React29.useRef(onDisconnect);
10099
10282
  onDisconnectRef.current = onDisconnect;
10100
- React28.useEffect(() => {
10283
+ React29.useEffect(() => {
10101
10284
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
10102
10285
  }, []);
10103
- React28.useEffect(() => {
10286
+ React29.useEffect(() => {
10104
10287
  if (!wallet || !publishableKey) {
10105
10288
  setBalanceText(null);
10106
10289
  return;
@@ -10227,7 +10410,7 @@ function BrowserWalletButton({
10227
10410
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
10228
10411
  };
10229
10412
  const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
10230
- const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React28.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
10413
+ const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React29.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
10231
10414
  size: 36,
10232
10415
  className: "uf-rounded-lg",
10233
10416
  variant: "color"
@@ -10372,7 +10555,7 @@ function BrowserWalletButton({
10372
10555
  }
10373
10556
 
10374
10557
  // src/components/deposits/buttons/StripeLinkButton.tsx
10375
- var React29 = __toESM(require("react"));
10558
+ var React30 = __toESM(require("react"));
10376
10559
  var import_lucide_react23 = require("lucide-react");
10377
10560
  var import_jsx_runtime42 = require("react/jsx-runtime");
10378
10561
  var t4 = i18n.depositModal.stripeLink;
@@ -10383,9 +10566,9 @@ function StripeLinkButton({
10383
10566
  iconUrl
10384
10567
  }) {
10385
10568
  const { colors: colors2, fonts, components } = useTheme();
10386
- const [isHovered, setIsHovered] = React29.useState(false);
10387
- const [isTouchDevice, setIsTouchDevice] = React29.useState(false);
10388
- React29.useEffect(() => {
10569
+ const [isHovered, setIsHovered] = React30.useState(false);
10570
+ const [isTouchDevice, setIsTouchDevice] = React30.useState(false);
10571
+ React30.useEffect(() => {
10389
10572
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
10390
10573
  }, []);
10391
10574
  return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
@@ -10890,6 +11073,8 @@ function PayWithStripeLink({
10890
11073
  destinationChainType,
10891
11074
  destinationChainId,
10892
11075
  destinationTokenAddress,
11076
+ countryCode,
11077
+ subdivisionCode,
10893
11078
  wallets: externalWallets,
10894
11079
  email: emailProp,
10895
11080
  iconUrl,
@@ -11284,7 +11469,9 @@ function PayWithStripeLink({
11284
11469
  {
11285
11470
  tokenAddress: destinationTokenAddress,
11286
11471
  chainId: destinationChainId,
11287
- chainType: destinationChainType
11472
+ chainType: destinationChainType,
11473
+ countryCode,
11474
+ subdivisionCode
11288
11475
  },
11289
11476
  publishableKey
11290
11477
  ).then((token) => {
@@ -11303,7 +11490,14 @@ function PayWithStripeLink({
11303
11490
  return () => {
11304
11491
  cancelled = true;
11305
11492
  };
11306
- }, [publishableKey, destinationTokenAddress, destinationChainId, destinationChainType]);
11493
+ }, [
11494
+ publishableKey,
11495
+ destinationTokenAddress,
11496
+ destinationChainId,
11497
+ destinationChainType,
11498
+ countryCode,
11499
+ subdivisionCode
11500
+ ]);
11307
11501
  const destinationCurrency = stripeDestCurrency;
11308
11502
  const authInnerRef = (0, import_react17.useRef)(null);
11309
11503
  const paymentInnerRef = (0, import_react17.useRef)(null);
@@ -13016,10 +13210,16 @@ function PayWithStripeLink({
13016
13210
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
13017
13211
  "div",
13018
13212
  {
13019
- className: "uf-flex uf-flex-col uf-py-4 uf-overflow-y-auto uf-max-h-[70vh]",
13213
+ className: "uf-flex uf-flex-col uf-py-4 uf-overflow-y-auto uf-overflow-x-hidden uf-max-h-[70vh]",
13020
13214
  style: { backgroundColor: colors2.background },
13021
13215
  children: [
13022
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { ref: paymentMountRef, className: "uf-w-full uf-flex-1 uf-overflow-y-auto" }),
13216
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
13217
+ "div",
13218
+ {
13219
+ ref: paymentMountRef,
13220
+ className: "uf-w-full uf-flex-1 uf-overflow-y-auto uf-overflow-x-hidden"
13221
+ }
13222
+ ),
13023
13223
  !stripePaymentUIReady && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-8", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react25.Loader2, { className: "uf-w-8 uf-h-8 uf-animate-spin", style: { color: colors2.primary } }) }),
13024
13224
  error && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
13025
13225
  "div",
@@ -13037,7 +13237,7 @@ function PayWithStripeLink({
13037
13237
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
13038
13238
  "div",
13039
13239
  {
13040
- className: "uf-flex uf-flex-col uf-py-4 uf-overflow-y-auto uf-max-h-[70vh]",
13240
+ className: "uf-flex uf-flex-col uf-py-4 uf-overflow-y-auto uf-overflow-x-hidden uf-max-h-[70vh]",
13041
13241
  style: { backgroundColor: colors2.background },
13042
13242
  children: [
13043
13243
  displayPaymentTokens.length === 0 && !loading && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "uf-px-1 uf-mb-3 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
@@ -14152,25 +14352,38 @@ var import_lucide_react26 = require("lucide-react");
14152
14352
  var import_core25 = require("@unifold/core");
14153
14353
 
14154
14354
  // src/hooks/use-project-config.ts
14155
- var import_react_query8 = require("@tanstack/react-query");
14355
+ var import_react_query9 = require("@tanstack/react-query");
14156
14356
  var import_core22 = require("@unifold/core");
14157
14357
  function useProjectConfig({
14158
14358
  publishableKey,
14159
- enabled = true
14359
+ enabled = true,
14360
+ countryCode,
14361
+ subdivisionCode
14160
14362
  }) {
14161
- const { data: projectConfig, isLoading } = (0, import_react_query8.useQuery)({
14162
- queryKey: ["unifold", "projectConfig", publishableKey],
14163
- queryFn: () => (0, import_core22.getProjectConfig)(publishableKey),
14363
+ const {
14364
+ data: projectConfig,
14365
+ isLoading,
14366
+ error
14367
+ } = (0, import_react_query9.useQuery)({
14368
+ // Country is part of the key so a region change refetches the region-aware
14369
+ // config. Omitted when undefined so callers that don't pass a country keep
14370
+ // sharing the base cache entry.
14371
+ queryKey: countryCode ? ["unifold", "projectConfig", publishableKey, countryCode, subdivisionCode ?? null] : ["unifold", "projectConfig", publishableKey],
14372
+ queryFn: () => (0, import_core22.getProjectConfig)(publishableKey, countryCode ? { countryCode, subdivisionCode } : void 0),
14164
14373
  enabled,
14374
+ // Keep the previous (e.g. no-country) config visible while the region-aware
14375
+ // config refetches after the country resolves, so unrelated config-driven
14376
+ // UI doesn't flash back to defaults.
14377
+ placeholderData: import_react_query9.keepPreviousData,
14165
14378
  staleTime: 1e3 * 60 * 30,
14166
14379
  refetchOnMount: true,
14167
14380
  refetchOnWindowFocus: true
14168
14381
  });
14169
- return { projectConfig, isLoading };
14382
+ return { projectConfig, isLoading, error: error ?? null };
14170
14383
  }
14171
14384
 
14172
14385
  // src/hooks/use-supported-deposit-tokens.ts
14173
- var import_react_query9 = require("@tanstack/react-query");
14386
+ var import_react_query10 = require("@tanstack/react-query");
14174
14387
  var import_core23 = require("@unifold/core");
14175
14388
  function useSupportedDepositTokens(publishableKey, options) {
14176
14389
  const hasDestination = options?.destination_token_address && options?.destination_chain_id && options?.destination_chain_type;
@@ -14183,7 +14396,7 @@ function useSupportedDepositTokens(publishableKey, options) {
14183
14396
  ...options?.product_type ? { product_type: options.product_type } : {}
14184
14397
  };
14185
14398
  const hasFilteredOptions = Object.keys(filteredOptions).length > 0;
14186
- return (0, import_react_query9.useQuery)({
14399
+ return (0, import_react_query10.useQuery)({
14187
14400
  queryKey: [
14188
14401
  "unifold",
14189
14402
  "supportedDepositTokens",
@@ -14204,14 +14417,14 @@ function useSupportedDepositTokens(publishableKey, options) {
14204
14417
  }
14205
14418
 
14206
14419
  // src/hooks/use-integration-transfer-default-token.ts
14207
- var import_react_query10 = require("@tanstack/react-query");
14420
+ var import_react_query11 = require("@tanstack/react-query");
14208
14421
  var import_core24 = require("@unifold/core");
14209
14422
  function useIntegrationTransferDefaultToken({
14210
14423
  params,
14211
14424
  publishableKey,
14212
14425
  enabled = true
14213
14426
  }) {
14214
- return (0, import_react_query10.useQuery)({
14427
+ return (0, import_react_query11.useQuery)({
14215
14428
  queryKey: [
14216
14429
  "unifold",
14217
14430
  "integrationTransferDefaultToken",
@@ -14282,7 +14495,8 @@ function CoinbaseConnect({
14282
14495
  defaultSourceChainType,
14283
14496
  defaultSourceChainId,
14284
14497
  defaultSourceTokenAddress,
14285
- defaultSourceSymbol
14498
+ defaultSourceSymbol,
14499
+ prefilledAmountUsd
14286
14500
  }) {
14287
14501
  const { colors: colors2, fonts, components } = useTheme();
14288
14502
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -14605,7 +14819,8 @@ function CoinbaseConnect({
14605
14819
  };
14606
14820
  const handleSelectAsset = (asset) => {
14607
14821
  setSelectedAsset(asset);
14608
- setSendAmount("");
14822
+ const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
14823
+ setSendAmount(cleanedPrefilled);
14609
14824
  transitionTo("enter_amount");
14610
14825
  };
14611
14826
  const handleCreateTransfer = async () => {
@@ -16191,13 +16406,13 @@ function CoinbaseConnect({
16191
16406
  CoinbaseConnect.displayName = "CoinbaseConnect";
16192
16407
 
16193
16408
  // src/hooks/use-exchanges.ts
16194
- var import_react_query11 = require("@tanstack/react-query");
16409
+ var import_react_query12 = require("@tanstack/react-query");
16195
16410
  var import_core26 = require("@unifold/core");
16196
16411
  function useExchanges({
16197
16412
  publishableKey,
16198
16413
  enabled = true
16199
16414
  }) {
16200
- const { data: exchanges = [], isLoading } = (0, import_react_query11.useQuery)({
16415
+ const { data: exchanges = [], isLoading } = (0, import_react_query12.useQuery)({
16201
16416
  queryKey: ["unifold", "exchanges", publishableKey],
16202
16417
  queryFn: () => (0, import_core26.getExchanges)(void 0, publishableKey).then((res) => res.data),
16203
16418
  enabled,
@@ -16209,13 +16424,13 @@ function useExchanges({
16209
16424
  }
16210
16425
 
16211
16426
  // src/hooks/use-apple-pay-providers.ts
16212
- var import_react_query12 = require("@tanstack/react-query");
16427
+ var import_react_query13 = require("@tanstack/react-query");
16213
16428
  var import_core27 = require("@unifold/core");
16214
16429
  function useApplePayProviders({
16215
16430
  publishableKey,
16216
16431
  enabled = true
16217
16432
  }) {
16218
- const { data: providers, isLoading } = (0, import_react_query12.useQuery)({
16433
+ const { data: providers, isLoading } = (0, import_react_query13.useQuery)({
16219
16434
  queryKey: ["unifold", "applePayProviders", publishableKey],
16220
16435
  queryFn: () => (0, import_core27.getApplePayProviders)(publishableKey),
16221
16436
  enabled,
@@ -16227,50 +16442,32 @@ function useApplePayProviders({
16227
16442
  }
16228
16443
 
16229
16444
  // src/components/deposits/DepositModal.tsx
16230
- var import_core38 = require("@unifold/core");
16445
+ var import_core37 = require("@unifold/core");
16231
16446
 
16232
16447
  // src/hooks/use-allowed-country.ts
16233
- var import_react_query13 = require("@tanstack/react-query");
16234
- var import_core28 = require("@unifold/core");
16235
16448
  function useAllowedCountry(publishableKey) {
16449
+ const { userIpInfo, isLoading: isIpLoading, error: ipError } = useUserIp();
16236
16450
  const {
16237
- data: ipData,
16238
- isLoading: isIpLoading,
16239
- error: ipError
16240
- } = (0, import_react_query13.useQuery)({
16241
- queryKey: ["unifold", "ipAddress"],
16242
- queryFn: () => (0, import_core28.getIpAddress)(),
16243
- refetchOnMount: false,
16244
- refetchOnReconnect: true,
16245
- refetchOnWindowFocus: false,
16246
- staleTime: 1e3 * 60 * 60,
16247
- // 1 hour
16248
- gcTime: 1e3 * 60 * 60 * 24
16249
- // 24 hours
16250
- });
16251
- const {
16252
- data: configData,
16451
+ projectConfig,
16253
16452
  isLoading: isConfigLoading,
16254
16453
  error: configError
16255
- } = (0, import_react_query13.useQuery)({
16256
- queryKey: ["unifold", "projectConfig", publishableKey],
16257
- queryFn: () => (0, import_core28.getProjectConfig)(publishableKey),
16258
- refetchOnMount: false,
16259
- refetchOnReconnect: true,
16260
- refetchOnWindowFocus: false,
16261
- staleTime: 1e3 * 60 * 5,
16262
- // 5 minutes
16263
- gcTime: 1e3 * 60 * 60
16264
- // 1 hour
16454
+ } = useProjectConfig({
16455
+ publishableKey,
16456
+ // Wait for the IP so we issue a single country-aware config request rather
16457
+ // than a country-less fetch followed by a country-aware refetch. Shares the
16458
+ // query key with DepositModal's useProjectConfig, so they dedupe.
16459
+ enabled: !isIpLoading,
16460
+ countryCode: userIpInfo?.alpha2,
16461
+ subdivisionCode: userIpInfo?.subdivisionCode ?? void 0
16265
16462
  });
16266
16463
  const isLoading = isIpLoading || isConfigLoading;
16267
16464
  const error = ipError || configError || null;
16465
+ const userSubdivision = userIpInfo?.subdivisionCode || userIpInfo?.state || "";
16268
16466
  let isAllowed = null;
16269
- if (ipData && configData) {
16270
- const blockedCodes = configData.blocked_country_codes || [];
16271
- const blockedSubdivisions = configData.blocked_country_subdivisions || [];
16272
- const userCountryUpper = ipData.alpha2.toUpperCase();
16273
- const userSubdivision = ipData.subdivision_code || ipData.state || "";
16467
+ if (userIpInfo && projectConfig) {
16468
+ const blockedCodes = projectConfig.blocked_country_codes || [];
16469
+ const blockedSubdivisions = projectConfig.blocked_country_subdivisions || [];
16470
+ const userCountryUpper = userIpInfo.alpha2.toUpperCase();
16274
16471
  const userSubdivisionUpper = userSubdivision.toUpperCase();
16275
16472
  const isCountryBlocked = blockedCodes.some((code) => code.toUpperCase() === userCountryUpper);
16276
16473
  const isSubdivisionBlocked = blockedSubdivisions.some((entry) => {
@@ -16279,12 +16476,11 @@ function useAllowedCountry(publishableKey) {
16279
16476
  });
16280
16477
  isAllowed = !isCountryBlocked && !isSubdivisionBlocked;
16281
16478
  }
16282
- const subdivisionCode = ipData?.subdivision_code || ipData?.state || "" || null;
16283
16479
  return {
16284
16480
  isAllowed,
16285
- alpha2: ipData?.alpha2 ?? null,
16286
- country: ipData?.country ?? null,
16287
- subdivisionCode,
16481
+ alpha2: userIpInfo?.alpha2 ?? null,
16482
+ country: userIpInfo?.country ?? null,
16483
+ subdivisionCode: userSubdivision || null,
16288
16484
  isLoading,
16289
16485
  error
16290
16486
  };
@@ -16292,7 +16488,7 @@ function useAllowedCountry(publishableKey) {
16292
16488
 
16293
16489
  // src/hooks/use-address-validation.ts
16294
16490
  var import_react_query14 = require("@tanstack/react-query");
16295
- var import_core29 = require("@unifold/core");
16491
+ var import_core28 = require("@unifold/core");
16296
16492
  function useAddressValidation({
16297
16493
  recipientAddress,
16298
16494
  destinationChainType,
@@ -16312,7 +16508,7 @@ function useAddressValidation({
16312
16508
  destinationChainId,
16313
16509
  destinationTokenAddress
16314
16510
  ],
16315
- queryFn: () => (0, import_core29.verifyRecipientAddress)(
16511
+ queryFn: () => (0, import_core28.verifyRecipientAddress)(
16316
16512
  {
16317
16513
  chain_type: destinationChainType,
16318
16514
  chain_id: destinationChainId,
@@ -16356,14 +16552,14 @@ var import_lucide_react30 = require("lucide-react");
16356
16552
  var import_react19 = require("react");
16357
16553
 
16358
16554
  // src/components/shared/ThemeStyleInjector.tsx
16359
- var React31 = __toESM(require("react"));
16555
+ var React32 = __toESM(require("react"));
16360
16556
  var import_jsx_runtime46 = require("react/jsx-runtime");
16361
16557
  function ThemeStyleInjector({
16362
16558
  children,
16363
16559
  className
16364
16560
  }) {
16365
16561
  const { colors: colors2, fonts, mode } = useTheme();
16366
- const cssVars = React31.useMemo(() => {
16562
+ const cssVars = React32.useMemo(() => {
16367
16563
  const hexToHSL = (hex) => {
16368
16564
  hex = hex.replace("#", "");
16369
16565
  const r = parseInt(hex.slice(0, 2), 16) / 255;
@@ -16423,7 +16619,7 @@ function ThemeStyleInjector({
16423
16619
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
16424
16620
  };
16425
16621
  }, [colors2, fonts.regular]);
16426
- React31.useEffect(() => {
16622
+ React32.useEffect(() => {
16427
16623
  if (typeof document === "undefined") return;
16428
16624
  if (fonts.regular) {
16429
16625
  document.documentElement.style.setProperty("--uf-font-family", fonts.regular);
@@ -16593,7 +16789,7 @@ function PoweredByUnifold({
16593
16789
  }
16594
16790
 
16595
16791
  // src/components/deposits/DepositsModal.tsx
16596
- var import_core30 = require("@unifold/core");
16792
+ var import_core29 = require("@unifold/core");
16597
16793
  var import_jsx_runtime48 = require("react/jsx-runtime");
16598
16794
  function DepositsModal({
16599
16795
  open,
@@ -16611,7 +16807,7 @@ function DepositsModal({
16611
16807
  if (!open || !userId) return;
16612
16808
  const fetchExecutions = async () => {
16613
16809
  try {
16614
- const response = await (0, import_core30.queryExecutions)(userId, publishableKey, import_core30.ActionType.Deposit);
16810
+ const response = await (0, import_core29.queryExecutions)(userId, publishableKey, import_core29.ActionType.Deposit);
16615
16811
  const sorted = [...response.data].sort((a, b) => {
16616
16812
  const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
16617
16813
  const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
@@ -17597,7 +17793,7 @@ function useCopyAddress() {
17597
17793
  }
17598
17794
 
17599
17795
  // src/components/shared/tooltip.tsx
17600
- var React32 = __toESM(require("react"));
17796
+ var React33 = __toESM(require("react"));
17601
17797
  var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"));
17602
17798
  var import_jsx_runtime52 = require("react/jsx-runtime");
17603
17799
  var TooltipProvider = TooltipPrimitive.Provider;
@@ -17605,20 +17801,20 @@ function Tooltip({
17605
17801
  children,
17606
17802
  ...props
17607
17803
  }) {
17608
- const [open, setOpen] = React32.useState(props.defaultOpen ?? false);
17804
+ const [open, setOpen] = React33.useState(props.defaultOpen ?? false);
17609
17805
  const isControlled = props.open !== void 0;
17610
17806
  const isOpen = isControlled ? props.open : open;
17611
17807
  const onOpenChange = isControlled ? props.onOpenChange : (nextOpen) => setOpen(nextOpen);
17612
17808
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TooltipContext.Provider, { value: { open: isOpen, onOpenChange }, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TooltipPrimitive.Root, { ...props, open: isOpen, onOpenChange, children }) });
17613
17809
  }
17614
- var TooltipContext = React32.createContext({
17810
+ var TooltipContext = React33.createContext({
17615
17811
  open: false,
17616
17812
  onOpenChange: () => {
17617
17813
  }
17618
17814
  });
17619
- var TooltipTrigger = React32.forwardRef(({ onClick, ...props }, ref) => {
17620
- const { open, onOpenChange } = React32.useContext(TooltipContext);
17621
- const handleClick = React32.useCallback(
17815
+ var TooltipTrigger = React33.forwardRef(({ onClick, ...props }, ref) => {
17816
+ const { open, onOpenChange } = React33.useContext(TooltipContext);
17817
+ const handleClick = React33.useCallback(
17622
17818
  (e) => {
17623
17819
  onOpenChange(!open);
17624
17820
  onClick?.(e);
@@ -17628,7 +17824,7 @@ var TooltipTrigger = React32.forwardRef(({ onClick, ...props }, ref) => {
17628
17824
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TooltipPrimitive.Trigger, { ref, onClick: handleClick, ...props });
17629
17825
  });
17630
17826
  TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
17631
- var TooltipContent = React32.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
17827
+ var TooltipContent = React33.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
17632
17828
  const { themeClass, colors: colors2 } = useTheme();
17633
17829
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
17634
17830
  TooltipPrimitive.Content,
@@ -17648,11 +17844,11 @@ var TooltipContent = React32.forwardRef(({ className, sideOffset = 4, ...props }
17648
17844
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
17649
17845
 
17650
17846
  // src/components/deposits/TransferCryptoSingleInput.tsx
17651
- var import_core32 = require("@unifold/core");
17847
+ var import_core31 = require("@unifold/core");
17652
17848
 
17653
17849
  // src/hooks/use-hypercore-activation.ts
17654
17850
  var import_react_query15 = require("@tanstack/react-query");
17655
- var import_core31 = require("@unifold/core");
17851
+ var import_core30 = require("@unifold/core");
17656
17852
 
17657
17853
  // src/lib/constants.ts
17658
17854
  var HYPERCORE_CHAIN_ID = "1337";
@@ -17672,7 +17868,7 @@ function useHypercoreActivation(params) {
17672
17868
  const hasAddresses = !!recipient && !!source;
17673
17869
  const { data, isLoading } = (0, import_react_query15.useQuery)({
17674
17870
  queryKey: ["unifold", "hypercoreActivation", source, recipient, publishableKey],
17675
- queryFn: () => (0, import_core31.checkHypercoreActivation)(
17871
+ queryFn: () => (0, import_core30.checkHypercoreActivation)(
17676
17872
  {
17677
17873
  source_address: source,
17678
17874
  recipient_address: recipient
@@ -17756,6 +17952,7 @@ function TransferCryptoSingleInput({
17756
17952
  onDepositError,
17757
17953
  wallets: externalWallets,
17758
17954
  onSourceTokenChange,
17955
+ prefilledAmountUsd,
17759
17956
  checkoutQuote,
17760
17957
  isCheckoutQuoteLoading = false,
17761
17958
  persistCheckingIndicator = false,
@@ -17820,7 +18017,7 @@ function TransferCryptoSingleInput({
17820
18017
  (c) => c.chain_type === currentChainCombo.chainType && c.chain_id === currentChainCombo.chainId
17821
18018
  ) : void 0;
17822
18019
  const currentChainType = currentChainData?.chain_type || "ethereum";
17823
- const currentWallet = (0, import_core32.getWalletByChainType)(wallets, currentChainType);
18020
+ const currentWallet = (0, import_core31.getWalletByChainType)(wallets, currentChainType);
17824
18021
  const depositAddress = currentWallet?.address || "";
17825
18022
  const {
17826
18023
  executions: depositExecutions,
@@ -17899,6 +18096,22 @@ function TransferCryptoSingleInput({
17899
18096
  const maxSlippage = currentChainFromBackend?.max_slippage_percent ?? 0.25;
17900
18097
  const processingTime = currentChainFromBackend?.estimated_processing_time ?? null;
17901
18098
  const minDepositUsd = currentChainFromBackend?.minimum_deposit_amount_usd ?? 3;
18099
+ const parsedPrefilledUsd = (0, import_react23.useMemo)(() => {
18100
+ const value = parseFloat(prefilledAmountUsd ?? "");
18101
+ return Number.isFinite(value) && value > 0 ? value : null;
18102
+ }, [prefilledAmountUsd]);
18103
+ const effectivePrefilledUsd = (0, import_react23.useMemo)(() => {
18104
+ if (parsedPrefilledUsd === null) return null;
18105
+ return Math.max(parsedPrefilledUsd, minDepositUsd);
18106
+ }, [parsedPrefilledUsd, minDepositUsd]);
18107
+ const prefillDisplay = (0, import_react23.useMemo)(() => {
18108
+ if (effectivePrefilledUsd === null) return null;
18109
+ const usdLabel = `$${effectivePrefilledUsd.toFixed(2)}`;
18110
+ if (selectedToken?.is_stablecoin) {
18111
+ return `${effectivePrefilledUsd.toFixed(2)} ${selectedToken.symbol} (${usdLabel})`;
18112
+ }
18113
+ return `${usdLabel} USD`;
18114
+ }, [effectivePrefilledUsd, selectedToken]);
17902
18115
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(TooltipProvider, { delayDuration: 0, skipDelayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
17903
18116
  "div",
17904
18117
  {
@@ -18025,7 +18238,7 @@ function TransferCryptoSingleInput({
18025
18238
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { children: "Retrying automatically every 5 seconds..." })
18026
18239
  ] })
18027
18240
  ] }),
18028
- (checkoutQuote || isCheckoutQuoteLoading) && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
18241
+ (checkoutQuote || isCheckoutQuoteLoading || prefillDisplay) && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
18029
18242
  "div",
18030
18243
  {
18031
18244
  className: "uf-rounded-xl uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
@@ -18049,7 +18262,7 @@ function TransferCryptoSingleInput({
18049
18262
  className: "uf-text-sm uf-font-semibold",
18050
18263
  style: { color: components.card.titleColor, fontFamily: fonts.semibold },
18051
18264
  children: [
18052
- checkoutQuote.isStablecoin ? (0, import_core32.formatStablecoinAmount)(
18265
+ checkoutQuote.isStablecoin ? (0, import_core31.formatStablecoinAmount)(
18053
18266
  checkoutQuote.sourceAmount,
18054
18267
  checkoutQuote.sourceTokenDecimals
18055
18268
  ) : (Number(checkoutQuote.sourceAmount) / 10 ** checkoutQuote.sourceTokenDecimals).toFixed(Math.min(checkoutQuote.sourceTokenDecimals, 6)),
@@ -18069,6 +18282,13 @@ function TransferCryptoSingleInput({
18069
18282
  )
18070
18283
  ]
18071
18284
  }
18285
+ ) : prefillDisplay ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
18286
+ "span",
18287
+ {
18288
+ className: "uf-text-sm uf-font-semibold",
18289
+ style: { color: components.card.titleColor, fontFamily: fonts.semibold },
18290
+ children: prefillDisplay
18291
+ }
18072
18292
  ) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
18073
18293
  "div",
18074
18294
  {
@@ -18402,14 +18622,14 @@ var import_react24 = require("react");
18402
18622
  var import_lucide_react32 = require("lucide-react");
18403
18623
 
18404
18624
  // src/components/shared/select.tsx
18405
- var React33 = __toESM(require("react"));
18625
+ var React34 = __toESM(require("react"));
18406
18626
  var SelectPrimitive = __toESM(require("@radix-ui/react-select"));
18407
18627
  var import_lucide_react31 = require("lucide-react");
18408
18628
  var import_jsx_runtime55 = require("react/jsx-runtime");
18409
18629
  var Select = SelectPrimitive.Root;
18410
18630
  var SelectGroup = SelectPrimitive.Group;
18411
18631
  var SelectValue = SelectPrimitive.Value;
18412
- var SelectTrigger = React33.forwardRef(({ className, style, children, ...props }, ref) => {
18632
+ var SelectTrigger = React34.forwardRef(({ className, style, children, ...props }, ref) => {
18413
18633
  const { components } = useTheme();
18414
18634
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
18415
18635
  SelectPrimitive.Trigger,
@@ -18433,7 +18653,7 @@ var SelectTrigger = React33.forwardRef(({ className, style, children, ...props }
18433
18653
  );
18434
18654
  });
18435
18655
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
18436
- var SelectScrollUpButton = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18656
+ var SelectScrollUpButton = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18437
18657
  SelectPrimitive.ScrollUpButton,
18438
18658
  {
18439
18659
  ref,
@@ -18443,7 +18663,7 @@ var SelectScrollUpButton = React33.forwardRef(({ className, ...props }, ref) =>
18443
18663
  }
18444
18664
  ));
18445
18665
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
18446
- var SelectScrollDownButton = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18666
+ var SelectScrollDownButton = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18447
18667
  SelectPrimitive.ScrollDownButton,
18448
18668
  {
18449
18669
  ref,
@@ -18453,7 +18673,7 @@ var SelectScrollDownButton = React33.forwardRef(({ className, ...props }, ref) =
18453
18673
  }
18454
18674
  ));
18455
18675
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
18456
- var SelectContent = React33.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
18676
+ var SelectContent = React34.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
18457
18677
  const { themeClass, colors: colors2, components } = useTheme();
18458
18678
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
18459
18679
  SelectPrimitive.Content,
@@ -18491,7 +18711,7 @@ var SelectContent = React33.forwardRef(({ className, style, children, position =
18491
18711
  ) });
18492
18712
  });
18493
18713
  SelectContent.displayName = SelectPrimitive.Content.displayName;
18494
- var SelectLabel = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18714
+ var SelectLabel = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18495
18715
  SelectPrimitive.Label,
18496
18716
  {
18497
18717
  ref,
@@ -18500,7 +18720,7 @@ var SelectLabel = React33.forwardRef(({ className, ...props }, ref) => /* @__PUR
18500
18720
  }
18501
18721
  ));
18502
18722
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
18503
- var SelectItem = React33.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
18723
+ var SelectItem = React34.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
18504
18724
  SelectPrimitive.Item,
18505
18725
  {
18506
18726
  ref,
@@ -18516,7 +18736,7 @@ var SelectItem = React33.forwardRef(({ className, children, ...props }, ref) =>
18516
18736
  }
18517
18737
  ));
18518
18738
  SelectItem.displayName = SelectPrimitive.Item.displayName;
18519
- var SelectSeparator = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18739
+ var SelectSeparator = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18520
18740
  SelectPrimitive.Separator,
18521
18741
  {
18522
18742
  ref,
@@ -18527,7 +18747,7 @@ var SelectSeparator = React33.forwardRef(({ className, ...props }, ref) => /* @_
18527
18747
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
18528
18748
 
18529
18749
  // src/components/deposits/TransferCryptoDoubleInput.tsx
18530
- var import_core33 = require("@unifold/core");
18750
+ var import_core32 = require("@unifold/core");
18531
18751
  var import_jsx_runtime56 = require("react/jsx-runtime");
18532
18752
  var t7 = i18n.transferCrypto;
18533
18753
  var getChainKey3 = (chainId, chainType) => {
@@ -18548,6 +18768,7 @@ function TransferCryptoDoubleInput({
18548
18768
  defaultSourceChainId,
18549
18769
  defaultSourceTokenAddress,
18550
18770
  defaultSourceSymbol,
18771
+ prefilledAmountUsd,
18551
18772
  depositConfirmationMode = "auto_ui",
18552
18773
  onExecutionsChange,
18553
18774
  onDepositSuccess,
@@ -18611,7 +18832,7 @@ function TransferCryptoDoubleInput({
18611
18832
  (c) => c.chain_type === currentChainCombo.chainType && c.chain_id === currentChainCombo.chainId
18612
18833
  ) : void 0;
18613
18834
  const currentChainType = currentChainData?.chain_type || "ethereum";
18614
- const currentWallet = (0, import_core33.getWalletByChainType)(wallets, currentChainType);
18835
+ const currentWallet = (0, import_core32.getWalletByChainType)(wallets, currentChainType);
18615
18836
  const depositAddress = currentWallet?.address || "";
18616
18837
  const {
18617
18838
  executions: depositExecutions,
@@ -18672,6 +18893,22 @@ function TransferCryptoDoubleInput({
18672
18893
  const maxSlippage = currentChainFromBackend?.max_slippage_percent ?? 0.25;
18673
18894
  const processingTime = currentChainFromBackend?.estimated_processing_time ?? null;
18674
18895
  const minDepositUsd = currentChainFromBackend?.minimum_deposit_amount_usd ?? 3;
18896
+ const parsedPrefilledUsd = (0, import_react24.useMemo)(() => {
18897
+ const value = parseFloat(prefilledAmountUsd ?? "");
18898
+ return Number.isFinite(value) && value > 0 ? value : null;
18899
+ }, [prefilledAmountUsd]);
18900
+ const effectivePrefilledUsd = (0, import_react24.useMemo)(() => {
18901
+ if (parsedPrefilledUsd === null) return null;
18902
+ return Math.max(parsedPrefilledUsd, minDepositUsd);
18903
+ }, [parsedPrefilledUsd, minDepositUsd]);
18904
+ const prefillDisplay = (0, import_react24.useMemo)(() => {
18905
+ if (effectivePrefilledUsd === null) return null;
18906
+ const usdLabel = `$${effectivePrefilledUsd.toFixed(2)}`;
18907
+ if (selectedToken?.is_stablecoin) {
18908
+ return `${effectivePrefilledUsd.toFixed(2)} ${selectedToken.symbol} (${usdLabel})`;
18909
+ }
18910
+ return `${usdLabel} USD`;
18911
+ }, [effectivePrefilledUsd, selectedToken]);
18675
18912
  const renderTokenItem = (tokenData) => {
18676
18913
  return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
18677
18914
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
@@ -18852,9 +19089,38 @@ function TransferCryptoDoubleInput({
18852
19089
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { children: "Retrying automatically every 5 seconds..." })
18853
19090
  ] })
18854
19091
  ] }),
18855
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pt-2", children: [
18856
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
18857
- "div",
19092
+ prefillDisplay && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
19093
+ "div",
19094
+ {
19095
+ className: "uf-rounded-xl uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
19096
+ style: {
19097
+ backgroundColor: components.card.backgroundColor,
19098
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
19099
+ borderRadius: components.card.borderRadius
19100
+ },
19101
+ children: [
19102
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
19103
+ "span",
19104
+ {
19105
+ className: "uf-text-xs",
19106
+ style: { color: components.card.subtitleColor, fontFamily: fonts.regular },
19107
+ children: "You send"
19108
+ }
19109
+ ),
19110
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
19111
+ "span",
19112
+ {
19113
+ className: "uf-text-sm uf-font-semibold",
19114
+ style: { color: components.card.titleColor, fontFamily: fonts.semibold },
19115
+ children: prefillDisplay
19116
+ }
19117
+ )
19118
+ ]
19119
+ }
19120
+ ),
19121
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pt-2", children: [
19122
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
19123
+ "div",
18858
19124
  {
18859
19125
  className: "uf-text-xs uf-mb-2 uf-flex uf-items-center uf-gap-1",
18860
19126
  style: { color: components.card.labelColor },
@@ -19134,12 +19400,12 @@ function TransferCryptoDoubleInput({
19134
19400
  }
19135
19401
 
19136
19402
  // src/components/deposits/WalletConnect.tsx
19137
- var React34 = __toESM(require("react"));
19403
+ var React35 = __toESM(require("react"));
19138
19404
  var import_lucide_react36 = require("lucide-react");
19139
- var import_core37 = require("@unifold/core");
19405
+ var import_core36 = require("@unifold/core");
19140
19406
 
19141
19407
  // src/lib/send-hypercore.ts
19142
- var import_core34 = require("@unifold/core");
19408
+ var import_core33 = require("@unifold/core");
19143
19409
  function isHypercoreChain(chainId) {
19144
19410
  return chainId === HYPERCORE_CHAIN_ID;
19145
19411
  }
@@ -19150,7 +19416,7 @@ async function sendHypercoreEvmTransfer(params) {
19150
19416
  params: []
19151
19417
  });
19152
19418
  const activeChainId = String(parseInt(currentChainHex, 16));
19153
- const buildResult = await (0, import_core34.buildHypercoreTransaction)(
19419
+ const buildResult = await (0, import_core33.buildHypercoreTransaction)(
19154
19420
  {
19155
19421
  signature_chain_id: activeChainId,
19156
19422
  recipient_address: recipientAddress,
@@ -19163,7 +19429,7 @@ async function sendHypercoreEvmTransfer(params) {
19163
19429
  method: "eth_signTypedData_v4",
19164
19430
  params: [fromAddress, JSON.stringify(buildResult.typed_data)]
19165
19431
  });
19166
- await (0, import_core34.sendHypercoreTransaction)(
19432
+ await (0, import_core33.sendHypercoreTransaction)(
19167
19433
  {
19168
19434
  action_payload: buildResult.action_payload,
19169
19435
  signature,
@@ -19176,7 +19442,7 @@ async function sendHypercoreEvmTransfer(params) {
19176
19442
 
19177
19443
  // src/hooks/use-deposit-quote.ts
19178
19444
  var import_react_query16 = require("@tanstack/react-query");
19179
- var import_core35 = require("@unifold/core");
19445
+ var import_core34 = require("@unifold/core");
19180
19446
  function useDepositQuote(params) {
19181
19447
  const {
19182
19448
  publishableKey,
@@ -19217,7 +19483,7 @@ function useDepositQuote(params) {
19217
19483
  stablecoinParity,
19218
19484
  publishableKey
19219
19485
  ],
19220
- queryFn: () => (0, import_core35.getDepositQuote)(request, publishableKey),
19486
+ queryFn: () => (0, import_core34.getDepositQuote)(request, publishableKey),
19221
19487
  enabled: enabled && !!publishableKey && !!sourceChainType && !!sourceChainId && !!sourceTokenAddress && !!destinationAmount && destinationAmount !== "0" && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress,
19222
19488
  staleTime: 3e4,
19223
19489
  gcTime: 5 * 6e4,
@@ -19231,14 +19497,14 @@ function useDepositQuote(params) {
19231
19497
 
19232
19498
  // src/hooks/use-external-wallets.ts
19233
19499
  var import_react_query17 = require("@tanstack/react-query");
19234
- var import_core36 = require("@unifold/core");
19500
+ var import_core35 = require("@unifold/core");
19235
19501
  function useExternalWallets({
19236
19502
  publishableKey,
19237
19503
  enabled = true
19238
19504
  }) {
19239
19505
  const { data: wallets = [], isLoading } = (0, import_react_query17.useQuery)({
19240
19506
  queryKey: ["unifold", "external-wallets", publishableKey],
19241
- queryFn: () => (0, import_core36.getExternalWallets)(publishableKey).then((res) => res.data),
19507
+ queryFn: () => (0, import_core35.getExternalWallets)(publishableKey).then((res) => res.data),
19242
19508
  enabled: enabled && !!publishableKey,
19243
19509
  staleTime: 1e3 * 60 * 30,
19244
19510
  refetchOnMount: false,
@@ -20483,7 +20749,7 @@ function WalletConnect({
20483
20749
  amountQuickSelect = "percentage",
20484
20750
  onWalletDisconnect,
20485
20751
  onWalletConnected,
20486
- prefillAmountUsd,
20752
+ prefilledAmountUsd,
20487
20753
  checkoutAmountUsd,
20488
20754
  checkoutReceivedUsd,
20489
20755
  onNewDeposit,
@@ -20505,28 +20771,28 @@ function WalletConnect({
20505
20771
  onExecutionsChange
20506
20772
  }) {
20507
20773
  const { colors: colors2, fonts, components, mode } = useTheme();
20508
- const walletProvidedAtMount = React34.useRef(!!initialWalletInfo && !!initialDepositWallet);
20509
- const [activeWalletInfo, setActiveWalletInfo] = React34.useState(
20774
+ const walletProvidedAtMount = React35.useRef(!!initialWalletInfo && !!initialDepositWallet);
20775
+ const [activeWalletInfo, setActiveWalletInfo] = React35.useState(
20510
20776
  initialWalletInfo ?? null
20511
20777
  );
20512
- const [activeDepositWallet, setActiveDepositWallet] = React34.useState(
20778
+ const [activeDepositWallet, setActiveDepositWallet] = React35.useState(
20513
20779
  initialDepositWallet ?? null
20514
20780
  );
20515
20781
  const initialView = initialWalletInfo && initialDepositWallet ? "select_token" : "select_wallet";
20516
- const [view, setView] = React34.useState(initialView);
20517
- const [isTransitioning, setIsTransitioning] = React34.useState(false);
20518
- const viewRef = React34.useRef(initialView);
20782
+ const [view, setView] = React35.useState(initialView);
20783
+ const [isTransitioning, setIsTransitioning] = React35.useState(false);
20784
+ const viewRef = React35.useRef(initialView);
20519
20785
  const standalone = !canGoBack && !walletProvidedAtMount.current;
20520
20786
  const { wallet: detectedWallet, isLoading: detectingWallet } = useDetectedBrowserWallet({
20521
20787
  enabled: standalone
20522
20788
  });
20523
- const [autoResolved, setAutoResolved] = React34.useState(false);
20524
- const [selectedWalletDef, setSelectedWalletDef] = React34.useState(null);
20525
- const [connectingNetwork, setConnectingNetwork] = React34.useState(null);
20526
- const [walletError, setWalletError] = React34.useState(null);
20527
- const [isWalletConnecting, setIsWalletConnecting] = React34.useState(false);
20528
- const [eip6963ProviderCount, setEip6963ProviderCount] = React34.useState(0);
20529
- React34.useEffect(() => {
20789
+ const [autoResolved, setAutoResolved] = React35.useState(false);
20790
+ const [selectedWalletDef, setSelectedWalletDef] = React35.useState(null);
20791
+ const [connectingNetwork, setConnectingNetwork] = React35.useState(null);
20792
+ const [walletError, setWalletError] = React35.useState(null);
20793
+ const [isWalletConnecting, setIsWalletConnecting] = React35.useState(false);
20794
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React35.useState(0);
20795
+ React35.useEffect(() => {
20530
20796
  const store = getEip6963Store();
20531
20797
  if (!store) return;
20532
20798
  setEip6963ProviderCount(store.getProviders().length);
@@ -20535,7 +20801,7 @@ function WalletConnect({
20535
20801
  });
20536
20802
  }, []);
20537
20803
  const { wallets: backendWallets } = useExternalWallets({ publishableKey });
20538
- const walletDefinitions = React34.useMemo(
20804
+ const walletDefinitions = React35.useMemo(
20539
20805
  () => backendWallets.length > 0 ? backendWallets.map((w) => ({
20540
20806
  id: w.id,
20541
20807
  name: w.name,
@@ -20546,32 +20812,32 @@ function WalletConnect({
20546
20812
  })) : FALLBACK_WALLET_DEFINITIONS,
20547
20813
  [backendWallets]
20548
20814
  );
20549
- const [recentWalletId, setRecentWalletIdState] = React34.useState(getLastOpenedWallet);
20550
- React34.useEffect(() => {
20815
+ const [recentWalletId, setRecentWalletIdState] = React35.useState(getLastOpenedWallet);
20816
+ React35.useEffect(() => {
20551
20817
  if (view === "select_wallet") {
20552
20818
  setRecentWalletIdState(getLastOpenedWallet());
20553
20819
  }
20554
20820
  }, [view]);
20555
- const availableWallets = React34.useMemo(
20821
+ const availableWallets = React35.useMemo(
20556
20822
  () => detectAvailableWallets(walletDefinitions, recentWalletId),
20557
20823
  [walletDefinitions, eip6963ProviderCount, recentWalletId]
20558
20824
  );
20559
- const [isMobile, setIsMobile] = React34.useState(false);
20560
- React34.useEffect(() => {
20825
+ const [isMobile, setIsMobile] = React35.useState(false);
20826
+ React35.useEffect(() => {
20561
20827
  setIsMobile(isMobileDevice());
20562
20828
  }, []);
20563
- const mobileDepositAddresses = React34.useMemo(
20829
+ const mobileDepositAddresses = React35.useMemo(
20564
20830
  () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
20565
20831
  [depositWallets]
20566
20832
  );
20567
- const mobileDepositWalletIds = React34.useMemo(
20833
+ const mobileDepositWalletIds = React35.useMemo(
20568
20834
  () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
20569
20835
  [depositWallets]
20570
20836
  );
20571
- const [mobileRedirect, setMobileRedirect] = React34.useState(null);
20572
- const [pendingMobileWallet, setPendingMobileWallet] = React34.useState(null);
20573
- const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React34.useState(false);
20574
- React34.useEffect(() => {
20837
+ const [mobileRedirect, setMobileRedirect] = React35.useState(null);
20838
+ const [pendingMobileWallet, setPendingMobileWallet] = React35.useState(null);
20839
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React35.useState(false);
20840
+ React35.useEffect(() => {
20575
20841
  if (!standalone || autoResolved || detectingWallet) return;
20576
20842
  if (!detectedWallet) {
20577
20843
  setAutoResolved(true);
@@ -20597,32 +20863,36 @@ function WalletConnect({
20597
20863
  depositWallets,
20598
20864
  depositWalletsLoading
20599
20865
  ]);
20600
- React34.useEffect(() => {
20866
+ React35.useEffect(() => {
20601
20867
  if (!standalone || autoResolved) return;
20602
20868
  const t13 = setTimeout(() => setAutoResolved(true), 5e3);
20603
20869
  return () => clearTimeout(t13);
20604
20870
  }, [standalone, autoResolved]);
20605
- const [balances, setBalances] = React34.useState([]);
20606
- const [isLoading, setIsLoading] = React34.useState(false);
20607
- const [selectedBalance, setSelectedBalance] = React34.useState(null);
20608
- const [totalBalanceUsd, setTotalBalanceUsd] = React34.useState(null);
20609
- const [error, setError] = React34.useState(null);
20610
- const [isDisconnectingWallet, setIsDisconnectingWallet] = React34.useState(false);
20611
- const [amountUsd, setAmountUsd] = React34.useState(prefillAmountUsd ?? "");
20612
- const [isConfirming, setIsConfirming] = React34.useState(false);
20613
- const [hasSignedTransaction, setHasSignedTransaction] = React34.useState(false);
20614
- const [tokenChainDetails, setTokenChainDetails] = React34.useState(null);
20615
- const [loadingTokenDetails, setLoadingTokenDetails] = React34.useState(false);
20616
- const [showTransactionDetails, setShowTransactionDetails] = React34.useState(false);
20617
- const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React34.useState(null);
20871
+ const [balances, setBalances] = React35.useState([]);
20872
+ const [isLoading, setIsLoading] = React35.useState(false);
20873
+ const [selectedBalance, setSelectedBalance] = React35.useState(null);
20874
+ const [totalBalanceUsd, setTotalBalanceUsd] = React35.useState(null);
20875
+ const [error, setError] = React35.useState(null);
20876
+ const [isDisconnectingWallet, setIsDisconnectingWallet] = React35.useState(false);
20877
+ const [amountUsd, setAmountUsd] = React35.useState(prefilledAmountUsd ?? "");
20878
+ const [isConfirming, setIsConfirming] = React35.useState(false);
20879
+ const [hasSignedTransaction, setHasSignedTransaction] = React35.useState(false);
20880
+ const [tokenChainDetails, setTokenChainDetails] = React35.useState(null);
20881
+ const [loadingTokenDetails, setLoadingTokenDetails] = React35.useState(false);
20882
+ const [showTransactionDetails, setShowTransactionDetails] = React35.useState(false);
20883
+ const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React35.useState(null);
20618
20884
  const walletInfo = activeWalletInfo;
20619
20885
  const depositWallet = activeDepositWallet;
20620
20886
  const hasWallet = !!activeWalletInfo && !!activeDepositWallet;
20887
+ React35.useEffect(() => {
20888
+ const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
20889
+ setAmountUsd(cleanedPrefilled);
20890
+ }, [prefilledAmountUsd]);
20621
20891
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
20622
20892
  const recipientAddress = activeDepositWallet?.address ?? "";
20623
20893
  const isCheckoutMode = !!checkoutAmountUsd;
20624
20894
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
20625
- const transitionTo = React34.useCallback((nextView) => {
20895
+ const transitionTo = React35.useCallback((nextView) => {
20626
20896
  if (nextView === viewRef.current) return;
20627
20897
  setIsTransitioning(true);
20628
20898
  setTimeout(() => {
@@ -20638,7 +20908,7 @@ function WalletConnect({
20638
20908
  };
20639
20909
  const openMobileWalletBrowse = async (wallet, depositAddresses) => {
20640
20910
  try {
20641
- const res = await (0, import_core37.getWalletMobileDeepLink)(
20911
+ const res = await (0, import_core36.getWalletMobileDeepLink)(
20642
20912
  wallet.id,
20643
20913
  depositAddresses,
20644
20914
  publishableKey
@@ -20687,7 +20957,7 @@ function WalletConnect({
20687
20957
  if (!selectedWalletDef) return;
20688
20958
  handleConnectWallet(selectedWalletDef, network);
20689
20959
  };
20690
- React34.useEffect(() => {
20960
+ React35.useEffect(() => {
20691
20961
  if (!pendingMobileWallet) return;
20692
20962
  if (mobileDepositAddresses.length > 0) {
20693
20963
  const wallet = pendingMobileWallet;
@@ -20851,7 +21121,7 @@ function WalletConnect({
20851
21121
  publishableKey,
20852
21122
  enabled: !!activeWalletInfo && !!recipientAddress
20853
21123
  });
20854
- const effectiveDestinationAmount = React34.useMemo(() => {
21124
+ const effectiveDestinationAmount = React35.useMemo(() => {
20855
21125
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
20856
21126
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
20857
21127
  const remaining = BigInt(checkoutRemainingBaseUnits);
@@ -20879,7 +21149,7 @@ function WalletConnect({
20879
21149
  stablecoinParity,
20880
21150
  enabled: isCheckoutMode && !!selectedToken && !!checkoutDestination && effectiveDestinationAmount !== "0"
20881
21151
  });
20882
- const activeCheckoutQuote = React34.useMemo(() => {
21152
+ const activeCheckoutQuote = React35.useMemo(() => {
20883
21153
  if (!isCheckoutMode) return null;
20884
21154
  if (walletCheckoutQuote)
20885
21155
  return {
@@ -20909,10 +21179,10 @@ function WalletConnect({
20909
21179
  onDepositSuccess,
20910
21180
  onDepositError
20911
21181
  });
20912
- React34.useEffect(() => {
21182
+ React35.useEffect(() => {
20913
21183
  onExecutionsChange?.(depositExecutions);
20914
21184
  }, [depositExecutions, onExecutionsChange]);
20915
- const latestDepositExecution = React34.useMemo(() => {
21185
+ const latestDepositExecution = React35.useMemo(() => {
20916
21186
  if (depositExecutions.length === 0) return null;
20917
21187
  return [...depositExecutions].sort((a, b) => {
20918
21188
  const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
@@ -20920,21 +21190,21 @@ function WalletConnect({
20920
21190
  return tb - ta;
20921
21191
  })[0];
20922
21192
  }, [depositExecutions]);
20923
- React34.useEffect(() => {
21193
+ React35.useEffect(() => {
20924
21194
  if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
20925
21195
  transitionTo("mobile_deposit_status");
20926
21196
  }
20927
21197
  }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
20928
- React34.useEffect(() => {
20929
- if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
21198
+ React35.useEffect(() => {
21199
+ if (!isCheckoutMode || !tokenChainDetails || view !== "enter_amount") return;
20930
21200
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
20931
21201
  const currentAmount = parseFloat(amountUsd) || 0;
20932
21202
  if (currentAmount > 0 && currentAmount < minDeposit) setAmountUsd(minDeposit.toFixed(2));
20933
- }, [tokenChainDetails, view, prefillAmountUsd]);
20934
- React34.useEffect(() => {
21203
+ }, [isCheckoutMode, tokenChainDetails, view, amountUsd]);
21204
+ React35.useEffect(() => {
20935
21205
  if (view === "review") setShowTransactionDetails(false);
20936
21206
  }, [view]);
20937
- React34.useEffect(() => {
21207
+ React35.useEffect(() => {
20938
21208
  if (view !== "enter_amount" && view !== "review" || !selectedBalance || !activeDepositWallet)
20939
21209
  return;
20940
21210
  let cancelled = false;
@@ -20949,7 +21219,7 @@ function WalletConnect({
20949
21219
  destination_chain_type: activeDepositWallet.destination_chain_type,
20950
21220
  ...productType ? { product_type: productType } : {}
20951
21221
  };
20952
- const response = await (0, import_core37.getSupportedDepositTokens)(publishableKey, options);
21222
+ const response = await (0, import_core36.getSupportedDepositTokens)(publishableKey, options);
20953
21223
  if (cancelled) return;
20954
21224
  const supportedToken = response.data.find(
20955
21225
  (t13) => t13.symbol.toLowerCase() === token.symbol.toLowerCase()
@@ -20971,13 +21241,13 @@ function WalletConnect({
20971
21241
  cancelled = true;
20972
21242
  };
20973
21243
  }, [view, selectedBalance, publishableKey, activeDepositWallet]);
20974
- React34.useEffect(() => {
21244
+ React35.useEffect(() => {
20975
21245
  if (!activeWalletInfo || !activeDepositWallet) return;
20976
21246
  let cancelled = false;
20977
21247
  setIsLoading(true);
20978
21248
  setError(null);
20979
21249
  const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
20980
- (0, import_core37.getAddressBalances)(activeWalletInfo.address, sct, publishableKey).then((response) => {
21250
+ (0, import_core36.getAddressBalances)(activeWalletInfo.address, sct, publishableKey).then((response) => {
20981
21251
  if (cancelled) return;
20982
21252
  const nonZero = response.balances.filter((b) => b.amount !== "0");
20983
21253
  const defaultSource = {
@@ -21036,21 +21306,21 @@ function WalletConnect({
21036
21306
  defaultSourceTokenAddress,
21037
21307
  defaultSourceSymbol
21038
21308
  ]);
21039
- const usdToTokenRate = React34.useMemo(() => {
21309
+ const usdToTokenRate = React35.useMemo(() => {
21040
21310
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
21041
21311
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
21042
21312
  const balanceUsd = parseFloat(selectedBalance.amount_usd);
21043
21313
  if (balanceAmount === 0 || balanceUsd === 0) return 0;
21044
21314
  return balanceAmount / balanceUsd;
21045
21315
  }, [selectedBalance, selectedToken]);
21046
- const tokenAmount = React34.useMemo(() => {
21316
+ const tokenAmount = React35.useMemo(() => {
21047
21317
  if (isCheckoutMode && activeCheckoutQuote && selectedToken)
21048
21318
  return Number(activeCheckoutQuote.sourceAmount) / 10 ** activeCheckoutQuote.sourceTokenDecimals;
21049
21319
  const usdNum = parseFloat(amountUsd) || 0;
21050
21320
  if (usdNum === 0 || usdToTokenRate === 0) return 0;
21051
21321
  return usdNum * usdToTokenRate;
21052
21322
  }, [amountUsd, usdToTokenRate, isCheckoutMode, activeCheckoutQuote, selectedToken]);
21053
- React34.useEffect(() => {
21323
+ React35.useEffect(() => {
21054
21324
  if (isCheckoutMode && activeCheckoutQuote?.sourceAmountUsd && view === "enter_amount")
21055
21325
  setAmountUsd(activeCheckoutQuote.sourceAmountUsd);
21056
21326
  }, [isCheckoutMode, activeCheckoutQuote, view]);
@@ -21059,7 +21329,7 @@ function WalletConnect({
21059
21329
  const inputUsdNum = parseFloat(amountUsd) || 0;
21060
21330
  const minDepositUsd = tokenChainDetails?.minimum_deposit_amount_usd || 0;
21061
21331
  const isValidAmount = isCheckoutMode && activeCheckoutQuote ? tokenAmount > 0 && tokenAmount <= maxTokenAmount : inputUsdNum > 0 && inputUsdNum <= maxUsdAmount && inputUsdNum >= minDepositUsd;
21062
- const formattedTokenAmount = React34.useMemo(() => {
21332
+ const formattedTokenAmount = React35.useMemo(() => {
21063
21333
  if (tokenAmount === 0 || !selectedToken) return null;
21064
21334
  return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
21065
21335
  }, [tokenAmount, selectedToken]);
@@ -21092,7 +21362,7 @@ function WalletConnect({
21092
21362
  break;
21093
21363
  case "enter_amount":
21094
21364
  transitionTo("select_token");
21095
- setAmountUsd(prefillAmountUsd ?? "");
21365
+ setAmountUsd(prefilledAmountUsd ?? "");
21096
21366
  setTokenChainDetails(null);
21097
21367
  break;
21098
21368
  case "review":
@@ -21124,7 +21394,7 @@ function WalletConnect({
21124
21394
  setSelectedBalance(null);
21125
21395
  setBalances([]);
21126
21396
  setTotalBalanceUsd(null);
21127
- setAmountUsd(prefillAmountUsd ?? "");
21397
+ setAmountUsd(prefilledAmountUsd ?? "");
21128
21398
  setError(null);
21129
21399
  };
21130
21400
  if (standalone) {
@@ -21253,7 +21523,7 @@ function WalletConnect({
21253
21523
  if (!provider.publicKey) await provider.connect();
21254
21524
  const isNative = token.token_address === "native" || token.token_address === "So11111111111111111111111111111111111111112" || token.token_address === "";
21255
21525
  const smallestUnit = isNative ? decimalToSmallestUnit(amountStr, 9) : decimalToSmallestUnit(amountStr, token.decimals);
21256
- const buildResp = await (0, import_core37.buildSolanaTransaction)(
21526
+ const buildResp = await (0, import_core36.buildSolanaTransaction)(
21257
21527
  {
21258
21528
  chain_id: "mainnet",
21259
21529
  token_address: token.token_address === "" ? "native" : token.token_address,
@@ -21275,7 +21545,7 @@ function WalletConnect({
21275
21545
  const ser = signed.serialize();
21276
21546
  let bs = "";
21277
21547
  for (let i = 0; i < ser.length; i++) bs += String.fromCharCode(ser[i]);
21278
- const resp = await (0, import_core37.sendSolanaTransaction)(
21548
+ const resp = await (0, import_core36.sendSolanaTransaction)(
21279
21549
  { chain_id: "mainnet", signed_transaction: btoa(bs) },
21280
21550
  publishableKey
21281
21551
  );
@@ -21321,7 +21591,7 @@ function WalletConnect({
21321
21591
  } else if (isHypercoreToken) {
21322
21592
  let sendAmount = tokenAmount;
21323
21593
  try {
21324
- const activation = await (0, import_core37.checkHypercoreActivation)(
21594
+ const activation = await (0, import_core36.checkHypercoreActivation)(
21325
21595
  { source_address: walletInfo.address, recipient_address: recipientAddress },
21326
21596
  publishableKey
21327
21597
  );
@@ -21369,116 +21639,131 @@ function WalletConnect({
21369
21639
  ] });
21370
21640
  }
21371
21641
  if (view === "select_wallet") {
21372
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { style: viewTransitionStyle, children: [
21373
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21374
- DepositHeader,
21642
+ return (
21643
+ // Mobile: flex column that fills the full-height sheet so the wallet list
21644
+ // scrolls and the footer pins to the bottom. Desktop (sm:): content-sized.
21645
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
21646
+ "div",
21375
21647
  {
21376
- title: "Connect Wallet",
21377
- showBack: canGoBack,
21378
- onBack: handleBack,
21379
- onClose
21380
- }
21381
- ),
21382
- /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uf-pb-4", children: [
21383
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21384
- "p",
21385
- {
21386
- className: "uf-text-sm uf-text-center uf-pb-4",
21387
- style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
21388
- children: isMobile ? "Open this page in your wallet's app to connect" : "Select a wallet to connect"
21389
- }
21390
- ),
21391
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
21392
- const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
21393
- const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
21394
- const isPending = pendingMobileWallet?.id === wallet.id;
21395
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
21396
- "button",
21397
- {
21398
- onClick: () => void handleWalletClick(wallet),
21399
- disabled: isWalletConnecting || !!pendingMobileWallet,
21400
- className: "uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between hover:uf-opacity-90 disabled:uf-opacity-50",
21401
- style: {
21402
- backgroundColor: components.card.backgroundColor,
21403
- borderRadius: components.card.borderRadius,
21404
- border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
21405
- },
21406
- children: [
21407
- /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
21408
- WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21409
- WalletIconWithNetwork,
21410
- {
21411
- WalletIcon: WALLET_ICONS3[wallet.id],
21412
- networks: wallet.networks,
21413
- size: 40,
21414
- className: "uf-rounded-lg"
21415
- }
21416
- ) : /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
21417
- /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
21418
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21419
- "div",
21420
- {
21421
- className: "uf-text-sm uf-font-medium",
21422
- style: { color: components.card.titleColor, fontFamily: fonts.medium },
21423
- children: wallet.name
21424
- }
21425
- ),
21426
- wallet.id === recentWalletId && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21427
- "span",
21428
- {
21429
- className: "uf-text-xs uf-px-2 uf-py-0.5 uf-rounded-full",
21430
- style: {
21431
- backgroundColor: colors2.primary + "20",
21432
- color: colors2.primary,
21433
- fontFamily: fonts.medium
21434
- },
21435
- children: "Last used"
21436
- }
21437
- )
21438
- ] })
21439
- ] }),
21440
- isPending ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21441
- import_lucide_react36.Loader2,
21442
- {
21443
- className: "uf-w-4 uf-h-4 uf-animate-spin",
21444
- style: { color: colors2.primary }
21445
- }
21446
- ) : wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21447
- "span",
21648
+ style: viewTransitionStyle,
21649
+ className: "uf-flex uf-min-h-0 uf-flex-1 uf-flex-col sm:uf-block",
21650
+ children: [
21651
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21652
+ DepositHeader,
21653
+ {
21654
+ title: "Connect Wallet",
21655
+ showBack: canGoBack,
21656
+ onBack: handleBack,
21657
+ onClose
21658
+ }
21659
+ ),
21660
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uf-pb-4 uf-flex uf-min-h-0 uf-flex-1 uf-flex-col sm:uf-block", children: [
21661
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21662
+ "p",
21663
+ {
21664
+ className: "uf-text-sm uf-text-center uf-pb-4",
21665
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
21666
+ children: isMobile ? "Open this page in your wallet's app to connect" : "Select a wallet to connect"
21667
+ }
21668
+ ),
21669
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "uf-space-y-2 uf-min-h-0 uf-flex-1 uf-overflow-y-auto sm:uf-flex-none sm:uf-max-h-[330px] [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: availableWallets.filter((wallet) => {
21670
+ if (!isMobile || wallet.isInstalled) return true;
21671
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
21672
+ return wallet.supportsMobileBrowse !== false && platformAllowed;
21673
+ }).map((wallet) => {
21674
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
21675
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
21676
+ const isPending = pendingMobileWallet?.id === wallet.id;
21677
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
21678
+ "button",
21448
21679
  {
21449
- className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full",
21680
+ onClick: () => void handleWalletClick(wallet),
21681
+ disabled: isWalletConnecting || !!pendingMobileWallet,
21682
+ className: "uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between hover:uf-opacity-90 disabled:uf-opacity-50",
21450
21683
  style: {
21451
- backgroundColor: colors2.primary + "20",
21452
- color: colors2.primary,
21453
- fontFamily: fonts.medium
21684
+ backgroundColor: components.card.backgroundColor,
21685
+ borderRadius: components.card.borderRadius,
21686
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
21454
21687
  },
21455
- children: "Detected"
21456
- }
21457
- ) : /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
21458
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21459
- "span",
21460
- {
21461
- className: "uf-text-xs",
21462
- style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
21463
- children: showOpenInApp ? "Open" : "Install"
21464
- }
21465
- ),
21466
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21467
- import_lucide_react36.ExternalLink,
21468
- {
21469
- className: "uf-w-3 uf-h-3",
21470
- style: { color: colors2.foregroundMuted }
21471
- }
21472
- )
21473
- ] })
21474
- ]
21475
- },
21476
- wallet.id
21477
- );
21478
- }) }),
21479
- walletError && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
21480
- ] })
21481
- ] });
21688
+ children: [
21689
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
21690
+ WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21691
+ WalletIconWithNetwork,
21692
+ {
21693
+ WalletIcon: WALLET_ICONS3[wallet.id],
21694
+ networks: wallet.networks,
21695
+ size: 40,
21696
+ className: "uf-rounded-lg"
21697
+ }
21698
+ ) : /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
21699
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
21700
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21701
+ "div",
21702
+ {
21703
+ className: "uf-text-sm uf-font-medium",
21704
+ style: { color: components.card.titleColor, fontFamily: fonts.medium },
21705
+ children: wallet.name
21706
+ }
21707
+ ),
21708
+ wallet.id === recentWalletId && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21709
+ "span",
21710
+ {
21711
+ className: "uf-text-xs uf-px-2 uf-py-0.5 uf-rounded-full",
21712
+ style: {
21713
+ backgroundColor: colors2.primary + "20",
21714
+ color: colors2.primary,
21715
+ fontFamily: fonts.medium
21716
+ },
21717
+ children: "Last used"
21718
+ }
21719
+ )
21720
+ ] })
21721
+ ] }),
21722
+ isPending ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21723
+ import_lucide_react36.Loader2,
21724
+ {
21725
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
21726
+ style: { color: colors2.primary }
21727
+ }
21728
+ ) : wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21729
+ "span",
21730
+ {
21731
+ className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full",
21732
+ style: {
21733
+ backgroundColor: colors2.primary + "20",
21734
+ color: colors2.primary,
21735
+ fontFamily: fonts.medium
21736
+ },
21737
+ children: "Detected"
21738
+ }
21739
+ ) : /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
21740
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21741
+ "span",
21742
+ {
21743
+ className: "uf-text-xs",
21744
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
21745
+ children: showOpenInApp ? "Open" : "Install"
21746
+ }
21747
+ ),
21748
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
21749
+ import_lucide_react36.ExternalLink,
21750
+ {
21751
+ className: "uf-w-3 uf-h-3",
21752
+ style: { color: colors2.foregroundMuted }
21753
+ }
21754
+ )
21755
+ ] })
21756
+ ]
21757
+ },
21758
+ wallet.id
21759
+ );
21760
+ }) }),
21761
+ walletError && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
21762
+ ] })
21763
+ ]
21764
+ }
21765
+ )
21766
+ );
21482
21767
  }
21483
21768
  const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
21484
21769
  const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
@@ -21683,8 +21968,8 @@ function WalletConnect({
21683
21968
  ] }) });
21684
21969
  }
21685
21970
  if (view === "mobile_deposit_status" && latestDepositExecution) {
21686
- const isComplete = latestDepositExecution.status === import_core37.ExecutionStatus.SUCCEEDED;
21687
- const isFailed = latestDepositExecution.status === import_core37.ExecutionStatus.FAILED;
21971
+ const isComplete = latestDepositExecution.status === import_core36.ExecutionStatus.SUCCEEDED;
21972
+ const isFailed = latestDepositExecution.status === import_core36.ExecutionStatus.FAILED;
21688
21973
  const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
21689
21974
  return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { style: viewTransitionStyle, children: [
21690
21975
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
@@ -21836,6 +22121,15 @@ function SkeletonButton({ variant = "default" }) {
21836
22121
  ] });
21837
22122
  }
21838
22123
  var t8 = i18n.depositModal;
22124
+ function normalizePrefilledUsdAmount(value) {
22125
+ if (!value) return void 0;
22126
+ const cleaned = value.replace(/[^0-9.]/g, "");
22127
+ if (!cleaned) return void 0;
22128
+ const normalizedNumeric = cleaned.replace(/(\..*)\./g, "$1");
22129
+ const parsed = parseFloat(normalizedNumeric);
22130
+ if (!Number.isFinite(parsed) || parsed <= 0) return void 0;
22131
+ return parseFloat(parsed.toFixed(2)).toString();
22132
+ }
21839
22133
  function depositTabForScreen(screen) {
21840
22134
  return screen === "card" || screen === "cashapp" || screen === "bank_transfer" || screen === "stripe_link" || screen === "apple_pay" ? "cash" : "crypto";
21841
22135
  }
@@ -21855,6 +22149,7 @@ function DepositModal({
21855
22149
  defaultSourceChainId,
21856
22150
  defaultSourceTokenAddress,
21857
22151
  defaultSourceSymbol,
22152
+ prefilledAmountUsd,
21858
22153
  hideDepositTracker,
21859
22154
  showBalanceHeader = false,
21860
22155
  transferInputVariant = "double_input",
@@ -21870,7 +22165,9 @@ function DepositModal({
21870
22165
  applePayTitle = "Pay with Apple Pay",
21871
22166
  applePaySubTitle = "Instant",
21872
22167
  enableBankTransfer,
21873
- enableStripeLink = false,
22168
+ // No default: left undefined so the backend `stripe_link.enabled` can govern
22169
+ // (via the `??` chain in showStripeLink) once a dashboard toggle exists.
22170
+ enableStripeLink,
21874
22171
  userEmail,
21875
22172
  hideDepositFlowInfo = false,
21876
22173
  hideDisplayDescription = false,
@@ -21888,6 +22185,10 @@ function DepositModal({
21888
22185
  depositTrackerSubTitle = t8.depositTracker.subtitle
21889
22186
  }) {
21890
22187
  const { colors: colors2, fonts, components } = useTheme();
22188
+ const normalizedPrefilledAmountUsd = (0, import_react26.useMemo)(
22189
+ () => normalizePrefilledUsdAmount(prefilledAmountUsd),
22190
+ [prefilledAmountUsd]
22191
+ );
21891
22192
  const onDepositSuccessFor = (0, import_react26.useCallback)(
21892
22193
  (method) => onDepositSuccess || onEvent ? (data) => {
21893
22194
  const payload = { ...data, method };
@@ -21951,14 +22252,18 @@ function DepositModal({
21951
22252
  const [allExecutions, setAllExecutions] = (0, import_react26.useState)([]);
21952
22253
  const [selectedExecution, setSelectedExecution] = (0, import_react26.useState)(null);
21953
22254
  const [depositExecutions, setDepositExecutions] = (0, import_react26.useState)([]);
22255
+ const { userIpInfo, isLoading: isLoadingIp } = useUserIp();
21954
22256
  const { projectConfig } = useProjectConfig({
21955
22257
  publishableKey,
21956
- enabled: open
22258
+ enabled: open && !isLoadingIp,
22259
+ countryCode: userIpInfo?.alpha2,
22260
+ subdivisionCode: userIpInfo?.subdivisionCode ?? void 0
21957
22261
  });
21958
22262
  const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
21959
22263
  const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
21960
22264
  const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
21961
22265
  const showFiatOnramp = !projectConfig?.fiat_onramp?.is_hidden && (enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true);
22266
+ const showStripeLink = !projectConfig?.stripe_link?.is_hidden && (enableStripeLink ?? projectConfig?.stripe_link?.enabled ?? false);
21962
22267
  const showConnectExchange = enableConnectExchange ?? projectConfig?.connect_exchange?.enabled ?? true;
21963
22268
  const showCashApp = enableCashApp ?? projectConfig?.cash_app?.enabled ?? true;
21964
22269
  const showApplePay = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
@@ -21967,18 +22272,18 @@ function DepositModal({
21967
22272
  const [integrationExchanges, setIntegrationExchanges] = (0, import_react26.useState)([]);
21968
22273
  (0, import_react26.useEffect)(() => {
21969
22274
  if (!showConnectExchange || !open) return;
21970
- (0, import_core38.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
22275
+ (0, import_core37.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
21971
22276
  });
21972
22277
  }, [showConnectExchange, open, publishableKey]);
21973
22278
  const [connectedExchange, setConnectedExchange] = (0, import_react26.useState)(() => {
21974
22279
  if (!showConnectExchange) return null;
21975
- const stored = getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22280
+ const stored = getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
21976
22281
  if (!stored) return null;
21977
22282
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
21978
22283
  });
21979
22284
  (0, import_react26.useEffect)(() => {
21980
22285
  if (!showConnectExchange || !open || view !== "main") return;
21981
- const stored = getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22286
+ const stored = getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
21982
22287
  if (!stored) {
21983
22288
  setConnectedExchange(null);
21984
22289
  return;
@@ -21998,24 +22303,24 @@ function DepositModal({
21998
22303
  }) : null;
21999
22304
  setConnectedExchange((prev) => prev ? { ...prev, balanceUsd, isLoading: false } : null);
22000
22305
  };
22001
- (0, import_core38.getIntegrationHoldings)(import_core38.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
22306
+ (0, import_core37.getIntegrationHoldings)(import_core37.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
22002
22307
  try {
22003
- const refreshResult = await (0, import_core38.refreshIntegrationToken)(stored.access_token, publishableKey);
22004
- if (!getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE)) return;
22308
+ const refreshResult = await (0, import_core37.refreshIntegrationToken)(stored.access_token, publishableKey);
22309
+ if (!getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE)) return;
22005
22310
  setStoredIntegrationToken({
22006
- integration_provider: import_core38.IntegrationProvider.COINBASE,
22311
+ integration_provider: import_core37.IntegrationProvider.COINBASE,
22007
22312
  access_token: refreshResult.access_token,
22008
22313
  expires_at: refreshResult.expires_at
22009
22314
  });
22010
- const retryResult = await (0, import_core38.getIntegrationHoldings)(
22011
- import_core38.IntegrationProvider.COINBASE,
22315
+ const retryResult = await (0, import_core37.getIntegrationHoldings)(
22316
+ import_core37.IntegrationProvider.COINBASE,
22012
22317
  refreshResult.access_token,
22013
22318
  publishableKey
22014
22319
  );
22015
22320
  processHoldings(retryResult);
22016
22321
  } catch {
22017
- if (!getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE)) return;
22018
- clearStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22322
+ if (!getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE)) return;
22323
+ clearStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
22019
22324
  setConnectedExchange(null);
22020
22325
  }
22021
22326
  });
@@ -22023,7 +22328,7 @@ function DepositModal({
22023
22328
  (0, import_react26.useEffect)(() => {
22024
22329
  if (!connectedExchange || integrationExchanges.length === 0) return;
22025
22330
  const cbExchange = integrationExchanges.find(
22026
- (e) => e.service_provider === import_core38.IntegrationProvider.COINBASE
22331
+ (e) => e.service_provider === import_core37.IntegrationProvider.COINBASE
22027
22332
  );
22028
22333
  const iconUrl = cbExchange?.icon_urls?.find((u) => u.format === "svg")?.url || cbExchange?.icon_urls?.find((u) => u.format === "png")?.url || cbExchange?.icon_url;
22029
22334
  if (iconUrl && iconUrl !== connectedExchange.iconUrl) {
@@ -22104,7 +22409,6 @@ function DepositModal({
22104
22409
  publishableKey,
22105
22410
  enabled: open && showPayWithExchange
22106
22411
  });
22107
- const { userIpInfo, isLoading: isLoadingIp } = useUserIp();
22108
22412
  const { providers: bankTransferProviders, isLoading: bankTransferProvidersLoading } = useBankTransferProviders({
22109
22413
  publishableKey,
22110
22414
  enabled: open && !!userIpInfo?.alpha2,
@@ -22129,7 +22433,7 @@ function DepositModal({
22129
22433
  if (view !== "tracker" || !userId) return;
22130
22434
  const fetchExecutions = async () => {
22131
22435
  try {
22132
- const response = await (0, import_core38.queryExecutions)(userId, publishableKey, import_core38.ActionType.Deposit);
22436
+ const response = await (0, import_core37.queryExecutions)(userId, publishableKey, import_core37.ActionType.Deposit);
22133
22437
  const sorted = [...response.data].sort((a, b) => {
22134
22438
  const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
22135
22439
  const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
@@ -22231,11 +22535,11 @@ function DepositModal({
22231
22535
  if (view === "wallet_connect" && sessionOpenedFromMenu) setView("main");
22232
22536
  };
22233
22537
  const handleExchangeDisconnect = () => {
22234
- const stored = getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22538
+ const stored = getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
22235
22539
  if (stored) {
22236
- (0, import_core38.revokeIntegrationToken)(stored.access_token, publishableKey);
22540
+ (0, import_core37.revokeIntegrationToken)(stored.access_token, publishableKey);
22237
22541
  }
22238
- clearStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22542
+ clearStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
22239
22543
  setConnectedExchange(null);
22240
22544
  if (view === "coinbase_connect" && sessionOpenedFromMenu) setView("main");
22241
22545
  };
@@ -22282,6 +22586,12 @@ function DepositModal({
22282
22586
  const [cashAppView, setCashAppView] = (0, import_react26.useState)("amount");
22283
22587
  const [stripeLinkStep, setStripeLinkStep] = (0, import_react26.useState)("amount");
22284
22588
  const stripeLinkBackRef = (0, import_react26.useRef)(null);
22589
+ (0, import_react26.useEffect)(() => {
22590
+ if (view === "stripe_link" && !showStripeLink && effectiveInitialScreen === "main") {
22591
+ setView("main");
22592
+ setStripeLinkStep("amount");
22593
+ }
22594
+ }, [view, showStripeLink, effectiveInitialScreen]);
22285
22595
  const [cashAppAmount, setCashAppAmount] = (0, import_react26.useState)("");
22286
22596
  const [applePayView, setApplePayView] = (0, import_react26.useState)("email_input");
22287
22597
  const applePayHandleRef = (0, import_react26.useRef)(null);
@@ -22506,7 +22816,7 @@ function DepositModal({
22506
22816
  },
22507
22817
  "cashapp"
22508
22818
  ) : null;
22509
- const stripeLinkMenuButton = enableStripeLink ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22819
+ const stripeLinkMenuButton = showStripeLink ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22510
22820
  StripeLinkButton,
22511
22821
  {
22512
22822
  onClick: () => setView("stripe_link"),
@@ -22554,11 +22864,13 @@ function DepositModal({
22554
22864
  connectExchangeMenuButton
22555
22865
  ].filter(Boolean);
22556
22866
  const cashMenuButtons = [
22867
+ // Stripe "Pay with Link" is intentionally listed first so it always sits
22868
+ // above "Deposit with Card".
22869
+ stripeLinkMenuButton,
22557
22870
  depositWithCardMenuButton,
22558
22871
  applePayMenuButton,
22559
22872
  cashAppMenuButton,
22560
- bankTransferMenuButton,
22561
- stripeLinkMenuButton
22873
+ bankTransferMenuButton
22562
22874
  ].filter(Boolean);
22563
22875
  const depositTabs = [
22564
22876
  { id: "crypto", label: "Use Crypto", icon: import_lucide_react37.Bitcoin, buttons: cryptoMenuButtons },
@@ -22653,13 +22965,13 @@ function DepositModal({
22653
22965
  const stackedOptions = [
22654
22966
  transferCryptoMenuButton,
22655
22967
  connectWalletMenuButton,
22968
+ stripeLinkMenuButton,
22656
22969
  depositWithCardMenuButton,
22657
22970
  applePayMenuButton,
22658
22971
  payWithExchangeMenuButton,
22659
22972
  connectExchangeMenuButton,
22660
22973
  cashAppMenuButton,
22661
22974
  bankTransferMenuButton,
22662
- stripeLinkMenuButton,
22663
22975
  depositTrackerMenuButton
22664
22976
  ].filter(Boolean);
22665
22977
  return renderScrollableOptions(stackedOptions);
@@ -22675,410 +22987,461 @@ function DepositModal({
22675
22987
  {
22676
22988
  ref: hideOverlay ? containerCallbackRef : void 0,
22677
22989
  hideOverlay,
22678
- className: `sm:uf-max-w-[400px] uf-border-secondary uf-text-foreground uf-gap-0 [&>button]:uf-hidden ${hideOverlay ? `uf-p-6 uf-overflow-hidden ${themeClass}` : `uf-p-0 uf-overflow-visible ${view === "main" ? "!uf-top-auto !uf-h-auto !uf-max-h-[85vh] sm:!uf-max-h-none sm:!uf-top-[50%]" : "!uf-top-0 !uf-h-full sm:!uf-h-auto sm:!uf-top-[50%]"} ${themeClass}`}`,
22990
+ className: `sm:uf-max-w-[400px] uf-border-secondary uf-text-foreground uf-gap-0 [&>button]:uf-hidden ${hideOverlay ? `uf-p-6 uf-overflow-hidden ${themeClass}` : `uf-p-0 uf-overflow-visible ${view === "main" ? "!uf-top-auto !uf-h-auto !uf-max-h-[85vh] sm:!uf-max-h-none sm:!uf-top-[50%]" : "!uf-top-0 !uf-h-full sm:!uf-h-auto sm:!uf-top-[50%]"} ${// wallet_connect fills the full-height mobile sheet. DialogContent
22991
+ // is a grid, and its single auto row only *grows* to fill free
22992
+ // space (align-content: stretch) — it never shrinks below content,
22993
+ // so a long wallet list would balloon the row past the viewport and
22994
+ // push the footer off-screen instead of scrolling. Clamp the row to
22995
+ // the modal height with minmax(0,1fr) so the inner overflow-y-auto
22996
+ // list scrolls with the footer pinned. Reset to content-sized on
22997
+ // desktop (sm:) where the modal is auto-height and centered.
22998
+ view === "wallet_connect" ? "[grid-template-rows:minmax(0,1fr)] sm:[grid-template-rows:none]" : ""} ${themeClass}`}`,
22679
22999
  style: { backgroundColor: colors2.background },
22680
23000
  onPointerDownOutside: (e) => e.preventDefault(),
22681
23001
  onInteractOutside: (e) => e.preventDefault(),
22682
23002
  children: [
22683
23003
  /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(DialogTitle, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
22684
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-min-h-0 uf-max-h-full", children: [
22685
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22686
- DepositHeader,
22687
- {
22688
- title: modalTitle || "Deposit",
22689
- showClose: !hideOverlay,
22690
- onClose: handleClose,
22691
- showBalance: showBalanceHeader,
22692
- balanceAddress: recipientAddress,
22693
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
22694
- balanceChainId: destinationChainId,
22695
- balanceTokenAddress: destinationTokenAddress,
22696
- projectName: projectConfig?.project_name,
22697
- publishableKey
22698
- }
22699
- ) }),
22700
- renderMainMenuBody(),
22701
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-flex-shrink-0", children: depositPoweredByFooter })
22702
- ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
22703
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22704
- DepositHeader,
22705
- {
22706
- title: transferCryptoTitle,
22707
- showBack: showBackTransfer,
22708
- onBack: handleBack,
22709
- onClose: handleClose,
22710
- showBalance: showBalanceHeader,
22711
- balanceAddress: recipientAddress,
22712
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
22713
- balanceChainId: destinationChainId,
22714
- balanceTokenAddress: destinationTokenAddress,
22715
- projectName: projectConfig?.project_name,
22716
- publishableKey
22717
- }
22718
- ),
22719
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
22720
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22721
- TransferCryptoSingleInput,
22722
- {
22723
- userId,
22724
- publishableKey,
22725
- recipientAddress,
22726
- destinationChainType,
22727
- destinationChainId,
22728
- destinationTokenAddress,
22729
- defaultSourceChainType,
22730
- defaultSourceChainId,
22731
- defaultSourceTokenAddress,
22732
- defaultSourceSymbol,
22733
- depositConfirmationMode,
22734
- onExecutionsChange: setDepositExecutions,
22735
- onDepositSuccess: onDepositSuccessFor("transfer"),
22736
- onDepositError: onDepositErrorFor("transfer"),
22737
- wallets
22738
- }
22739
- ) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22740
- TransferCryptoDoubleInput,
22741
- {
22742
- userId,
22743
- publishableKey,
22744
- recipientAddress,
22745
- destinationChainType,
22746
- destinationChainId,
22747
- destinationTokenAddress,
22748
- defaultSourceChainType,
22749
- defaultSourceChainId,
22750
- defaultSourceTokenAddress,
22751
- defaultSourceSymbol,
22752
- depositConfirmationMode,
22753
- onExecutionsChange: setDepositExecutions,
22754
- onDepositSuccess: onDepositSuccessFor("transfer"),
22755
- onDepositError: onDepositErrorFor("transfer"),
22756
- wallets
22757
- }
22758
- ),
22759
- depositPoweredByFooter
22760
- ] })
22761
- ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
22762
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22763
- DepositHeader,
22764
- {
22765
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
22766
- showBack: showBackTracker,
22767
- onBack: handleBack,
22768
- onClose: handleClose
22769
- }
22770
- ),
22771
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
22772
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22773
- "div",
22774
- {
22775
- className: "uf-text-sm",
22776
- style: {
22777
- color: components.container.subtitleColor,
22778
- fontFamily: fonts.regular
22779
- },
22780
- children: "No deposits yet"
22781
- }
22782
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22783
- DepositExecutionItem,
22784
- {
22785
- execution,
22786
- onClick: () => setSelectedExecution(execution)
22787
- },
22788
- execution.id
22789
- )) }) }),
22790
- depositPoweredByFooter
22791
- ] })
22792
- ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
22793
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22794
- DepositHeader,
22795
- {
22796
- title: cardView === "quotes" ? t8.quotes : depositWithCardTitle,
22797
- showBack: showBackCard,
22798
- onBack: handleBack,
22799
- onClose: handleClose,
22800
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
22801
- showBalance: showBalanceHeader,
22802
- balanceAddress: recipientAddress,
22803
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
22804
- balanceChainId: destinationChainId,
22805
- balanceTokenAddress: destinationTokenAddress,
22806
- projectName: projectConfig?.project_name,
22807
- publishableKey
22808
- }
22809
- ),
22810
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
22811
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : !showFiatOnramp ? (
22812
- // Fiat on-ramp resolved hidden/disabled after a direct open
22813
- // (e.g. platform `is_hidden` for a Stripe Link-only project).
22814
- // Show a geo-restriction screen rather than the card UI so the
22815
- // hard-hide is honoured without a flash of "Pay with Card".
22816
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(GeoRestrictionScreen, { methodName: "Card" })
22817
- ) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22818
- BuyWithCard,
22819
- {
22820
- userId,
22821
- publishableKey,
22822
- view: cardView,
22823
- onViewChange: handleCardViewChange,
22824
- destinationTokenSymbol,
22825
- recipientAddress,
22826
- destinationChainType,
22827
- destinationChainId,
22828
- destinationTokenAddress,
22829
- onDepositSuccess: onDepositSuccessFor("card"),
22830
- onDepositError: onDepositErrorFor("card"),
22831
- onEvent,
22832
- themeClass,
22833
- wallets,
22834
- assetCdnUrl: projectConfig?.asset_cdn_url,
22835
- hideDepositFlowInfo,
22836
- hideDisplayDescription
22837
- }
22838
- ),
22839
- depositPoweredByFooter
22840
- ] })
22841
- ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
22842
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22843
- DepositHeader,
22844
- {
22845
- title: payWithExchangeTitle,
22846
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
22847
- onBack: handleBack,
22848
- onClose: handleClose
22849
- }
22850
- ),
22851
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
22852
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22853
- PayWithExchange,
22854
- {
22855
- userId,
22856
- publishableKey,
22857
- exchanges,
22858
- view: exchangeView,
22859
- onViewChange: setExchangeView,
22860
- destinationTokenSymbol,
22861
- recipientAddress,
22862
- destinationChainType,
22863
- destinationChainId,
22864
- destinationTokenAddress,
22865
- onDepositSuccess: onDepositSuccessFor("pay_with_exchange"),
22866
- onDepositError: onDepositErrorFor("pay_with_exchange"),
22867
- wallets,
22868
- defaultToken: defaultToken ?? null
22869
- }
22870
- ),
22871
- depositPoweredByFooter
22872
- ] })
22873
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
22874
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22875
- CoinbaseConnect,
22876
- {
22877
- publishableKey,
22878
- userId,
22879
- wallets,
22880
- recipientAddress,
22881
- destinationTokenAddress: destinationTokenAddress ?? "",
22882
- destinationChainId: destinationChainId ?? "",
22883
- destinationChainType: destinationChainType ?? "",
22884
- onDepositSuccess: onDepositSuccessFor("exchange_connect"),
22885
- onDepositError: onDepositErrorFor("exchange_connect"),
22886
- onTransferError: (error) => {
22887
- onDepositErrorFor("exchange_connect")?.({
22888
- message: error.message,
22889
- error
22890
- });
22891
- },
22892
- onBack: handleBack,
22893
- onClose: handleClose,
22894
- onDisconnect: handleExchangeDisconnect,
22895
- skipToHoldings: coinbaseSkipToHoldings,
22896
- canGoBack: sessionOpenedFromMenu,
22897
- onExecutionsChange: setDepositExecutions,
22898
- defaultSourceChainType,
22899
- defaultSourceChainId,
22900
- defaultSourceTokenAddress,
22901
- defaultSourceSymbol
22902
- }
22903
- ),
22904
- depositPoweredByFooter
22905
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
22906
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22907
- WalletConnect,
22908
- {
22909
- walletInfo: browserWalletInfo ?? void 0,
22910
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
22911
- wallets,
22912
- userId,
22913
- publishableKey,
22914
- assetCdnUrl: projectConfig?.asset_cdn_url,
22915
- projectName: projectConfig?.project_name,
22916
- onError: (error) => {
22917
- onDepositErrorFor("wallet_connect")?.({
22918
- message: error.message,
22919
- error
22920
- });
22921
- },
22922
- onDepositSuccess: onDepositSuccessFor("wallet_connect"),
22923
- onDepositError: onDepositErrorFor("wallet_connect"),
22924
- amountQuickSelect: browserWalletAmountQuickSelect,
22925
- onWalletDisconnect: handleWalletDisconnect,
22926
- onWalletConnected: (info, dw) => {
22927
- setBrowserWalletInfo({ ...info, depositWallet: dw });
22928
- setStoredWalletState(info.type);
22929
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
22930
- },
22931
- onBack: handleBack,
22932
- onClose: handleClose,
22933
- defaultSourceChainType,
22934
- defaultSourceChainId,
22935
- defaultSourceTokenAddress,
22936
- defaultSourceSymbol,
22937
- canGoBack: sessionOpenedFromMenu,
22938
- depositWalletsLoading: walletsLoading
22939
- }
22940
- ),
22941
- depositPoweredByFooter
22942
- ] }) : view === "bank_transfer" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
22943
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22944
- DepositHeader,
22945
- {
22946
- title: t8.bankTransfer.title,
22947
- showBack: bankTransferView !== "providers" || sessionOpenedFromMenu,
22948
- onBack: handleBack,
22949
- onClose: handleClose
22950
- }
22951
- ),
22952
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
22953
- bankTransferProvidersLoading ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SkeletonButton, { variant: "with-icons" }) : !hasEnabledBankTransferProvider ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(GeoRestrictionScreen, { methodName: "Bank Transfer" }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22954
- BankTransfer,
22955
- {
22956
- userId,
22957
- publishableKey,
22958
- view: bankTransferView,
22959
- onViewChange: setBankTransferView,
22960
- recipientAddress,
22961
- destinationChainType,
22962
- destinationChainId,
22963
- destinationTokenAddress,
22964
- destinationTokenSymbol,
22965
- wallets,
22966
- defaultToken: defaultToken ?? null,
22967
- assetCdnUrl: projectConfig?.asset_cdn_url,
22968
- onEvent,
22969
- onDepositSuccess,
22970
- onDepositError
22971
- }
22972
- ),
22973
- depositPoweredByFooter
22974
- ] })
22975
- ] }) : view === "stripe_link" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
22976
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22977
- DepositHeader,
22978
- {
22979
- title: "Deposit with Link",
22980
- showBack: stripeLinkStep !== "checkout" && stripeLinkStep !== "success",
22981
- onBack: handleBack,
22982
- showClose: stripeLinkStep !== "checkout",
22983
- onClose: handleClose
22984
- }
22985
- ),
22986
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
22987
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22988
- PayWithStripeLink,
22989
- {
22990
- userId,
22991
- publishableKey,
22992
- recipientAddress,
22993
- destinationChainType,
22994
- destinationChainId,
22995
- destinationTokenAddress,
22996
- wallets,
22997
- email: userEmail,
22998
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/link.svg` : void 0,
22999
- step: stripeLinkStep,
23000
- onStepChange: setStripeLinkStep,
23001
- backHandlerRef: stripeLinkBackRef,
23002
- onDepositSuccess,
23003
- onDepositError
23004
- }
23005
- ),
23006
- depositPoweredByFooter
23007
- ] })
23008
- ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23009
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23010
- DepositHeader,
23011
- {
23012
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
23013
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
23014
- onBack: handleBack,
23015
- onClose: handleClose
23016
- }
23017
- ),
23018
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23019
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23020
- PayWithCashApp,
23021
- {
23022
- userId,
23023
- publishableKey,
23024
- recipientAddress,
23025
- destinationChainType,
23026
- destinationChainId,
23027
- destinationTokenAddress,
23028
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
23029
- view: cashAppView,
23030
- onViewChange: setCashAppView,
23031
- onAmountChange: setCashAppAmount,
23032
- onEvent,
23033
- onDepositSuccess: onDepositSuccessFor("cashapp"),
23034
- onDepositError: onDepositErrorFor("cashapp"),
23035
- wallets
23036
- }
23037
- ),
23038
- depositPoweredByFooter
23039
- ] })
23040
- ] }) : view === "apple_pay" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23041
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23042
- DepositHeader,
23043
- {
23044
- title: applePayHeaderTitle,
23045
- showBack: applePayShowBack,
23046
- onBack: () => {
23047
- const handled = applePayHandleRef.current?.requestBack() ?? false;
23048
- if (!handled) handleBack();
23049
- },
23050
- onClose: handleClose
23051
- }
23052
- ),
23053
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23054
- applePayProvidersLoading ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SkeletonButton, { variant: "with-icons" }) : !hasEnabledApplePayProvider ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(GeoRestrictionScreen, { methodName: "Apple Pay" }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23055
- BuyWithApplePay,
23056
- {
23057
- ref: applePayHandleRef,
23058
- userId,
23059
- publishableKey,
23060
- destinationChainType,
23061
- destinationChainId,
23062
- destinationTokenAddress,
23063
- userEmail,
23064
- wallets,
23065
- onViewChange: setApplePayView,
23066
- onEvent,
23067
- onDepositSuccess: onDepositSuccessFor("apple_pay"),
23068
- onDepositError: onDepositErrorFor("apple_pay"),
23069
- exitLabel: sessionOpenedFromMenu ? "Return" : "Close",
23070
- onExit: () => {
23071
- if (sessionOpenedFromMenu) {
23072
- setView("main");
23073
- } else {
23074
- handleClose();
23004
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23005
+ ThemeStyleInjector,
23006
+ {
23007
+ className: view === "wallet_connect" ? "uf-flex uf-min-h-0 uf-flex-col" : void 0,
23008
+ children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-min-h-0 uf-max-h-full", children: [
23009
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23010
+ DepositHeader,
23011
+ {
23012
+ title: modalTitle || "Deposit",
23013
+ showClose: !hideOverlay,
23014
+ onClose: handleClose,
23015
+ showBalance: showBalanceHeader,
23016
+ balanceAddress: recipientAddress,
23017
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
23018
+ balanceChainId: destinationChainId,
23019
+ balanceTokenAddress: destinationTokenAddress,
23020
+ projectName: projectConfig?.project_name,
23021
+ publishableKey
23022
+ }
23023
+ ) }),
23024
+ renderMainMenuBody(),
23025
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-flex-shrink-0", children: depositPoweredByFooter })
23026
+ ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23027
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23028
+ DepositHeader,
23029
+ {
23030
+ title: transferCryptoTitle,
23031
+ showBack: showBackTransfer,
23032
+ onBack: handleBack,
23033
+ onClose: handleClose,
23034
+ showBalance: showBalanceHeader,
23035
+ balanceAddress: recipientAddress,
23036
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
23037
+ balanceChainId: destinationChainId,
23038
+ balanceTokenAddress: destinationTokenAddress,
23039
+ projectName: projectConfig?.project_name,
23040
+ publishableKey
23041
+ }
23042
+ ),
23043
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23044
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23045
+ TransferCryptoSingleInput,
23046
+ {
23047
+ userId,
23048
+ publishableKey,
23049
+ recipientAddress,
23050
+ destinationChainType,
23051
+ destinationChainId,
23052
+ destinationTokenAddress,
23053
+ defaultSourceChainType,
23054
+ defaultSourceChainId,
23055
+ defaultSourceTokenAddress,
23056
+ defaultSourceSymbol,
23057
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
23058
+ depositConfirmationMode,
23059
+ onExecutionsChange: setDepositExecutions,
23060
+ onDepositSuccess: onDepositSuccessFor("transfer"),
23061
+ onDepositError: onDepositErrorFor("transfer"),
23062
+ wallets
23063
+ }
23064
+ ) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23065
+ TransferCryptoDoubleInput,
23066
+ {
23067
+ userId,
23068
+ publishableKey,
23069
+ recipientAddress,
23070
+ destinationChainType,
23071
+ destinationChainId,
23072
+ destinationTokenAddress,
23073
+ defaultSourceChainType,
23074
+ defaultSourceChainId,
23075
+ defaultSourceTokenAddress,
23076
+ defaultSourceSymbol,
23077
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
23078
+ depositConfirmationMode,
23079
+ onExecutionsChange: setDepositExecutions,
23080
+ onDepositSuccess: onDepositSuccessFor("transfer"),
23081
+ onDepositError: onDepositErrorFor("transfer"),
23082
+ wallets
23075
23083
  }
23084
+ ),
23085
+ depositPoweredByFooter
23086
+ ] })
23087
+ ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23088
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23089
+ DepositHeader,
23090
+ {
23091
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
23092
+ showBack: showBackTracker,
23093
+ onBack: handleBack,
23094
+ onClose: handleClose
23076
23095
  }
23077
- }
23078
- ),
23079
- depositPoweredByFooter
23080
- ] })
23081
- ] }) : null })
23096
+ ),
23097
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23098
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23099
+ "div",
23100
+ {
23101
+ className: "uf-text-sm",
23102
+ style: {
23103
+ color: components.container.subtitleColor,
23104
+ fontFamily: fonts.regular
23105
+ },
23106
+ children: "No deposits yet"
23107
+ }
23108
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23109
+ DepositExecutionItem,
23110
+ {
23111
+ execution,
23112
+ onClick: () => setSelectedExecution(execution)
23113
+ },
23114
+ execution.id
23115
+ )) }) }),
23116
+ depositPoweredByFooter
23117
+ ] })
23118
+ ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23119
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23120
+ DepositHeader,
23121
+ {
23122
+ title: cardView === "quotes" ? t8.quotes : depositWithCardTitle,
23123
+ showBack: showBackCard,
23124
+ onBack: handleBack,
23125
+ onClose: handleClose,
23126
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
23127
+ showBalance: showBalanceHeader,
23128
+ balanceAddress: recipientAddress,
23129
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
23130
+ balanceChainId: destinationChainId,
23131
+ balanceTokenAddress: destinationTokenAddress,
23132
+ projectName: projectConfig?.project_name,
23133
+ publishableKey
23134
+ }
23135
+ ),
23136
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23137
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : !showFiatOnramp ? (
23138
+ // Fiat on-ramp resolved hidden/disabled after a direct open
23139
+ // (e.g. platform `is_hidden` for a Stripe Link-only project).
23140
+ // Show a geo-restriction screen rather than the card UI so the
23141
+ // hard-hide is honoured without a flash of "Pay with Card".
23142
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(GeoRestrictionScreen, { methodName: "Card" })
23143
+ ) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23144
+ BuyWithCard,
23145
+ {
23146
+ userId,
23147
+ publishableKey,
23148
+ view: cardView,
23149
+ onViewChange: handleCardViewChange,
23150
+ destinationTokenSymbol,
23151
+ recipientAddress,
23152
+ destinationChainType,
23153
+ destinationChainId,
23154
+ destinationTokenAddress,
23155
+ onDepositSuccess: onDepositSuccessFor("card"),
23156
+ onDepositError: onDepositErrorFor("card"),
23157
+ onEvent,
23158
+ themeClass,
23159
+ wallets,
23160
+ assetCdnUrl: projectConfig?.asset_cdn_url,
23161
+ hideDepositFlowInfo,
23162
+ hideDisplayDescription,
23163
+ prefilledAmountUsd: normalizedPrefilledAmountUsd
23164
+ }
23165
+ ),
23166
+ depositPoweredByFooter
23167
+ ] })
23168
+ ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23169
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23170
+ DepositHeader,
23171
+ {
23172
+ title: payWithExchangeTitle,
23173
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
23174
+ onBack: handleBack,
23175
+ onClose: handleClose
23176
+ }
23177
+ ),
23178
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23179
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23180
+ PayWithExchange,
23181
+ {
23182
+ userId,
23183
+ publishableKey,
23184
+ exchanges,
23185
+ view: exchangeView,
23186
+ onViewChange: setExchangeView,
23187
+ destinationTokenSymbol,
23188
+ recipientAddress,
23189
+ destinationChainType,
23190
+ destinationChainId,
23191
+ destinationTokenAddress,
23192
+ onDepositSuccess: onDepositSuccessFor("pay_with_exchange"),
23193
+ onDepositError: onDepositErrorFor("pay_with_exchange"),
23194
+ wallets,
23195
+ defaultToken: defaultToken ?? null
23196
+ }
23197
+ ),
23198
+ depositPoweredByFooter
23199
+ ] })
23200
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23201
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23202
+ CoinbaseConnect,
23203
+ {
23204
+ publishableKey,
23205
+ userId,
23206
+ wallets,
23207
+ recipientAddress,
23208
+ destinationTokenAddress: destinationTokenAddress ?? "",
23209
+ destinationChainId: destinationChainId ?? "",
23210
+ destinationChainType: destinationChainType ?? "",
23211
+ onDepositSuccess: onDepositSuccessFor("exchange_connect"),
23212
+ onDepositError: onDepositErrorFor("exchange_connect"),
23213
+ onTransferError: (error) => {
23214
+ onDepositErrorFor("exchange_connect")?.({
23215
+ message: error.message,
23216
+ error
23217
+ });
23218
+ },
23219
+ onBack: handleBack,
23220
+ onClose: handleClose,
23221
+ onDisconnect: handleExchangeDisconnect,
23222
+ skipToHoldings: coinbaseSkipToHoldings,
23223
+ canGoBack: sessionOpenedFromMenu,
23224
+ onExecutionsChange: setDepositExecutions,
23225
+ defaultSourceChainType,
23226
+ defaultSourceChainId,
23227
+ defaultSourceTokenAddress,
23228
+ defaultSourceSymbol,
23229
+ prefilledAmountUsd: normalizedPrefilledAmountUsd
23230
+ }
23231
+ ),
23232
+ depositPoweredByFooter
23233
+ ] }) : view === "wallet_connect" ? (
23234
+ // Mobile: flex-fill the full-height dialog body so the wallet list
23235
+ // can grow and scroll, with the footer pinned to the bottom.
23236
+ // Desktop (sm:): stays content-sized.
23237
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
23238
+ "div",
23239
+ {
23240
+ className: "uf-flex uf-flex-col uf-gap-1.5 uf-min-h-0 uf-flex-1 sm:uf-flex-none",
23241
+ children: [
23242
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23243
+ WalletConnect,
23244
+ {
23245
+ walletInfo: browserWalletInfo ?? void 0,
23246
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
23247
+ wallets,
23248
+ userId,
23249
+ publishableKey,
23250
+ assetCdnUrl: projectConfig?.asset_cdn_url,
23251
+ projectName: projectConfig?.project_name,
23252
+ onError: (error) => {
23253
+ onDepositErrorFor("wallet_connect")?.({
23254
+ message: error.message,
23255
+ error
23256
+ });
23257
+ },
23258
+ onDepositSuccess: onDepositSuccessFor("wallet_connect"),
23259
+ onDepositError: onDepositErrorFor("wallet_connect"),
23260
+ amountQuickSelect: browserWalletAmountQuickSelect,
23261
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
23262
+ onWalletDisconnect: handleWalletDisconnect,
23263
+ onWalletConnected: (info, dw) => {
23264
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
23265
+ setStoredWalletState(info.type);
23266
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
23267
+ },
23268
+ onBack: handleBack,
23269
+ onClose: handleClose,
23270
+ defaultSourceChainType,
23271
+ defaultSourceChainId,
23272
+ defaultSourceTokenAddress,
23273
+ defaultSourceSymbol,
23274
+ canGoBack: sessionOpenedFromMenu,
23275
+ depositWalletsLoading: walletsLoading
23276
+ }
23277
+ ),
23278
+ depositPoweredByFooter
23279
+ ]
23280
+ }
23281
+ )
23282
+ ) : view === "bank_transfer" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23283
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23284
+ DepositHeader,
23285
+ {
23286
+ title: t8.bankTransfer.title,
23287
+ showBack: bankTransferView !== "providers" || sessionOpenedFromMenu,
23288
+ onBack: handleBack,
23289
+ onClose: handleClose
23290
+ }
23291
+ ),
23292
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23293
+ bankTransferProvidersLoading ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SkeletonButton, { variant: "with-icons" }) : !hasEnabledBankTransferProvider ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(GeoRestrictionScreen, { methodName: "Bank Transfer" }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23294
+ BankTransfer,
23295
+ {
23296
+ userId,
23297
+ publishableKey,
23298
+ view: bankTransferView,
23299
+ onViewChange: setBankTransferView,
23300
+ recipientAddress,
23301
+ destinationChainType,
23302
+ destinationChainId,
23303
+ destinationTokenAddress,
23304
+ destinationTokenSymbol,
23305
+ wallets,
23306
+ defaultToken: defaultToken ?? null,
23307
+ assetCdnUrl: projectConfig?.asset_cdn_url,
23308
+ onEvent,
23309
+ onDepositSuccess,
23310
+ onDepositError,
23311
+ prefilledAmountUsd: normalizedPrefilledAmountUsd
23312
+ }
23313
+ ),
23314
+ depositPoweredByFooter
23315
+ ] })
23316
+ ] }) : view === "stripe_link" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23317
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23318
+ DepositHeader,
23319
+ {
23320
+ title: "Deposit with Link",
23321
+ showBack: stripeLinkStep !== "checkout" && stripeLinkStep !== "success",
23322
+ onBack: handleBack,
23323
+ showClose: stripeLinkStep !== "checkout" && stripeLinkStep !== "auth",
23324
+ onClose: handleClose
23325
+ }
23326
+ ),
23327
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23328
+ isLoadingIp ? (
23329
+ // Hold the geo decision until IP resolves so we don't mount
23330
+ // PayWithStripeLink (which kicks off config/OAuth work) for a
23331
+ // deep-link user who turns out to be outside the US.
23332
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SkeletonButton, { variant: "with-icons" })
23333
+ ) : !showStripeLink ? (
23334
+ // Stripe Link's crypto on-ramp is US-only. On a direct open
23335
+ // (initialScreen="stripe_link") the row isn't in a menu to
23336
+ // fall back to, so show a geo-restriction screen rather than
23337
+ // the Link UI.
23338
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23339
+ GeoRestrictionScreen,
23340
+ {
23341
+ methodName: t8.stripeLink.title,
23342
+ message: "Pay with Link is only available in the US."
23343
+ }
23344
+ )
23345
+ ) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23346
+ PayWithStripeLink,
23347
+ {
23348
+ userId,
23349
+ publishableKey,
23350
+ recipientAddress,
23351
+ destinationChainType,
23352
+ destinationChainId,
23353
+ destinationTokenAddress,
23354
+ countryCode: userIpInfo?.alpha2,
23355
+ subdivisionCode: userIpInfo?.subdivisionCode ?? void 0,
23356
+ wallets,
23357
+ email: userEmail,
23358
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/link.svg` : void 0,
23359
+ step: stripeLinkStep,
23360
+ onStepChange: setStripeLinkStep,
23361
+ backHandlerRef: stripeLinkBackRef,
23362
+ onDepositSuccess,
23363
+ onDepositError
23364
+ }
23365
+ ),
23366
+ depositPoweredByFooter
23367
+ ] })
23368
+ ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23369
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23370
+ DepositHeader,
23371
+ {
23372
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
23373
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
23374
+ onBack: handleBack,
23375
+ onClose: handleClose
23376
+ }
23377
+ ),
23378
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23379
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23380
+ PayWithCashApp,
23381
+ {
23382
+ userId,
23383
+ publishableKey,
23384
+ recipientAddress,
23385
+ destinationChainType,
23386
+ destinationChainId,
23387
+ destinationTokenAddress,
23388
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
23389
+ view: cashAppView,
23390
+ onViewChange: setCashAppView,
23391
+ onAmountChange: setCashAppAmount,
23392
+ onEvent,
23393
+ onDepositSuccess: onDepositSuccessFor("cashapp"),
23394
+ onDepositError: onDepositErrorFor("cashapp"),
23395
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
23396
+ wallets
23397
+ }
23398
+ ),
23399
+ depositPoweredByFooter
23400
+ ] })
23401
+ ] }) : view === "apple_pay" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
23402
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23403
+ DepositHeader,
23404
+ {
23405
+ title: applePayHeaderTitle,
23406
+ showBack: applePayShowBack,
23407
+ onBack: () => {
23408
+ const handled = applePayHandleRef.current?.requestBack() ?? false;
23409
+ if (!handled) handleBack();
23410
+ },
23411
+ onClose: handleClose
23412
+ }
23413
+ ),
23414
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23415
+ applePayProvidersLoading ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SkeletonButton, { variant: "with-icons" }) : !hasEnabledApplePayProvider ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(GeoRestrictionScreen, { methodName: "Apple Pay" }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23416
+ BuyWithApplePay,
23417
+ {
23418
+ ref: applePayHandleRef,
23419
+ userId,
23420
+ publishableKey,
23421
+ destinationChainType,
23422
+ destinationChainId,
23423
+ destinationTokenAddress,
23424
+ userEmail,
23425
+ wallets,
23426
+ onViewChange: setApplePayView,
23427
+ onEvent,
23428
+ onDepositSuccess: onDepositSuccessFor("apple_pay"),
23429
+ onDepositError: onDepositErrorFor("apple_pay"),
23430
+ exitLabel: sessionOpenedFromMenu ? "Return" : "Close",
23431
+ onExit: () => {
23432
+ if (sessionOpenedFromMenu) {
23433
+ setView("main");
23434
+ } else {
23435
+ handleClose();
23436
+ }
23437
+ }
23438
+ }
23439
+ ),
23440
+ depositPoweredByFooter
23441
+ ] })
23442
+ ] }) : null
23443
+ }
23444
+ )
23082
23445
  ]
23083
23446
  }
23084
23447
  )
@@ -23092,13 +23455,13 @@ var import_lucide_react38 = require("lucide-react");
23092
23455
 
23093
23456
  // src/hooks/use-payment-intent.ts
23094
23457
  var import_react_query18 = require("@tanstack/react-query");
23095
- var import_core39 = require("@unifold/core");
23458
+ var import_core38 = require("@unifold/core");
23096
23459
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["succeeded", "expired", "refunded", "canceled"]);
23097
23460
  function usePaymentIntent(params) {
23098
23461
  const { clientSecret, publishableKey, enabled = true, pollingInterval = 3e3 } = params;
23099
23462
  return (0, import_react_query18.useQuery)({
23100
23463
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
23101
- queryFn: () => (0, import_core39.retrievePaymentIntent)(clientSecret, publishableKey),
23464
+ queryFn: () => (0, import_core38.retrievePaymentIntent)(clientSecret, publishableKey),
23102
23465
  enabled: enabled && !!clientSecret && !!publishableKey,
23103
23466
  staleTime: 0,
23104
23467
  refetchInterval: (query) => {
@@ -23114,7 +23477,7 @@ function usePaymentIntent(params) {
23114
23477
  }
23115
23478
 
23116
23479
  // src/components/checkout/CheckoutModal.tsx
23117
- var import_core40 = require("@unifold/core");
23480
+ var import_core39 = require("@unifold/core");
23118
23481
  var import_jsx_runtime64 = require("react/jsx-runtime");
23119
23482
  function mapToCheckoutPaymentIntent(pi) {
23120
23483
  return {
@@ -23200,8 +23563,8 @@ function CheckoutModal({
23200
23563
  if (isSucceeded && richIntent) {
23201
23564
  const createdSec = data.paymentIntent?.updated_at ? Math.floor(new Date(data.paymentIntent.updated_at).getTime() / 1e3) : Math.floor(Date.now() / 1e3);
23202
23565
  onEvent?.({
23203
- id: (0, import_core40.generatePrefixedKSUID)("sevt"),
23204
- type: import_core40.CheckoutEventType.PAYMENT_INTENT_SUCCEEDED,
23566
+ id: (0, import_core39.generatePrefixedKSUID)("sevt"),
23567
+ type: import_core39.CheckoutEventType.PAYMENT_INTENT_SUCCEEDED,
23205
23568
  created: createdSec,
23206
23569
  method,
23207
23570
  data: { object: richIntent }
@@ -23529,253 +23892,275 @@ function CheckoutModal({
23529
23892
  return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(PortalContainerProvider, { value: null, children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Dialog, { open, onOpenChange: handleClose, modal: true, children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23530
23893
  DialogContent,
23531
23894
  {
23532
- className: `sm:uf-max-w-[400px] uf-border-secondary uf-text-foreground uf-gap-0 [&>button]:uf-hidden uf-p-0 uf-overflow-visible ${view === "main" ? "!uf-top-auto !uf-h-auto !uf-max-h-[60vh] sm:!uf-max-h-none sm:!uf-top-[50%]" : "!uf-top-0 !uf-h-full sm:!uf-h-auto sm:!uf-top-[50%]"} ${themeClass}`,
23895
+ className: `sm:uf-max-w-[400px] uf-border-secondary uf-text-foreground uf-gap-0 [&>button]:uf-hidden uf-p-0 uf-overflow-visible ${view === "main" ? "!uf-top-auto !uf-h-auto !uf-max-h-[60vh] sm:!uf-max-h-none sm:!uf-top-[50%]" : "!uf-top-0 !uf-h-full sm:!uf-h-auto sm:!uf-top-[50%]"} ${// wallet_connect fills the full-height mobile sheet. DialogContent is a
23896
+ // grid whose single auto row only grows to fill free space and never
23897
+ // shrinks below content, so a long wallet list would balloon the row
23898
+ // past the viewport and push the footer off-screen. Clamp the row to
23899
+ // the modal height with minmax(0,1fr) so the inner overflow-y-auto list
23900
+ // scrolls with the footer pinned. Reset to content-sized on desktop.
23901
+ view === "wallet_connect" ? "[grid-template-rows:minmax(0,1fr)] sm:[grid-template-rows:none]" : ""} ${themeClass}`,
23533
23902
  style: { backgroundColor: colors2.background },
23534
23903
  onPointerDownOutside: (e) => e.preventDefault(),
23535
23904
  onInteractOutside: (e) => e.preventDefault(),
23536
- children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
23537
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(DepositHeader, { title: modalTitle || "Checkout", showClose: true, onClose: handleClose }),
23538
- /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23539
- piLoading ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-space-y-3", children: [
23540
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23541
- "div",
23542
- {
23543
- className: "uf-rounded-xl uf-p-4 uf-animate-pulse",
23544
- style: {
23545
- backgroundColor: components.card.backgroundColor,
23546
- borderRadius: components.card.borderRadius,
23547
- border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
23548
- },
23549
- children: /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-gap-2", children: [
23550
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23551
- "div",
23905
+ children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23906
+ ThemeStyleInjector,
23907
+ {
23908
+ className: view === "wallet_connect" ? "uf-flex uf-min-h-0 uf-flex-col" : void 0,
23909
+ children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
23910
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(DepositHeader, { title: modalTitle || "Checkout", showClose: true, onClose: handleClose }),
23911
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23912
+ piLoading ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-space-y-3", children: [
23913
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23914
+ "div",
23915
+ {
23916
+ className: "uf-rounded-xl uf-p-4 uf-animate-pulse",
23917
+ style: {
23918
+ backgroundColor: components.card.backgroundColor,
23919
+ borderRadius: components.card.borderRadius,
23920
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
23921
+ },
23922
+ children: /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-gap-2", children: [
23923
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23924
+ "div",
23925
+ {
23926
+ className: "uf-h-8 uf-w-24 uf-rounded",
23927
+ style: {
23928
+ backgroundColor: components.card.borderColor
23929
+ }
23930
+ }
23931
+ ),
23932
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23933
+ "div",
23934
+ {
23935
+ className: "uf-h-4 uf-w-16 uf-rounded",
23936
+ style: {
23937
+ backgroundColor: components.card.borderColor
23938
+ }
23939
+ }
23940
+ )
23941
+ ] })
23942
+ }
23943
+ ),
23944
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SkeletonButton2, {}),
23945
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SkeletonButton2, {})
23946
+ ] }) : piError ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
23947
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react38.AlertTriangle, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
23948
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23949
+ "h3",
23950
+ {
23951
+ className: "uf-text-lg uf-font-semibold uf-mb-2",
23952
+ style: {
23953
+ color: colors2.foreground,
23954
+ fontFamily: fonts.semibold
23955
+ },
23956
+ children: "Unable to Load Checkout"
23957
+ }
23958
+ ),
23959
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23960
+ "p",
23961
+ {
23962
+ className: "uf-text-sm uf-max-w-[280px]",
23963
+ style: {
23964
+ color: colors2.foregroundMuted,
23965
+ fontFamily: fonts.regular
23966
+ },
23967
+ children: piError instanceof Error ? piError.message : "Something went wrong. Please try again."
23968
+ }
23969
+ )
23970
+ ] }) : paymentIntent ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-space-y-3", children: [
23971
+ progressSection,
23972
+ (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
23973
+ showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23974
+ TransferCryptoButton,
23552
23975
  {
23553
- className: "uf-h-8 uf-w-24 uf-rounded",
23554
- style: {
23555
- backgroundColor: components.card.borderColor
23556
- }
23976
+ onClick: () => {
23977
+ lastCheckoutMethodRef.current = "transfer";
23978
+ setView("transfer");
23979
+ },
23980
+ title: i18n.checkoutModal.transferCrypto.title,
23981
+ subtitle: i18n.checkoutModal.transferCrypto.subtitle,
23982
+ featuredTokens: projectConfig?.transfer_crypto.networks
23557
23983
  }
23558
23984
  ),
23559
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23560
- "div",
23985
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23986
+ BrowserWalletButton,
23561
23987
  {
23562
- className: "uf-h-4 uf-w-16 uf-rounded",
23563
- style: {
23564
- backgroundColor: components.card.borderColor
23565
- }
23988
+ onClick: handleBrowserWalletClick,
23989
+ onConnectClick: handleWalletConnectClick,
23990
+ onDisconnect: handleWalletDisconnect,
23991
+ chainType: browserWalletChainType,
23992
+ publishableKey,
23993
+ featuredWallets: projectConfig?.connect_wallet?.wallets,
23994
+ subtitle: i18n.checkoutModal.browserWallet.subtitle
23566
23995
  }
23567
23996
  )
23568
23997
  ] })
23569
- }
23570
- ),
23571
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SkeletonButton2, {}),
23572
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SkeletonButton2, {})
23573
- ] }) : piError ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
23574
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react38.AlertTriangle, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
23998
+ ] }) : null,
23999
+ poweredByFooter
24000
+ ] })
24001
+ ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
23575
24002
  /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23576
- "h3",
24003
+ DepositHeader,
23577
24004
  {
23578
- className: "uf-text-lg uf-font-semibold uf-mb-2",
23579
- style: {
23580
- color: colors2.foreground,
23581
- fontFamily: fonts.semibold
23582
- },
23583
- children: "Unable to Load Checkout"
24005
+ title: modalTitle || "Checkout",
24006
+ showBack: true,
24007
+ onBack: handleBack,
24008
+ onClose: handleClose
23584
24009
  }
23585
24010
  ),
23586
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23587
- "p",
23588
- {
23589
- className: "uf-text-sm uf-max-w-[280px]",
23590
- style: {
23591
- color: colors2.foregroundMuted,
23592
- fontFamily: fonts.regular
23593
- },
23594
- children: piError instanceof Error ? piError.message : "Something went wrong. Please try again."
23595
- }
23596
- )
23597
- ] }) : paymentIntent ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-space-y-3", children: [
23598
- progressSection,
23599
- (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
23600
- showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23601
- TransferCryptoButton,
23602
- {
23603
- onClick: () => {
23604
- lastCheckoutMethodRef.current = "transfer";
23605
- setView("transfer");
23606
- },
23607
- title: i18n.checkoutModal.transferCrypto.title,
23608
- subtitle: i18n.checkoutModal.transferCrypto.subtitle,
23609
- featuredTokens: projectConfig?.transfer_crypto.networks
23610
- }
23611
- ),
23612
- showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23613
- BrowserWalletButton,
23614
- {
23615
- onClick: handleBrowserWalletClick,
23616
- onConnectClick: handleWalletConnectClick,
23617
- onDisconnect: handleWalletDisconnect,
23618
- chainType: browserWalletChainType,
23619
- publishableKey,
23620
- featuredWallets: projectConfig?.connect_wallet?.wallets,
23621
- subtitle: i18n.checkoutModal.browserWallet.subtitle
23622
- }
23623
- )
23624
- ] })
23625
- ] }) : null,
23626
- poweredByFooter
23627
- ] })
23628
- ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
23629
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23630
- DepositHeader,
23631
- {
23632
- title: modalTitle || "Checkout",
23633
- showBack: true,
23634
- onBack: handleBack,
23635
- onClose: handleClose
23636
- }
23637
- ),
23638
- /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23639
- paymentIntent ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
23640
- (() => {
23641
- const receivedUsd = parseFloat(
23642
- paymentIntent.destination_amount_received_usd || paymentIntent.amount_received_usd
23643
- );
23644
- const totalUsd = parseFloat(
23645
- paymentIntent.destination_amount_usd || paymentIntent.amount_usd
23646
- );
23647
- const pct = totalUsd > 0 ? Math.min(receivedUsd / totalUsd * 100, 100) : 0;
23648
- return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-space-y-2", children: [
23649
- /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between", children: [
23650
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23651
- "span",
23652
- {
23653
- className: "uf-text-xs",
23654
- style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
23655
- children: "Received"
23656
- }
23657
- ),
23658
- /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
23659
- "span",
23660
- {
23661
- className: "uf-text-xs",
23662
- style: { color: colors2.foreground, fontFamily: fonts.medium },
23663
- children: [
23664
- "$",
23665
- receivedUsd.toFixed(2),
23666
- " / $",
23667
- totalUsd.toFixed(2)
23668
- ]
23669
- }
23670
- )
23671
- ] }),
23672
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23673
- "div",
23674
- {
23675
- className: "uf-w-full uf-h-1.5 uf-rounded-full uf-overflow-hidden",
23676
- style: { backgroundColor: colors2.border },
23677
- children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
24011
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
24012
+ paymentIntent ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
24013
+ (() => {
24014
+ const receivedUsd = parseFloat(
24015
+ paymentIntent.destination_amount_received_usd || paymentIntent.amount_received_usd
24016
+ );
24017
+ const totalUsd = parseFloat(
24018
+ paymentIntent.destination_amount_usd || paymentIntent.amount_usd
24019
+ );
24020
+ const pct = totalUsd > 0 ? Math.min(receivedUsd / totalUsd * 100, 100) : 0;
24021
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-space-y-2", children: [
24022
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between", children: [
24023
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
24024
+ "span",
24025
+ {
24026
+ className: "uf-text-xs",
24027
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
24028
+ children: "Received"
24029
+ }
24030
+ ),
24031
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
24032
+ "span",
24033
+ {
24034
+ className: "uf-text-xs",
24035
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
24036
+ children: [
24037
+ "$",
24038
+ receivedUsd.toFixed(2),
24039
+ " / $",
24040
+ totalUsd.toFixed(2)
24041
+ ]
24042
+ }
24043
+ )
24044
+ ] }),
24045
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23678
24046
  "div",
23679
24047
  {
23680
- className: "uf-h-full uf-rounded-full uf-transition-all uf-duration-500",
23681
- style: {
23682
- width: `${pct}%`,
23683
- backgroundColor: paymentIntent.status === "succeeded" ? "rgb(34, 197, 94)" : colors2.primary
23684
- }
24048
+ className: "uf-w-full uf-h-1.5 uf-rounded-full uf-overflow-hidden",
24049
+ style: { backgroundColor: colors2.border },
24050
+ children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
24051
+ "div",
24052
+ {
24053
+ className: "uf-h-full uf-rounded-full uf-transition-all uf-duration-500",
24054
+ style: {
24055
+ width: `${pct}%`,
24056
+ backgroundColor: paymentIntent.status === "succeeded" ? "rgb(34, 197, 94)" : colors2.primary
24057
+ }
24058
+ }
24059
+ )
23685
24060
  }
23686
24061
  )
24062
+ ] });
24063
+ })(),
24064
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
24065
+ TransferCryptoSingleInput,
24066
+ {
24067
+ userId: paymentIntent.user_id || "",
24068
+ publishableKey,
24069
+ clientSecret,
24070
+ recipientAddress: paymentIntent.recipient_address,
24071
+ destinationChainType: paymentIntent.destination_chain_type,
24072
+ destinationChainId: paymentIntent.destination_chain_id,
24073
+ destinationTokenAddress: paymentIntent.destination_token_address,
24074
+ defaultSourceChainType,
24075
+ defaultSourceChainId,
24076
+ defaultSourceTokenAddress,
24077
+ defaultSourceSymbol,
24078
+ depositConfirmationMode: "auto_ui",
24079
+ wallets,
24080
+ onSourceTokenChange: setSelectedSource,
24081
+ persistCheckingIndicator: true,
24082
+ productType: "payment",
24083
+ checkoutQuote: effectiveCheckoutQuote,
24084
+ isCheckoutQuoteLoading: isQuoteLoading || isQuoteFetching
23687
24085
  }
23688
24086
  )
23689
- ] });
23690
- })(),
23691
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23692
- TransferCryptoSingleInput,
24087
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SkeletonButton2, {}),
24088
+ poweredByFooter
24089
+ ] })
24090
+ ] }) : view === "wallet_connect" && paymentIntent ? (
24091
+ // Mobile: flex-fill the full-height sheet so the wallet list grows and
24092
+ // scrolls with the footer pinned. Desktop (sm:): content-sized.
24093
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
24094
+ "div",
23693
24095
  {
23694
- userId: paymentIntent.user_id || "",
23695
- publishableKey,
23696
- clientSecret,
23697
- recipientAddress: paymentIntent.recipient_address,
23698
- destinationChainType: paymentIntent.destination_chain_type,
23699
- destinationChainId: paymentIntent.destination_chain_id,
23700
- destinationTokenAddress: paymentIntent.destination_token_address,
23701
- defaultSourceChainType,
23702
- defaultSourceChainId,
23703
- defaultSourceTokenAddress,
23704
- defaultSourceSymbol,
23705
- depositConfirmationMode: "auto_ui",
23706
- wallets,
23707
- onSourceTokenChange: setSelectedSource,
23708
- persistCheckingIndicator: true,
23709
- productType: "payment",
23710
- checkoutQuote: effectiveCheckoutQuote,
23711
- isCheckoutQuoteLoading: isQuoteLoading || isQuoteFetching
24096
+ className: "uf-flex uf-flex-col uf-gap-1.5 uf-min-h-0 uf-flex-1 sm:uf-flex-none",
24097
+ children: [
24098
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
24099
+ WalletConnect,
24100
+ {
24101
+ walletInfo: browserWalletInfo ?? void 0,
24102
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
24103
+ wallets,
24104
+ userId: paymentIntent.user_id || "",
24105
+ publishableKey,
24106
+ clientSecret,
24107
+ prefilledAmountUsd: remainingAmountUsd,
24108
+ checkoutAmountUsd: paymentIntent.amount_usd,
24109
+ checkoutReceivedUsd: paymentIntent.amount_received_usd,
24110
+ checkoutDestination: {
24111
+ chainType: paymentIntent.destination_chain_type,
24112
+ chainId: paymentIntent.destination_chain_id,
24113
+ tokenAddress: paymentIntent.destination_token_address,
24114
+ decimals: paymentIntent.destination_token_decimals ?? 6
24115
+ },
24116
+ productType: "payment",
24117
+ stablecoinParity: paymentIntent.stablecoin_parity ?? false,
24118
+ checkoutRemainingBaseUnits: (() => {
24119
+ const remaining = BigInt(paymentIntent.amount) - BigInt(paymentIntent.amount_received);
24120
+ return remaining > 0n ? remaining.toString() : "0";
24121
+ })(),
24122
+ onSuccess: (_txHash) => {
24123
+ emitCheckoutSuccess(
24124
+ {
24125
+ paymentIntentId: paymentIntent.id,
24126
+ status: "processing",
24127
+ paymentIntent
24128
+ },
24129
+ "wallet_connect"
24130
+ );
24131
+ },
24132
+ onError: (error) => {
24133
+ onCheckoutError?.({
24134
+ message: error.message,
24135
+ error,
24136
+ method: "wallet_connect"
24137
+ });
24138
+ },
24139
+ onWalletDisconnect: handleWalletDisconnect,
24140
+ onWalletConnected: (info, dw) => {
24141
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
24142
+ setStoredWalletState(info.type);
24143
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
24144
+ lastCheckoutMethodRef.current = "wallet_connect";
24145
+ },
24146
+ onNewDeposit: () => setView("main"),
24147
+ onDone: () => setView("main"),
24148
+ paymentIntentStatus: paymentIntent.status,
24149
+ onBack: handleBack,
24150
+ onClose: handleClose,
24151
+ defaultSourceChainType,
24152
+ defaultSourceChainId,
24153
+ defaultSourceTokenAddress,
24154
+ defaultSourceSymbol
24155
+ }
24156
+ ),
24157
+ poweredByFooter
24158
+ ]
23712
24159
  }
23713
24160
  )
23714
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SkeletonButton2, {}),
23715
- poweredByFooter
23716
- ] })
23717
- ] }) : view === "wallet_connect" && paymentIntent ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23718
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
23719
- WalletConnect,
23720
- {
23721
- walletInfo: browserWalletInfo ?? void 0,
23722
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
23723
- wallets,
23724
- userId: paymentIntent.user_id || "",
23725
- publishableKey,
23726
- clientSecret,
23727
- prefillAmountUsd: remainingAmountUsd,
23728
- checkoutAmountUsd: paymentIntent.amount_usd,
23729
- checkoutReceivedUsd: paymentIntent.amount_received_usd,
23730
- checkoutDestination: {
23731
- chainType: paymentIntent.destination_chain_type,
23732
- chainId: paymentIntent.destination_chain_id,
23733
- tokenAddress: paymentIntent.destination_token_address,
23734
- decimals: paymentIntent.destination_token_decimals ?? 6
23735
- },
23736
- productType: "payment",
23737
- stablecoinParity: paymentIntent.stablecoin_parity ?? false,
23738
- checkoutRemainingBaseUnits: (() => {
23739
- const remaining = BigInt(paymentIntent.amount) - BigInt(paymentIntent.amount_received);
23740
- return remaining > 0n ? remaining.toString() : "0";
23741
- })(),
23742
- onSuccess: (_txHash) => {
23743
- emitCheckoutSuccess(
23744
- {
23745
- paymentIntentId: paymentIntent.id,
23746
- status: "processing",
23747
- paymentIntent
23748
- },
23749
- "wallet_connect"
23750
- );
23751
- },
23752
- onError: (error) => {
23753
- onCheckoutError?.({
23754
- message: error.message,
23755
- error,
23756
- method: "wallet_connect"
23757
- });
23758
- },
23759
- onWalletDisconnect: handleWalletDisconnect,
23760
- onWalletConnected: (info, dw) => {
23761
- setBrowserWalletInfo({ ...info, depositWallet: dw });
23762
- setStoredWalletState(info.type);
23763
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
23764
- lastCheckoutMethodRef.current = "wallet_connect";
23765
- },
23766
- onNewDeposit: () => setView("main"),
23767
- onDone: () => setView("main"),
23768
- paymentIntentStatus: paymentIntent.status,
23769
- onBack: handleBack,
23770
- onClose: handleClose,
23771
- defaultSourceChainType,
23772
- defaultSourceChainId,
23773
- defaultSourceTokenAddress,
23774
- defaultSourceSymbol
23775
- }
23776
- ),
23777
- poweredByFooter
23778
- ] }) : null })
24161
+ ) : null
24162
+ }
24163
+ )
23779
24164
  }
23780
24165
  ) }) });
23781
24166
  }
@@ -23786,11 +24171,11 @@ var import_lucide_react41 = require("lucide-react");
23786
24171
 
23787
24172
  // src/hooks/use-supported-destination-tokens.ts
23788
24173
  var import_react_query19 = require("@tanstack/react-query");
23789
- var import_core41 = require("@unifold/core");
24174
+ var import_core40 = require("@unifold/core");
23790
24175
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
23791
24176
  return (0, import_react_query19.useQuery)({
23792
24177
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
23793
- queryFn: () => (0, import_core41.getSupportedDestinationTokens)(publishableKey),
24178
+ queryFn: () => (0, import_core40.getSupportedDestinationTokens)(publishableKey),
23794
24179
  staleTime: 1e3 * 60 * 5,
23795
24180
  gcTime: 1e3 * 60 * 30,
23796
24181
  refetchOnMount: false,
@@ -23818,7 +24203,7 @@ function useDefaultDestinationToken({
23818
24203
 
23819
24204
  // src/hooks/use-source-token-validation.ts
23820
24205
  var import_react_query20 = require("@tanstack/react-query");
23821
- var import_core42 = require("@unifold/core");
24206
+ var import_core41 = require("@unifold/core");
23822
24207
  function useSourceTokenValidation(params) {
23823
24208
  const {
23824
24209
  sourceChainType,
@@ -23839,7 +24224,7 @@ function useSourceTokenValidation(params) {
23839
24224
  publishableKey
23840
24225
  ],
23841
24226
  queryFn: async () => {
23842
- const res = await (0, import_core42.getSupportedDepositTokens)(publishableKey);
24227
+ const res = await (0, import_core41.getSupportedDepositTokens)(publishableKey);
23843
24228
  let matchedMinUsd = null;
23844
24229
  let matchedProcessingTime = null;
23845
24230
  let matchedSlippage = null;
@@ -23878,7 +24263,7 @@ function useSourceTokenValidation(params) {
23878
24263
 
23879
24264
  // src/hooks/use-address-balance.ts
23880
24265
  var import_react_query21 = require("@tanstack/react-query");
23881
- var import_core43 = require("@unifold/core");
24266
+ var import_core42 = require("@unifold/core");
23882
24267
  function useAddressBalance(params) {
23883
24268
  const { address, chainType, chainId, tokenAddress, publishableKey, enabled = true } = params;
23884
24269
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
@@ -23893,7 +24278,7 @@ function useAddressBalance(params) {
23893
24278
  publishableKey
23894
24279
  ],
23895
24280
  queryFn: async () => {
23896
- const res = await (0, import_core43.getAddressBalance)(
24281
+ const res = await (0, import_core42.getAddressBalance)(
23897
24282
  address,
23898
24283
  chainType,
23899
24284
  chainId,
@@ -23939,12 +24324,12 @@ function useAddressBalance(params) {
23939
24324
 
23940
24325
  // src/hooks/use-executions.ts
23941
24326
  var import_react_query22 = require("@tanstack/react-query");
23942
- var import_core44 = require("@unifold/core");
24327
+ var import_core43 = require("@unifold/core");
23943
24328
  function useExecutions(userId, publishableKey, options) {
23944
- const actionType = options?.actionType ?? import_core44.ActionType.Deposit;
24329
+ const actionType = options?.actionType ?? import_core43.ActionType.Deposit;
23945
24330
  return (0, import_react_query22.useQuery)({
23946
24331
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
23947
- queryFn: () => (0, import_core44.queryExecutions)(userId, publishableKey, actionType),
24332
+ queryFn: () => (0, import_core43.queryExecutions)(userId, publishableKey, actionType),
23948
24333
  enabled: (options?.enabled ?? true) && !!userId,
23949
24334
  refetchInterval: options?.refetchInterval ?? 3e3,
23950
24335
  staleTime: 0,
@@ -23955,7 +24340,7 @@ function useExecutions(userId, publishableKey, options) {
23955
24340
 
23956
24341
  // src/hooks/use-withdraw-polling.ts
23957
24342
  var import_react28 = require("react");
23958
- var import_core45 = require("@unifold/core");
24343
+ var import_core44 = require("@unifold/core");
23959
24344
  var POLL_INTERVAL_MS3 = 2500;
23960
24345
  var POLL_ENDPOINT_INTERVAL_MS2 = 5e3;
23961
24346
  var CUTOFF_BUFFER_MS2 = 6e4;
@@ -23968,8 +24353,8 @@ function useWithdrawPolling({
23968
24353
  onWithdrawError
23969
24354
  }) {
23970
24355
  const createExecutionSuccessEvent = (execution) => ({
23971
- id: (0, import_core45.generatePrefixedKSUID)("sevt"),
23972
- type: import_core45.WithdrawEventType.DIRECT_EXECUTION_SUCCEEDED,
24356
+ id: (0, import_core44.generatePrefixedKSUID)("sevt"),
24357
+ type: import_core44.WithdrawEventType.DIRECT_EXECUTION_SUCCEEDED,
23973
24358
  created: execution.updated_at ? Math.floor(new Date(execution.updated_at).getTime() / 1e3) : execution.created_at ? Math.floor(new Date(execution.created_at).getTime() / 1e3) : Math.floor(Date.now() / 1e3),
23974
24359
  data: { object: mapToDirectExecution(execution) }
23975
24360
  });
@@ -24020,7 +24405,7 @@ function useWithdrawPolling({
24020
24405
  const enabledAt = enabledAtRef.current;
24021
24406
  const poll = async () => {
24022
24407
  try {
24023
- const response = await (0, import_core45.queryExecutions)(userId, publishableKey, import_core45.ActionType.Withdraw);
24408
+ const response = await (0, import_core44.queryExecutions)(userId, publishableKey, import_core44.ActionType.Withdraw);
24024
24409
  const cutoff = new Date(enabledAt.getTime() - CUTOFF_BUFFER_MS2);
24025
24410
  const sorted = [...response.data].sort((a, b) => {
24026
24411
  const tA = a.created_at ? new Date(a.created_at).getTime() : 0;
@@ -24028,11 +24413,11 @@ function useWithdrawPolling({
24028
24413
  return tB - tA;
24029
24414
  });
24030
24415
  const inProgress = [
24031
- import_core45.ExecutionStatus.PENDING,
24032
- import_core45.ExecutionStatus.WAITING,
24033
- import_core45.ExecutionStatus.DELAYED
24416
+ import_core44.ExecutionStatus.PENDING,
24417
+ import_core44.ExecutionStatus.WAITING,
24418
+ import_core44.ExecutionStatus.DELAYED
24034
24419
  ];
24035
- const terminal = [import_core45.ExecutionStatus.SUCCEEDED, import_core45.ExecutionStatus.FAILED];
24420
+ const terminal = [import_core44.ExecutionStatus.SUCCEEDED, import_core44.ExecutionStatus.FAILED];
24036
24421
  let target = null;
24037
24422
  for (const ex of sorted) {
24038
24423
  const t13 = ex.created_at ? new Date(ex.created_at) : null;
@@ -24062,7 +24447,7 @@ function useWithdrawPolling({
24062
24447
  }
24063
24448
  return [...list, ex];
24064
24449
  });
24065
- if (ex.status === import_core45.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
24450
+ if (ex.status === import_core44.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
24066
24451
  onSuccessRef.current?.({
24067
24452
  message: "Withdrawal completed successfully",
24068
24453
  executionId: ex.id,
@@ -24070,7 +24455,7 @@ function useWithdrawPolling({
24070
24455
  transaction: ex,
24071
24456
  execution: createExecutionSuccessEvent(ex)
24072
24457
  });
24073
- } else if (ex.status === import_core45.ExecutionStatus.FAILED && prev !== import_core45.ExecutionStatus.FAILED) {
24458
+ } else if (ex.status === import_core44.ExecutionStatus.FAILED && prev !== import_core44.ExecutionStatus.FAILED) {
24074
24459
  onErrorRef.current?.({
24075
24460
  message: "Withdrawal failed",
24076
24461
  code: "WITHDRAW_FAILED",
@@ -24099,7 +24484,7 @@ function useWithdrawPolling({
24099
24484
  if (!enabled || !depositWalletId) return;
24100
24485
  const trigger = async () => {
24101
24486
  try {
24102
- await (0, import_core45.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
24487
+ await (0, import_core44.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
24103
24488
  } catch {
24104
24489
  }
24105
24490
  };
@@ -24268,11 +24653,11 @@ function WithdrawDoubleInput({
24268
24653
  // src/components/withdrawals/WithdrawForm.tsx
24269
24654
  var import_react30 = require("react");
24270
24655
  var import_lucide_react39 = require("lucide-react");
24271
- var import_core50 = require("@unifold/core");
24656
+ var import_core49 = require("@unifold/core");
24272
24657
 
24273
24658
  // src/hooks/use-verify-recipient-address.ts
24274
24659
  var import_react_query23 = require("@tanstack/react-query");
24275
- var import_core46 = require("@unifold/core");
24660
+ var import_core45 = require("@unifold/core");
24276
24661
  function useVerifyRecipientAddress(params) {
24277
24662
  const {
24278
24663
  chainType,
@@ -24294,7 +24679,7 @@ function useVerifyRecipientAddress(params) {
24294
24679
  trimmedAddress,
24295
24680
  publishableKey
24296
24681
  ],
24297
- queryFn: () => (0, import_core46.verifyRecipientAddress)(
24682
+ queryFn: () => (0, import_core45.verifyRecipientAddress)(
24298
24683
  {
24299
24684
  chain_type: chainType,
24300
24685
  chain_id: chainId,
@@ -24313,7 +24698,7 @@ function useVerifyRecipientAddress(params) {
24313
24698
  }
24314
24699
 
24315
24700
  // src/components/withdrawals/send-withdraw.ts
24316
- var import_core47 = require("@unifold/core");
24701
+ var import_core46 = require("@unifold/core");
24317
24702
  async function sendEvmWithdraw(params) {
24318
24703
  const {
24319
24704
  provider,
@@ -24402,7 +24787,7 @@ async function sendSolanaWithdraw(params) {
24402
24787
  if (!provider.publicKey) {
24403
24788
  await provider.connect();
24404
24789
  }
24405
- const buildResponse = await (0, import_core47.buildSolanaTransaction)(
24790
+ const buildResponse = await (0, import_core46.buildSolanaTransaction)(
24406
24791
  {
24407
24792
  chain_id: "mainnet",
24408
24793
  token_address: sourceTokenAddress === "" ? "native" : sourceTokenAddress,
@@ -24428,7 +24813,7 @@ async function sendSolanaWithdraw(params) {
24428
24813
  for (let i = 0; i < serialized.length; i++) {
24429
24814
  binaryStr += String.fromCharCode(serialized[i]);
24430
24815
  }
24431
- const sendResponse = await (0, import_core47.sendSolanaTransaction)(
24816
+ const sendResponse = await (0, import_core46.sendSolanaTransaction)(
24432
24817
  { chain_id: "mainnet", signed_transaction: btoa(binaryStr) },
24433
24818
  publishableKey
24434
24819
  );
@@ -24529,11 +24914,11 @@ async function detectBrowserWallet(chainType, senderAddress) {
24529
24914
 
24530
24915
  // src/hooks/use-hypercore-withdraw-activation.ts
24531
24916
  var import_react29 = require("react");
24532
- var import_core49 = require("@unifold/core");
24917
+ var import_core48 = require("@unifold/core");
24533
24918
 
24534
24919
  // src/hooks/use-get-deposit-address.ts
24535
24920
  var import_react_query24 = require("@tanstack/react-query");
24536
- var import_core48 = require("@unifold/core");
24921
+ var import_core47 = require("@unifold/core");
24537
24922
  function useGetDepositAddress(params) {
24538
24923
  const {
24539
24924
  userId,
@@ -24558,7 +24943,7 @@ function useGetDepositAddress(params) {
24558
24943
  actionType ?? null,
24559
24944
  publishableKey
24560
24945
  ],
24561
- queryFn: () => (0, import_core48.getDepositAddress)(
24946
+ queryFn: () => (0, import_core47.getDepositAddress)(
24562
24947
  {
24563
24948
  external_user_id: userId,
24564
24949
  recipient_address: recipientAddress,
@@ -24612,7 +24997,7 @@ function useHypercoreWithdrawActivation(params) {
24612
24997
  destinationChainType,
24613
24998
  destinationChainId,
24614
24999
  destinationTokenAddress,
24615
- actionType: import_core49.ActionType.Withdraw,
25000
+ actionType: import_core48.ActionType.Withdraw,
24616
25001
  enabled: enabled && isHypercore(sourceChainId)
24617
25002
  });
24618
25003
  const depositWalletAddress = (0, import_react29.useMemo)(() => {
@@ -24903,7 +25288,7 @@ function WithdrawForm({
24903
25288
  let humanAmount = isMaxed ? balanceData.balanceHuman : toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
24904
25289
  if (isHypercoreChain(sourceChainId)) {
24905
25290
  try {
24906
- const check = await (0, import_core50.checkHypercoreActivation)(
25291
+ const check = await (0, import_core49.checkHypercoreActivation)(
24907
25292
  {
24908
25293
  source_address: senderAddress,
24909
25294
  recipient_address: depositWallet.address
@@ -25352,11 +25737,11 @@ function WithdrawForm({
25352
25737
 
25353
25738
  // src/components/withdrawals/WithdrawExecutionItem.tsx
25354
25739
  var import_lucide_react40 = require("lucide-react");
25355
- var import_core51 = require("@unifold/core");
25740
+ var import_core50 = require("@unifold/core");
25356
25741
  var import_jsx_runtime67 = require("react/jsx-runtime");
25357
25742
  function WithdrawExecutionItem({ execution, onClick }) {
25358
25743
  const { colors: colors2, fonts, components } = useTheme();
25359
- const isPending = execution.status === import_core51.ExecutionStatus.PENDING || execution.status === import_core51.ExecutionStatus.WAITING || execution.status === import_core51.ExecutionStatus.DELAYED;
25744
+ const isPending = execution.status === import_core50.ExecutionStatus.PENDING || execution.status === import_core50.ExecutionStatus.WAITING || execution.status === import_core50.ExecutionStatus.DELAYED;
25360
25745
  const formatDateTime = (timestamp) => {
25361
25746
  try {
25362
25747
  const date = new Date(timestamp);
@@ -25403,7 +25788,7 @@ function WithdrawExecutionItem({ execution, onClick }) {
25403
25788
  /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
25404
25789
  "img",
25405
25790
  {
25406
- src: execution.destination_token_metadata?.icon_url || (0, import_core51.getIconUrl)("/icons/tokens/svg/usdc.svg"),
25791
+ src: execution.destination_token_metadata?.icon_url || (0, import_core50.getIconUrl)("/icons/tokens/svg/usdc.svg"),
25407
25792
  alt: "Token",
25408
25793
  width: 36,
25409
25794
  height: 36,
@@ -25639,7 +26024,7 @@ function WithdrawConfirmingView({
25639
26024
  }
25640
26025
 
25641
26026
  // src/components/withdrawals/WithdrawModal.tsx
25642
- var import_core52 = require("@unifold/core");
26027
+ var import_core51 = require("@unifold/core");
25643
26028
  var import_jsx_runtime69 = require("react/jsx-runtime");
25644
26029
  var t11 = i18n.withdrawModal;
25645
26030
  var getChainKey5 = (chainId, chainType) => `${chainType}:${chainId}`;
@@ -25745,26 +26130,26 @@ function WithdrawModal({
25745
26130
  onWithdrawError
25746
26131
  });
25747
26132
  const { data: allWithdrawalsData } = useExecutions(externalUserId, publishableKey, {
25748
- actionType: import_core52.ActionType.Withdraw,
26133
+ actionType: import_core51.ActionType.Withdraw,
25749
26134
  enabled: open,
25750
26135
  refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
25751
26136
  });
25752
26137
  const allWithdrawals = allWithdrawalsData?.data ?? [];
25753
26138
  const handleDepositWalletCreation = (0, import_react32.useCallback)(
25754
26139
  async (params) => {
25755
- const { data: wallets } = await (0, import_core52.createDepositAddress)(
26140
+ const { data: wallets } = await (0, import_core51.createDepositAddress)(
25756
26141
  {
25757
26142
  external_user_id: externalUserId,
25758
26143
  destination_chain_type: params.destinationChainType,
25759
26144
  destination_chain_id: params.destinationChainId,
25760
26145
  destination_token_address: params.destinationTokenAddress,
25761
26146
  recipient_address: params.recipientAddress,
25762
- action_type: import_core52.ActionType.Withdraw,
26147
+ action_type: import_core51.ActionType.Withdraw,
25763
26148
  source_chain_type: sourceChainType
25764
26149
  },
25765
26150
  publishableKey
25766
26151
  );
25767
- const depositWallet = (0, import_core52.getWalletByChainType)(wallets, sourceChainType);
26152
+ const depositWallet = (0, import_core51.getWalletByChainType)(wallets, sourceChainType);
25768
26153
  if (!depositWallet) {
25769
26154
  throw new Error(`No deposit wallet available for ${sourceChainType}`);
25770
26155
  }