@unifold/ui-react 0.1.68 → 0.1.70-beta.1

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
@@ -114,6 +114,7 @@ __export(index_exports, {
114
114
  useDepositPolling: () => useDepositPolling,
115
115
  useDepositQuote: () => useDepositQuote,
116
116
  usePaymentIntent: () => usePaymentIntent,
117
+ usePublicIncident: () => usePublicIncident,
117
118
  useSourceTokenValidation: () => useSourceTokenValidation,
118
119
  useSupportedDepositTokens: () => useSupportedDepositTokens,
119
120
  useSupportedDestinationTokens: () => useSupportedDestinationTokens,
@@ -697,7 +698,9 @@ function GeoRestrictionScreen({ methodName, message }) {
697
698
  }
698
699
 
699
700
  // src/components/deposits/BuyWithCard.tsx
701
+ var React5 = __toESM(require("react"));
700
702
  var import_react8 = require("react");
703
+ var import_react_query3 = require("@tanstack/react-query");
701
704
  var import_lucide_react8 = require("lucide-react");
702
705
  var import_core9 = require("@unifold/core");
703
706
 
@@ -748,7 +751,13 @@ function useDepositAddress(params) {
748
751
  // 24 hours in cache
749
752
  refetchOnMount: false,
750
753
  refetchOnWindowFocus: false,
751
- retry: 3,
754
+ // Don't retry recipient-address validation errors — they're deterministic
755
+ // (a 400 won't succeed on retry) and we want to surface the invalid-address
756
+ // screen immediately rather than after 3 backoff attempts.
757
+ retry: (failureCount, error) => {
758
+ if ((0, import_core.isDepositAddressValidationError)(error)) return false;
759
+ return failureCount < 3;
760
+ },
752
761
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
753
762
  // 1s, 2s, 4s (max 10s)
754
763
  });
@@ -973,7 +982,8 @@ function DepositHeader({
973
982
  balanceChainId,
974
983
  balanceTokenAddress,
975
984
  projectName,
976
- publishableKey
985
+ publishableKey,
986
+ incident
977
987
  }) {
978
988
  const { colors: colors2, fonts, components } = useTheme();
979
989
  const [balance, setBalance] = (0, import_react2.useState)(null);
@@ -1071,19 +1081,64 @@ function DepositHeader({
1071
1081
  balanceTokenAddress,
1072
1082
  publishableKey
1073
1083
  ]);
1074
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-6", children: [
1075
- showBack ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1076
- "button",
1077
- {
1078
- onClick: onBack,
1079
- className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
1080
- style: { color: components.header.buttonColor },
1081
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.ArrowLeft, { className: "uf-w-5 uf-h-5" })
1082
- }
1083
- ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
1084
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center", children: [
1085
- badge ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
1086
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1084
+ const incidentMessages = incident?.messages ?? [];
1085
+ const showIncident = incident?.enabled && incidentMessages.length > 0;
1086
+ const incidentSeverity = incident?.severity ?? "degraded";
1087
+ const incidentSeverityLabel = incidentSeverity === "outage" ? "Outage" : incidentSeverity === "info" ? "Info" : "Degraded service";
1088
+ const incidentStyles = incidentSeverity === "outage" ? {
1089
+ bg: "rgba(239, 68, 68, 0.12)",
1090
+ border: "rgba(239, 68, 68, 0.35)",
1091
+ text: "#fca5a5",
1092
+ link: "#fca5a5"
1093
+ } : incidentSeverity === "info" ? {
1094
+ bg: "rgba(59, 130, 246, 0.12)",
1095
+ border: "rgba(59, 130, 246, 0.35)",
1096
+ text: "#93c5fd",
1097
+ link: "#93c5fd"
1098
+ } : {
1099
+ bg: "rgba(245, 158, 11, 0.12)",
1100
+ border: "rgba(245, 158, 11, 0.35)",
1101
+ text: "#fcd34d",
1102
+ link: "#fcd34d"
1103
+ };
1104
+ const IncidentIcon = incidentSeverity === "info" ? import_lucide_react3.Info : import_lucide_react3.AlertTriangle;
1105
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1106
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-6", children: [
1107
+ showBack ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1108
+ "button",
1109
+ {
1110
+ onClick: onBack,
1111
+ className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
1112
+ style: { color: components.header.buttonColor },
1113
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.ArrowLeft, { className: "uf-w-5 uf-h-5" })
1114
+ }
1115
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
1116
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center", children: [
1117
+ badge ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
1118
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1119
+ DialogTitle,
1120
+ {
1121
+ className: "uf-text-center uf-text-base",
1122
+ style: {
1123
+ color: components.header.titleColor,
1124
+ fontFamily: fonts.medium
1125
+ },
1126
+ children: title
1127
+ }
1128
+ ),
1129
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1130
+ "div",
1131
+ {
1132
+ className: "uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px]",
1133
+ style: {
1134
+ backgroundColor: colors2.card,
1135
+ color: colors2.foregroundMuted,
1136
+ fontFamily: fonts.regular
1137
+ },
1138
+ children: badge.count
1139
+ }
1140
+ )
1141
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1087
1142
  DialogTitle,
1088
1143
  {
1089
1144
  className: "uf-text-center uf-text-base",
@@ -1094,61 +1149,91 @@ function DepositHeader({
1094
1149
  children: title
1095
1150
  }
1096
1151
  ),
1097
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1152
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1098
1153
  "div",
1099
1154
  {
1100
- className: "uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px]",
1155
+ className: "uf-text-xs uf-mt-1",
1101
1156
  style: {
1102
- backgroundColor: colors2.card,
1103
1157
  color: colors2.foregroundMuted,
1104
1158
  fontFamily: fonts.regular
1105
1159
  },
1106
- children: badge.count
1160
+ children: subtitle
1107
1161
  }
1108
- )
1109
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1110
- DialogTitle,
1111
- {
1112
- className: "uf-text-center uf-text-base",
1113
- style: {
1114
- color: components.header.titleColor,
1115
- fontFamily: fonts.medium
1116
- },
1117
- children: title
1118
- }
1119
- ),
1120
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1121
- "div",
1122
- {
1123
- className: "uf-text-xs uf-mt-1",
1124
- style: {
1125
- color: colors2.foregroundMuted,
1126
- fontFamily: fonts.regular
1127
- },
1128
- children: subtitle
1129
- }
1130
- ) : showBalanceBlock ? isLoadingBalance && showBalanceSkeleton ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-1" }) : balance ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1131
- "div",
1162
+ ) : showBalanceBlock ? isLoadingBalance && showBalanceSkeleton ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-1" }) : balance ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1163
+ "div",
1164
+ {
1165
+ className: "uf-text-xs uf-mt-1",
1166
+ style: {
1167
+ color: colors2.foregroundMuted,
1168
+ fontFamily: fonts.regular
1169
+ },
1170
+ children: formatBalanceDisplay(balance, projectName)
1171
+ }
1172
+ ) : null : null
1173
+ ] }),
1174
+ showClose ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1175
+ "button",
1132
1176
  {
1133
- className: "uf-text-xs uf-mt-1",
1134
- style: {
1135
- color: colors2.foregroundMuted,
1136
- fontFamily: fonts.regular
1137
- },
1138
- children: formatBalanceDisplay(balance, projectName)
1177
+ onClick: onClose,
1178
+ className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
1179
+ style: { color: components.header.buttonColor },
1180
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.X, { className: "uf-w-5 uf-h-5" })
1139
1181
  }
1140
- ) : null : null
1182
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
1141
1183
  ] }),
1142
- showClose ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1143
- "button",
1184
+ showIncident && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1185
+ "div",
1144
1186
  {
1145
- onClick: onClose,
1146
- className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
1147
- style: { color: components.header.buttonColor },
1148
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.X, { className: "uf-w-5 uf-h-5" })
1187
+ className: "uf-rounded-lg uf-px-3 uf-py-2.5 uf-mb-4",
1188
+ style: {
1189
+ backgroundColor: incidentStyles.bg,
1190
+ border: `1px solid ${incidentStyles.border}`
1191
+ },
1192
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-flex uf-items-start uf-gap-2.5", children: [
1193
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1194
+ IncidentIcon,
1195
+ {
1196
+ className: "uf-w-4 uf-h-4 uf-mt-0.5 uf-shrink-0",
1197
+ style: { color: incidentStyles.text }
1198
+ }
1199
+ ),
1200
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "uf-min-w-0 uf-flex-1", children: [
1201
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-flex uf-items-center uf-gap-2 uf-mb-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1202
+ "span",
1203
+ {
1204
+ className: "uf-text-[11px] uf-leading-none uf-px-1.5 uf-py-1 uf-rounded-md",
1205
+ style: {
1206
+ color: incidentStyles.text,
1207
+ border: `1px solid ${incidentStyles.border}`,
1208
+ fontFamily: fonts.medium
1209
+ },
1210
+ children: incidentSeverityLabel
1211
+ }
1212
+ ) }),
1213
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1214
+ "div",
1215
+ {
1216
+ className: "uf-space-y-1",
1217
+ style: { color: incidentStyles.text, fontFamily: fonts.regular },
1218
+ children: incidentMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "uf-text-xs uf-leading-relaxed", children: message }, `${message}-${index}`))
1219
+ }
1220
+ ),
1221
+ incident.statusPageUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1222
+ "a",
1223
+ {
1224
+ href: incident.statusPageUrl,
1225
+ target: "_blank",
1226
+ rel: "noreferrer",
1227
+ className: "uf-inline-block uf-mt-1.5 uf-text-xs uf-underline uf-underline-offset-2",
1228
+ style: { color: incidentStyles.link, fontFamily: fonts.medium },
1229
+ children: "View status"
1230
+ }
1231
+ )
1232
+ ] })
1233
+ ] })
1149
1234
  }
1150
- ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
1151
- ] }) });
1235
+ )
1236
+ ] });
1152
1237
  }
1153
1238
 
1154
1239
  // src/components/currency/CurrencyListItem.tsx
@@ -1486,7 +1571,8 @@ var en_default = {
1486
1571
  },
1487
1572
  stripeLink: {
1488
1573
  title: "Pay with Link",
1489
- subtitle: "Buy with card or bank"
1574
+ subtitle: "Buy with card or bank",
1575
+ unavailableInRegionMessage: "Pay with Link is currently unavailable in your region."
1490
1576
  },
1491
1577
  browserWallet: {
1492
1578
  title: "Connect Wallet",
@@ -2685,13 +2771,25 @@ function BuyWithCard({
2685
2771
  wallets: externalWallets,
2686
2772
  assetCdnUrl,
2687
2773
  hideDepositFlowInfo = false,
2688
- hideDisplayDescription = false
2774
+ hideDisplayDescription = false,
2775
+ prefilledAmountUsd
2689
2776
  }) {
2690
2777
  const { colors: colors2, fonts, components } = useTheme();
2691
- const [amount, setAmount] = (0, import_react8.useState)("");
2778
+ const cleanedPrefilledAmountUsd = React5.useMemo(() => {
2779
+ if (!prefilledAmountUsd) return "";
2780
+ return prefilledAmountUsd.replace(/[^0-9.]/g, "");
2781
+ }, [prefilledAmountUsd]);
2782
+ const parsedPrefilledAmountUsd = React5.useMemo(() => {
2783
+ const parsed = parseFloat(cleanedPrefilledAmountUsd);
2784
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
2785
+ }, [cleanedPrefilledAmountUsd]);
2786
+ const shouldAutoConvertPrefilledRef = (0, import_react8.useRef)(!!cleanedPrefilledAmountUsd);
2787
+ const [amount, setAmount] = (0, import_react8.useState)(() => cleanedPrefilledAmountUsd);
2692
2788
  const [currency, setCurrency] = (0, import_react8.useState)("usd");
2693
2789
  const [hasManualCurrencySelection, setHasManualCurrencySelection] = (0, import_react8.useState)(false);
2694
- const [hasManualAmountEntry, setHasManualAmountEntry] = (0, import_react8.useState)(false);
2790
+ const [hasManualAmountEntry, setHasManualAmountEntry] = (0, import_react8.useState)(
2791
+ () => !!cleanedPrefilledAmountUsd
2792
+ );
2695
2793
  const [showCurrencyModal, setShowCurrencyModal] = (0, import_react8.useState)(false);
2696
2794
  const [quotes, setQuotes] = (0, import_react8.useState)([]);
2697
2795
  const [quotesLoading, setQuotesLoading] = (0, import_react8.useState)(false);
@@ -2748,6 +2846,71 @@ function BuyWithCard({
2748
2846
  const [preferredCurrencyCodes, setPreferredCurrencyCodes] = (0, import_react8.useState)([]);
2749
2847
  const [currenciesLoading, setCurrenciesLoading] = (0, import_react8.useState)(true);
2750
2848
  const [destinationToken, setDestinationToken] = (0, import_react8.useState)(null);
2849
+ (0, import_react8.useEffect)(() => {
2850
+ const hasPrefilledAmount = !!cleanedPrefilledAmountUsd;
2851
+ shouldAutoConvertPrefilledRef.current = hasPrefilledAmount;
2852
+ if (!hasPrefilledAmount) return;
2853
+ setAmount(cleanedPrefilledAmountUsd);
2854
+ setHasManualAmountEntry(true);
2855
+ }, [cleanedPrefilledAmountUsd]);
2856
+ const { data: fiatExchangeRatesResponse, isLoading: isFiatExchangeRatesLoading } = (0, import_react_query3.useQuery)({
2857
+ queryKey: ["fiat-exchange-rates", publishableKey],
2858
+ staleTime: 3e4,
2859
+ refetchInterval: 3e4,
2860
+ queryFn: async () => {
2861
+ try {
2862
+ return await (0, import_core9.getFiatExchangeRates)({}, publishableKey);
2863
+ } catch (error) {
2864
+ console.error("Error fetching fiat exchange rates:", error);
2865
+ return { base_currency: "usd", rates: {} };
2866
+ }
2867
+ }
2868
+ });
2869
+ const fiatExchangeRates = fiatExchangeRatesResponse?.rates ?? {};
2870
+ const convertAmountBetweenCurrencies = React5.useCallback(
2871
+ (rawAmount, fromCurrencyCode, toCurrencyCode) => {
2872
+ const parsedAmount = parseFloat(rawAmount);
2873
+ if (!Number.isFinite(parsedAmount) || parsedAmount <= 0) return null;
2874
+ const fromCode = fromCurrencyCode.toLowerCase();
2875
+ const toCode = toCurrencyCode.toLowerCase();
2876
+ const fromRate = fromCode === "usd" ? 1 : fiatExchangeRates[fromCode];
2877
+ const toRate = toCode === "usd" ? 1 : fiatExchangeRates[toCode];
2878
+ if (!Number.isFinite(fromRate) || fromRate <= 0) return null;
2879
+ if (!Number.isFinite(toRate) || toRate <= 0) return null;
2880
+ const usdAmount = parsedAmount / fromRate;
2881
+ return parseFloat((usdAmount * toRate).toFixed(2)).toString();
2882
+ },
2883
+ [fiatExchangeRates]
2884
+ );
2885
+ const getConvertedPrefilledAmount = React5.useCallback(
2886
+ (targetCurrencyCode) => {
2887
+ if (!parsedPrefilledAmountUsd) return null;
2888
+ const normalizedTargetCurrency = targetCurrencyCode.toLowerCase();
2889
+ const rate = normalizedTargetCurrency === "usd" ? 1 : fiatExchangeRates[normalizedTargetCurrency];
2890
+ if (!Number.isFinite(rate) || rate <= 0) return null;
2891
+ return parseFloat((parsedPrefilledAmountUsd * rate).toFixed(2)).toString();
2892
+ },
2893
+ [parsedPrefilledAmountUsd, fiatExchangeRates]
2894
+ );
2895
+ (0, import_react8.useEffect)(() => {
2896
+ if (!cleanedPrefilledAmountUsd || !shouldAutoConvertPrefilledRef.current) return;
2897
+ const convertedAmount = getConvertedPrefilledAmount(currency);
2898
+ if (!convertedAmount) {
2899
+ if (isFiatExchangeRatesLoading) return;
2900
+ const targetCurrency = currency.toLowerCase();
2901
+ if (targetCurrency !== "usd") {
2902
+ setCurrency("usd");
2903
+ }
2904
+ return;
2905
+ }
2906
+ setAmount(convertedAmount);
2907
+ setHasManualAmountEntry(true);
2908
+ }, [
2909
+ cleanedPrefilledAmountUsd,
2910
+ currency,
2911
+ getConvertedPrefilledAmount,
2912
+ isFiatExchangeRatesLoading
2913
+ ]);
2751
2914
  const depositWalletId = defaultToken ? (0, import_core9.getWalletByChainType)(wallets, defaultToken.destination_token_metadata.chain_type)?.id : void 0;
2752
2915
  const { executions, isPolling, showWaitingUi } = useDepositPolling({
2753
2916
  userId,
@@ -2778,6 +2941,7 @@ function BuyWithCard({
2778
2941
  }, [publishableKey]);
2779
2942
  (0, import_react8.useEffect)(() => {
2780
2943
  if (hasManualCurrencySelection) return;
2944
+ if (hasManualAmountEntry && !shouldAutoConvertPrefilledRef.current) return;
2781
2945
  if (fiatCurrencies.length === 0 || !userIpInfo?.alpha2) return;
2782
2946
  const userCountryCode = userIpInfo.alpha2;
2783
2947
  const matchingCurrency = fiatCurrencies.find((c) => c.country_codes.includes(userCountryCode));
@@ -2796,7 +2960,15 @@ function BuyWithCard({
2796
2960
  const prevCurrencyRef = (0, import_react8.useRef)(null);
2797
2961
  (0, import_react8.useEffect)(() => {
2798
2962
  if (fiatCurrencies.length === 0) return;
2963
+ if (shouldAutoConvertPrefilledRef.current) {
2964
+ prevCurrencyRef.current = currency;
2965
+ return;
2966
+ }
2799
2967
  if (prevCurrencyRef.current !== null && prevCurrencyRef.current !== currency) {
2968
+ if (hasManualAmountEntry) {
2969
+ prevCurrencyRef.current = currency;
2970
+ return;
2971
+ }
2800
2972
  const currentCurrency = fiatCurrencies.find(
2801
2973
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
2802
2974
  );
@@ -2805,7 +2977,7 @@ function BuyWithCard({
2805
2977
  }
2806
2978
  }
2807
2979
  prevCurrencyRef.current = currency;
2808
- }, [currency]);
2980
+ }, [currency, fiatCurrencies, hasManualAmountEntry]);
2809
2981
  (0, import_react8.useEffect)(() => {
2810
2982
  async function fetchDestinationToken() {
2811
2983
  try {
@@ -2982,6 +3154,7 @@ function BuyWithCard({
2982
3154
  return () => clearInterval(timer);
2983
3155
  }, [quotes.length, amount]);
2984
3156
  const handleAmountChange = (value) => {
3157
+ shouldAutoConvertPrefilledRef.current = false;
2985
3158
  if (value === "") {
2986
3159
  setAmount(value);
2987
3160
  setHasManualAmountEntry(true);
@@ -2995,6 +3168,7 @@ function BuyWithCard({
2995
3168
  }
2996
3169
  };
2997
3170
  const handleQuickAmount = (quickAmount) => {
3171
+ shouldAutoConvertPrefilledRef.current = false;
2998
3172
  setAmount(quickAmount.toString());
2999
3173
  setHasManualAmountEntry(true);
3000
3174
  };
@@ -3598,8 +3772,43 @@ function BuyWithCard({
3598
3772
  preferredCurrencyCodes,
3599
3773
  selectedCurrency: currency,
3600
3774
  onSelectCurrency: (currencyCode) => {
3601
- setCurrency(currencyCode.toLowerCase());
3775
+ const nextCurrency = currencyCode.toLowerCase();
3776
+ if (nextCurrency === currency.toLowerCase()) {
3777
+ setHasManualCurrencySelection(true);
3778
+ return;
3779
+ }
3780
+ const currentCurrency = currency;
3602
3781
  setHasManualCurrencySelection(true);
3782
+ if (shouldAutoConvertPrefilledRef.current) {
3783
+ const convertedAmount = getConvertedPrefilledAmount(nextCurrency);
3784
+ if (convertedAmount) {
3785
+ setCurrency(nextCurrency);
3786
+ setAmount(convertedAmount);
3787
+ setHasManualAmountEntry(true);
3788
+ } else {
3789
+ if (isFiatExchangeRatesLoading) return;
3790
+ const fallbackUsdAmount = getConvertedPrefilledAmount("usd");
3791
+ setCurrency("usd");
3792
+ if (fallbackUsdAmount) {
3793
+ setAmount(fallbackUsdAmount);
3794
+ setHasManualAmountEntry(true);
3795
+ }
3796
+ }
3797
+ return;
3798
+ }
3799
+ if (hasManualAmountEntry && amount) {
3800
+ const convertedAmount = convertAmountBetweenCurrencies(
3801
+ amount,
3802
+ currentCurrency,
3803
+ nextCurrency
3804
+ );
3805
+ if (convertedAmount) {
3806
+ setCurrency(nextCurrency);
3807
+ setAmount(convertedAmount);
3808
+ }
3809
+ return;
3810
+ }
3811
+ setCurrency(nextCurrency);
3603
3812
  },
3604
3813
  themeClass
3605
3814
  }
@@ -3618,7 +3827,7 @@ function BuyWithCard({
3618
3827
  }
3619
3828
 
3620
3829
  // src/components/deposits/BuyWithApplePay.tsx
3621
- var React5 = __toESM(require("react"));
3830
+ var React6 = __toESM(require("react"));
3622
3831
  var import_react10 = require("react");
3623
3832
  var import_lucide_react9 = require("lucide-react");
3624
3833
  var import_core13 = require("@unifold/core");
@@ -3665,13 +3874,13 @@ function isOnrampTokenFresh(contact) {
3665
3874
  }
3666
3875
 
3667
3876
  // src/hooks/use-coinbase-legal-agreements.ts
3668
- var import_react_query3 = require("@tanstack/react-query");
3877
+ var import_react_query4 = require("@tanstack/react-query");
3669
3878
  var import_core10 = require("@unifold/core");
3670
3879
  function useCoinbaseLegalAgreements({
3671
3880
  publishableKey,
3672
3881
  enabled = true
3673
3882
  }) {
3674
- return (0, import_react_query3.useQuery)({
3883
+ return (0, import_react_query4.useQuery)({
3675
3884
  queryKey: ["unifold", "coinbaseLegalAgreements", publishableKey],
3676
3885
  queryFn: () => (0, import_core10.getCoinbaseLegalAgreements)(publishableKey),
3677
3886
  enabled: enabled && !!publishableKey,
@@ -3687,7 +3896,7 @@ function useCoinbaseLegalAgreements({
3687
3896
  var import_react9 = require("react");
3688
3897
 
3689
3898
  // src/hooks/use-apple-pay-limits.ts
3690
- var import_react_query4 = require("@tanstack/react-query");
3899
+ var import_react_query5 = require("@tanstack/react-query");
3691
3900
  var import_core11 = require("@unifold/core");
3692
3901
  var US_E164_REGEX = /^\+1\d{10}$/;
3693
3902
  function useApplePayLimits({
@@ -3696,7 +3905,7 @@ function useApplePayLimits({
3696
3905
  enabled = true
3697
3906
  }) {
3698
3907
  const phoneValid = US_E164_REGEX.test(phone);
3699
- return (0, import_react_query4.useQuery)({
3908
+ return (0, import_react_query5.useQuery)({
3700
3909
  queryKey: ["unifold", "applePayLimits", phone, publishableKey],
3701
3910
  queryFn: ({ signal }) => (0, import_core11.getCoinbaseApplePayLimits)(phone, publishableKey, signal),
3702
3911
  enabled: enabled && phoneValid && !!publishableKey,
@@ -3786,7 +3995,7 @@ function useApplePayInitialScreen({
3786
3995
  }
3787
3996
 
3788
3997
  // src/hooks/use-default-onramp-token.ts
3789
- var import_react_query5 = require("@tanstack/react-query");
3998
+ var import_react_query6 = require("@tanstack/react-query");
3790
3999
  var import_core12 = require("@unifold/core");
3791
4000
  function useDefaultOnrampToken({
3792
4001
  publishableKey,
@@ -3802,7 +4011,7 @@ function useDefaultOnrampToken({
3802
4011
  isLoading,
3803
4012
  isError,
3804
4013
  error
3805
- } = (0, import_react_query5.useQuery)({
4014
+ } = (0, import_react_query6.useQuery)({
3806
4015
  queryKey: [
3807
4016
  "unifold",
3808
4017
  "defaultOnrampToken",
@@ -3879,7 +4088,7 @@ function parseCoinbasePostMessage(raw) {
3879
4088
  } : void 0
3880
4089
  };
3881
4090
  }
3882
- var BuyWithApplePay = React5.forwardRef(
4091
+ var BuyWithApplePay = React6.forwardRef(
3883
4092
  function BuyWithApplePay2({
3884
4093
  userId,
3885
4094
  publishableKey,
@@ -4038,7 +4247,7 @@ var BuyWithApplePay = React5.forwardRef(
4038
4247
  popupRef.current = null;
4039
4248
  };
4040
4249
  }, []);
4041
- React5.useImperativeHandle(
4250
+ React6.useImperativeHandle(
4042
4251
  ref,
4043
4252
  () => ({
4044
4253
  requestBack: () => {
@@ -5348,7 +5557,7 @@ function LegalDisclaimer({ legalAgreements, loading }) {
5348
5557
  children: [
5349
5558
  "By continuing, you agree to Coinbase's",
5350
5559
  " ",
5351
- agreements.map((a, idx, arr) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(React5.Fragment, { children: [
5560
+ agreements.map((a, idx, arr) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(React6.Fragment, { children: [
5352
5561
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5353
5562
  "a",
5354
5563
  {
@@ -5784,10 +5993,10 @@ function useIsMobileViewport() {
5784
5993
  }
5785
5994
 
5786
5995
  // src/hooks/use-cashapp-limits.ts
5787
- var import_react_query6 = require("@tanstack/react-query");
5996
+ var import_react_query7 = require("@tanstack/react-query");
5788
5997
  var import_core15 = require("@unifold/core");
5789
5998
  function useCashAppLimits({ publishableKey, currency = "usd" }) {
5790
- return (0, import_react_query6.useQuery)({
5999
+ return (0, import_react_query7.useQuery)({
5791
6000
  queryKey: ["unifold", "cashAppLimits", currency, publishableKey],
5792
6001
  queryFn: () => (0, import_core15.getCashAppLimits)(currency, publishableKey),
5793
6002
  enabled: !!publishableKey,
@@ -5803,6 +6012,7 @@ var POLL_INTERVAL_MS2 = 5e3;
5803
6012
  var FALLBACK_MIN_USD = 5;
5804
6013
  var SUGGESTED_AMOUNTS = [25, 50, 100];
5805
6014
  var t3 = i18n.depositModal.cashApp;
6015
+ var sanitizePrefilledUsd = (value) => value?.replace(/[^0-9.]/g, "") ?? "";
5806
6016
  function PayWithCashApp({
5807
6017
  userId,
5808
6018
  publishableKey,
@@ -5817,6 +6027,7 @@ function PayWithCashApp({
5817
6027
  onEvent,
5818
6028
  onDepositSuccess,
5819
6029
  onDepositError,
6030
+ prefilledAmountUsd,
5820
6031
  wallets = []
5821
6032
  }) {
5822
6033
  const { colors: colors2, fonts, components } = useTheme();
@@ -5832,7 +6043,7 @@ function PayWithCashApp({
5832
6043
  const { data: limits, isLoading: limitsLoading } = useCashAppLimits({ publishableKey });
5833
6044
  const minUsd = limits?.minimum_amount ?? FALLBACK_MIN_USD;
5834
6045
  const maxUsd = limits?.maximum_amount ?? null;
5835
- const [amount, setAmount] = (0, import_react14.useState)("");
6046
+ const [amount, setAmount] = (0, import_react14.useState)(() => sanitizePrefilledUsd(prefilledAmountUsd));
5836
6047
  const [loading, setLoading] = (0, import_react14.useState)(false);
5837
6048
  const [session, setSession] = (0, import_react14.useState)(null);
5838
6049
  const [status, setStatus] = (0, import_react14.useState)("pending");
@@ -5955,6 +6166,13 @@ function PayWithCashApp({
5955
6166
  return () => clearInterval(interval);
5956
6167
  }, [session, view, status, publishableKey, onDepositSuccess, onDepositError]);
5957
6168
  const [softExpired, setSoftExpired] = (0, import_react14.useState)(false);
6169
+ (0, import_react14.useEffect)(() => {
6170
+ if (!prefilledAmountUsd) return;
6171
+ const cleaned = sanitizePrefilledUsd(prefilledAmountUsd);
6172
+ if (!cleaned) return;
6173
+ setAmount(cleaned);
6174
+ onAmountChange?.(cleaned);
6175
+ }, [prefilledAmountUsd, onAmountChange]);
5958
6176
  (0, import_react14.useEffect)(() => {
5959
6177
  if (!session?.expires_at || view !== "payment") return;
5960
6178
  const expiresMs = new Date(session.expires_at).getTime();
@@ -6310,7 +6528,7 @@ var import_lucide_react12 = require("lucide-react");
6310
6528
  var import_core18 = require("@unifold/core");
6311
6529
 
6312
6530
  // src/hooks/use-bank-transfer-providers.ts
6313
- var import_react_query7 = require("@tanstack/react-query");
6531
+ var import_react_query8 = require("@tanstack/react-query");
6314
6532
  var import_core17 = require("@unifold/core");
6315
6533
  function useBankTransferProviders({
6316
6534
  publishableKey,
@@ -6318,7 +6536,7 @@ function useBankTransferProviders({
6318
6536
  countryCode
6319
6537
  }) {
6320
6538
  const normalizedCountry = countryCode?.toUpperCase();
6321
- const { data: providers, isLoading } = (0, import_react_query7.useQuery)({
6539
+ const { data: providers, isLoading } = (0, import_react_query8.useQuery)({
6322
6540
  queryKey: ["unifold", "bankTransferProviders", publishableKey, normalizedCountry ?? null],
6323
6541
  queryFn: () => (0, import_core17.getBankTransferProviders)(publishableKey, { countryCode: normalizedCountry }),
6324
6542
  enabled,
@@ -6359,7 +6577,8 @@ function BankTransfer({
6359
6577
  assetCdnUrl,
6360
6578
  onDepositSuccess,
6361
6579
  onEvent,
6362
- onDepositError
6580
+ onDepositError,
6581
+ prefilledAmountUsd
6363
6582
  }) {
6364
6583
  const { colors: colors2, fonts, components } = useTheme();
6365
6584
  const [internalView, setInternalView] = (0, import_react15.useState)("providers");
@@ -6369,6 +6588,10 @@ function BankTransfer({
6369
6588
  const [requestBase, setRequestBase] = (0, import_react15.useState)(null);
6370
6589
  const [activeRequest, setActiveRequest] = (0, import_react15.useState)(null);
6371
6590
  const [amount, setAmount] = (0, import_react15.useState)("");
6591
+ const [fiatExchangeRates, setFiatExchangeRates] = (0, import_react15.useState)({
6592
+ usd: 1
6593
+ });
6594
+ const providerSelectionRequestIdRef = (0, import_react15.useRef)(0);
6372
6595
  const currentView = externalView ?? internalView;
6373
6596
  const setView = (v) => {
6374
6597
  setInternalView(v);
@@ -6418,7 +6641,38 @@ function BankTransfer({
6418
6641
  () => destinationTokenSymbol?.toUpperCase() ?? defaultToken?.destination_token_metadata?.symbol?.toUpperCase() ?? defaultToken?.destination_currency?.toUpperCase() ?? "USDC",
6419
6642
  [destinationTokenSymbol, defaultToken]
6420
6643
  );
6421
- const handleProviderClick = (provider) => {
6644
+ const resolvePrefilledSourceAmount = (0, import_react15.useCallback)(
6645
+ async (sourceCurrencyCode) => {
6646
+ const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
6647
+ if (!cleanedPrefilled) return "";
6648
+ const prefilledUsd = parseFloat(cleanedPrefilled);
6649
+ if (!Number.isFinite(prefilledUsd) || prefilledUsd <= 0) return "";
6650
+ const sourceCurrency2 = sourceCurrencyCode.toLowerCase();
6651
+ let rate = sourceCurrency2 === "usd" ? 1 : fiatExchangeRates[sourceCurrency2];
6652
+ if ((!rate || rate <= 0) && sourceCurrency2 !== "usd") {
6653
+ try {
6654
+ const response = await (0, import_core18.getFiatExchangeRates)({}, publishableKey);
6655
+ if (response?.rates) {
6656
+ setFiatExchangeRates((prev) => ({
6657
+ ...prev,
6658
+ ...response.rates,
6659
+ usd: 1
6660
+ }));
6661
+ }
6662
+ const fetchedRate = response.rates?.[sourceCurrency2];
6663
+ if (Number.isFinite(fetchedRate) && fetchedRate > 0) {
6664
+ rate = fetchedRate;
6665
+ }
6666
+ } catch (error) {
6667
+ console.error("Error fetching fiat exchange rates for bank transfer:", error);
6668
+ }
6669
+ }
6670
+ if (!rate || rate <= 0) return sourceCurrency2 === "usd" ? cleanedPrefilled : "";
6671
+ return parseFloat((prefilledUsd * rate).toFixed(2)).toString();
6672
+ },
6673
+ [fiatExchangeRates, prefilledAmountUsd, publishableKey]
6674
+ );
6675
+ const handleProviderClick = async (provider) => {
6422
6676
  if (!provider.enabled) return;
6423
6677
  setSessionError(null);
6424
6678
  if (!defaultToken) {
@@ -6437,6 +6691,7 @@ function BankTransfer({
6437
6691
  });
6438
6692
  return;
6439
6693
  }
6694
+ const requestId = ++providerSelectionRequestIdRef.current;
6440
6695
  setRequestBase({
6441
6696
  service_provider: provider.service_provider,
6442
6697
  country_code: (userIpInfo?.alpha2 || "DE").toUpperCase(),
@@ -6450,7 +6705,10 @@ function BankTransfer({
6450
6705
  payment_method: provider.payment_methods[0]
6451
6706
  });
6452
6707
  setActiveProvider(provider);
6453
- setAmount("100");
6708
+ const convertedPrefilled = await resolvePrefilledSourceAmount(provider.source_currency);
6709
+ if (requestId !== providerSelectionRequestIdRef.current) return;
6710
+ const hasPrefilledAmount = !!prefilledAmountUsd?.replace(/[^0-9.]/g, "");
6711
+ setAmount(hasPrefilledAmount ? convertedPrefilled : "100");
6454
6712
  setView("amount");
6455
6713
  };
6456
6714
  const handleAmountChange = (value) => {
@@ -6548,7 +6806,7 @@ function BankTransfer({
6548
6806
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
6549
6807
  "button",
6550
6808
  {
6551
- onClick: () => handleProviderClick(provider),
6809
+ onClick: () => void handleProviderClick(provider),
6552
6810
  onMouseEnter: () => !disabled && setHoveredId(provider.service_provider),
6553
6811
  onMouseLeave: () => setHoveredId(null),
6554
6812
  disabled,
@@ -7117,7 +7375,7 @@ function DepositExecutionItem({ execution, onClick }) {
7117
7375
  }
7118
7376
 
7119
7377
  // src/components/deposits/buttons/TransferCryptoButton.tsx
7120
- var React6 = __toESM(require("react"));
7378
+ var React7 = __toESM(require("react"));
7121
7379
  var import_lucide_react14 = require("lucide-react");
7122
7380
  var import_jsx_runtime19 = require("react/jsx-runtime");
7123
7381
  function TransferCryptoButton({
@@ -7127,9 +7385,9 @@ function TransferCryptoButton({
7127
7385
  featuredTokens
7128
7386
  }) {
7129
7387
  const { colors: colors2, fonts, components } = useTheme();
7130
- const [isHovered, setIsHovered] = React6.useState(false);
7131
- const [isTouchDevice, setIsTouchDevice] = React6.useState(false);
7132
- React6.useEffect(() => {
7388
+ const [isHovered, setIsHovered] = React7.useState(false);
7389
+ const [isTouchDevice, setIsTouchDevice] = React7.useState(false);
7390
+ React7.useEffect(() => {
7133
7391
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7134
7392
  }, []);
7135
7393
  const sortedTokens = featuredTokens ? [...featuredTokens].sort((a, b) => a.position - b.position) : [];
@@ -7204,7 +7462,7 @@ function TransferCryptoButton({
7204
7462
  }
7205
7463
 
7206
7464
  // src/components/deposits/buttons/DepositWithCardButton.tsx
7207
- var React7 = __toESM(require("react"));
7465
+ var React8 = __toESM(require("react"));
7208
7466
  var import_lucide_react15 = require("lucide-react");
7209
7467
  var import_jsx_runtime20 = require("react/jsx-runtime");
7210
7468
  function DepositWithCardButton({
@@ -7214,9 +7472,9 @@ function DepositWithCardButton({
7214
7472
  paymentNetworks
7215
7473
  }) {
7216
7474
  const { colors: colors2, fonts, components } = useTheme();
7217
- const [isHovered, setIsHovered] = React7.useState(false);
7218
- const [isTouchDevice, setIsTouchDevice] = React7.useState(false);
7219
- React7.useEffect(() => {
7475
+ const [isHovered, setIsHovered] = React8.useState(false);
7476
+ const [isTouchDevice, setIsTouchDevice] = React8.useState(false);
7477
+ React8.useEffect(() => {
7220
7478
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7221
7479
  }, []);
7222
7480
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
@@ -7289,7 +7547,7 @@ function DepositWithCardButton({
7289
7547
  }
7290
7548
 
7291
7549
  // src/components/deposits/buttons/PayWithExchangeButton.tsx
7292
- var React8 = __toESM(require("react"));
7550
+ var React9 = __toESM(require("react"));
7293
7551
  var import_lucide_react16 = require("lucide-react");
7294
7552
  var import_jsx_runtime21 = require("react/jsx-runtime");
7295
7553
  function PayWithExchangeButton({
@@ -7300,9 +7558,9 @@ function PayWithExchangeButton({
7300
7558
  loading = false
7301
7559
  }) {
7302
7560
  const { colors: colors2, fonts, components } = useTheme();
7303
- const [isHovered, setIsHovered] = React8.useState(false);
7304
- const [isTouchDevice, setIsTouchDevice] = React8.useState(false);
7305
- React8.useEffect(() => {
7561
+ const [isHovered, setIsHovered] = React9.useState(false);
7562
+ const [isTouchDevice, setIsTouchDevice] = React9.useState(false);
7563
+ React9.useEffect(() => {
7306
7564
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7307
7565
  }, []);
7308
7566
  if (loading) {
@@ -7381,11 +7639,11 @@ function PayWithExchangeButton({
7381
7639
  }
7382
7640
 
7383
7641
  // src/components/deposits/buttons/ConnectExchangeButton.tsx
7384
- var React10 = __toESM(require("react"));
7642
+ var React11 = __toESM(require("react"));
7385
7643
  var import_lucide_react17 = require("lucide-react");
7386
7644
 
7387
7645
  // src/components/shared/button.tsx
7388
- var React9 = __toESM(require("react"));
7646
+ var React10 = __toESM(require("react"));
7389
7647
  var import_react_slot = require("@radix-ui/react-slot");
7390
7648
  var import_class_variance_authority = require("class-variance-authority");
7391
7649
  var import_jsx_runtime22 = require("react/jsx-runtime");
@@ -7414,11 +7672,11 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
7414
7672
  }
7415
7673
  }
7416
7674
  );
7417
- var Button = React9.forwardRef(
7675
+ var Button = React10.forwardRef(
7418
7676
  ({ className, variant, size, asChild = false, style, ...props }, ref) => {
7419
7677
  const Comp = asChild ? import_react_slot.Slot : "button";
7420
7678
  const { components, fonts } = useTheme();
7421
- const themeStyle = React9.useMemo(() => {
7679
+ const themeStyle = React10.useMemo(() => {
7422
7680
  const baseStyle = { ...style };
7423
7681
  if (variant === "default" || !variant) {
7424
7682
  baseStyle.backgroundColor = components.button.primaryBackground;
@@ -7456,9 +7714,9 @@ function ConnectExchangeButton({
7456
7714
  connectedExchange
7457
7715
  }) {
7458
7716
  const { colors: colors2, fonts, components } = useTheme();
7459
- const [isHovered, setIsHovered] = React10.useState(false);
7460
- const [isTouchDevice, setIsTouchDevice] = React10.useState(false);
7461
- React10.useEffect(() => {
7717
+ const [isHovered, setIsHovered] = React11.useState(false);
7718
+ const [isTouchDevice, setIsTouchDevice] = React11.useState(false);
7719
+ React11.useEffect(() => {
7462
7720
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7463
7721
  }, []);
7464
7722
  const isConnected = connectedExchange != null;
@@ -7598,7 +7856,7 @@ function ConnectExchangeButton({
7598
7856
  }
7599
7857
 
7600
7858
  // src/components/deposits/buttons/DepositTrackerButton.tsx
7601
- var React11 = __toESM(require("react"));
7859
+ var React12 = __toESM(require("react"));
7602
7860
  var import_lucide_react18 = require("lucide-react");
7603
7861
  var import_jsx_runtime24 = require("react/jsx-runtime");
7604
7862
  function DepositTrackerButton({
@@ -7608,9 +7866,9 @@ function DepositTrackerButton({
7608
7866
  badge
7609
7867
  }) {
7610
7868
  const { colors: colors2, fonts, components } = useTheme();
7611
- const [isHovered, setIsHovered] = React11.useState(false);
7612
- const [isTouchDevice, setIsTouchDevice] = React11.useState(false);
7613
- React11.useEffect(() => {
7869
+ const [isHovered, setIsHovered] = React12.useState(false);
7870
+ const [isTouchDevice, setIsTouchDevice] = React12.useState(false);
7871
+ React12.useEffect(() => {
7614
7872
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7615
7873
  }, []);
7616
7874
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
@@ -7681,14 +7939,14 @@ function DepositTrackerButton({
7681
7939
  }
7682
7940
 
7683
7941
  // src/components/deposits/buttons/CashAppButton.tsx
7684
- var React12 = __toESM(require("react"));
7942
+ var React13 = __toESM(require("react"));
7685
7943
  var import_lucide_react19 = require("lucide-react");
7686
7944
  var import_jsx_runtime25 = require("react/jsx-runtime");
7687
7945
  function CashAppButton({ onClick, title, subtitle, iconUrl }) {
7688
7946
  const { colors: colors2, fonts, components } = useTheme();
7689
- const [isHovered, setIsHovered] = React12.useState(false);
7690
- const [isTouchDevice, setIsTouchDevice] = React12.useState(false);
7691
- React12.useEffect(() => {
7947
+ const [isHovered, setIsHovered] = React13.useState(false);
7948
+ const [isTouchDevice, setIsTouchDevice] = React13.useState(false);
7949
+ React13.useEffect(() => {
7692
7950
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7693
7951
  }, []);
7694
7952
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
@@ -7752,7 +8010,7 @@ function CashAppButton({ onClick, title, subtitle, iconUrl }) {
7752
8010
  }
7753
8011
 
7754
8012
  // src/components/deposits/buttons/ApplePayButton.tsx
7755
- var React13 = __toESM(require("react"));
8013
+ var React14 = __toESM(require("react"));
7756
8014
  var import_lucide_react20 = require("lucide-react");
7757
8015
  var import_jsx_runtime26 = require("react/jsx-runtime");
7758
8016
  function AppleLogo({ className, style }) {
@@ -7775,11 +8033,11 @@ function AppleLogo({ className, style }) {
7775
8033
  }
7776
8034
  );
7777
8035
  }
7778
- function ApplePayButton({ onClick, title, subtitle }) {
8036
+ function ApplePayButton({ onClick, title, subtitle, iconUrl }) {
7779
8037
  const { colors: colors2, fonts, components } = useTheme();
7780
- const [isHovered, setIsHovered] = React13.useState(false);
7781
- const [isTouchDevice, setIsTouchDevice] = React13.useState(false);
7782
- React13.useEffect(() => {
8038
+ const [isHovered, setIsHovered] = React14.useState(false);
8039
+ const [isTouchDevice, setIsTouchDevice] = React14.useState(false);
8040
+ React14.useEffect(() => {
7783
8041
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7784
8042
  }, []);
7785
8043
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
@@ -7797,7 +8055,14 @@ function ApplePayButton({ onClick, title, subtitle }) {
7797
8055
  },
7798
8056
  children: [
7799
8057
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
7800
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AppleLogo, { className: "uf-w-5 uf-h-5", style: { color: components.card.iconColor } }) }),
8058
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "uf-rounded-lg uf-overflow-hidden uf-w-9 uf-h-9 uf-flex uf-items-center uf-justify-center", children: iconUrl ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("img", { src: iconUrl, alt: "Apple Pay", width: 36, height: 36, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
8059
+ "div",
8060
+ {
8061
+ className: "uf-w-9 uf-h-9 uf-rounded-lg uf-flex uf-items-center uf-justify-center",
8062
+ style: { backgroundColor: "#000" },
8063
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AppleLogo, { className: "uf-w-5 uf-h-5", style: { color: "#fff" } })
8064
+ }
8065
+ ) }),
7801
8066
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "uf-text-left", children: [
7802
8067
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7803
8068
  "div",
@@ -7836,7 +8101,7 @@ function ApplePayButton({ onClick, title, subtitle }) {
7836
8101
  }
7837
8102
 
7838
8103
  // src/components/deposits/buttons/BankTransferButton.tsx
7839
- var React14 = __toESM(require("react"));
8104
+ var React15 = __toESM(require("react"));
7840
8105
  var import_lucide_react21 = require("lucide-react");
7841
8106
  var import_jsx_runtime27 = require("react/jsx-runtime");
7842
8107
  function BankTransferButton({
@@ -7846,9 +8111,9 @@ function BankTransferButton({
7846
8111
  comingSoon = false
7847
8112
  }) {
7848
8113
  const { colors: colors2, fonts, components } = useTheme();
7849
- const [isHovered, setIsHovered] = React14.useState(false);
7850
- const [isTouchDevice, setIsTouchDevice] = React14.useState(false);
7851
- React14.useEffect(() => {
8114
+ const [isHovered, setIsHovered] = React15.useState(false);
8115
+ const [isTouchDevice, setIsTouchDevice] = React15.useState(false);
8116
+ React15.useEffect(() => {
7852
8117
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7853
8118
  }, []);
7854
8119
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
@@ -7906,7 +8171,7 @@ function BankTransferButton({
7906
8171
  }
7907
8172
 
7908
8173
  // src/components/deposits/buttons/BrowserWalletButton.tsx
7909
- var React28 = __toESM(require("react"));
8174
+ var React29 = __toESM(require("react"));
7910
8175
  var import_lucide_react22 = require("lucide-react");
7911
8176
  var import_core20 = require("@unifold/core");
7912
8177
 
@@ -7961,7 +8226,7 @@ function collectAllEip6963EthProviders() {
7961
8226
  }
7962
8227
 
7963
8228
  // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
7964
- var React15 = __toESM(require("react"));
8229
+ var React16 = __toESM(require("react"));
7965
8230
 
7966
8231
  // src/components/deposits/browser-wallets/detectConnectedWallet.ts
7967
8232
  function identifyEthWallet(provider, hint) {
@@ -8031,13 +8296,6 @@ function solanaCandidate(provider, type, name, icon) {
8031
8296
  if (provider.isConnected && provider.publicKey) {
8032
8297
  return { type, name, address: provider.publicKey.toString(), icon };
8033
8298
  }
8034
- try {
8035
- const resp = await provider.connect({ onlyIfTrusted: true });
8036
- if (resp.publicKey) {
8037
- return { type, name, address: resp.publicKey.toString(), icon };
8038
- }
8039
- } catch {
8040
- }
8041
8299
  return null;
8042
8300
  }
8043
8301
  };
@@ -8112,18 +8370,18 @@ async function detectConnectedBrowserWallet(chainType) {
8112
8370
  // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
8113
8371
  function useDetectedBrowserWallet(opts = {}) {
8114
8372
  const { chainType, enabled = true, onDisconnect } = opts;
8115
- const [wallet, setWallet] = React15.useState(null);
8116
- const [isLoading, setIsLoading] = React15.useState(enabled);
8117
- const [eip6963ProviderCount, setEip6963ProviderCount] = React15.useState(0);
8118
- const onDisconnectRef = React15.useRef(onDisconnect);
8373
+ const [wallet, setWallet] = React16.useState(null);
8374
+ const [isLoading, setIsLoading] = React16.useState(enabled);
8375
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React16.useState(0);
8376
+ const onDisconnectRef = React16.useRef(onDisconnect);
8119
8377
  onDisconnectRef.current = onDisconnect;
8120
- React15.useEffect(() => {
8378
+ React16.useEffect(() => {
8121
8379
  const store = getEip6963Store();
8122
8380
  if (!store) return;
8123
8381
  setEip6963ProviderCount(store.getProviders().length);
8124
8382
  return store.subscribe((providers) => setEip6963ProviderCount(providers.length));
8125
8383
  }, []);
8126
- React15.useEffect(() => {
8384
+ React16.useEffect(() => {
8127
8385
  if (!enabled) {
8128
8386
  setWallet(null);
8129
8387
  setIsLoading(false);
@@ -8266,11 +8524,185 @@ async function disconnectInjectedBrowserWallet(wallet) {
8266
8524
  );
8267
8525
  }
8268
8526
 
8527
+ // src/components/deposits/browser-wallets/providerResolvers.ts
8528
+ var STORED_TYPE_TO_EIP6963_WALLET_ID = {
8529
+ metamask: "metamask",
8530
+ "phantom-ethereum": "phantom",
8531
+ coinbase: "coinbase",
8532
+ trust: "trust",
8533
+ rainbow: "rainbow",
8534
+ rabby: "rabby",
8535
+ okx: "okx"
8536
+ };
8537
+ var EIP6963_WALLET_ID_TO_INFO = {
8538
+ metamask: { walletType: "metamask", name: "MetaMask", icon: "metamask" },
8539
+ phantom: { walletType: "phantom-ethereum", name: "Phantom", icon: "phantom" },
8540
+ coinbase: { walletType: "coinbase", name: "Coinbase Wallet", icon: "coinbase" },
8541
+ trust: { walletType: "trust", name: "Trust Wallet", icon: "trust" },
8542
+ rainbow: { walletType: "rainbow", name: "Rainbow", icon: "rainbow" },
8543
+ rabby: { walletType: "rabby", name: "Rabby", icon: "rabby" },
8544
+ okx: { walletType: "okx", name: "OKX Wallet", icon: "okx" }
8545
+ };
8546
+ var WALLET_ID_TO_WALLET_TYPE = {
8547
+ phantom: "phantom-ethereum",
8548
+ coinbase: "coinbase",
8549
+ trust: "trust",
8550
+ rainbow: "rainbow",
8551
+ rabby: "rabby",
8552
+ okx: "okx",
8553
+ metamask: "metamask"
8554
+ };
8555
+ var WALLET_TYPE_TO_WALLET_ID = {
8556
+ "phantom-ethereum": "phantom",
8557
+ coinbase: "coinbase",
8558
+ trust: "trust",
8559
+ okx: "okx",
8560
+ rainbow: "rainbow",
8561
+ rabby: "rabby",
8562
+ metamask: "metamask"
8563
+ };
8564
+ function isWalletType(value) {
8565
+ return value === "phantom-solana" || value === "phantom-ethereum" || value === "metamask" || value === "coinbase" || value === "solflare" || value === "backpack" || value === "glow" || value === "trust" || value === "rainbow" || value === "rabby" || value === "okx";
8566
+ }
8567
+ function walletIdToWalletType(walletId) {
8568
+ return WALLET_ID_TO_WALLET_TYPE[walletId] || "metamask";
8569
+ }
8570
+ function walletTypeToWalletId(walletType) {
8571
+ return WALLET_TYPE_TO_WALLET_ID[walletType] || walletType;
8572
+ }
8573
+ function getLegacyEvmProviders(win) {
8574
+ if (!win) return {};
8575
+ const anyWin = win;
8576
+ return {
8577
+ ethereum: anyWin.ethereum,
8578
+ phantomEthereum: anyWin.phantom?.ethereum,
8579
+ coinbaseEthereum: anyWin.coinbaseWalletExtension,
8580
+ trustEthereum: anyWin.trustwallet?.ethereum,
8581
+ okxEthereum: anyWin.okxwallet
8582
+ };
8583
+ }
8584
+ function getInjectedSolanaProviders(win) {
8585
+ if (!win) return {};
8586
+ const anyWin = win;
8587
+ return {
8588
+ phantomSolana: anyWin.phantom?.solana,
8589
+ solflare: anyWin.solflare,
8590
+ backpack: anyWin.backpack,
8591
+ glow: anyWin.glow,
8592
+ coinbaseSolana: anyWin.coinbaseSolana || anyWin.coinbaseWalletExtension?.solana,
8593
+ trustSolana: anyWin.trustwallet?.solana
8594
+ };
8595
+ }
8596
+ function describeEip6963Provider(wp) {
8597
+ const mapped = EIP6963_WALLET_ID_TO_INFO[wp.walletId];
8598
+ return {
8599
+ provider: wp.provider,
8600
+ walletType: mapped?.walletType ?? "metamask",
8601
+ name: mapped?.name ?? wp.info.name,
8602
+ icon: mapped?.icon ?? wp.info.icon
8603
+ };
8604
+ }
8605
+ function resolveQuickConnectEvmProvider(win) {
8606
+ const eip6963Providers = getEip6963Providers();
8607
+ if (eip6963Providers.length > 0) {
8608
+ const stored = getStoredWalletState();
8609
+ const preferredWalletId = stored?.walletType && isWalletType(stored.walletType) ? STORED_TYPE_TO_EIP6963_WALLET_ID[stored.walletType] : void 0;
8610
+ if (preferredWalletId) {
8611
+ const preferred = findProviderByWalletId(preferredWalletId);
8612
+ if (preferred) return describeEip6963Provider(preferred);
8613
+ }
8614
+ if (eip6963Providers.length === 1) {
8615
+ return describeEip6963Provider(eip6963Providers[0]);
8616
+ }
8617
+ return void 0;
8618
+ }
8619
+ const anyWin = win;
8620
+ const legacy = anyWin.phantom?.ethereum || anyWin.ethereum;
8621
+ if (!legacy) return void 0;
8622
+ const isPhantom = legacy.isPhantom;
8623
+ return {
8624
+ provider: legacy,
8625
+ walletType: isPhantom ? "phantom-ethereum" : "metamask",
8626
+ name: isPhantom ? "Phantom" : "MetaMask",
8627
+ icon: isPhantom ? "phantom" : "metamask"
8628
+ };
8629
+ }
8630
+ function resolveSolanaPublicKey(provider, response) {
8631
+ if (response?.publicKey) return { publicKey: response.publicKey };
8632
+ if (provider.publicKey) return { publicKey: provider.publicKey };
8633
+ return null;
8634
+ }
8635
+ function isUserRejectedSolanaConnectError(error) {
8636
+ if (!error || typeof error !== "object") return false;
8637
+ const maybeCode = "code" in error ? error.code : void 0;
8638
+ if (maybeCode === 4001) return true;
8639
+ const msg = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
8640
+ return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("rejected the request") || msg.includes("declined");
8641
+ }
8642
+ function isSolanaConnectTimeoutError(error) {
8643
+ return error instanceof Error && error.message.toLowerCase().includes("did not respond to the connection request");
8644
+ }
8645
+ async function connectSolanaProviderWithRecovery(provider, walletId, walletName) {
8646
+ if (provider.isConnected && provider.publicKey) {
8647
+ return { publicKey: provider.publicKey };
8648
+ }
8649
+ const connectOnce = () => provider.connect(walletId === "solflare" ? { onlyIfTrusted: false } : void 0);
8650
+ const withTimeout = async (ms = 2e4) => await Promise.race([
8651
+ connectOnce(),
8652
+ new Promise(
8653
+ (resolve, reject) => setTimeout(() => {
8654
+ const connected = resolveSolanaPublicKey(provider);
8655
+ if (connected) {
8656
+ resolve(connected);
8657
+ return;
8658
+ }
8659
+ reject(
8660
+ new Error(
8661
+ `${walletName} did not respond to the connection request. Please unlock the wallet and try again.`
8662
+ )
8663
+ );
8664
+ }, ms)
8665
+ )
8666
+ ]);
8667
+ if (walletId === "solflare") {
8668
+ await provider.disconnect?.().catch(() => {
8669
+ });
8670
+ }
8671
+ const connectAndResolve = async () => {
8672
+ try {
8673
+ const response = await withTimeout();
8674
+ const resolved = resolveSolanaPublicKey(provider, response);
8675
+ if (resolved) return resolved;
8676
+ await new Promise((resolve) => setTimeout(resolve, 120));
8677
+ const delayedResolved = resolveSolanaPublicKey(provider);
8678
+ if (delayedResolved) return delayedResolved;
8679
+ throw new Error(`${walletName} connected but did not expose a public key.`);
8680
+ } catch (error) {
8681
+ const connected = resolveSolanaPublicKey(provider);
8682
+ if (connected) return connected;
8683
+ throw error;
8684
+ }
8685
+ };
8686
+ try {
8687
+ return await connectAndResolve();
8688
+ } catch (err) {
8689
+ if (isUserRejectedSolanaConnectError(err)) throw err;
8690
+ if (isSolanaConnectTimeoutError(err)) throw err;
8691
+ if (walletId === "solflare") {
8692
+ await provider.disconnect?.().catch(() => {
8693
+ });
8694
+ await new Promise((resolve) => setTimeout(resolve, 150));
8695
+ return await connectAndResolve();
8696
+ }
8697
+ throw err;
8698
+ }
8699
+ }
8700
+
8269
8701
  // src/resources/icons/MetamaskIcon.tsx
8270
- var React16 = __toESM(require("react"));
8702
+ var React17 = __toESM(require("react"));
8271
8703
  var import_jsx_runtime28 = require("react/jsx-runtime");
8272
8704
  function MetamaskIcon({ size = 24, className, variant = "color" }) {
8273
- const id = React16.useId();
8705
+ const id = React17.useId();
8274
8706
  if (variant === "light" || variant === "dark") {
8275
8707
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
8276
8708
  "svg",
@@ -8392,10 +8824,10 @@ function MetamaskIcon({ size = 24, className, variant = "color" }) {
8392
8824
  }
8393
8825
 
8394
8826
  // src/resources/icons/PhantomIcon.tsx
8395
- var React17 = __toESM(require("react"));
8827
+ var React18 = __toESM(require("react"));
8396
8828
  var import_jsx_runtime29 = require("react/jsx-runtime");
8397
8829
  function PhantomIcon({ size = 24, className, variant = "color" }) {
8398
- const id = React17.useId();
8830
+ const id = React18.useId();
8399
8831
  if (variant === "light") {
8400
8832
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
8401
8833
  "svg",
@@ -8463,10 +8895,10 @@ function PhantomIcon({ size = 24, className, variant = "color" }) {
8463
8895
  }
8464
8896
 
8465
8897
  // src/resources/icons/CoinbaseIcon.tsx
8466
- var React18 = __toESM(require("react"));
8898
+ var React19 = __toESM(require("react"));
8467
8899
  var import_jsx_runtime30 = require("react/jsx-runtime");
8468
8900
  function CoinbaseIcon({ size = 24, className, variant = "color" }) {
8469
- const id = React18.useId();
8901
+ const id = React19.useId();
8470
8902
  if (variant === "light") {
8471
8903
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
8472
8904
  "svg",
@@ -8547,10 +8979,10 @@ function CoinbaseIcon({ size = 24, className, variant = "color" }) {
8547
8979
  }
8548
8980
 
8549
8981
  // src/resources/icons/RabbyIcon.tsx
8550
- var React19 = __toESM(require("react"));
8982
+ var React20 = __toESM(require("react"));
8551
8983
  var import_jsx_runtime31 = require("react/jsx-runtime");
8552
8984
  function RabbyIcon({ size = 24, className, variant = "color" }) {
8553
- const id = React19.useId();
8985
+ const id = React20.useId();
8554
8986
  if (variant === "light") {
8555
8987
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
8556
8988
  "svg",
@@ -8898,10 +9330,10 @@ function RabbyIcon({ size = 24, className, variant = "color" }) {
8898
9330
  }
8899
9331
 
8900
9332
  // src/resources/icons/RainbowIcon.tsx
8901
- var React20 = __toESM(require("react"));
9333
+ var React21 = __toESM(require("react"));
8902
9334
  var import_jsx_runtime32 = require("react/jsx-runtime");
8903
9335
  function RainbowIcon({ size = 24, className, variant = "color" }) {
8904
- const id = React20.useId();
9336
+ const id = React21.useId();
8905
9337
  if (variant === "light") {
8906
9338
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
8907
9339
  "svg",
@@ -9316,10 +9748,10 @@ function RainbowIcon({ size = 24, className, variant = "color" }) {
9316
9748
  }
9317
9749
 
9318
9750
  // src/resources/icons/TrustIcon.tsx
9319
- var React21 = __toESM(require("react"));
9751
+ var React22 = __toESM(require("react"));
9320
9752
  var import_jsx_runtime33 = require("react/jsx-runtime");
9321
9753
  function TrustIcon({ size = 24, className, variant = "color" }) {
9322
- const id = React21.useId();
9754
+ const id = React22.useId();
9323
9755
  if (variant === "light") {
9324
9756
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
9325
9757
  "svg",
@@ -9403,10 +9835,10 @@ function TrustIcon({ size = 24, className, variant = "color" }) {
9403
9835
  }
9404
9836
 
9405
9837
  // src/resources/icons/OkxIcon.tsx
9406
- var React22 = __toESM(require("react"));
9838
+ var React23 = __toESM(require("react"));
9407
9839
  var import_jsx_runtime34 = require("react/jsx-runtime");
9408
9840
  function OkxIcon({ size = 24, className, variant = "color" }) {
9409
- const id = React22.useId();
9841
+ const id = React23.useId();
9410
9842
  if (variant === "light") {
9411
9843
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
9412
9844
  "svg",
@@ -9462,10 +9894,10 @@ function OkxIcon({ size = 24, className, variant = "color" }) {
9462
9894
  }
9463
9895
 
9464
9896
  // src/resources/icons/GlowIcon.tsx
9465
- var React23 = __toESM(require("react"));
9897
+ var React24 = __toESM(require("react"));
9466
9898
  var import_jsx_runtime35 = require("react/jsx-runtime");
9467
9899
  function GlowIcon({ size = 24, className, variant = "color" }) {
9468
- const id = React23.useId();
9900
+ const id = React24.useId();
9469
9901
  if (variant === "light") {
9470
9902
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
9471
9903
  "svg",
@@ -9567,10 +9999,10 @@ function GlowIcon({ size = 24, className, variant = "color" }) {
9567
9999
  }
9568
10000
 
9569
10001
  // src/resources/icons/BackpackIcon.tsx
9570
- var React24 = __toESM(require("react"));
10002
+ var React25 = __toESM(require("react"));
9571
10003
  var import_jsx_runtime36 = require("react/jsx-runtime");
9572
10004
  function BackpackIcon({ size = 24, className, variant = "color" }) {
9573
- const id = React24.useId();
10005
+ const id = React25.useId();
9574
10006
  if (variant === "light") {
9575
10007
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
9576
10008
  "svg",
@@ -9644,10 +10076,10 @@ function BackpackIcon({ size = 24, className, variant = "color" }) {
9644
10076
  }
9645
10077
 
9646
10078
  // src/resources/icons/SolflareIcon.tsx
9647
- var React25 = __toESM(require("react"));
10079
+ var React26 = __toESM(require("react"));
9648
10080
  var import_jsx_runtime37 = require("react/jsx-runtime");
9649
10081
  function SolflareIcon({ size = 24, className, variant = "color" }) {
9650
- const id = React25.useId();
10082
+ const id = React26.useId();
9651
10083
  if (variant === "light") {
9652
10084
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
9653
10085
  "svg",
@@ -9715,10 +10147,10 @@ function SolflareIcon({ size = 24, className, variant = "color" }) {
9715
10147
  }
9716
10148
 
9717
10149
  // src/resources/icons/EthereumIcon.tsx
9718
- var React26 = __toESM(require("react"));
10150
+ var React27 = __toESM(require("react"));
9719
10151
  var import_jsx_runtime38 = require("react/jsx-runtime");
9720
10152
  function EthereumIcon({ size = 24, className, variant = "color" }) {
9721
- const id = React26.useId();
10153
+ const id = React27.useId();
9722
10154
  if (variant === "light") {
9723
10155
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
9724
10156
  "svg",
@@ -9843,10 +10275,10 @@ function EthereumIcon({ size = 24, className, variant = "color" }) {
9843
10275
  }
9844
10276
 
9845
10277
  // src/resources/icons/SolanaIcon.tsx
9846
- var React27 = __toESM(require("react"));
10278
+ var React28 = __toESM(require("react"));
9847
10279
  var import_jsx_runtime39 = require("react/jsx-runtime");
9848
10280
  function SolanaIcon({ size = 24, className, variant = "color" }) {
9849
- const id = React27.useId();
10281
+ const id = React28.useId();
9850
10282
  if (variant === "light") {
9851
10283
  return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
9852
10284
  "svg",
@@ -10070,7 +10502,11 @@ function WalletIconWithNetwork({
10070
10502
  }
10071
10503
 
10072
10504
  // src/components/deposits/buttons/BrowserWalletButton.tsx
10073
- var import_jsx_runtime41 = require("react/jsx-runtime");
10505
+ var import_jsx_runtime41 = (
10506
+ // Wallet announced via EIP-6963 with no internal icon component: render its
10507
+ // own advertised icon (`info.icon`) rather than a generic placeholder.
10508
+ require("react/jsx-runtime")
10509
+ );
10074
10510
  var WALLET_ICON_COMPONENTS = {
10075
10511
  metamask: MetamaskIcon,
10076
10512
  phantom: PhantomIcon,
@@ -10097,19 +10533,19 @@ function BrowserWalletButton({
10097
10533
  subtitle = i18n.depositModal.browserWallet.subtitle
10098
10534
  }) {
10099
10535
  const { colors: colors2, fonts, components } = useTheme();
10100
- const [isHovered, setIsHovered] = React28.useState(false);
10101
- const [isTouchDevice, setIsTouchDevice] = React28.useState(false);
10536
+ const [isHovered, setIsHovered] = React29.useState(false);
10537
+ const [isTouchDevice, setIsTouchDevice] = React29.useState(false);
10102
10538
  const { wallet, isLoading, setWallet } = useDetectedBrowserWallet({ chainType, onDisconnect });
10103
- const [isConnecting, setIsConnecting] = React28.useState(false);
10104
- const [balanceText, setBalanceText] = React28.useState(null);
10105
- const [isLoadingBalance, setIsLoadingBalance] = React28.useState(false);
10106
- const [isDisconnecting, setIsDisconnecting] = React28.useState(false);
10107
- const onDisconnectRef = React28.useRef(onDisconnect);
10539
+ const [isConnecting, setIsConnecting] = React29.useState(false);
10540
+ const [balanceText, setBalanceText] = React29.useState(null);
10541
+ const [isLoadingBalance, setIsLoadingBalance] = React29.useState(false);
10542
+ const [isDisconnecting, setIsDisconnecting] = React29.useState(false);
10543
+ const onDisconnectRef = React29.useRef(onDisconnect);
10108
10544
  onDisconnectRef.current = onDisconnect;
10109
- React28.useEffect(() => {
10545
+ React29.useEffect(() => {
10110
10546
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
10111
10547
  }, []);
10112
- React28.useEffect(() => {
10548
+ React29.useEffect(() => {
10113
10549
  if (!wallet || !publishableKey) {
10114
10550
  setBalanceText(null);
10115
10551
  return;
@@ -10178,21 +10614,19 @@ function BrowserWalletButton({
10178
10614
  }
10179
10615
  }
10180
10616
  if (!chainType || chainType === "ethereum") {
10181
- const ethProvider = window.phantom?.ethereum || window.ethereum;
10182
- if (ethProvider) {
10183
- const accounts = await ethProvider.request({
10617
+ const resolved = resolveQuickConnectEvmProvider(window);
10618
+ if (resolved) {
10619
+ const accounts = await resolved.provider.request({
10184
10620
  method: "eth_requestAccounts"
10185
10621
  });
10186
10622
  if (accounts && accounts.length > 0) {
10187
10623
  setUserDisconnectedWallet(false);
10188
- const isPhantom = ethProvider.isPhantom;
10189
- const walletType = isPhantom ? "phantom-ethereum" : "metamask";
10190
- setStoredWalletState(walletType);
10624
+ setStoredWalletState(resolved.walletType);
10191
10625
  setWallet({
10192
- type: walletType,
10193
- name: isPhantom ? "Phantom" : "MetaMask",
10626
+ type: resolved.walletType,
10627
+ name: resolved.name,
10194
10628
  address: accounts[0],
10195
- icon: isPhantom ? "phantom" : "metamask"
10629
+ icon: resolved.icon
10196
10630
  });
10197
10631
  }
10198
10632
  }
@@ -10226,7 +10660,10 @@ function BrowserWalletButton({
10226
10660
  if (isLoading) {
10227
10661
  return null;
10228
10662
  }
10229
- const hasWalletExtension = (!chainType || chainType === "ethereum") && getEip6963Providers().length > 0 || (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) || (!chainType || chainType === "ethereum") && (window.phantom?.ethereum || window.ethereum);
10663
+ const eip6963EvmProviderCount = getEip6963Providers().length;
10664
+ const legacyEvmProviders = getLegacyEvmProviders(window);
10665
+ const hasLegacyEvmProvider = eip6963EvmProviderCount === 0 && !!(legacyEvmProviders.ethereum || legacyEvmProviders.phantomEthereum || legacyEvmProviders.coinbaseEthereum || legacyEvmProviders.trustEthereum || legacyEvmProviders.okxEthereum);
10666
+ const hasWalletExtension = (!chainType || chainType === "ethereum") && eip6963EvmProviderCount > 0 || (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) || (!chainType || chainType === "ethereum") && hasLegacyEvmProvider;
10230
10667
  if (!onConnectClick && !wallet && !hasWalletExtension) {
10231
10668
  return null;
10232
10669
  }
@@ -10236,11 +10673,21 @@ function BrowserWalletButton({
10236
10673
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
10237
10674
  };
10238
10675
  const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
10239
- const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React28.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
10676
+ const isImageIcon = !!wallet && (wallet.icon.startsWith("data:") || wallet.icon.startsWith("http"));
10677
+ const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React29.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
10240
10678
  size: 36,
10241
10679
  className: "uf-rounded-lg",
10242
10680
  variant: "color"
10243
- }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "uf-w-9 uf-h-9 uf-rounded-lg uf-bg-gray-500" }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react22.Wallet, { className: "uf-w-5 uf-h-5", style: { color: components.card.iconColor } }) });
10681
+ }) : isImageIcon ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10682
+ "img",
10683
+ {
10684
+ src: wallet.icon,
10685
+ alt: wallet.name,
10686
+ width: 36,
10687
+ height: 36,
10688
+ className: "uf-rounded-lg uf-w-9 uf-h-9"
10689
+ }
10690
+ ) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "uf-w-9 uf-h-9 uf-rounded-lg uf-bg-gray-500" }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react22.Wallet, { className: "uf-w-5 uf-h-5", style: { color: components.card.iconColor } }) });
10244
10691
  const titleSubtitleBlock = /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "uf-text-left uf-min-w-0", children: [
10245
10692
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
10246
10693
  "div",
@@ -10381,7 +10828,7 @@ function BrowserWalletButton({
10381
10828
  }
10382
10829
 
10383
10830
  // src/components/deposits/buttons/StripeLinkButton.tsx
10384
- var React29 = __toESM(require("react"));
10831
+ var React30 = __toESM(require("react"));
10385
10832
  var import_lucide_react23 = require("lucide-react");
10386
10833
  var import_jsx_runtime42 = require("react/jsx-runtime");
10387
10834
  var t4 = i18n.depositModal.stripeLink;
@@ -10392,9 +10839,9 @@ function StripeLinkButton({
10392
10839
  iconUrl
10393
10840
  }) {
10394
10841
  const { colors: colors2, fonts, components } = useTheme();
10395
- const [isHovered, setIsHovered] = React29.useState(false);
10396
- const [isTouchDevice, setIsTouchDevice] = React29.useState(false);
10397
- React29.useEffect(() => {
10842
+ const [isHovered, setIsHovered] = React30.useState(false);
10843
+ const [isTouchDevice, setIsTouchDevice] = React30.useState(false);
10844
+ React30.useEffect(() => {
10398
10845
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
10399
10846
  }, []);
10400
10847
  return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
@@ -10899,6 +11346,8 @@ function PayWithStripeLink({
10899
11346
  destinationChainType,
10900
11347
  destinationChainId,
10901
11348
  destinationTokenAddress,
11349
+ countryCode,
11350
+ subdivisionCode,
10902
11351
  wallets: externalWallets,
10903
11352
  email: emailProp,
10904
11353
  iconUrl,
@@ -11293,7 +11742,9 @@ function PayWithStripeLink({
11293
11742
  {
11294
11743
  tokenAddress: destinationTokenAddress,
11295
11744
  chainId: destinationChainId,
11296
- chainType: destinationChainType
11745
+ chainType: destinationChainType,
11746
+ countryCode,
11747
+ subdivisionCode
11297
11748
  },
11298
11749
  publishableKey
11299
11750
  ).then((token) => {
@@ -11312,7 +11763,14 @@ function PayWithStripeLink({
11312
11763
  return () => {
11313
11764
  cancelled = true;
11314
11765
  };
11315
- }, [publishableKey, destinationTokenAddress, destinationChainId, destinationChainType]);
11766
+ }, [
11767
+ publishableKey,
11768
+ destinationTokenAddress,
11769
+ destinationChainId,
11770
+ destinationChainType,
11771
+ countryCode,
11772
+ subdivisionCode
11773
+ ]);
11316
11774
  const destinationCurrency = stripeDestCurrency;
11317
11775
  const authInnerRef = (0, import_react17.useRef)(null);
11318
11776
  const paymentInnerRef = (0, import_react17.useRef)(null);
@@ -14167,7 +14625,7 @@ var import_lucide_react26 = require("lucide-react");
14167
14625
  var import_core25 = require("@unifold/core");
14168
14626
 
14169
14627
  // src/hooks/use-project-config.ts
14170
- var import_react_query8 = require("@tanstack/react-query");
14628
+ var import_react_query9 = require("@tanstack/react-query");
14171
14629
  var import_core22 = require("@unifold/core");
14172
14630
  function useProjectConfig({
14173
14631
  publishableKey,
@@ -14179,7 +14637,7 @@ function useProjectConfig({
14179
14637
  data: projectConfig,
14180
14638
  isLoading,
14181
14639
  error
14182
- } = (0, import_react_query8.useQuery)({
14640
+ } = (0, import_react_query9.useQuery)({
14183
14641
  // Country is part of the key so a region change refetches the region-aware
14184
14642
  // config. Omitted when undefined so callers that don't pass a country keep
14185
14643
  // sharing the base cache entry.
@@ -14189,7 +14647,7 @@ function useProjectConfig({
14189
14647
  // Keep the previous (e.g. no-country) config visible while the region-aware
14190
14648
  // config refetches after the country resolves, so unrelated config-driven
14191
14649
  // UI doesn't flash back to defaults.
14192
- placeholderData: import_react_query8.keepPreviousData,
14650
+ placeholderData: import_react_query9.keepPreviousData,
14193
14651
  staleTime: 1e3 * 60 * 30,
14194
14652
  refetchOnMount: true,
14195
14653
  refetchOnWindowFocus: true
@@ -14198,7 +14656,7 @@ function useProjectConfig({
14198
14656
  }
14199
14657
 
14200
14658
  // src/hooks/use-supported-deposit-tokens.ts
14201
- var import_react_query9 = require("@tanstack/react-query");
14659
+ var import_react_query10 = require("@tanstack/react-query");
14202
14660
  var import_core23 = require("@unifold/core");
14203
14661
  function useSupportedDepositTokens(publishableKey, options) {
14204
14662
  const hasDestination = options?.destination_token_address && options?.destination_chain_id && options?.destination_chain_type;
@@ -14211,7 +14669,7 @@ function useSupportedDepositTokens(publishableKey, options) {
14211
14669
  ...options?.product_type ? { product_type: options.product_type } : {}
14212
14670
  };
14213
14671
  const hasFilteredOptions = Object.keys(filteredOptions).length > 0;
14214
- return (0, import_react_query9.useQuery)({
14672
+ return (0, import_react_query10.useQuery)({
14215
14673
  queryKey: [
14216
14674
  "unifold",
14217
14675
  "supportedDepositTokens",
@@ -14232,14 +14690,14 @@ function useSupportedDepositTokens(publishableKey, options) {
14232
14690
  }
14233
14691
 
14234
14692
  // src/hooks/use-integration-transfer-default-token.ts
14235
- var import_react_query10 = require("@tanstack/react-query");
14693
+ var import_react_query11 = require("@tanstack/react-query");
14236
14694
  var import_core24 = require("@unifold/core");
14237
14695
  function useIntegrationTransferDefaultToken({
14238
14696
  params,
14239
14697
  publishableKey,
14240
14698
  enabled = true
14241
14699
  }) {
14242
- return (0, import_react_query10.useQuery)({
14700
+ return (0, import_react_query11.useQuery)({
14243
14701
  queryKey: [
14244
14702
  "unifold",
14245
14703
  "integrationTransferDefaultToken",
@@ -14310,7 +14768,8 @@ function CoinbaseConnect({
14310
14768
  defaultSourceChainType,
14311
14769
  defaultSourceChainId,
14312
14770
  defaultSourceTokenAddress,
14313
- defaultSourceSymbol
14771
+ defaultSourceSymbol,
14772
+ prefilledAmountUsd
14314
14773
  }) {
14315
14774
  const { colors: colors2, fonts, components } = useTheme();
14316
14775
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -14633,7 +15092,8 @@ function CoinbaseConnect({
14633
15092
  };
14634
15093
  const handleSelectAsset = (asset) => {
14635
15094
  setSelectedAsset(asset);
14636
- setSendAmount("");
15095
+ const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
15096
+ setSendAmount(cleanedPrefilled);
14637
15097
  transitionTo("enter_amount");
14638
15098
  };
14639
15099
  const handleCreateTransfer = async () => {
@@ -16219,13 +16679,13 @@ function CoinbaseConnect({
16219
16679
  CoinbaseConnect.displayName = "CoinbaseConnect";
16220
16680
 
16221
16681
  // src/hooks/use-exchanges.ts
16222
- var import_react_query11 = require("@tanstack/react-query");
16682
+ var import_react_query12 = require("@tanstack/react-query");
16223
16683
  var import_core26 = require("@unifold/core");
16224
16684
  function useExchanges({
16225
16685
  publishableKey,
16226
16686
  enabled = true
16227
16687
  }) {
16228
- const { data: exchanges = [], isLoading } = (0, import_react_query11.useQuery)({
16688
+ const { data: exchanges = [], isLoading } = (0, import_react_query12.useQuery)({
16229
16689
  queryKey: ["unifold", "exchanges", publishableKey],
16230
16690
  queryFn: () => (0, import_core26.getExchanges)(void 0, publishableKey).then((res) => res.data),
16231
16691
  enabled,
@@ -16236,16 +16696,38 @@ function useExchanges({
16236
16696
  return { exchanges, isLoading };
16237
16697
  }
16238
16698
 
16239
- // src/hooks/use-apple-pay-providers.ts
16240
- var import_react_query12 = require("@tanstack/react-query");
16699
+ // src/hooks/use-public-incident.ts
16700
+ var import_react_query13 = require("@tanstack/react-query");
16241
16701
  var import_core27 = require("@unifold/core");
16702
+ function usePublicIncident({
16703
+ publishableKey,
16704
+ enabled = true
16705
+ }) {
16706
+ const {
16707
+ data: incident,
16708
+ isLoading,
16709
+ error
16710
+ } = (0, import_react_query13.useQuery)({
16711
+ queryKey: ["unifold", "publicIncident", publishableKey],
16712
+ queryFn: () => (0, import_core27.getPublicIncident)(publishableKey),
16713
+ enabled,
16714
+ staleTime: 1e3 * 30,
16715
+ refetchInterval: 1e3 * 30,
16716
+ refetchOnWindowFocus: true
16717
+ });
16718
+ return { incident, isLoading, error: error ?? null };
16719
+ }
16720
+
16721
+ // src/hooks/use-apple-pay-providers.ts
16722
+ var import_react_query14 = require("@tanstack/react-query");
16723
+ var import_core28 = require("@unifold/core");
16242
16724
  function useApplePayProviders({
16243
16725
  publishableKey,
16244
16726
  enabled = true
16245
16727
  }) {
16246
- const { data: providers, isLoading } = (0, import_react_query12.useQuery)({
16728
+ const { data: providers, isLoading } = (0, import_react_query14.useQuery)({
16247
16729
  queryKey: ["unifold", "applePayProviders", publishableKey],
16248
- queryFn: () => (0, import_core27.getApplePayProviders)(publishableKey),
16730
+ queryFn: () => (0, import_core28.getApplePayProviders)(publishableKey),
16249
16731
  enabled,
16250
16732
  staleTime: 1e3 * 60 * 30,
16251
16733
  refetchOnMount: true,
@@ -16255,7 +16737,7 @@ function useApplePayProviders({
16255
16737
  }
16256
16738
 
16257
16739
  // src/components/deposits/DepositModal.tsx
16258
- var import_core37 = require("@unifold/core");
16740
+ var import_core38 = require("@unifold/core");
16259
16741
 
16260
16742
  // src/hooks/use-allowed-country.ts
16261
16743
  function useAllowedCountry(publishableKey) {
@@ -16300,8 +16782,8 @@ function useAllowedCountry(publishableKey) {
16300
16782
  }
16301
16783
 
16302
16784
  // src/hooks/use-address-validation.ts
16303
- var import_react_query13 = require("@tanstack/react-query");
16304
- var import_core28 = require("@unifold/core");
16785
+ var import_react_query15 = require("@tanstack/react-query");
16786
+ var import_core29 = require("@unifold/core");
16305
16787
  function useAddressValidation({
16306
16788
  recipientAddress,
16307
16789
  destinationChainType,
@@ -16312,7 +16794,7 @@ function useAddressValidation({
16312
16794
  refetchOnMount = false
16313
16795
  }) {
16314
16796
  const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
16315
- const { data, isLoading, error } = (0, import_react_query13.useQuery)({
16797
+ const { data, isLoading, error } = (0, import_react_query15.useQuery)({
16316
16798
  queryKey: [
16317
16799
  "unifold",
16318
16800
  "addressValidation",
@@ -16321,7 +16803,7 @@ function useAddressValidation({
16321
16803
  destinationChainId,
16322
16804
  destinationTokenAddress
16323
16805
  ],
16324
- queryFn: () => (0, import_core28.verifyRecipientAddress)(
16806
+ queryFn: () => (0, import_core29.verifyRecipientAddress)(
16325
16807
  {
16326
16808
  chain_type: destinationChainType,
16327
16809
  chain_id: destinationChainId,
@@ -16343,6 +16825,7 @@ function useAddressValidation({
16343
16825
  return {
16344
16826
  isValid: null,
16345
16827
  failureCode: null,
16828
+ message: null,
16346
16829
  metadata: null,
16347
16830
  isLoading: false,
16348
16831
  error: null
@@ -16351,6 +16834,7 @@ function useAddressValidation({
16351
16834
  return {
16352
16835
  isValid: data?.valid ?? null,
16353
16836
  failureCode: data?.failure_code ?? null,
16837
+ message: data?.message ?? null,
16354
16838
  metadata: data?.metadata ?? null,
16355
16839
  isLoading,
16356
16840
  error: error ?? null
@@ -16365,14 +16849,14 @@ var import_lucide_react30 = require("lucide-react");
16365
16849
  var import_react19 = require("react");
16366
16850
 
16367
16851
  // src/components/shared/ThemeStyleInjector.tsx
16368
- var React31 = __toESM(require("react"));
16852
+ var React32 = __toESM(require("react"));
16369
16853
  var import_jsx_runtime46 = require("react/jsx-runtime");
16370
16854
  function ThemeStyleInjector({
16371
16855
  children,
16372
16856
  className
16373
16857
  }) {
16374
16858
  const { colors: colors2, fonts, mode } = useTheme();
16375
- const cssVars = React31.useMemo(() => {
16859
+ const cssVars = React32.useMemo(() => {
16376
16860
  const hexToHSL = (hex) => {
16377
16861
  hex = hex.replace("#", "");
16378
16862
  const r = parseInt(hex.slice(0, 2), 16) / 255;
@@ -16432,7 +16916,7 @@ function ThemeStyleInjector({
16432
16916
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
16433
16917
  };
16434
16918
  }, [colors2, fonts.regular]);
16435
- React31.useEffect(() => {
16919
+ React32.useEffect(() => {
16436
16920
  if (typeof document === "undefined") return;
16437
16921
  if (fonts.regular) {
16438
16922
  document.documentElement.style.setProperty("--uf-font-family", fonts.regular);
@@ -16602,7 +17086,7 @@ function PoweredByUnifold({
16602
17086
  }
16603
17087
 
16604
17088
  // src/components/deposits/DepositsModal.tsx
16605
- var import_core29 = require("@unifold/core");
17089
+ var import_core30 = require("@unifold/core");
16606
17090
  var import_jsx_runtime48 = require("react/jsx-runtime");
16607
17091
  function DepositsModal({
16608
17092
  open,
@@ -16620,7 +17104,7 @@ function DepositsModal({
16620
17104
  if (!open || !userId) return;
16621
17105
  const fetchExecutions = async () => {
16622
17106
  try {
16623
- const response = await (0, import_core29.queryExecutions)(userId, publishableKey, import_core29.ActionType.Deposit);
17107
+ const response = await (0, import_core30.queryExecutions)(userId, publishableKey, import_core30.ActionType.Deposit);
16624
17108
  const sorted = [...response.data].sort((a, b) => {
16625
17109
  const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
16626
17110
  const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
@@ -17203,6 +17687,37 @@ var import_react21 = require("react");
17203
17687
  var getChainKey = (chainId, chainType) => {
17204
17688
  return `${chainType}:${chainId}`;
17205
17689
  };
17690
+ function getStoredSelection(key) {
17691
+ if (typeof window === "undefined") return null;
17692
+ try {
17693
+ const raw = localStorage.getItem(key);
17694
+ if (!raw) return null;
17695
+ const parsed = JSON.parse(raw);
17696
+ if (parsed && typeof parsed.symbol === "string" && typeof parsed.chainType === "string" && typeof parsed.chainId === "string") {
17697
+ return parsed;
17698
+ }
17699
+ } catch {
17700
+ }
17701
+ return null;
17702
+ }
17703
+ function saveStoredSelection(key, symbol, chainType, chainId) {
17704
+ if (typeof window === "undefined") return;
17705
+ try {
17706
+ localStorage.setItem(key, JSON.stringify({ symbol, chainType, chainId }));
17707
+ } catch {
17708
+ }
17709
+ }
17710
+ function resolveFromStorage(tokens, stored) {
17711
+ for (const t13 of tokens) {
17712
+ if (t13.symbol !== stored.symbol) continue;
17713
+ const matchedChain = t13.chains.find(
17714
+ (c) => c.chain_type === stored.chainType && c.chain_id === stored.chainId
17715
+ );
17716
+ if (matchedChain) return { token: t13, chain: matchedChain };
17717
+ if (t13.chains.length > 0) return { token: t13, chain: t13.chains[0] };
17718
+ }
17719
+ return null;
17720
+ }
17206
17721
  function resolveToken(tokens, defaultChainType, defaultChainId, defaultTokenAddress, defaultSymbol) {
17207
17722
  if (!tokens.length) return null;
17208
17723
  let selectedToken;
@@ -17252,27 +17767,73 @@ function useDefaultToken({
17252
17767
  defaultChainType,
17253
17768
  defaultChainId,
17254
17769
  defaultTokenAddress,
17255
- defaultSymbol
17770
+ defaultSymbol,
17771
+ storageKey: storageKey2
17256
17772
  }) {
17257
- const [token, setToken] = (0, import_react21.useState)(null);
17258
- const [chain, setChain] = (0, import_react21.useState)(null);
17773
+ const [token, setTokenState] = (0, import_react21.useState)(null);
17774
+ const [chain, setChainState] = (0, import_react21.useState)(null);
17259
17775
  const [initialSelectionDone, setInitialSelectionDone] = (0, import_react21.useState)(false);
17260
17776
  const appliedDefaultsRef = (0, import_react21.useRef)("");
17777
+ const tokenRef = (0, import_react21.useRef)(null);
17778
+ const chainRef = (0, import_react21.useRef)(null);
17779
+ tokenRef.current = token;
17780
+ chainRef.current = chain;
17781
+ const setToken = (0, import_react21.useCallback)(
17782
+ (newToken) => {
17783
+ tokenRef.current = newToken;
17784
+ setTokenState(newToken);
17785
+ if (storageKey2 && chainRef.current) {
17786
+ const [chainType, chainId] = chainRef.current.split(":");
17787
+ saveStoredSelection(storageKey2, newToken, chainType, chainId);
17788
+ }
17789
+ },
17790
+ [storageKey2]
17791
+ );
17792
+ const setChain = (0, import_react21.useCallback)(
17793
+ (newChain) => {
17794
+ chainRef.current = newChain;
17795
+ setChainState(newChain);
17796
+ if (storageKey2 && tokenRef.current) {
17797
+ const [chainType, chainId] = newChain.split(":");
17798
+ saveStoredSelection(storageKey2, tokenRef.current, chainType, chainId);
17799
+ }
17800
+ },
17801
+ [storageKey2]
17802
+ );
17261
17803
  (0, import_react21.useEffect)(() => {
17262
17804
  if (!tokens.length) return;
17263
17805
  const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
17264
17806
  const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
17265
17807
  if (initialSelectionDone && !defaultsChanged) return;
17266
- const result = resolveToken(
17267
- tokens,
17268
- defaultChainType,
17269
- defaultChainId,
17270
- defaultTokenAddress,
17271
- defaultSymbol
17272
- );
17808
+ const hasExplicitDefaults = defaultTokenAddress && defaultChainType && defaultChainId || defaultSymbol && defaultChainType && defaultChainId;
17809
+ let result = null;
17810
+ if (hasExplicitDefaults) {
17811
+ result = resolveToken(
17812
+ tokens,
17813
+ defaultChainType,
17814
+ defaultChainId,
17815
+ defaultTokenAddress,
17816
+ defaultSymbol
17817
+ );
17818
+ if (result) {
17819
+ const matched = defaultTokenAddress && result.chain.token_address.toLowerCase() === defaultTokenAddress.toLowerCase() && result.chain.chain_type === defaultChainType && result.chain.chain_id === defaultChainId || defaultSymbol && result.token.symbol === defaultSymbol && result.chain.chain_type === defaultChainType && result.chain.chain_id === defaultChainId;
17820
+ if (!matched) {
17821
+ result = null;
17822
+ }
17823
+ }
17824
+ }
17825
+ if (!result && storageKey2) {
17826
+ const stored = getStoredSelection(storageKey2);
17827
+ if (stored) {
17828
+ result = resolveFromStorage(tokens, stored);
17829
+ }
17830
+ }
17831
+ if (!result) {
17832
+ result = resolveToken(tokens);
17833
+ }
17273
17834
  if (result) {
17274
- setToken(result.token.symbol);
17275
- setChain(getChainKey(result.chain.chain_id, result.chain.chain_type));
17835
+ setTokenState(result.token.symbol);
17836
+ setChainState(getChainKey(result.chain.chain_id, result.chain.chain_type));
17276
17837
  appliedDefaultsRef.current = defaultsKey;
17277
17838
  setInitialSelectionDone(true);
17278
17839
  }
@@ -17282,7 +17843,8 @@ function useDefaultToken({
17282
17843
  defaultSymbol,
17283
17844
  defaultChainType,
17284
17845
  defaultChainId,
17285
- initialSelectionDone
17846
+ initialSelectionDone,
17847
+ storageKey2
17286
17848
  ]);
17287
17849
  (0, import_react21.useEffect)(() => {
17288
17850
  if (!tokens.length || !token) return;
@@ -17293,13 +17855,14 @@ function useDefaultToken({
17293
17855
  });
17294
17856
  if (!isChainAvailable) {
17295
17857
  const firstChain = currentToken.chains[0];
17296
- setChain(getChainKey(firstChain.chain_id, firstChain.chain_type));
17858
+ setChainState(getChainKey(firstChain.chain_id, firstChain.chain_type));
17297
17859
  }
17298
17860
  }, [token, tokens, chain]);
17299
17861
  return { token, chain, setToken, setChain, initialSelectionDone };
17300
17862
  }
17301
17863
 
17302
17864
  // src/hooks/use-default-source-token.ts
17865
+ var STORAGE_KEY2 = "unifold_last_deposit_from_token";
17303
17866
  function useDefaultSourceToken({
17304
17867
  supportedTokens,
17305
17868
  defaultSourceChainType,
@@ -17312,7 +17875,8 @@ function useDefaultSourceToken({
17312
17875
  defaultChainType: defaultSourceChainType,
17313
17876
  defaultChainId: defaultSourceChainId,
17314
17877
  defaultTokenAddress: defaultSourceTokenAddress,
17315
- defaultSymbol: defaultSourceSymbol
17878
+ defaultSymbol: defaultSourceSymbol,
17879
+ storageKey: STORAGE_KEY2
17316
17880
  });
17317
17881
  }
17318
17882
 
@@ -17606,7 +18170,7 @@ function useCopyAddress() {
17606
18170
  }
17607
18171
 
17608
18172
  // src/components/shared/tooltip.tsx
17609
- var React32 = __toESM(require("react"));
18173
+ var React33 = __toESM(require("react"));
17610
18174
  var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"));
17611
18175
  var import_jsx_runtime52 = require("react/jsx-runtime");
17612
18176
  var TooltipProvider = TooltipPrimitive.Provider;
@@ -17614,20 +18178,20 @@ function Tooltip({
17614
18178
  children,
17615
18179
  ...props
17616
18180
  }) {
17617
- const [open, setOpen] = React32.useState(props.defaultOpen ?? false);
18181
+ const [open, setOpen] = React33.useState(props.defaultOpen ?? false);
17618
18182
  const isControlled = props.open !== void 0;
17619
18183
  const isOpen = isControlled ? props.open : open;
17620
18184
  const onOpenChange = isControlled ? props.onOpenChange : (nextOpen) => setOpen(nextOpen);
17621
18185
  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 }) });
17622
18186
  }
17623
- var TooltipContext = React32.createContext({
18187
+ var TooltipContext = React33.createContext({
17624
18188
  open: false,
17625
18189
  onOpenChange: () => {
17626
18190
  }
17627
18191
  });
17628
- var TooltipTrigger = React32.forwardRef(({ onClick, ...props }, ref) => {
17629
- const { open, onOpenChange } = React32.useContext(TooltipContext);
17630
- const handleClick = React32.useCallback(
18192
+ var TooltipTrigger = React33.forwardRef(({ onClick, ...props }, ref) => {
18193
+ const { open, onOpenChange } = React33.useContext(TooltipContext);
18194
+ const handleClick = React33.useCallback(
17631
18195
  (e) => {
17632
18196
  onOpenChange(!open);
17633
18197
  onClick?.(e);
@@ -17637,7 +18201,7 @@ var TooltipTrigger = React32.forwardRef(({ onClick, ...props }, ref) => {
17637
18201
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TooltipPrimitive.Trigger, { ref, onClick: handleClick, ...props });
17638
18202
  });
17639
18203
  TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
17640
- var TooltipContent = React32.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
18204
+ var TooltipContent = React33.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
17641
18205
  const { themeClass, colors: colors2 } = useTheme();
17642
18206
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
17643
18207
  TooltipPrimitive.Content,
@@ -17657,11 +18221,11 @@ var TooltipContent = React32.forwardRef(({ className, sideOffset = 4, ...props }
17657
18221
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
17658
18222
 
17659
18223
  // src/components/deposits/TransferCryptoSingleInput.tsx
17660
- var import_core31 = require("@unifold/core");
18224
+ var import_core32 = require("@unifold/core");
17661
18225
 
17662
18226
  // src/hooks/use-hypercore-activation.ts
17663
- var import_react_query14 = require("@tanstack/react-query");
17664
- var import_core30 = require("@unifold/core");
18227
+ var import_react_query16 = require("@tanstack/react-query");
18228
+ var import_core31 = require("@unifold/core");
17665
18229
 
17666
18230
  // src/lib/constants.ts
17667
18231
  var HYPERCORE_CHAIN_ID = "1337";
@@ -17679,9 +18243,9 @@ function useHypercoreActivation(params) {
17679
18243
  const recipient = recipientAddress?.trim() ?? "";
17680
18244
  const source = sourceAddress?.trim() ?? "";
17681
18245
  const hasAddresses = !!recipient && !!source;
17682
- const { data, isLoading } = (0, import_react_query14.useQuery)({
18246
+ const { data, isLoading } = (0, import_react_query16.useQuery)({
17683
18247
  queryKey: ["unifold", "hypercoreActivation", source, recipient, publishableKey],
17684
- queryFn: () => (0, import_core30.checkHypercoreActivation)(
18248
+ queryFn: () => (0, import_core31.checkHypercoreActivation)(
17685
18249
  {
17686
18250
  source_address: source,
17687
18251
  recipient_address: recipient
@@ -17765,6 +18329,7 @@ function TransferCryptoSingleInput({
17765
18329
  onDepositError,
17766
18330
  wallets: externalWallets,
17767
18331
  onSourceTokenChange,
18332
+ prefilledAmountUsd,
17768
18333
  checkoutQuote,
17769
18334
  isCheckoutQuoteLoading = false,
17770
18335
  persistCheckingIndicator = false,
@@ -17829,7 +18394,7 @@ function TransferCryptoSingleInput({
17829
18394
  (c) => c.chain_type === currentChainCombo.chainType && c.chain_id === currentChainCombo.chainId
17830
18395
  ) : void 0;
17831
18396
  const currentChainType = currentChainData?.chain_type || "ethereum";
17832
- const currentWallet = (0, import_core31.getWalletByChainType)(wallets, currentChainType);
18397
+ const currentWallet = (0, import_core32.getWalletByChainType)(wallets, currentChainType);
17833
18398
  const depositAddress = currentWallet?.address || "";
17834
18399
  const {
17835
18400
  executions: depositExecutions,
@@ -17908,6 +18473,22 @@ function TransferCryptoSingleInput({
17908
18473
  const maxSlippage = currentChainFromBackend?.max_slippage_percent ?? 0.25;
17909
18474
  const processingTime = currentChainFromBackend?.estimated_processing_time ?? null;
17910
18475
  const minDepositUsd = currentChainFromBackend?.minimum_deposit_amount_usd ?? 3;
18476
+ const parsedPrefilledUsd = (0, import_react23.useMemo)(() => {
18477
+ const value = parseFloat(prefilledAmountUsd ?? "");
18478
+ return Number.isFinite(value) && value > 0 ? value : null;
18479
+ }, [prefilledAmountUsd]);
18480
+ const effectivePrefilledUsd = (0, import_react23.useMemo)(() => {
18481
+ if (parsedPrefilledUsd === null) return null;
18482
+ return Math.max(parsedPrefilledUsd, minDepositUsd);
18483
+ }, [parsedPrefilledUsd, minDepositUsd]);
18484
+ const prefillDisplay = (0, import_react23.useMemo)(() => {
18485
+ if (effectivePrefilledUsd === null) return null;
18486
+ const usdLabel = `$${effectivePrefilledUsd.toFixed(2)}`;
18487
+ if (selectedToken?.is_stablecoin) {
18488
+ return `${effectivePrefilledUsd.toFixed(2)} ${selectedToken.symbol} (${usdLabel})`;
18489
+ }
18490
+ return `${usdLabel} USD`;
18491
+ }, [effectivePrefilledUsd, selectedToken]);
17911
18492
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(TooltipProvider, { delayDuration: 0, skipDelayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
17912
18493
  "div",
17913
18494
  {
@@ -18034,7 +18615,7 @@ function TransferCryptoSingleInput({
18034
18615
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { children: "Retrying automatically every 5 seconds..." })
18035
18616
  ] })
18036
18617
  ] }),
18037
- (checkoutQuote || isCheckoutQuoteLoading) && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
18618
+ (checkoutQuote || isCheckoutQuoteLoading || prefillDisplay) && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
18038
18619
  "div",
18039
18620
  {
18040
18621
  className: "uf-rounded-xl uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
@@ -18058,7 +18639,7 @@ function TransferCryptoSingleInput({
18058
18639
  className: "uf-text-sm uf-font-semibold",
18059
18640
  style: { color: components.card.titleColor, fontFamily: fonts.semibold },
18060
18641
  children: [
18061
- checkoutQuote.isStablecoin ? (0, import_core31.formatStablecoinAmount)(
18642
+ checkoutQuote.isStablecoin ? (0, import_core32.formatStablecoinAmount)(
18062
18643
  checkoutQuote.sourceAmount,
18063
18644
  checkoutQuote.sourceTokenDecimals
18064
18645
  ) : (Number(checkoutQuote.sourceAmount) / 10 ** checkoutQuote.sourceTokenDecimals).toFixed(Math.min(checkoutQuote.sourceTokenDecimals, 6)),
@@ -18078,6 +18659,13 @@ function TransferCryptoSingleInput({
18078
18659
  )
18079
18660
  ]
18080
18661
  }
18662
+ ) : prefillDisplay ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
18663
+ "span",
18664
+ {
18665
+ className: "uf-text-sm uf-font-semibold",
18666
+ style: { color: components.card.titleColor, fontFamily: fonts.semibold },
18667
+ children: prefillDisplay
18668
+ }
18081
18669
  ) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
18082
18670
  "div",
18083
18671
  {
@@ -18411,14 +18999,14 @@ var import_react24 = require("react");
18411
18999
  var import_lucide_react32 = require("lucide-react");
18412
19000
 
18413
19001
  // src/components/shared/select.tsx
18414
- var React33 = __toESM(require("react"));
19002
+ var React34 = __toESM(require("react"));
18415
19003
  var SelectPrimitive = __toESM(require("@radix-ui/react-select"));
18416
19004
  var import_lucide_react31 = require("lucide-react");
18417
19005
  var import_jsx_runtime55 = require("react/jsx-runtime");
18418
19006
  var Select = SelectPrimitive.Root;
18419
19007
  var SelectGroup = SelectPrimitive.Group;
18420
19008
  var SelectValue = SelectPrimitive.Value;
18421
- var SelectTrigger = React33.forwardRef(({ className, style, children, ...props }, ref) => {
19009
+ var SelectTrigger = React34.forwardRef(({ className, style, children, ...props }, ref) => {
18422
19010
  const { components } = useTheme();
18423
19011
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
18424
19012
  SelectPrimitive.Trigger,
@@ -18442,7 +19030,7 @@ var SelectTrigger = React33.forwardRef(({ className, style, children, ...props }
18442
19030
  );
18443
19031
  });
18444
19032
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
18445
- var SelectScrollUpButton = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
19033
+ var SelectScrollUpButton = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18446
19034
  SelectPrimitive.ScrollUpButton,
18447
19035
  {
18448
19036
  ref,
@@ -18452,7 +19040,7 @@ var SelectScrollUpButton = React33.forwardRef(({ className, ...props }, ref) =>
18452
19040
  }
18453
19041
  ));
18454
19042
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
18455
- var SelectScrollDownButton = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
19043
+ var SelectScrollDownButton = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18456
19044
  SelectPrimitive.ScrollDownButton,
18457
19045
  {
18458
19046
  ref,
@@ -18462,7 +19050,7 @@ var SelectScrollDownButton = React33.forwardRef(({ className, ...props }, ref) =
18462
19050
  }
18463
19051
  ));
18464
19052
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
18465
- var SelectContent = React33.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
19053
+ var SelectContent = React34.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
18466
19054
  const { themeClass, colors: colors2, components } = useTheme();
18467
19055
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
18468
19056
  SelectPrimitive.Content,
@@ -18500,7 +19088,7 @@ var SelectContent = React33.forwardRef(({ className, style, children, position =
18500
19088
  ) });
18501
19089
  });
18502
19090
  SelectContent.displayName = SelectPrimitive.Content.displayName;
18503
- var SelectLabel = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
19091
+ var SelectLabel = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18504
19092
  SelectPrimitive.Label,
18505
19093
  {
18506
19094
  ref,
@@ -18509,7 +19097,7 @@ var SelectLabel = React33.forwardRef(({ className, ...props }, ref) => /* @__PUR
18509
19097
  }
18510
19098
  ));
18511
19099
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
18512
- var SelectItem = React33.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
19100
+ var SelectItem = React34.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
18513
19101
  SelectPrimitive.Item,
18514
19102
  {
18515
19103
  ref,
@@ -18525,7 +19113,7 @@ var SelectItem = React33.forwardRef(({ className, children, ...props }, ref) =>
18525
19113
  }
18526
19114
  ));
18527
19115
  SelectItem.displayName = SelectPrimitive.Item.displayName;
18528
- var SelectSeparator = React33.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
19116
+ var SelectSeparator = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
18529
19117
  SelectPrimitive.Separator,
18530
19118
  {
18531
19119
  ref,
@@ -18536,7 +19124,7 @@ var SelectSeparator = React33.forwardRef(({ className, ...props }, ref) => /* @_
18536
19124
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
18537
19125
 
18538
19126
  // src/components/deposits/TransferCryptoDoubleInput.tsx
18539
- var import_core32 = require("@unifold/core");
19127
+ var import_core33 = require("@unifold/core");
18540
19128
  var import_jsx_runtime56 = require("react/jsx-runtime");
18541
19129
  var t7 = i18n.transferCrypto;
18542
19130
  var getChainKey3 = (chainId, chainType) => {
@@ -18557,6 +19145,7 @@ function TransferCryptoDoubleInput({
18557
19145
  defaultSourceChainId,
18558
19146
  defaultSourceTokenAddress,
18559
19147
  defaultSourceSymbol,
19148
+ prefilledAmountUsd,
18560
19149
  depositConfirmationMode = "auto_ui",
18561
19150
  onExecutionsChange,
18562
19151
  onDepositSuccess,
@@ -18620,7 +19209,7 @@ function TransferCryptoDoubleInput({
18620
19209
  (c) => c.chain_type === currentChainCombo.chainType && c.chain_id === currentChainCombo.chainId
18621
19210
  ) : void 0;
18622
19211
  const currentChainType = currentChainData?.chain_type || "ethereum";
18623
- const currentWallet = (0, import_core32.getWalletByChainType)(wallets, currentChainType);
19212
+ const currentWallet = (0, import_core33.getWalletByChainType)(wallets, currentChainType);
18624
19213
  const depositAddress = currentWallet?.address || "";
18625
19214
  const {
18626
19215
  executions: depositExecutions,
@@ -18681,6 +19270,22 @@ function TransferCryptoDoubleInput({
18681
19270
  const maxSlippage = currentChainFromBackend?.max_slippage_percent ?? 0.25;
18682
19271
  const processingTime = currentChainFromBackend?.estimated_processing_time ?? null;
18683
19272
  const minDepositUsd = currentChainFromBackend?.minimum_deposit_amount_usd ?? 3;
19273
+ const parsedPrefilledUsd = (0, import_react24.useMemo)(() => {
19274
+ const value = parseFloat(prefilledAmountUsd ?? "");
19275
+ return Number.isFinite(value) && value > 0 ? value : null;
19276
+ }, [prefilledAmountUsd]);
19277
+ const effectivePrefilledUsd = (0, import_react24.useMemo)(() => {
19278
+ if (parsedPrefilledUsd === null) return null;
19279
+ return Math.max(parsedPrefilledUsd, minDepositUsd);
19280
+ }, [parsedPrefilledUsd, minDepositUsd]);
19281
+ const prefillDisplay = (0, import_react24.useMemo)(() => {
19282
+ if (effectivePrefilledUsd === null) return null;
19283
+ const usdLabel = `$${effectivePrefilledUsd.toFixed(2)}`;
19284
+ if (selectedToken?.is_stablecoin) {
19285
+ return `${effectivePrefilledUsd.toFixed(2)} ${selectedToken.symbol} (${usdLabel})`;
19286
+ }
19287
+ return `${usdLabel} USD`;
19288
+ }, [effectivePrefilledUsd, selectedToken]);
18684
19289
  const renderTokenItem = (tokenData) => {
18685
19290
  return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
18686
19291
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
@@ -18861,6 +19466,35 @@ function TransferCryptoDoubleInput({
18861
19466
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { children: "Retrying automatically every 5 seconds..." })
18862
19467
  ] })
18863
19468
  ] }),
19469
+ prefillDisplay && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
19470
+ "div",
19471
+ {
19472
+ className: "uf-rounded-xl uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
19473
+ style: {
19474
+ backgroundColor: components.card.backgroundColor,
19475
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
19476
+ borderRadius: components.card.borderRadius
19477
+ },
19478
+ children: [
19479
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
19480
+ "span",
19481
+ {
19482
+ className: "uf-text-xs",
19483
+ style: { color: components.card.subtitleColor, fontFamily: fonts.regular },
19484
+ children: "You send"
19485
+ }
19486
+ ),
19487
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
19488
+ "span",
19489
+ {
19490
+ className: "uf-text-sm uf-font-semibold",
19491
+ style: { color: components.card.titleColor, fontFamily: fonts.semibold },
19492
+ children: prefillDisplay
19493
+ }
19494
+ )
19495
+ ]
19496
+ }
19497
+ ),
18864
19498
  /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pt-2", children: [
18865
19499
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
18866
19500
  "div",
@@ -19143,12 +19777,12 @@ function TransferCryptoDoubleInput({
19143
19777
  }
19144
19778
 
19145
19779
  // src/components/deposits/WalletConnect.tsx
19146
- var React34 = __toESM(require("react"));
19780
+ var React35 = __toESM(require("react"));
19147
19781
  var import_lucide_react36 = require("lucide-react");
19148
- var import_core36 = require("@unifold/core");
19782
+ var import_core37 = require("@unifold/core");
19149
19783
 
19150
19784
  // src/lib/send-hypercore.ts
19151
- var import_core33 = require("@unifold/core");
19785
+ var import_core34 = require("@unifold/core");
19152
19786
  function isHypercoreChain(chainId) {
19153
19787
  return chainId === HYPERCORE_CHAIN_ID;
19154
19788
  }
@@ -19159,7 +19793,7 @@ async function sendHypercoreEvmTransfer(params) {
19159
19793
  params: []
19160
19794
  });
19161
19795
  const activeChainId = String(parseInt(currentChainHex, 16));
19162
- const buildResult = await (0, import_core33.buildHypercoreTransaction)(
19796
+ const buildResult = await (0, import_core34.buildHypercoreTransaction)(
19163
19797
  {
19164
19798
  signature_chain_id: activeChainId,
19165
19799
  recipient_address: recipientAddress,
@@ -19172,7 +19806,7 @@ async function sendHypercoreEvmTransfer(params) {
19172
19806
  method: "eth_signTypedData_v4",
19173
19807
  params: [fromAddress, JSON.stringify(buildResult.typed_data)]
19174
19808
  });
19175
- await (0, import_core33.sendHypercoreTransaction)(
19809
+ await (0, import_core34.sendHypercoreTransaction)(
19176
19810
  {
19177
19811
  action_payload: buildResult.action_payload,
19178
19812
  signature,
@@ -19184,8 +19818,8 @@ async function sendHypercoreEvmTransfer(params) {
19184
19818
  }
19185
19819
 
19186
19820
  // src/hooks/use-deposit-quote.ts
19187
- var import_react_query15 = require("@tanstack/react-query");
19188
- var import_core34 = require("@unifold/core");
19821
+ var import_react_query17 = require("@tanstack/react-query");
19822
+ var import_core35 = require("@unifold/core");
19189
19823
  function useDepositQuote(params) {
19190
19824
  const {
19191
19825
  publishableKey,
@@ -19211,7 +19845,7 @@ function useDepositQuote(params) {
19211
19845
  ...adjustForSlippage ? { adjust_for_slippage: true } : {},
19212
19846
  ...stablecoinParity ? { stablecoin_parity: true } : {}
19213
19847
  };
19214
- return (0, import_react_query15.useQuery)({
19848
+ return (0, import_react_query17.useQuery)({
19215
19849
  queryKey: [
19216
19850
  "unifold",
19217
19851
  "depositQuote",
@@ -19226,7 +19860,7 @@ function useDepositQuote(params) {
19226
19860
  stablecoinParity,
19227
19861
  publishableKey
19228
19862
  ],
19229
- queryFn: () => (0, import_core34.getDepositQuote)(request, publishableKey),
19863
+ queryFn: () => (0, import_core35.getDepositQuote)(request, publishableKey),
19230
19864
  enabled: enabled && !!publishableKey && !!sourceChainType && !!sourceChainId && !!sourceTokenAddress && !!destinationAmount && destinationAmount !== "0" && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress,
19231
19865
  staleTime: 3e4,
19232
19866
  gcTime: 5 * 6e4,
@@ -19239,15 +19873,15 @@ function useDepositQuote(params) {
19239
19873
  }
19240
19874
 
19241
19875
  // src/hooks/use-external-wallets.ts
19242
- var import_react_query16 = require("@tanstack/react-query");
19243
- var import_core35 = require("@unifold/core");
19876
+ var import_react_query18 = require("@tanstack/react-query");
19877
+ var import_core36 = require("@unifold/core");
19244
19878
  function useExternalWallets({
19245
19879
  publishableKey,
19246
19880
  enabled = true
19247
19881
  }) {
19248
- const { data: wallets = [], isLoading } = (0, import_react_query16.useQuery)({
19882
+ const { data: wallets = [], isLoading } = (0, import_react_query18.useQuery)({
19249
19883
  queryKey: ["unifold", "external-wallets", publishableKey],
19250
- queryFn: () => (0, import_core35.getExternalWallets)(publishableKey).then((res) => res.data),
19884
+ queryFn: () => (0, import_core36.getExternalWallets)(publishableKey).then((res) => res.data),
19251
19885
  enabled: enabled && !!publishableKey,
19252
19886
  staleTime: 1e3 * 60 * 30,
19253
19887
  refetchOnMount: false,
@@ -20356,33 +20990,11 @@ function balancesRepresentSameToken(a, b) {
20356
20990
  if (!tokenA || !tokenB) return false;
20357
20991
  return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
20358
20992
  }
20359
- function getSolanaProviders() {
20360
- if (typeof window === "undefined") return {};
20361
- const win = window;
20362
- return {
20363
- phantomSolana: win.phantom?.solana,
20364
- solflare: win.solflare,
20365
- backpack: win.backpack,
20366
- glow: win.glow,
20367
- coinbaseSolana: win.coinbaseSolana || win.coinbaseWalletExtension?.solana
20368
- };
20369
- }
20370
- function getLegacyEvmProviders() {
20371
- if (typeof window === "undefined") return {};
20372
- const win = window;
20373
- return {
20374
- ethereum: win.ethereum,
20375
- phantomEthereum: win.phantom?.ethereum,
20376
- coinbaseEthereum: win.coinbaseWalletExtension,
20377
- trustEthereum: win.trustwallet?.ethereum,
20378
- okxEthereum: win.okxwallet
20379
- };
20380
- }
20381
20993
  function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
20382
- const solProviders = getSolanaProviders();
20383
- const legacyEvm = getLegacyEvmProviders();
20384
- const eip6963List = getEip6963Providers();
20385
20994
  const win = typeof window !== "undefined" ? window : null;
20995
+ const solProviders = getInjectedSolanaProviders(win);
20996
+ const legacyEvm = getLegacyEvmProviders(win);
20997
+ const eip6963List = getEip6963Providers();
20386
20998
  const hasEip6963 = (walletId) => eip6963List.some((d) => {
20387
20999
  const rdns = d.info?.rdns || "";
20388
21000
  switch (walletId) {
@@ -20492,7 +21104,7 @@ function WalletConnect({
20492
21104
  amountQuickSelect = "percentage",
20493
21105
  onWalletDisconnect,
20494
21106
  onWalletConnected,
20495
- prefillAmountUsd,
21107
+ prefilledAmountUsd,
20496
21108
  checkoutAmountUsd,
20497
21109
  checkoutReceivedUsd,
20498
21110
  onNewDeposit,
@@ -20514,28 +21126,28 @@ function WalletConnect({
20514
21126
  onExecutionsChange
20515
21127
  }) {
20516
21128
  const { colors: colors2, fonts, components, mode } = useTheme();
20517
- const walletProvidedAtMount = React34.useRef(!!initialWalletInfo && !!initialDepositWallet);
20518
- const [activeWalletInfo, setActiveWalletInfo] = React34.useState(
21129
+ const walletProvidedAtMount = React35.useRef(!!initialWalletInfo && !!initialDepositWallet);
21130
+ const [activeWalletInfo, setActiveWalletInfo] = React35.useState(
20519
21131
  initialWalletInfo ?? null
20520
21132
  );
20521
- const [activeDepositWallet, setActiveDepositWallet] = React34.useState(
21133
+ const [activeDepositWallet, setActiveDepositWallet] = React35.useState(
20522
21134
  initialDepositWallet ?? null
20523
21135
  );
20524
21136
  const initialView = initialWalletInfo && initialDepositWallet ? "select_token" : "select_wallet";
20525
- const [view, setView] = React34.useState(initialView);
20526
- const [isTransitioning, setIsTransitioning] = React34.useState(false);
20527
- const viewRef = React34.useRef(initialView);
21137
+ const [view, setView] = React35.useState(initialView);
21138
+ const [isTransitioning, setIsTransitioning] = React35.useState(false);
21139
+ const viewRef = React35.useRef(initialView);
20528
21140
  const standalone = !canGoBack && !walletProvidedAtMount.current;
20529
21141
  const { wallet: detectedWallet, isLoading: detectingWallet } = useDetectedBrowserWallet({
20530
21142
  enabled: standalone
20531
21143
  });
20532
- const [autoResolved, setAutoResolved] = React34.useState(false);
20533
- const [selectedWalletDef, setSelectedWalletDef] = React34.useState(null);
20534
- const [connectingNetwork, setConnectingNetwork] = React34.useState(null);
20535
- const [walletError, setWalletError] = React34.useState(null);
20536
- const [isWalletConnecting, setIsWalletConnecting] = React34.useState(false);
20537
- const [eip6963ProviderCount, setEip6963ProviderCount] = React34.useState(0);
20538
- React34.useEffect(() => {
21144
+ const [autoResolved, setAutoResolved] = React35.useState(false);
21145
+ const [selectedWalletDef, setSelectedWalletDef] = React35.useState(null);
21146
+ const [connectingNetwork, setConnectingNetwork] = React35.useState(null);
21147
+ const [walletError, setWalletError] = React35.useState(null);
21148
+ const [isWalletConnecting, setIsWalletConnecting] = React35.useState(false);
21149
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React35.useState(0);
21150
+ React35.useEffect(() => {
20539
21151
  const store = getEip6963Store();
20540
21152
  if (!store) return;
20541
21153
  setEip6963ProviderCount(store.getProviders().length);
@@ -20544,7 +21156,7 @@ function WalletConnect({
20544
21156
  });
20545
21157
  }, []);
20546
21158
  const { wallets: backendWallets } = useExternalWallets({ publishableKey });
20547
- const walletDefinitions = React34.useMemo(
21159
+ const walletDefinitions = React35.useMemo(
20548
21160
  () => backendWallets.length > 0 ? backendWallets.map((w) => ({
20549
21161
  id: w.id,
20550
21162
  name: w.name,
@@ -20555,32 +21167,32 @@ function WalletConnect({
20555
21167
  })) : FALLBACK_WALLET_DEFINITIONS,
20556
21168
  [backendWallets]
20557
21169
  );
20558
- const [recentWalletId, setRecentWalletIdState] = React34.useState(getLastOpenedWallet);
20559
- React34.useEffect(() => {
21170
+ const [recentWalletId, setRecentWalletIdState] = React35.useState(getLastOpenedWallet);
21171
+ React35.useEffect(() => {
20560
21172
  if (view === "select_wallet") {
20561
21173
  setRecentWalletIdState(getLastOpenedWallet());
20562
21174
  }
20563
21175
  }, [view]);
20564
- const availableWallets = React34.useMemo(
21176
+ const availableWallets = React35.useMemo(
20565
21177
  () => detectAvailableWallets(walletDefinitions, recentWalletId),
20566
21178
  [walletDefinitions, eip6963ProviderCount, recentWalletId]
20567
21179
  );
20568
- const [isMobile, setIsMobile] = React34.useState(false);
20569
- React34.useEffect(() => {
21180
+ const [isMobile, setIsMobile] = React35.useState(false);
21181
+ React35.useEffect(() => {
20570
21182
  setIsMobile(isMobileDevice());
20571
21183
  }, []);
20572
- const mobileDepositAddresses = React34.useMemo(
21184
+ const mobileDepositAddresses = React35.useMemo(
20573
21185
  () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
20574
21186
  [depositWallets]
20575
21187
  );
20576
- const mobileDepositWalletIds = React34.useMemo(
21188
+ const mobileDepositWalletIds = React35.useMemo(
20577
21189
  () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
20578
21190
  [depositWallets]
20579
21191
  );
20580
- const [mobileRedirect, setMobileRedirect] = React34.useState(null);
20581
- const [pendingMobileWallet, setPendingMobileWallet] = React34.useState(null);
20582
- const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React34.useState(false);
20583
- React34.useEffect(() => {
21192
+ const [mobileRedirect, setMobileRedirect] = React35.useState(null);
21193
+ const [pendingMobileWallet, setPendingMobileWallet] = React35.useState(null);
21194
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React35.useState(false);
21195
+ React35.useEffect(() => {
20584
21196
  if (!standalone || autoResolved || detectingWallet) return;
20585
21197
  if (!detectedWallet) {
20586
21198
  setAutoResolved(true);
@@ -20606,32 +21218,36 @@ function WalletConnect({
20606
21218
  depositWallets,
20607
21219
  depositWalletsLoading
20608
21220
  ]);
20609
- React34.useEffect(() => {
21221
+ React35.useEffect(() => {
20610
21222
  if (!standalone || autoResolved) return;
20611
21223
  const t13 = setTimeout(() => setAutoResolved(true), 5e3);
20612
21224
  return () => clearTimeout(t13);
20613
21225
  }, [standalone, autoResolved]);
20614
- const [balances, setBalances] = React34.useState([]);
20615
- const [isLoading, setIsLoading] = React34.useState(false);
20616
- const [selectedBalance, setSelectedBalance] = React34.useState(null);
20617
- const [totalBalanceUsd, setTotalBalanceUsd] = React34.useState(null);
20618
- const [error, setError] = React34.useState(null);
20619
- const [isDisconnectingWallet, setIsDisconnectingWallet] = React34.useState(false);
20620
- const [amountUsd, setAmountUsd] = React34.useState(prefillAmountUsd ?? "");
20621
- const [isConfirming, setIsConfirming] = React34.useState(false);
20622
- const [hasSignedTransaction, setHasSignedTransaction] = React34.useState(false);
20623
- const [tokenChainDetails, setTokenChainDetails] = React34.useState(null);
20624
- const [loadingTokenDetails, setLoadingTokenDetails] = React34.useState(false);
20625
- const [showTransactionDetails, setShowTransactionDetails] = React34.useState(false);
20626
- const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React34.useState(null);
21226
+ const [balances, setBalances] = React35.useState([]);
21227
+ const [isLoading, setIsLoading] = React35.useState(false);
21228
+ const [selectedBalance, setSelectedBalance] = React35.useState(null);
21229
+ const [totalBalanceUsd, setTotalBalanceUsd] = React35.useState(null);
21230
+ const [error, setError] = React35.useState(null);
21231
+ const [isDisconnectingWallet, setIsDisconnectingWallet] = React35.useState(false);
21232
+ const [amountUsd, setAmountUsd] = React35.useState(prefilledAmountUsd ?? "");
21233
+ const [isConfirming, setIsConfirming] = React35.useState(false);
21234
+ const [hasSignedTransaction, setHasSignedTransaction] = React35.useState(false);
21235
+ const [tokenChainDetails, setTokenChainDetails] = React35.useState(null);
21236
+ const [loadingTokenDetails, setLoadingTokenDetails] = React35.useState(false);
21237
+ const [showTransactionDetails, setShowTransactionDetails] = React35.useState(false);
21238
+ const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React35.useState(null);
20627
21239
  const walletInfo = activeWalletInfo;
20628
21240
  const depositWallet = activeDepositWallet;
20629
21241
  const hasWallet = !!activeWalletInfo && !!activeDepositWallet;
21242
+ React35.useEffect(() => {
21243
+ const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
21244
+ setAmountUsd(cleanedPrefilled);
21245
+ }, [prefilledAmountUsd]);
20630
21246
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
20631
21247
  const recipientAddress = activeDepositWallet?.address ?? "";
20632
21248
  const isCheckoutMode = !!checkoutAmountUsd;
20633
21249
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
20634
- const transitionTo = React34.useCallback((nextView) => {
21250
+ const transitionTo = React35.useCallback((nextView) => {
20635
21251
  if (nextView === viewRef.current) return;
20636
21252
  setIsTransitioning(true);
20637
21253
  setTimeout(() => {
@@ -20647,10 +21263,13 @@ function WalletConnect({
20647
21263
  };
20648
21264
  const openMobileWalletBrowse = async (wallet, depositAddresses) => {
20649
21265
  try {
20650
- const res = await (0, import_core36.getWalletMobileDeepLink)(
21266
+ const cleanedAmountUsd = amountUsd?.replace(/[^0-9.]/g, "") ?? "";
21267
+ const forwardedAmountUsd = parseFloat(cleanedAmountUsd) > 0 ? cleanedAmountUsd : void 0;
21268
+ const res = await (0, import_core37.getWalletMobileDeepLink)(
20651
21269
  wallet.id,
20652
21270
  depositAddresses,
20653
- publishableKey
21271
+ publishableKey,
21272
+ forwardedAmountUsd
20654
21273
  );
20655
21274
  if (res.deeplink) {
20656
21275
  setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
@@ -20696,7 +21315,7 @@ function WalletConnect({
20696
21315
  if (!selectedWalletDef) return;
20697
21316
  handleConnectWallet(selectedWalletDef, network);
20698
21317
  };
20699
- React34.useEffect(() => {
21318
+ React35.useEffect(() => {
20700
21319
  if (!pendingMobileWallet) return;
20701
21320
  if (mobileDepositAddresses.length > 0) {
20702
21321
  const wallet = pendingMobileWallet;
@@ -20739,7 +21358,7 @@ function WalletConnect({
20739
21358
  const eip6963Match = findProviderByWalletId(wallet.id);
20740
21359
  let provider = eip6963Match?.provider;
20741
21360
  if (!provider) {
20742
- const legacyEvm = getLegacyEvmProviders();
21361
+ const legacyEvm = getLegacyEvmProviders(win);
20743
21362
  switch (wallet.id) {
20744
21363
  case "metamask":
20745
21364
  if (legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom)
@@ -20771,16 +21390,7 @@ function WalletConnect({
20771
21390
  const accounts = await provider.request({ method: "eth_requestAccounts" });
20772
21391
  if (!accounts?.length) throw new Error("No accounts returned from wallet");
20773
21392
  setUserDisconnectedWallet(false);
20774
- const walletIdToType = {
20775
- phantom: "phantom-ethereum",
20776
- coinbase: "coinbase",
20777
- trust: "trust",
20778
- rainbow: "rainbow",
20779
- rabby: "rabby",
20780
- okx: "okx",
20781
- metamask: "metamask"
20782
- };
20783
- const walletType = walletIdToType[wallet.id] || "metamask";
21393
+ const walletType = walletIdToWalletType(wallet.id);
20784
21394
  setStoredWalletState(walletType);
20785
21395
  connectedInfo = {
20786
21396
  type: walletType,
@@ -20789,7 +21399,7 @@ function WalletConnect({
20789
21399
  icon: wallet.id
20790
21400
  };
20791
21401
  } else {
20792
- const solProviders = getSolanaProviders();
21402
+ const solProviders = getInjectedSolanaProviders(win);
20793
21403
  let provider;
20794
21404
  switch (wallet.id) {
20795
21405
  case "phantom":
@@ -20808,11 +21418,11 @@ function WalletConnect({
20808
21418
  provider = solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
20809
21419
  break;
20810
21420
  case "trust":
20811
- provider = win?.trustwallet?.solana;
21421
+ provider = solProviders.trustSolana;
20812
21422
  break;
20813
21423
  }
20814
21424
  if (!provider) throw new Error(`${wallet.name} Solana wallet not found.`);
20815
- const response = await provider.connect();
21425
+ const response = await connectSolanaProviderWithRecovery(provider, wallet.id, wallet.name);
20816
21426
  setUserDisconnectedWallet(false);
20817
21427
  const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
20818
21428
  setStoredWalletState(walletType);
@@ -20860,7 +21470,7 @@ function WalletConnect({
20860
21470
  publishableKey,
20861
21471
  enabled: !!activeWalletInfo && !!recipientAddress
20862
21472
  });
20863
- const effectiveDestinationAmount = React34.useMemo(() => {
21473
+ const effectiveDestinationAmount = React35.useMemo(() => {
20864
21474
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
20865
21475
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
20866
21476
  const remaining = BigInt(checkoutRemainingBaseUnits);
@@ -20888,7 +21498,7 @@ function WalletConnect({
20888
21498
  stablecoinParity,
20889
21499
  enabled: isCheckoutMode && !!selectedToken && !!checkoutDestination && effectiveDestinationAmount !== "0"
20890
21500
  });
20891
- const activeCheckoutQuote = React34.useMemo(() => {
21501
+ const activeCheckoutQuote = React35.useMemo(() => {
20892
21502
  if (!isCheckoutMode) return null;
20893
21503
  if (walletCheckoutQuote)
20894
21504
  return {
@@ -20918,10 +21528,10 @@ function WalletConnect({
20918
21528
  onDepositSuccess,
20919
21529
  onDepositError
20920
21530
  });
20921
- React34.useEffect(() => {
21531
+ React35.useEffect(() => {
20922
21532
  onExecutionsChange?.(depositExecutions);
20923
21533
  }, [depositExecutions, onExecutionsChange]);
20924
- const latestDepositExecution = React34.useMemo(() => {
21534
+ const latestDepositExecution = React35.useMemo(() => {
20925
21535
  if (depositExecutions.length === 0) return null;
20926
21536
  return [...depositExecutions].sort((a, b) => {
20927
21537
  const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
@@ -20929,21 +21539,21 @@ function WalletConnect({
20929
21539
  return tb - ta;
20930
21540
  })[0];
20931
21541
  }, [depositExecutions]);
20932
- React34.useEffect(() => {
21542
+ React35.useEffect(() => {
20933
21543
  if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
20934
21544
  transitionTo("mobile_deposit_status");
20935
21545
  }
20936
21546
  }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
20937
- React34.useEffect(() => {
20938
- if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
21547
+ React35.useEffect(() => {
21548
+ if (!isCheckoutMode || !tokenChainDetails || view !== "enter_amount") return;
20939
21549
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
20940
21550
  const currentAmount = parseFloat(amountUsd) || 0;
20941
21551
  if (currentAmount > 0 && currentAmount < minDeposit) setAmountUsd(minDeposit.toFixed(2));
20942
- }, [tokenChainDetails, view, prefillAmountUsd]);
20943
- React34.useEffect(() => {
21552
+ }, [isCheckoutMode, tokenChainDetails, view, amountUsd]);
21553
+ React35.useEffect(() => {
20944
21554
  if (view === "review") setShowTransactionDetails(false);
20945
21555
  }, [view]);
20946
- React34.useEffect(() => {
21556
+ React35.useEffect(() => {
20947
21557
  if (view !== "enter_amount" && view !== "review" || !selectedBalance || !activeDepositWallet)
20948
21558
  return;
20949
21559
  let cancelled = false;
@@ -20958,7 +21568,7 @@ function WalletConnect({
20958
21568
  destination_chain_type: activeDepositWallet.destination_chain_type,
20959
21569
  ...productType ? { product_type: productType } : {}
20960
21570
  };
20961
- const response = await (0, import_core36.getSupportedDepositTokens)(publishableKey, options);
21571
+ const response = await (0, import_core37.getSupportedDepositTokens)(publishableKey, options);
20962
21572
  if (cancelled) return;
20963
21573
  const supportedToken = response.data.find(
20964
21574
  (t13) => t13.symbol.toLowerCase() === token.symbol.toLowerCase()
@@ -20980,13 +21590,13 @@ function WalletConnect({
20980
21590
  cancelled = true;
20981
21591
  };
20982
21592
  }, [view, selectedBalance, publishableKey, activeDepositWallet]);
20983
- React34.useEffect(() => {
21593
+ React35.useEffect(() => {
20984
21594
  if (!activeWalletInfo || !activeDepositWallet) return;
20985
21595
  let cancelled = false;
20986
21596
  setIsLoading(true);
20987
21597
  setError(null);
20988
21598
  const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
20989
- (0, import_core36.getAddressBalances)(activeWalletInfo.address, sct, publishableKey).then((response) => {
21599
+ (0, import_core37.getAddressBalances)(activeWalletInfo.address, sct, publishableKey).then((response) => {
20990
21600
  if (cancelled) return;
20991
21601
  const nonZero = response.balances.filter((b) => b.amount !== "0");
20992
21602
  const defaultSource = {
@@ -21045,21 +21655,21 @@ function WalletConnect({
21045
21655
  defaultSourceTokenAddress,
21046
21656
  defaultSourceSymbol
21047
21657
  ]);
21048
- const usdToTokenRate = React34.useMemo(() => {
21658
+ const usdToTokenRate = React35.useMemo(() => {
21049
21659
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
21050
21660
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
21051
21661
  const balanceUsd = parseFloat(selectedBalance.amount_usd);
21052
21662
  if (balanceAmount === 0 || balanceUsd === 0) return 0;
21053
21663
  return balanceAmount / balanceUsd;
21054
21664
  }, [selectedBalance, selectedToken]);
21055
- const tokenAmount = React34.useMemo(() => {
21665
+ const tokenAmount = React35.useMemo(() => {
21056
21666
  if (isCheckoutMode && activeCheckoutQuote && selectedToken)
21057
21667
  return Number(activeCheckoutQuote.sourceAmount) / 10 ** activeCheckoutQuote.sourceTokenDecimals;
21058
21668
  const usdNum = parseFloat(amountUsd) || 0;
21059
21669
  if (usdNum === 0 || usdToTokenRate === 0) return 0;
21060
21670
  return usdNum * usdToTokenRate;
21061
21671
  }, [amountUsd, usdToTokenRate, isCheckoutMode, activeCheckoutQuote, selectedToken]);
21062
- React34.useEffect(() => {
21672
+ React35.useEffect(() => {
21063
21673
  if (isCheckoutMode && activeCheckoutQuote?.sourceAmountUsd && view === "enter_amount")
21064
21674
  setAmountUsd(activeCheckoutQuote.sourceAmountUsd);
21065
21675
  }, [isCheckoutMode, activeCheckoutQuote, view]);
@@ -21068,7 +21678,7 @@ function WalletConnect({
21068
21678
  const inputUsdNum = parseFloat(amountUsd) || 0;
21069
21679
  const minDepositUsd = tokenChainDetails?.minimum_deposit_amount_usd || 0;
21070
21680
  const isValidAmount = isCheckoutMode && activeCheckoutQuote ? tokenAmount > 0 && tokenAmount <= maxTokenAmount : inputUsdNum > 0 && inputUsdNum <= maxUsdAmount && inputUsdNum >= minDepositUsd;
21071
- const formattedTokenAmount = React34.useMemo(() => {
21681
+ const formattedTokenAmount = React35.useMemo(() => {
21072
21682
  if (tokenAmount === 0 || !selectedToken) return null;
21073
21683
  return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
21074
21684
  }, [tokenAmount, selectedToken]);
@@ -21101,7 +21711,7 @@ function WalletConnect({
21101
21711
  break;
21102
21712
  case "enter_amount":
21103
21713
  transitionTo("select_token");
21104
- setAmountUsd(prefillAmountUsd ?? "");
21714
+ setAmountUsd(prefilledAmountUsd ?? "");
21105
21715
  setTokenChainDetails(null);
21106
21716
  break;
21107
21717
  case "review":
@@ -21133,7 +21743,7 @@ function WalletConnect({
21133
21743
  setSelectedBalance(null);
21134
21744
  setBalances([]);
21135
21745
  setTotalBalanceUsd(null);
21136
- setAmountUsd(prefillAmountUsd ?? "");
21746
+ setAmountUsd(prefilledAmountUsd ?? "");
21137
21747
  setError(null);
21138
21748
  };
21139
21749
  if (standalone) {
@@ -21163,16 +21773,7 @@ function WalletConnect({
21163
21773
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
21164
21774
  };
21165
21775
  const resolveEvmProvider = () => {
21166
- const walletIdMap = {
21167
- "phantom-ethereum": "phantom",
21168
- coinbase: "coinbase",
21169
- trust: "trust",
21170
- okx: "okx",
21171
- rainbow: "rainbow",
21172
- rabby: "rabby",
21173
- metamask: "metamask"
21174
- };
21175
- const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
21776
+ const lookupId = walletTypeToWalletId(walletInfo.type);
21176
21777
  const eip6963Match = findProviderByWalletId(lookupId);
21177
21778
  let provider = eip6963Match?.provider;
21178
21779
  if (!provider) {
@@ -21262,7 +21863,7 @@ function WalletConnect({
21262
21863
  if (!provider.publicKey) await provider.connect();
21263
21864
  const isNative = token.token_address === "native" || token.token_address === "So11111111111111111111111111111111111111112" || token.token_address === "";
21264
21865
  const smallestUnit = isNative ? decimalToSmallestUnit(amountStr, 9) : decimalToSmallestUnit(amountStr, token.decimals);
21265
- const buildResp = await (0, import_core36.buildSolanaTransaction)(
21866
+ const buildResp = await (0, import_core37.buildSolanaTransaction)(
21266
21867
  {
21267
21868
  chain_id: "mainnet",
21268
21869
  token_address: token.token_address === "" ? "native" : token.token_address,
@@ -21284,7 +21885,7 @@ function WalletConnect({
21284
21885
  const ser = signed.serialize();
21285
21886
  let bs = "";
21286
21887
  for (let i = 0; i < ser.length; i++) bs += String.fromCharCode(ser[i]);
21287
- const resp = await (0, import_core36.sendSolanaTransaction)(
21888
+ const resp = await (0, import_core37.sendSolanaTransaction)(
21288
21889
  { chain_id: "mainnet", signed_transaction: btoa(bs) },
21289
21890
  publishableKey
21290
21891
  );
@@ -21330,7 +21931,7 @@ function WalletConnect({
21330
21931
  } else if (isHypercoreToken) {
21331
21932
  let sendAmount = tokenAmount;
21332
21933
  try {
21333
- const activation = await (0, import_core36.checkHypercoreActivation)(
21934
+ const activation = await (0, import_core37.checkHypercoreActivation)(
21334
21935
  { source_address: walletInfo.address, recipient_address: recipientAddress },
21335
21936
  publishableKey
21336
21937
  );
@@ -21707,8 +22308,8 @@ function WalletConnect({
21707
22308
  ] }) });
21708
22309
  }
21709
22310
  if (view === "mobile_deposit_status" && latestDepositExecution) {
21710
- const isComplete = latestDepositExecution.status === import_core36.ExecutionStatus.SUCCEEDED;
21711
- const isFailed = latestDepositExecution.status === import_core36.ExecutionStatus.FAILED;
22311
+ const isComplete = latestDepositExecution.status === import_core37.ExecutionStatus.SUCCEEDED;
22312
+ const isFailed = latestDepositExecution.status === import_core37.ExecutionStatus.FAILED;
21712
22313
  const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
21713
22314
  return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { style: viewTransitionStyle, children: [
21714
22315
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
@@ -21860,6 +22461,15 @@ function SkeletonButton({ variant = "default" }) {
21860
22461
  ] });
21861
22462
  }
21862
22463
  var t8 = i18n.depositModal;
22464
+ function normalizePrefilledUsdAmount(value) {
22465
+ if (!value) return void 0;
22466
+ const cleaned = value.replace(/[^0-9.]/g, "");
22467
+ if (!cleaned) return void 0;
22468
+ const normalizedNumeric = cleaned.replace(/(\..*)\./g, "$1");
22469
+ const parsed = parseFloat(normalizedNumeric);
22470
+ if (!Number.isFinite(parsed) || parsed <= 0) return void 0;
22471
+ return parseFloat(parsed.toFixed(2)).toString();
22472
+ }
21863
22473
  function depositTabForScreen(screen) {
21864
22474
  return screen === "card" || screen === "cashapp" || screen === "bank_transfer" || screen === "stripe_link" || screen === "apple_pay" ? "cash" : "crypto";
21865
22475
  }
@@ -21879,6 +22489,7 @@ function DepositModal({
21879
22489
  defaultSourceChainId,
21880
22490
  defaultSourceTokenAddress,
21881
22491
  defaultSourceSymbol,
22492
+ prefilledAmountUsd,
21882
22493
  hideDepositTracker,
21883
22494
  showBalanceHeader = false,
21884
22495
  transferInputVariant = "double_input",
@@ -21894,6 +22505,7 @@ function DepositModal({
21894
22505
  applePayTitle = "Pay with Apple Pay",
21895
22506
  applePaySubTitle = "Instant",
21896
22507
  enableBankTransfer,
22508
+ enableIncidentBanner = false,
21897
22509
  // No default: left undefined so the backend `stripe_link.enabled` can govern
21898
22510
  // (via the `??` chain in showStripeLink) once a dashboard toggle exists.
21899
22511
  enableStripeLink,
@@ -21914,6 +22526,10 @@ function DepositModal({
21914
22526
  depositTrackerSubTitle = t8.depositTracker.subtitle
21915
22527
  }) {
21916
22528
  const { colors: colors2, fonts, components } = useTheme();
22529
+ const normalizedPrefilledAmountUsd = (0, import_react26.useMemo)(
22530
+ () => normalizePrefilledUsdAmount(prefilledAmountUsd),
22531
+ [prefilledAmountUsd]
22532
+ );
21917
22533
  const onDepositSuccessFor = (0, import_react26.useCallback)(
21918
22534
  (method) => onDepositSuccess || onEvent ? (data) => {
21919
22535
  const payload = { ...data, method };
@@ -21935,7 +22551,7 @@ function DepositModal({
21935
22551
  const s = initialScreen ?? "main";
21936
22552
  if (s === "tracker" && hideDepositTracker === true) return "main";
21937
22553
  if (s === "cashapp" && enableCashApp === false) return "main";
21938
- if (s === "stripe_link" && !enableStripeLink) return "main";
22554
+ if (s === "stripe_link" && enableStripeLink === false) return "main";
21939
22555
  if (s === "apple_pay" && enableApplePay === false) return "main";
21940
22556
  if (s === "card" && enableFiatOnramp === false) return "main";
21941
22557
  if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
@@ -21994,21 +22610,31 @@ function DepositModal({
21994
22610
  const showApplePay = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
21995
22611
  const showBankTransfer = enableBankTransfer ?? projectConfig?.bank_transfer?.enabled ?? true;
21996
22612
  const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
22613
+ const { incident: publicIncident } = usePublicIncident({
22614
+ publishableKey,
22615
+ enabled: open && enableIncidentBanner
22616
+ });
22617
+ const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
22618
+ enabled: true,
22619
+ messages: publicIncident.messages,
22620
+ severity: publicIncident.severity,
22621
+ statusPageUrl: publicIncident.status_page_url
22622
+ } : void 0;
21997
22623
  const [integrationExchanges, setIntegrationExchanges] = (0, import_react26.useState)([]);
21998
22624
  (0, import_react26.useEffect)(() => {
21999
22625
  if (!showConnectExchange || !open) return;
22000
- (0, import_core37.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
22626
+ (0, import_core38.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
22001
22627
  });
22002
22628
  }, [showConnectExchange, open, publishableKey]);
22003
22629
  const [connectedExchange, setConnectedExchange] = (0, import_react26.useState)(() => {
22004
22630
  if (!showConnectExchange) return null;
22005
- const stored = getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
22631
+ const stored = getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22006
22632
  if (!stored) return null;
22007
22633
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
22008
22634
  });
22009
22635
  (0, import_react26.useEffect)(() => {
22010
22636
  if (!showConnectExchange || !open || view !== "main") return;
22011
- const stored = getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
22637
+ const stored = getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22012
22638
  if (!stored) {
22013
22639
  setConnectedExchange(null);
22014
22640
  return;
@@ -22028,24 +22654,24 @@ function DepositModal({
22028
22654
  }) : null;
22029
22655
  setConnectedExchange((prev) => prev ? { ...prev, balanceUsd, isLoading: false } : null);
22030
22656
  };
22031
- (0, import_core37.getIntegrationHoldings)(import_core37.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
22657
+ (0, import_core38.getIntegrationHoldings)(import_core38.IntegrationProvider.COINBASE, stored.access_token, publishableKey).then(processHoldings).catch(async () => {
22032
22658
  try {
22033
- const refreshResult = await (0, import_core37.refreshIntegrationToken)(stored.access_token, publishableKey);
22034
- if (!getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE)) return;
22659
+ const refreshResult = await (0, import_core38.refreshIntegrationToken)(stored.access_token, publishableKey);
22660
+ if (!getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE)) return;
22035
22661
  setStoredIntegrationToken({
22036
- integration_provider: import_core37.IntegrationProvider.COINBASE,
22662
+ integration_provider: import_core38.IntegrationProvider.COINBASE,
22037
22663
  access_token: refreshResult.access_token,
22038
22664
  expires_at: refreshResult.expires_at
22039
22665
  });
22040
- const retryResult = await (0, import_core37.getIntegrationHoldings)(
22041
- import_core37.IntegrationProvider.COINBASE,
22666
+ const retryResult = await (0, import_core38.getIntegrationHoldings)(
22667
+ import_core38.IntegrationProvider.COINBASE,
22042
22668
  refreshResult.access_token,
22043
22669
  publishableKey
22044
22670
  );
22045
22671
  processHoldings(retryResult);
22046
22672
  } catch {
22047
- if (!getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE)) return;
22048
- clearStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
22673
+ if (!getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE)) return;
22674
+ clearStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22049
22675
  setConnectedExchange(null);
22050
22676
  }
22051
22677
  });
@@ -22053,14 +22679,18 @@ function DepositModal({
22053
22679
  (0, import_react26.useEffect)(() => {
22054
22680
  if (!connectedExchange || integrationExchanges.length === 0) return;
22055
22681
  const cbExchange = integrationExchanges.find(
22056
- (e) => e.service_provider === import_core37.IntegrationProvider.COINBASE
22682
+ (e) => e.service_provider === import_core38.IntegrationProvider.COINBASE
22057
22683
  );
22058
22684
  const iconUrl = cbExchange?.icon_urls?.find((u) => u.format === "svg")?.url || cbExchange?.icon_urls?.find((u) => u.format === "png")?.url || cbExchange?.icon_url;
22059
22685
  if (iconUrl && iconUrl !== connectedExchange.iconUrl) {
22060
22686
  setConnectedExchange((prev) => prev ? { ...prev, iconUrl } : prev);
22061
22687
  }
22062
22688
  }, [integrationExchanges, connectedExchange]);
22063
- const { data: depositAddressResponse, isLoading: walletsLoading } = useDepositAddress({
22689
+ const {
22690
+ data: depositAddressResponse,
22691
+ isLoading: walletsLoading,
22692
+ error: walletsError
22693
+ } = useDepositAddress({
22064
22694
  userId,
22065
22695
  publishableKey,
22066
22696
  recipientAddress,
@@ -22158,7 +22788,7 @@ function DepositModal({
22158
22788
  if (view !== "tracker" || !userId) return;
22159
22789
  const fetchExecutions = async () => {
22160
22790
  try {
22161
- const response = await (0, import_core37.queryExecutions)(userId, publishableKey, import_core37.ActionType.Deposit);
22791
+ const response = await (0, import_core38.queryExecutions)(userId, publishableKey, import_core38.ActionType.Deposit);
22162
22792
  const sorted = [...response.data].sort((a, b) => {
22163
22793
  const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
22164
22794
  const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
@@ -22193,6 +22823,7 @@ function DepositModal({
22193
22823
  const {
22194
22824
  isValid: isAddressValid,
22195
22825
  failureCode: addressFailureCode,
22826
+ message: addressFailureMessage,
22196
22827
  metadata: addressFailureMetadata,
22197
22828
  isLoading: isAddressValidationLoading
22198
22829
  } = useAddressValidation({
@@ -22206,17 +22837,31 @@ function DepositModal({
22206
22837
  refetchOnMount: "always"
22207
22838
  });
22208
22839
  const addressValidationMessages = i18n.transferCrypto.addressValidation;
22209
- const getAddressValidationErrorMessage = (code, metadata) => {
22840
+ const getAddressValidationErrorMessage = (message, code, metadata) => {
22841
+ if (message && message.trim().length > 0) return message;
22210
22842
  if (!code) return addressValidationMessages.defaultError;
22211
22843
  const errors = addressValidationMessages.errors;
22212
22844
  const template = errors[code] ?? addressValidationMessages.defaultError;
22213
22845
  return interpolate(template, metadata);
22214
22846
  };
22847
+ const walletsRecipientError = (0, import_core38.isDepositAddressValidationError)(walletsError) ? walletsError.message : null;
22848
+ const isRecipientAddressInvalid = isAddressValid === false || walletsRecipientError !== null;
22849
+ const recipientInvalidMessage = getAddressValidationErrorMessage(
22850
+ addressFailureMessage ?? walletsRecipientError,
22851
+ addressFailureCode,
22852
+ addressFailureMetadata
22853
+ );
22215
22854
  const openingScreen = effectiveInitialScreen;
22216
22855
  const sessionOpenedFromMenu = openingScreen === "main";
22217
22856
  const standaloneNeedsDepositPrereq = openingScreen !== "main" && (view === "transfer" || view === "card");
22218
22857
  let depositPrerequisiteBody;
22219
- if (isCountryLoading || isAddressValidationLoading || tokensLoading || walletsLoading || !projectConfig || // Bank-transfer row visibility depends on the country-gated providers
22858
+ if (isRecipientAddressInvalid) {
22859
+ depositPrerequisiteBody = /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
22860
+ /* @__PURE__ */ (0, import_jsx_runtime63.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_runtime63.jsx)(import_lucide_react37.AlertTriangle, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
22861
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
22862
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: recipientInvalidMessage })
22863
+ ] });
22864
+ } else if (isCountryLoading || isAddressValidationLoading || tokensLoading || walletsLoading || !projectConfig || // Bank-transfer row visibility depends on the country-gated providers
22220
22865
  // fetch — block the menu on it so the row never flashes in or out.
22221
22866
  showBankTransfer && bankTransferProvidersLoading || // Same for Apple Pay: row visibility depends on the geo/platform-gated
22222
22867
  // providers fetch — block the menu so the row doesn't pop in or out.
@@ -22238,12 +22883,6 @@ function DepositModal({
22238
22883
  /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "No Tokens Available" }),
22239
22884
  /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: "There are no supported tokens available from your current location." })
22240
22885
  ] });
22241
- } else if (isAddressValid === false) {
22242
- depositPrerequisiteBody = /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
22243
- /* @__PURE__ */ (0, import_jsx_runtime63.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_runtime63.jsx)(import_lucide_react37.AlertTriangle, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
22244
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
22245
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: getAddressValidationErrorMessage(addressFailureCode, addressFailureMetadata) })
22246
- ] });
22247
22886
  } else {
22248
22887
  depositPrerequisiteBody = null;
22249
22888
  }
@@ -22260,11 +22899,11 @@ function DepositModal({
22260
22899
  if (view === "wallet_connect" && sessionOpenedFromMenu) setView("main");
22261
22900
  };
22262
22901
  const handleExchangeDisconnect = () => {
22263
- const stored = getStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
22902
+ const stored = getStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22264
22903
  if (stored) {
22265
- (0, import_core37.revokeIntegrationToken)(stored.access_token, publishableKey);
22904
+ (0, import_core38.revokeIntegrationToken)(stored.access_token, publishableKey);
22266
22905
  }
22267
- clearStoredIntegrationToken(import_core37.IntegrationProvider.COINBASE);
22906
+ clearStoredIntegrationToken(import_core38.IntegrationProvider.COINBASE);
22268
22907
  setConnectedExchange(null);
22269
22908
  if (view === "coinbase_connect" && sessionOpenedFromMenu) setView("main");
22270
22909
  };
@@ -22737,6 +23376,7 @@ function DepositModal({
22737
23376
  title: modalTitle || "Deposit",
22738
23377
  showClose: !hideOverlay,
22739
23378
  onClose: handleClose,
23379
+ incident: activeIncident,
22740
23380
  showBalance: showBalanceHeader,
22741
23381
  balanceAddress: recipientAddress,
22742
23382
  balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
@@ -22756,6 +23396,7 @@ function DepositModal({
22756
23396
  showBack: showBackTransfer,
22757
23397
  onBack: handleBack,
22758
23398
  onClose: handleClose,
23399
+ incident: activeIncident,
22759
23400
  showBalance: showBalanceHeader,
22760
23401
  balanceAddress: recipientAddress,
22761
23402
  balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
@@ -22779,6 +23420,7 @@ function DepositModal({
22779
23420
  defaultSourceChainId,
22780
23421
  defaultSourceTokenAddress,
22781
23422
  defaultSourceSymbol,
23423
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
22782
23424
  depositConfirmationMode,
22783
23425
  onExecutionsChange: setDepositExecutions,
22784
23426
  onDepositSuccess: onDepositSuccessFor("transfer"),
@@ -22798,6 +23440,7 @@ function DepositModal({
22798
23440
  defaultSourceChainId,
22799
23441
  defaultSourceTokenAddress,
22800
23442
  defaultSourceSymbol,
23443
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
22801
23444
  depositConfirmationMode,
22802
23445
  onExecutionsChange: setDepositExecutions,
22803
23446
  onDepositSuccess: onDepositSuccessFor("transfer"),
@@ -22814,7 +23457,8 @@ function DepositModal({
22814
23457
  title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
22815
23458
  showBack: showBackTracker,
22816
23459
  onBack: handleBack,
22817
- onClose: handleClose
23460
+ onClose: handleClose,
23461
+ incident: activeIncident
22818
23462
  }
22819
23463
  ),
22820
23464
  /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -22846,6 +23490,7 @@ function DepositModal({
22846
23490
  showBack: showBackCard,
22847
23491
  onBack: handleBack,
22848
23492
  onClose: handleClose,
23493
+ incident: activeIncident,
22849
23494
  badge: cardView === "quotes" ? { count: quotesCount } : void 0,
22850
23495
  showBalance: showBalanceHeader,
22851
23496
  balanceAddress: recipientAddress,
@@ -22882,7 +23527,8 @@ function DepositModal({
22882
23527
  wallets,
22883
23528
  assetCdnUrl: projectConfig?.asset_cdn_url,
22884
23529
  hideDepositFlowInfo,
22885
- hideDisplayDescription
23530
+ hideDisplayDescription,
23531
+ prefilledAmountUsd: normalizedPrefilledAmountUsd
22886
23532
  }
22887
23533
  ),
22888
23534
  depositPoweredByFooter
@@ -22894,7 +23540,8 @@ function DepositModal({
22894
23540
  title: payWithExchangeTitle,
22895
23541
  showBack: exchangeView === "pending" || sessionOpenedFromMenu,
22896
23542
  onBack: handleBack,
22897
- onClose: handleClose
23543
+ onClose: handleClose,
23544
+ incident: activeIncident
22898
23545
  }
22899
23546
  ),
22900
23547
  /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -22947,7 +23594,8 @@ function DepositModal({
22947
23594
  defaultSourceChainType,
22948
23595
  defaultSourceChainId,
22949
23596
  defaultSourceTokenAddress,
22950
- defaultSourceSymbol
23597
+ defaultSourceSymbol,
23598
+ prefilledAmountUsd: normalizedPrefilledAmountUsd
22951
23599
  }
22952
23600
  ),
22953
23601
  depositPoweredByFooter
@@ -22979,6 +23627,7 @@ function DepositModal({
22979
23627
  onDepositSuccess: onDepositSuccessFor("wallet_connect"),
22980
23628
  onDepositError: onDepositErrorFor("wallet_connect"),
22981
23629
  amountQuickSelect: browserWalletAmountQuickSelect,
23630
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
22982
23631
  onWalletDisconnect: handleWalletDisconnect,
22983
23632
  onWalletConnected: (info, dw) => {
22984
23633
  setBrowserWalletInfo({ ...info, depositWallet: dw });
@@ -23006,7 +23655,8 @@ function DepositModal({
23006
23655
  title: t8.bankTransfer.title,
23007
23656
  showBack: bankTransferView !== "providers" || sessionOpenedFromMenu,
23008
23657
  onBack: handleBack,
23009
- onClose: handleClose
23658
+ onClose: handleClose,
23659
+ incident: activeIncident
23010
23660
  }
23011
23661
  ),
23012
23662
  /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -23027,7 +23677,8 @@ function DepositModal({
23027
23677
  assetCdnUrl: projectConfig?.asset_cdn_url,
23028
23678
  onEvent,
23029
23679
  onDepositSuccess,
23030
- onDepositError
23680
+ onDepositError,
23681
+ prefilledAmountUsd: normalizedPrefilledAmountUsd
23031
23682
  }
23032
23683
  ),
23033
23684
  depositPoweredByFooter
@@ -23039,26 +23690,24 @@ function DepositModal({
23039
23690
  title: "Deposit with Link",
23040
23691
  showBack: stripeLinkStep !== "checkout" && stripeLinkStep !== "success",
23041
23692
  onBack: handleBack,
23042
- showClose: stripeLinkStep !== "checkout",
23693
+ incident: activeIncident,
23694
+ showClose: stripeLinkStep !== "checkout" && stripeLinkStep !== "auth",
23043
23695
  onClose: handleClose
23044
23696
  }
23045
23697
  ),
23046
23698
  /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23047
23699
  isLoadingIp ? (
23048
- // Hold the geo decision until IP resolves so we don't mount
23049
- // PayWithStripeLink (which kicks off config/OAuth work) for a
23050
- // deep-link user who turns out to be outside the US.
23700
+ // Wait for location so the first config fetch is region-aware.
23051
23701
  /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SkeletonButton, { variant: "with-icons" })
23052
23702
  ) : !showStripeLink ? (
23053
- // Stripe Link's crypto on-ramp is US-only. On a direct open
23054
- // (initialScreen="stripe_link") the row isn't in a menu to
23055
- // fall back to, so show a geo-restriction screen rather than
23056
- // the Link UI.
23703
+ // Direct opens (initialScreen="stripe_link") have no menu row
23704
+ // to fall back to, so render an unavailable state when backend
23705
+ // config resolves Stripe Link disabled/hidden.
23057
23706
  /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
23058
23707
  GeoRestrictionScreen,
23059
23708
  {
23060
23709
  methodName: t8.stripeLink.title,
23061
- message: "Pay with Link is only available in the US."
23710
+ message: t8.stripeLink.unavailableInRegionMessage
23062
23711
  }
23063
23712
  )
23064
23713
  ) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
@@ -23070,6 +23719,8 @@ function DepositModal({
23070
23719
  destinationChainType,
23071
23720
  destinationChainId,
23072
23721
  destinationTokenAddress,
23722
+ countryCode: userIpInfo?.alpha2,
23723
+ subdivisionCode: userIpInfo?.subdivisionCode ?? void 0,
23073
23724
  wallets,
23074
23725
  email: userEmail,
23075
23726
  iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/link.svg` : void 0,
@@ -23089,7 +23740,8 @@ function DepositModal({
23089
23740
  title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
23090
23741
  showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
23091
23742
  onBack: handleBack,
23092
- onClose: handleClose
23743
+ onClose: handleClose,
23744
+ incident: activeIncident
23093
23745
  }
23094
23746
  ),
23095
23747
  /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -23109,6 +23761,7 @@ function DepositModal({
23109
23761
  onEvent,
23110
23762
  onDepositSuccess: onDepositSuccessFor("cashapp"),
23111
23763
  onDepositError: onDepositErrorFor("cashapp"),
23764
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
23112
23765
  wallets
23113
23766
  }
23114
23767
  ),
@@ -23124,7 +23777,8 @@ function DepositModal({
23124
23777
  const handled = applePayHandleRef.current?.requestBack() ?? false;
23125
23778
  if (!handled) handleBack();
23126
23779
  },
23127
- onClose: handleClose
23780
+ onClose: handleClose,
23781
+ incident: activeIncident
23128
23782
  }
23129
23783
  ),
23130
23784
  /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -23170,14 +23824,14 @@ var import_react27 = require("react");
23170
23824
  var import_lucide_react38 = require("lucide-react");
23171
23825
 
23172
23826
  // src/hooks/use-payment-intent.ts
23173
- var import_react_query17 = require("@tanstack/react-query");
23174
- var import_core38 = require("@unifold/core");
23827
+ var import_react_query19 = require("@tanstack/react-query");
23828
+ var import_core39 = require("@unifold/core");
23175
23829
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["succeeded", "expired", "refunded", "canceled"]);
23176
23830
  function usePaymentIntent(params) {
23177
23831
  const { clientSecret, publishableKey, enabled = true, pollingInterval = 3e3 } = params;
23178
- return (0, import_react_query17.useQuery)({
23832
+ return (0, import_react_query19.useQuery)({
23179
23833
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
23180
- queryFn: () => (0, import_core38.retrievePaymentIntent)(clientSecret, publishableKey),
23834
+ queryFn: () => (0, import_core39.retrievePaymentIntent)(clientSecret, publishableKey),
23181
23835
  enabled: enabled && !!clientSecret && !!publishableKey,
23182
23836
  staleTime: 0,
23183
23837
  refetchInterval: (query) => {
@@ -23193,7 +23847,7 @@ function usePaymentIntent(params) {
23193
23847
  }
23194
23848
 
23195
23849
  // src/components/checkout/CheckoutModal.tsx
23196
- var import_core39 = require("@unifold/core");
23850
+ var import_core40 = require("@unifold/core");
23197
23851
  var import_jsx_runtime64 = require("react/jsx-runtime");
23198
23852
  function mapToCheckoutPaymentIntent(pi) {
23199
23853
  return {
@@ -23251,6 +23905,7 @@ function CheckoutModal({
23251
23905
  modalTitle,
23252
23906
  enableTransferCrypto,
23253
23907
  enableConnectWallet,
23908
+ enableIncidentBanner = false,
23254
23909
  defaultSourceChainType,
23255
23910
  defaultSourceChainId,
23256
23911
  defaultSourceTokenAddress,
@@ -23279,8 +23934,8 @@ function CheckoutModal({
23279
23934
  if (isSucceeded && richIntent) {
23280
23935
  const createdSec = data.paymentIntent?.updated_at ? Math.floor(new Date(data.paymentIntent.updated_at).getTime() / 1e3) : Math.floor(Date.now() / 1e3);
23281
23936
  onEvent?.({
23282
- id: (0, import_core39.generatePrefixedKSUID)("sevt"),
23283
- type: import_core39.CheckoutEventType.PAYMENT_INTENT_SUCCEEDED,
23937
+ id: (0, import_core40.generatePrefixedKSUID)("sevt"),
23938
+ type: import_core40.CheckoutEventType.PAYMENT_INTENT_SUCCEEDED,
23284
23939
  created: createdSec,
23285
23940
  method,
23286
23941
  data: { object: richIntent }
@@ -23322,6 +23977,16 @@ function CheckoutModal({
23322
23977
  });
23323
23978
  const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
23324
23979
  const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
23980
+ const { incident: publicIncident } = usePublicIncident({
23981
+ publishableKey,
23982
+ enabled: open && enableIncidentBanner
23983
+ });
23984
+ const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
23985
+ enabled: true,
23986
+ messages: publicIncident.messages,
23987
+ severity: publicIncident.severity,
23988
+ statusPageUrl: publicIncident.status_page_url
23989
+ } : void 0;
23325
23990
  (0, import_react27.useEffect)(() => {
23326
23991
  if (view === "transfer" && !showTransferCrypto) {
23327
23992
  setView("main");
@@ -23623,7 +24288,15 @@ function CheckoutModal({
23623
24288
  {
23624
24289
  className: view === "wallet_connect" ? "uf-flex uf-min-h-0 uf-flex-col" : void 0,
23625
24290
  children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
23626
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(DepositHeader, { title: modalTitle || "Checkout", showClose: true, onClose: handleClose }),
24291
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
24292
+ DepositHeader,
24293
+ {
24294
+ title: modalTitle || "Checkout",
24295
+ showClose: true,
24296
+ onClose: handleClose,
24297
+ incident: activeIncident
24298
+ }
24299
+ ),
23627
24300
  /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
23628
24301
  piLoading ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-space-y-3", children: [
23629
24302
  /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
@@ -23721,7 +24394,8 @@ function CheckoutModal({
23721
24394
  title: modalTitle || "Checkout",
23722
24395
  showBack: true,
23723
24396
  onBack: handleBack,
23724
- onClose: handleClose
24397
+ onClose: handleClose,
24398
+ incident: activeIncident
23725
24399
  }
23726
24400
  ),
23727
24401
  /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -23820,7 +24494,7 @@ function CheckoutModal({
23820
24494
  userId: paymentIntent.user_id || "",
23821
24495
  publishableKey,
23822
24496
  clientSecret,
23823
- prefillAmountUsd: remainingAmountUsd,
24497
+ prefilledAmountUsd: remainingAmountUsd,
23824
24498
  checkoutAmountUsd: paymentIntent.amount_usd,
23825
24499
  checkoutReceivedUsd: paymentIntent.amount_received_usd,
23826
24500
  checkoutDestination: {
@@ -23886,12 +24560,12 @@ var import_react32 = require("react");
23886
24560
  var import_lucide_react41 = require("lucide-react");
23887
24561
 
23888
24562
  // src/hooks/use-supported-destination-tokens.ts
23889
- var import_react_query18 = require("@tanstack/react-query");
23890
- var import_core40 = require("@unifold/core");
24563
+ var import_react_query20 = require("@tanstack/react-query");
24564
+ var import_core41 = require("@unifold/core");
23891
24565
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
23892
- return (0, import_react_query18.useQuery)({
24566
+ return (0, import_react_query20.useQuery)({
23893
24567
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
23894
- queryFn: () => (0, import_core40.getSupportedDestinationTokens)(publishableKey),
24568
+ queryFn: () => (0, import_core41.getSupportedDestinationTokens)(publishableKey),
23895
24569
  staleTime: 1e3 * 60 * 5,
23896
24570
  gcTime: 1e3 * 60 * 30,
23897
24571
  refetchOnMount: false,
@@ -23901,6 +24575,7 @@ function useSupportedDestinationTokens(publishableKey, enabled = true) {
23901
24575
  }
23902
24576
 
23903
24577
  // src/hooks/use-default-destination-token.ts
24578
+ var STORAGE_KEY3 = "unifold_last_withdraw_to_token";
23904
24579
  function useDefaultDestinationToken({
23905
24580
  destinationTokens,
23906
24581
  defaultDestinationChainType,
@@ -23913,13 +24588,14 @@ function useDefaultDestinationToken({
23913
24588
  defaultChainType: defaultDestinationChainType,
23914
24589
  defaultChainId: defaultDestinationChainId,
23915
24590
  defaultTokenAddress: defaultDestinationTokenAddress,
23916
- defaultSymbol: defaultDestinationSymbol
24591
+ defaultSymbol: defaultDestinationSymbol,
24592
+ storageKey: STORAGE_KEY3
23917
24593
  });
23918
24594
  }
23919
24595
 
23920
24596
  // src/hooks/use-source-token-validation.ts
23921
- var import_react_query19 = require("@tanstack/react-query");
23922
- var import_core41 = require("@unifold/core");
24597
+ var import_react_query21 = require("@tanstack/react-query");
24598
+ var import_core42 = require("@unifold/core");
23923
24599
  function useSourceTokenValidation(params) {
23924
24600
  const {
23925
24601
  sourceChainType,
@@ -23930,7 +24606,7 @@ function useSourceTokenValidation(params) {
23930
24606
  enabled = true
23931
24607
  } = params;
23932
24608
  const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
23933
- return (0, import_react_query19.useQuery)({
24609
+ return (0, import_react_query21.useQuery)({
23934
24610
  queryKey: [
23935
24611
  "unifold",
23936
24612
  "sourceTokenValidation",
@@ -23940,7 +24616,7 @@ function useSourceTokenValidation(params) {
23940
24616
  publishableKey
23941
24617
  ],
23942
24618
  queryFn: async () => {
23943
- const res = await (0, import_core41.getSupportedDepositTokens)(publishableKey);
24619
+ const res = await (0, import_core42.getSupportedDepositTokens)(publishableKey);
23944
24620
  let matchedMinUsd = null;
23945
24621
  let matchedProcessingTime = null;
23946
24622
  let matchedSlippage = null;
@@ -23978,12 +24654,12 @@ function useSourceTokenValidation(params) {
23978
24654
  }
23979
24655
 
23980
24656
  // src/hooks/use-address-balance.ts
23981
- var import_react_query20 = require("@tanstack/react-query");
23982
- var import_core42 = require("@unifold/core");
24657
+ var import_react_query22 = require("@tanstack/react-query");
24658
+ var import_core43 = require("@unifold/core");
23983
24659
  function useAddressBalance(params) {
23984
24660
  const { address, chainType, chainId, tokenAddress, publishableKey, enabled = true } = params;
23985
24661
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
23986
- return (0, import_react_query20.useQuery)({
24662
+ return (0, import_react_query22.useQuery)({
23987
24663
  queryKey: [
23988
24664
  "unifold",
23989
24665
  "addressBalance",
@@ -23994,7 +24670,7 @@ function useAddressBalance(params) {
23994
24670
  publishableKey
23995
24671
  ],
23996
24672
  queryFn: async () => {
23997
- const res = await (0, import_core42.getAddressBalance)(
24673
+ const res = await (0, import_core43.getAddressBalance)(
23998
24674
  address,
23999
24675
  chainType,
24000
24676
  chainId,
@@ -24039,13 +24715,13 @@ function useAddressBalance(params) {
24039
24715
  }
24040
24716
 
24041
24717
  // src/hooks/use-executions.ts
24042
- var import_react_query21 = require("@tanstack/react-query");
24043
- var import_core43 = require("@unifold/core");
24718
+ var import_react_query23 = require("@tanstack/react-query");
24719
+ var import_core44 = require("@unifold/core");
24044
24720
  function useExecutions(userId, publishableKey, options) {
24045
- const actionType = options?.actionType ?? import_core43.ActionType.Deposit;
24046
- return (0, import_react_query21.useQuery)({
24721
+ const actionType = options?.actionType ?? import_core44.ActionType.Deposit;
24722
+ return (0, import_react_query23.useQuery)({
24047
24723
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
24048
- queryFn: () => (0, import_core43.queryExecutions)(userId, publishableKey, actionType),
24724
+ queryFn: () => (0, import_core44.queryExecutions)(userId, publishableKey, actionType),
24049
24725
  enabled: (options?.enabled ?? true) && !!userId,
24050
24726
  refetchInterval: options?.refetchInterval ?? 3e3,
24051
24727
  staleTime: 0,
@@ -24056,7 +24732,7 @@ function useExecutions(userId, publishableKey, options) {
24056
24732
 
24057
24733
  // src/hooks/use-withdraw-polling.ts
24058
24734
  var import_react28 = require("react");
24059
- var import_core44 = require("@unifold/core");
24735
+ var import_core45 = require("@unifold/core");
24060
24736
  var POLL_INTERVAL_MS3 = 2500;
24061
24737
  var POLL_ENDPOINT_INTERVAL_MS2 = 5e3;
24062
24738
  var CUTOFF_BUFFER_MS2 = 6e4;
@@ -24069,8 +24745,8 @@ function useWithdrawPolling({
24069
24745
  onWithdrawError
24070
24746
  }) {
24071
24747
  const createExecutionSuccessEvent = (execution) => ({
24072
- id: (0, import_core44.generatePrefixedKSUID)("sevt"),
24073
- type: import_core44.WithdrawEventType.DIRECT_EXECUTION_SUCCEEDED,
24748
+ id: (0, import_core45.generatePrefixedKSUID)("sevt"),
24749
+ type: import_core45.WithdrawEventType.DIRECT_EXECUTION_SUCCEEDED,
24074
24750
  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),
24075
24751
  data: { object: mapToDirectExecution(execution) }
24076
24752
  });
@@ -24121,7 +24797,7 @@ function useWithdrawPolling({
24121
24797
  const enabledAt = enabledAtRef.current;
24122
24798
  const poll = async () => {
24123
24799
  try {
24124
- const response = await (0, import_core44.queryExecutions)(userId, publishableKey, import_core44.ActionType.Withdraw);
24800
+ const response = await (0, import_core45.queryExecutions)(userId, publishableKey, import_core45.ActionType.Withdraw);
24125
24801
  const cutoff = new Date(enabledAt.getTime() - CUTOFF_BUFFER_MS2);
24126
24802
  const sorted = [...response.data].sort((a, b) => {
24127
24803
  const tA = a.created_at ? new Date(a.created_at).getTime() : 0;
@@ -24129,11 +24805,11 @@ function useWithdrawPolling({
24129
24805
  return tB - tA;
24130
24806
  });
24131
24807
  const inProgress = [
24132
- import_core44.ExecutionStatus.PENDING,
24133
- import_core44.ExecutionStatus.WAITING,
24134
- import_core44.ExecutionStatus.DELAYED
24808
+ import_core45.ExecutionStatus.PENDING,
24809
+ import_core45.ExecutionStatus.WAITING,
24810
+ import_core45.ExecutionStatus.DELAYED
24135
24811
  ];
24136
- const terminal = [import_core44.ExecutionStatus.SUCCEEDED, import_core44.ExecutionStatus.FAILED];
24812
+ const terminal = [import_core45.ExecutionStatus.SUCCEEDED, import_core45.ExecutionStatus.FAILED];
24137
24813
  let target = null;
24138
24814
  for (const ex of sorted) {
24139
24815
  const t13 = ex.created_at ? new Date(ex.created_at) : null;
@@ -24163,7 +24839,7 @@ function useWithdrawPolling({
24163
24839
  }
24164
24840
  return [...list, ex];
24165
24841
  });
24166
- if (ex.status === import_core44.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
24842
+ if (ex.status === import_core45.ExecutionStatus.SUCCEEDED && (!prev || inProgress.includes(prev))) {
24167
24843
  onSuccessRef.current?.({
24168
24844
  message: "Withdrawal completed successfully",
24169
24845
  executionId: ex.id,
@@ -24171,7 +24847,7 @@ function useWithdrawPolling({
24171
24847
  transaction: ex,
24172
24848
  execution: createExecutionSuccessEvent(ex)
24173
24849
  });
24174
- } else if (ex.status === import_core44.ExecutionStatus.FAILED && prev !== import_core44.ExecutionStatus.FAILED) {
24850
+ } else if (ex.status === import_core45.ExecutionStatus.FAILED && prev !== import_core45.ExecutionStatus.FAILED) {
24175
24851
  onErrorRef.current?.({
24176
24852
  message: "Withdrawal failed",
24177
24853
  code: "WITHDRAW_FAILED",
@@ -24200,7 +24876,7 @@ function useWithdrawPolling({
24200
24876
  if (!enabled || !depositWalletId) return;
24201
24877
  const trigger = async () => {
24202
24878
  try {
24203
- await (0, import_core44.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
24879
+ await (0, import_core45.pollDirectExecutions)({ deposit_wallet_id: depositWalletId }, publishableKey);
24204
24880
  } catch {
24205
24881
  }
24206
24882
  };
@@ -24369,11 +25045,11 @@ function WithdrawDoubleInput({
24369
25045
  // src/components/withdrawals/WithdrawForm.tsx
24370
25046
  var import_react30 = require("react");
24371
25047
  var import_lucide_react39 = require("lucide-react");
24372
- var import_core49 = require("@unifold/core");
25048
+ var import_core50 = require("@unifold/core");
24373
25049
 
24374
25050
  // src/hooks/use-verify-recipient-address.ts
24375
- var import_react_query22 = require("@tanstack/react-query");
24376
- var import_core45 = require("@unifold/core");
25051
+ var import_react_query24 = require("@tanstack/react-query");
25052
+ var import_core46 = require("@unifold/core");
24377
25053
  function useVerifyRecipientAddress(params) {
24378
25054
  const {
24379
25055
  chainType,
@@ -24385,7 +25061,7 @@ function useVerifyRecipientAddress(params) {
24385
25061
  } = params;
24386
25062
  const trimmedAddress = recipientAddress?.trim() || "";
24387
25063
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
24388
- return (0, import_react_query22.useQuery)({
25064
+ return (0, import_react_query24.useQuery)({
24389
25065
  queryKey: [
24390
25066
  "unifold",
24391
25067
  "verifyRecipientAddress",
@@ -24395,7 +25071,7 @@ function useVerifyRecipientAddress(params) {
24395
25071
  trimmedAddress,
24396
25072
  publishableKey
24397
25073
  ],
24398
- queryFn: () => (0, import_core45.verifyRecipientAddress)(
25074
+ queryFn: () => (0, import_core46.verifyRecipientAddress)(
24399
25075
  {
24400
25076
  chain_type: chainType,
24401
25077
  chain_id: chainId,
@@ -24414,7 +25090,7 @@ function useVerifyRecipientAddress(params) {
24414
25090
  }
24415
25091
 
24416
25092
  // src/components/withdrawals/send-withdraw.ts
24417
- var import_core46 = require("@unifold/core");
25093
+ var import_core47 = require("@unifold/core");
24418
25094
  async function sendEvmWithdraw(params) {
24419
25095
  const {
24420
25096
  provider,
@@ -24503,7 +25179,7 @@ async function sendSolanaWithdraw(params) {
24503
25179
  if (!provider.publicKey) {
24504
25180
  await provider.connect();
24505
25181
  }
24506
- const buildResponse = await (0, import_core46.buildSolanaTransaction)(
25182
+ const buildResponse = await (0, import_core47.buildSolanaTransaction)(
24507
25183
  {
24508
25184
  chain_id: "mainnet",
24509
25185
  token_address: sourceTokenAddress === "" ? "native" : sourceTokenAddress,
@@ -24529,7 +25205,7 @@ async function sendSolanaWithdraw(params) {
24529
25205
  for (let i = 0; i < serialized.length; i++) {
24530
25206
  binaryStr += String.fromCharCode(serialized[i]);
24531
25207
  }
24532
- const sendResponse = await (0, import_core46.sendSolanaTransaction)(
25208
+ const sendResponse = await (0, import_core47.sendSolanaTransaction)(
24533
25209
  { chain_id: "mainnet", signed_transaction: btoa(binaryStr) },
24534
25210
  publishableKey
24535
25211
  );
@@ -24630,11 +25306,11 @@ async function detectBrowserWallet(chainType, senderAddress) {
24630
25306
 
24631
25307
  // src/hooks/use-hypercore-withdraw-activation.ts
24632
25308
  var import_react29 = require("react");
24633
- var import_core48 = require("@unifold/core");
25309
+ var import_core49 = require("@unifold/core");
24634
25310
 
24635
25311
  // src/hooks/use-get-deposit-address.ts
24636
- var import_react_query23 = require("@tanstack/react-query");
24637
- var import_core47 = require("@unifold/core");
25312
+ var import_react_query25 = require("@tanstack/react-query");
25313
+ var import_core48 = require("@unifold/core");
24638
25314
  function useGetDepositAddress(params) {
24639
25315
  const {
24640
25316
  userId,
@@ -24647,7 +25323,7 @@ function useGetDepositAddress(params) {
24647
25323
  enabled = true
24648
25324
  } = params;
24649
25325
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
24650
- return (0, import_react_query23.useQuery)({
25326
+ return (0, import_react_query25.useQuery)({
24651
25327
  queryKey: [
24652
25328
  "unifold",
24653
25329
  "getDepositAddress",
@@ -24659,7 +25335,7 @@ function useGetDepositAddress(params) {
24659
25335
  actionType ?? null,
24660
25336
  publishableKey
24661
25337
  ],
24662
- queryFn: () => (0, import_core47.getDepositAddress)(
25338
+ queryFn: () => (0, import_core48.getDepositAddress)(
24663
25339
  {
24664
25340
  external_user_id: userId,
24665
25341
  recipient_address: recipientAddress,
@@ -24713,7 +25389,7 @@ function useHypercoreWithdrawActivation(params) {
24713
25389
  destinationChainType,
24714
25390
  destinationChainId,
24715
25391
  destinationTokenAddress,
24716
- actionType: import_core48.ActionType.Withdraw,
25392
+ actionType: import_core49.ActionType.Withdraw,
24717
25393
  enabled: enabled && isHypercore(sourceChainId)
24718
25394
  });
24719
25395
  const depositWalletAddress = (0, import_react29.useMemo)(() => {
@@ -24843,6 +25519,9 @@ function WithdrawForm({
24843
25519
  if (isDebouncing || isVerifyingAddress) return null;
24844
25520
  if (verifyError) return t10.invalidAddress;
24845
25521
  if (addressVerification && !addressVerification.valid) {
25522
+ if (addressVerification.message && addressVerification.message.trim().length > 0) {
25523
+ return addressVerification.message;
25524
+ }
24846
25525
  if (addressVerification.failure_code === "account_not_found")
24847
25526
  return `Account not found on ${selectedChain?.chain_name}`;
24848
25527
  if (addressVerification.failure_code === "not_opted_in")
@@ -25004,7 +25683,7 @@ function WithdrawForm({
25004
25683
  let humanAmount = isMaxed ? balanceData.balanceHuman : toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
25005
25684
  if (isHypercoreChain(sourceChainId)) {
25006
25685
  try {
25007
- const check = await (0, import_core49.checkHypercoreActivation)(
25686
+ const check = await (0, import_core50.checkHypercoreActivation)(
25008
25687
  {
25009
25688
  source_address: senderAddress,
25010
25689
  recipient_address: depositWallet.address
@@ -25453,11 +26132,11 @@ function WithdrawForm({
25453
26132
 
25454
26133
  // src/components/withdrawals/WithdrawExecutionItem.tsx
25455
26134
  var import_lucide_react40 = require("lucide-react");
25456
- var import_core50 = require("@unifold/core");
26135
+ var import_core51 = require("@unifold/core");
25457
26136
  var import_jsx_runtime67 = require("react/jsx-runtime");
25458
26137
  function WithdrawExecutionItem({ execution, onClick }) {
25459
26138
  const { colors: colors2, fonts, components } = useTheme();
25460
- const isPending = execution.status === import_core50.ExecutionStatus.PENDING || execution.status === import_core50.ExecutionStatus.WAITING || execution.status === import_core50.ExecutionStatus.DELAYED;
26139
+ const isPending = execution.status === import_core51.ExecutionStatus.PENDING || execution.status === import_core51.ExecutionStatus.WAITING || execution.status === import_core51.ExecutionStatus.DELAYED;
25461
26140
  const formatDateTime = (timestamp) => {
25462
26141
  try {
25463
26142
  const date = new Date(timestamp);
@@ -25504,7 +26183,7 @@ function WithdrawExecutionItem({ execution, onClick }) {
25504
26183
  /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
25505
26184
  "img",
25506
26185
  {
25507
- src: execution.destination_token_metadata?.icon_url || (0, import_core50.getIconUrl)("/icons/tokens/svg/usdc.svg"),
26186
+ src: execution.destination_token_metadata?.icon_url || (0, import_core51.getIconUrl)("/icons/tokens/svg/usdc.svg"),
25508
26187
  alt: "Token",
25509
26188
  width: 36,
25510
26189
  height: 36,
@@ -25740,7 +26419,7 @@ function WithdrawConfirmingView({
25740
26419
  }
25741
26420
 
25742
26421
  // src/components/withdrawals/WithdrawModal.tsx
25743
- var import_core51 = require("@unifold/core");
26422
+ var import_core52 = require("@unifold/core");
25744
26423
  var import_jsx_runtime69 = require("react/jsx-runtime");
25745
26424
  var t11 = i18n.withdrawModal;
25746
26425
  var getChainKey5 = (chainId, chainType) => `${chainType}:${chainId}`;
@@ -25846,26 +26525,26 @@ function WithdrawModal({
25846
26525
  onWithdrawError
25847
26526
  });
25848
26527
  const { data: allWithdrawalsData } = useExecutions(externalUserId, publishableKey, {
25849
- actionType: import_core51.ActionType.Withdraw,
26528
+ actionType: import_core52.ActionType.Withdraw,
25850
26529
  enabled: open,
25851
26530
  refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
25852
26531
  });
25853
26532
  const allWithdrawals = allWithdrawalsData?.data ?? [];
25854
26533
  const handleDepositWalletCreation = (0, import_react32.useCallback)(
25855
26534
  async (params) => {
25856
- const { data: wallets } = await (0, import_core51.createDepositAddress)(
26535
+ const { data: wallets } = await (0, import_core52.createDepositAddress)(
25857
26536
  {
25858
26537
  external_user_id: externalUserId,
25859
26538
  destination_chain_type: params.destinationChainType,
25860
26539
  destination_chain_id: params.destinationChainId,
25861
26540
  destination_token_address: params.destinationTokenAddress,
25862
26541
  recipient_address: params.recipientAddress,
25863
- action_type: import_core51.ActionType.Withdraw,
26542
+ action_type: import_core52.ActionType.Withdraw,
25864
26543
  source_chain_type: sourceChainType
25865
26544
  },
25866
26545
  publishableKey
25867
26546
  );
25868
- const depositWallet = (0, import_core51.getWalletByChainType)(wallets, sourceChainType);
26547
+ const depositWallet = (0, import_core52.getWalletByChainType)(wallets, sourceChainType);
25869
26548
  if (!depositWallet) {
25870
26549
  throw new Error(`No deposit wallet available for ${sourceChainType}`);
25871
26550
  }
@@ -26390,6 +27069,7 @@ function WithdrawTokenSelector({ tokens, onSelect, onBack }) {
26390
27069
  useDepositPolling,
26391
27070
  useDepositQuote,
26392
27071
  usePaymentIntent,
27072
+ usePublicIncident,
26393
27073
  useSourceTokenValidation,
26394
27074
  useSupportedDepositTokens,
26395
27075
  useSupportedDestinationTokens,