@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.d.mts +75 -23
- package/dist/index.d.ts +75 -23
- package/dist/index.js +1167 -487
- package/dist/index.mjs +1255 -572
- package/dist/styles-base.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
useState as useState40,
|
|
4
4
|
useEffect as useEffect34,
|
|
5
5
|
useLayoutEffect as useLayoutEffect2,
|
|
6
|
-
useCallback as
|
|
7
|
-
useRef as
|
|
8
|
-
useMemo as
|
|
6
|
+
useCallback as useCallback11,
|
|
7
|
+
useRef as useRef13,
|
|
8
|
+
useMemo as useMemo14
|
|
9
9
|
} from "react";
|
|
10
|
-
import { ChevronRight as ChevronRight18, MapPinOff as MapPinOff2, AlertTriangle as
|
|
10
|
+
import { ChevronRight as ChevronRight18, MapPinOff as MapPinOff2, AlertTriangle as AlertTriangle4, Bitcoin, DollarSign as DollarSign3 } from "lucide-react";
|
|
11
11
|
|
|
12
12
|
// src/components/shared/dialog.tsx
|
|
13
13
|
import * as React3 from "react";
|
|
@@ -579,13 +579,16 @@ function GeoRestrictionScreen({ methodName, message }) {
|
|
|
579
579
|
}
|
|
580
580
|
|
|
581
581
|
// src/components/deposits/BuyWithCard.tsx
|
|
582
|
+
import * as React5 from "react";
|
|
582
583
|
import { useState as useState10, useEffect as useEffect6, useRef as useRef2 } from "react";
|
|
584
|
+
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
583
585
|
import { ChevronDown as ChevronDown2, ChevronRight } from "lucide-react";
|
|
584
586
|
import {
|
|
585
587
|
getOnrampQuotes,
|
|
586
588
|
getOnrampSessionStartUrl,
|
|
587
589
|
getWalletByChainType,
|
|
588
590
|
getFiatCurrencies,
|
|
591
|
+
getFiatExchangeRates,
|
|
589
592
|
getTokenMetadata,
|
|
590
593
|
getIconUrlWithCdn,
|
|
591
594
|
getPreferredIconUrl as getPreferredIconUrl2,
|
|
@@ -597,7 +600,8 @@ import {
|
|
|
597
600
|
// src/hooks/use-deposit-address.ts
|
|
598
601
|
import { useQuery } from "@tanstack/react-query";
|
|
599
602
|
import {
|
|
600
|
-
createDepositAddress
|
|
603
|
+
createDepositAddress,
|
|
604
|
+
isDepositAddressValidationError
|
|
601
605
|
} from "@unifold/core";
|
|
602
606
|
function useDepositAddress(params) {
|
|
603
607
|
const {
|
|
@@ -643,7 +647,13 @@ function useDepositAddress(params) {
|
|
|
643
647
|
// 24 hours in cache
|
|
644
648
|
refetchOnMount: false,
|
|
645
649
|
refetchOnWindowFocus: false,
|
|
646
|
-
retry
|
|
650
|
+
// Don't retry recipient-address validation errors — they're deterministic
|
|
651
|
+
// (a 400 won't succeed on retry) and we want to surface the invalid-address
|
|
652
|
+
// screen immediately rather than after 3 backoff attempts.
|
|
653
|
+
retry: (failureCount, error) => {
|
|
654
|
+
if (isDepositAddressValidationError(error)) return false;
|
|
655
|
+
return failureCount < 3;
|
|
656
|
+
},
|
|
647
657
|
retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
|
|
648
658
|
// 1s, 2s, 4s (max 10s)
|
|
649
659
|
});
|
|
@@ -664,7 +674,7 @@ function useDebounce(value, delay) {
|
|
|
664
674
|
import { useState as useState5 } from "react";
|
|
665
675
|
|
|
666
676
|
// src/components/deposits/DepositHeader.tsx
|
|
667
|
-
import { ArrowLeft, X as X2 } from "lucide-react";
|
|
677
|
+
import { AlertTriangle, ArrowLeft, Info, X as X2 } from "lucide-react";
|
|
668
678
|
import { useEffect as useEffect3, useLayoutEffect, useState as useState3 } from "react";
|
|
669
679
|
import { getAddressBalance } from "@unifold/core";
|
|
670
680
|
|
|
@@ -870,7 +880,8 @@ function DepositHeader({
|
|
|
870
880
|
balanceChainId,
|
|
871
881
|
balanceTokenAddress,
|
|
872
882
|
projectName,
|
|
873
|
-
publishableKey
|
|
883
|
+
publishableKey,
|
|
884
|
+
incident
|
|
874
885
|
}) {
|
|
875
886
|
const { colors: colors2, fonts, components } = useTheme();
|
|
876
887
|
const [balance, setBalance] = useState3(null);
|
|
@@ -968,19 +979,64 @@ function DepositHeader({
|
|
|
968
979
|
balanceTokenAddress,
|
|
969
980
|
publishableKey
|
|
970
981
|
]);
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
982
|
+
const incidentMessages = incident?.messages ?? [];
|
|
983
|
+
const showIncident = incident?.enabled && incidentMessages.length > 0;
|
|
984
|
+
const incidentSeverity = incident?.severity ?? "degraded";
|
|
985
|
+
const incidentSeverityLabel = incidentSeverity === "outage" ? "Outage" : incidentSeverity === "info" ? "Info" : "Degraded service";
|
|
986
|
+
const incidentStyles = incidentSeverity === "outage" ? {
|
|
987
|
+
bg: "rgba(239, 68, 68, 0.12)",
|
|
988
|
+
border: "rgba(239, 68, 68, 0.35)",
|
|
989
|
+
text: "#fca5a5",
|
|
990
|
+
link: "#fca5a5"
|
|
991
|
+
} : incidentSeverity === "info" ? {
|
|
992
|
+
bg: "rgba(59, 130, 246, 0.12)",
|
|
993
|
+
border: "rgba(59, 130, 246, 0.35)",
|
|
994
|
+
text: "#93c5fd",
|
|
995
|
+
link: "#93c5fd"
|
|
996
|
+
} : {
|
|
997
|
+
bg: "rgba(245, 158, 11, 0.12)",
|
|
998
|
+
border: "rgba(245, 158, 11, 0.35)",
|
|
999
|
+
text: "#fcd34d",
|
|
1000
|
+
link: "#fcd34d"
|
|
1001
|
+
};
|
|
1002
|
+
const IncidentIcon = incidentSeverity === "info" ? Info : AlertTriangle;
|
|
1003
|
+
return /* @__PURE__ */ jsxs3("div", { children: [
|
|
1004
|
+
/* @__PURE__ */ jsxs3("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-6", children: [
|
|
1005
|
+
showBack ? /* @__PURE__ */ jsx4(
|
|
1006
|
+
"button",
|
|
1007
|
+
{
|
|
1008
|
+
onClick: onBack,
|
|
1009
|
+
className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
|
|
1010
|
+
style: { color: components.header.buttonColor },
|
|
1011
|
+
children: /* @__PURE__ */ jsx4(ArrowLeft, { className: "uf-w-5 uf-h-5" })
|
|
1012
|
+
}
|
|
1013
|
+
) : /* @__PURE__ */ jsx4("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
|
|
1014
|
+
/* @__PURE__ */ jsxs3("div", { className: "uf-flex uf-flex-col uf-items-center", children: [
|
|
1015
|
+
badge ? /* @__PURE__ */ jsxs3("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
|
|
1016
|
+
/* @__PURE__ */ jsx4(
|
|
1017
|
+
DialogTitle,
|
|
1018
|
+
{
|
|
1019
|
+
className: "uf-text-center uf-text-base",
|
|
1020
|
+
style: {
|
|
1021
|
+
color: components.header.titleColor,
|
|
1022
|
+
fontFamily: fonts.medium
|
|
1023
|
+
},
|
|
1024
|
+
children: title
|
|
1025
|
+
}
|
|
1026
|
+
),
|
|
1027
|
+
/* @__PURE__ */ jsx4(
|
|
1028
|
+
"div",
|
|
1029
|
+
{
|
|
1030
|
+
className: "uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px]",
|
|
1031
|
+
style: {
|
|
1032
|
+
backgroundColor: colors2.card,
|
|
1033
|
+
color: colors2.foregroundMuted,
|
|
1034
|
+
fontFamily: fonts.regular
|
|
1035
|
+
},
|
|
1036
|
+
children: badge.count
|
|
1037
|
+
}
|
|
1038
|
+
)
|
|
1039
|
+
] }) : /* @__PURE__ */ jsx4(
|
|
984
1040
|
DialogTitle,
|
|
985
1041
|
{
|
|
986
1042
|
className: "uf-text-center uf-text-base",
|
|
@@ -991,61 +1047,91 @@ function DepositHeader({
|
|
|
991
1047
|
children: title
|
|
992
1048
|
}
|
|
993
1049
|
),
|
|
994
|
-
/* @__PURE__ */ jsx4(
|
|
1050
|
+
subtitle ? /* @__PURE__ */ jsx4(
|
|
995
1051
|
"div",
|
|
996
1052
|
{
|
|
997
|
-
className: "uf-
|
|
1053
|
+
className: "uf-text-xs uf-mt-1",
|
|
998
1054
|
style: {
|
|
999
|
-
backgroundColor: colors2.card,
|
|
1000
1055
|
color: colors2.foregroundMuted,
|
|
1001
1056
|
fontFamily: fonts.regular
|
|
1002
1057
|
},
|
|
1003
|
-
children:
|
|
1058
|
+
children: subtitle
|
|
1004
1059
|
}
|
|
1005
|
-
)
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
),
|
|
1017
|
-
|
|
1018
|
-
"
|
|
1060
|
+
) : showBalanceBlock ? isLoadingBalance && showBalanceSkeleton ? /* @__PURE__ */ jsx4("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-1" }) : balance ? /* @__PURE__ */ jsx4(
|
|
1061
|
+
"div",
|
|
1062
|
+
{
|
|
1063
|
+
className: "uf-text-xs uf-mt-1",
|
|
1064
|
+
style: {
|
|
1065
|
+
color: colors2.foregroundMuted,
|
|
1066
|
+
fontFamily: fonts.regular
|
|
1067
|
+
},
|
|
1068
|
+
children: formatBalanceDisplay(balance, projectName)
|
|
1069
|
+
}
|
|
1070
|
+
) : null : null
|
|
1071
|
+
] }),
|
|
1072
|
+
showClose ? /* @__PURE__ */ jsx4(
|
|
1073
|
+
"button",
|
|
1019
1074
|
{
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
},
|
|
1025
|
-
children: subtitle
|
|
1075
|
+
onClick: onClose,
|
|
1076
|
+
className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
|
|
1077
|
+
style: { color: components.header.buttonColor },
|
|
1078
|
+
children: /* @__PURE__ */ jsx4(X2, { className: "uf-w-5 uf-h-5" })
|
|
1026
1079
|
}
|
|
1027
|
-
) :
|
|
1028
|
-
"div",
|
|
1029
|
-
{
|
|
1030
|
-
className: "uf-text-xs uf-mt-1",
|
|
1031
|
-
style: {
|
|
1032
|
-
color: colors2.foregroundMuted,
|
|
1033
|
-
fontFamily: fonts.regular
|
|
1034
|
-
},
|
|
1035
|
-
children: formatBalanceDisplay(balance, projectName)
|
|
1036
|
-
}
|
|
1037
|
-
) : null : null
|
|
1080
|
+
) : /* @__PURE__ */ jsx4("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
|
|
1038
1081
|
] }),
|
|
1039
|
-
|
|
1040
|
-
"
|
|
1082
|
+
showIncident && /* @__PURE__ */ jsx4(
|
|
1083
|
+
"div",
|
|
1041
1084
|
{
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1085
|
+
className: "uf-rounded-lg uf-px-3 uf-py-2.5 uf-mb-4",
|
|
1086
|
+
style: {
|
|
1087
|
+
backgroundColor: incidentStyles.bg,
|
|
1088
|
+
border: `1px solid ${incidentStyles.border}`
|
|
1089
|
+
},
|
|
1090
|
+
children: /* @__PURE__ */ jsxs3("div", { className: "uf-flex uf-items-start uf-gap-2.5", children: [
|
|
1091
|
+
/* @__PURE__ */ jsx4(
|
|
1092
|
+
IncidentIcon,
|
|
1093
|
+
{
|
|
1094
|
+
className: "uf-w-4 uf-h-4 uf-mt-0.5 uf-shrink-0",
|
|
1095
|
+
style: { color: incidentStyles.text }
|
|
1096
|
+
}
|
|
1097
|
+
),
|
|
1098
|
+
/* @__PURE__ */ jsxs3("div", { className: "uf-min-w-0 uf-flex-1", children: [
|
|
1099
|
+
/* @__PURE__ */ jsx4("div", { className: "uf-flex uf-items-center uf-gap-2 uf-mb-1.5", children: /* @__PURE__ */ jsx4(
|
|
1100
|
+
"span",
|
|
1101
|
+
{
|
|
1102
|
+
className: "uf-text-[11px] uf-leading-none uf-px-1.5 uf-py-1 uf-rounded-md",
|
|
1103
|
+
style: {
|
|
1104
|
+
color: incidentStyles.text,
|
|
1105
|
+
border: `1px solid ${incidentStyles.border}`,
|
|
1106
|
+
fontFamily: fonts.medium
|
|
1107
|
+
},
|
|
1108
|
+
children: incidentSeverityLabel
|
|
1109
|
+
}
|
|
1110
|
+
) }),
|
|
1111
|
+
/* @__PURE__ */ jsx4(
|
|
1112
|
+
"div",
|
|
1113
|
+
{
|
|
1114
|
+
className: "uf-space-y-1",
|
|
1115
|
+
style: { color: incidentStyles.text, fontFamily: fonts.regular },
|
|
1116
|
+
children: incidentMessages.map((message, index) => /* @__PURE__ */ jsx4("p", { className: "uf-text-xs uf-leading-relaxed", children: message }, `${message}-${index}`))
|
|
1117
|
+
}
|
|
1118
|
+
),
|
|
1119
|
+
incident.statusPageUrl && /* @__PURE__ */ jsx4(
|
|
1120
|
+
"a",
|
|
1121
|
+
{
|
|
1122
|
+
href: incident.statusPageUrl,
|
|
1123
|
+
target: "_blank",
|
|
1124
|
+
rel: "noreferrer",
|
|
1125
|
+
className: "uf-inline-block uf-mt-1.5 uf-text-xs uf-underline uf-underline-offset-2",
|
|
1126
|
+
style: { color: incidentStyles.link, fontFamily: fonts.medium },
|
|
1127
|
+
children: "View status"
|
|
1128
|
+
}
|
|
1129
|
+
)
|
|
1130
|
+
] })
|
|
1131
|
+
] })
|
|
1046
1132
|
}
|
|
1047
|
-
)
|
|
1048
|
-
] })
|
|
1133
|
+
)
|
|
1134
|
+
] });
|
|
1049
1135
|
}
|
|
1050
1136
|
|
|
1051
1137
|
// src/components/currency/CurrencyListItem.tsx
|
|
@@ -1383,7 +1469,8 @@ var en_default = {
|
|
|
1383
1469
|
},
|
|
1384
1470
|
stripeLink: {
|
|
1385
1471
|
title: "Pay with Link",
|
|
1386
|
-
subtitle: "Buy with card or bank"
|
|
1472
|
+
subtitle: "Buy with card or bank",
|
|
1473
|
+
unavailableInRegionMessage: "Pay with Link is currently unavailable in your region."
|
|
1387
1474
|
},
|
|
1388
1475
|
browserWallet: {
|
|
1389
1476
|
title: "Connect Wallet",
|
|
@@ -2595,13 +2682,25 @@ function BuyWithCard({
|
|
|
2595
2682
|
wallets: externalWallets,
|
|
2596
2683
|
assetCdnUrl,
|
|
2597
2684
|
hideDepositFlowInfo = false,
|
|
2598
|
-
hideDisplayDescription = false
|
|
2685
|
+
hideDisplayDescription = false,
|
|
2686
|
+
prefilledAmountUsd
|
|
2599
2687
|
}) {
|
|
2600
2688
|
const { colors: colors2, fonts, components } = useTheme();
|
|
2601
|
-
const
|
|
2689
|
+
const cleanedPrefilledAmountUsd = React5.useMemo(() => {
|
|
2690
|
+
if (!prefilledAmountUsd) return "";
|
|
2691
|
+
return prefilledAmountUsd.replace(/[^0-9.]/g, "");
|
|
2692
|
+
}, [prefilledAmountUsd]);
|
|
2693
|
+
const parsedPrefilledAmountUsd = React5.useMemo(() => {
|
|
2694
|
+
const parsed = parseFloat(cleanedPrefilledAmountUsd);
|
|
2695
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
2696
|
+
}, [cleanedPrefilledAmountUsd]);
|
|
2697
|
+
const shouldAutoConvertPrefilledRef = useRef2(!!cleanedPrefilledAmountUsd);
|
|
2698
|
+
const [amount, setAmount] = useState10(() => cleanedPrefilledAmountUsd);
|
|
2602
2699
|
const [currency, setCurrency] = useState10("usd");
|
|
2603
2700
|
const [hasManualCurrencySelection, setHasManualCurrencySelection] = useState10(false);
|
|
2604
|
-
const [hasManualAmountEntry, setHasManualAmountEntry] = useState10(
|
|
2701
|
+
const [hasManualAmountEntry, setHasManualAmountEntry] = useState10(
|
|
2702
|
+
() => !!cleanedPrefilledAmountUsd
|
|
2703
|
+
);
|
|
2605
2704
|
const [showCurrencyModal, setShowCurrencyModal] = useState10(false);
|
|
2606
2705
|
const [quotes, setQuotes] = useState10([]);
|
|
2607
2706
|
const [quotesLoading, setQuotesLoading] = useState10(false);
|
|
@@ -2658,6 +2757,71 @@ function BuyWithCard({
|
|
|
2658
2757
|
const [preferredCurrencyCodes, setPreferredCurrencyCodes] = useState10([]);
|
|
2659
2758
|
const [currenciesLoading, setCurrenciesLoading] = useState10(true);
|
|
2660
2759
|
const [destinationToken, setDestinationToken] = useState10(null);
|
|
2760
|
+
useEffect6(() => {
|
|
2761
|
+
const hasPrefilledAmount = !!cleanedPrefilledAmountUsd;
|
|
2762
|
+
shouldAutoConvertPrefilledRef.current = hasPrefilledAmount;
|
|
2763
|
+
if (!hasPrefilledAmount) return;
|
|
2764
|
+
setAmount(cleanedPrefilledAmountUsd);
|
|
2765
|
+
setHasManualAmountEntry(true);
|
|
2766
|
+
}, [cleanedPrefilledAmountUsd]);
|
|
2767
|
+
const { data: fiatExchangeRatesResponse, isLoading: isFiatExchangeRatesLoading } = useQuery3({
|
|
2768
|
+
queryKey: ["fiat-exchange-rates", publishableKey],
|
|
2769
|
+
staleTime: 3e4,
|
|
2770
|
+
refetchInterval: 3e4,
|
|
2771
|
+
queryFn: async () => {
|
|
2772
|
+
try {
|
|
2773
|
+
return await getFiatExchangeRates({}, publishableKey);
|
|
2774
|
+
} catch (error) {
|
|
2775
|
+
console.error("Error fetching fiat exchange rates:", error);
|
|
2776
|
+
return { base_currency: "usd", rates: {} };
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
});
|
|
2780
|
+
const fiatExchangeRates = fiatExchangeRatesResponse?.rates ?? {};
|
|
2781
|
+
const convertAmountBetweenCurrencies = React5.useCallback(
|
|
2782
|
+
(rawAmount, fromCurrencyCode, toCurrencyCode) => {
|
|
2783
|
+
const parsedAmount = parseFloat(rawAmount);
|
|
2784
|
+
if (!Number.isFinite(parsedAmount) || parsedAmount <= 0) return null;
|
|
2785
|
+
const fromCode = fromCurrencyCode.toLowerCase();
|
|
2786
|
+
const toCode = toCurrencyCode.toLowerCase();
|
|
2787
|
+
const fromRate = fromCode === "usd" ? 1 : fiatExchangeRates[fromCode];
|
|
2788
|
+
const toRate = toCode === "usd" ? 1 : fiatExchangeRates[toCode];
|
|
2789
|
+
if (!Number.isFinite(fromRate) || fromRate <= 0) return null;
|
|
2790
|
+
if (!Number.isFinite(toRate) || toRate <= 0) return null;
|
|
2791
|
+
const usdAmount = parsedAmount / fromRate;
|
|
2792
|
+
return parseFloat((usdAmount * toRate).toFixed(2)).toString();
|
|
2793
|
+
},
|
|
2794
|
+
[fiatExchangeRates]
|
|
2795
|
+
);
|
|
2796
|
+
const getConvertedPrefilledAmount = React5.useCallback(
|
|
2797
|
+
(targetCurrencyCode) => {
|
|
2798
|
+
if (!parsedPrefilledAmountUsd) return null;
|
|
2799
|
+
const normalizedTargetCurrency = targetCurrencyCode.toLowerCase();
|
|
2800
|
+
const rate = normalizedTargetCurrency === "usd" ? 1 : fiatExchangeRates[normalizedTargetCurrency];
|
|
2801
|
+
if (!Number.isFinite(rate) || rate <= 0) return null;
|
|
2802
|
+
return parseFloat((parsedPrefilledAmountUsd * rate).toFixed(2)).toString();
|
|
2803
|
+
},
|
|
2804
|
+
[parsedPrefilledAmountUsd, fiatExchangeRates]
|
|
2805
|
+
);
|
|
2806
|
+
useEffect6(() => {
|
|
2807
|
+
if (!cleanedPrefilledAmountUsd || !shouldAutoConvertPrefilledRef.current) return;
|
|
2808
|
+
const convertedAmount = getConvertedPrefilledAmount(currency);
|
|
2809
|
+
if (!convertedAmount) {
|
|
2810
|
+
if (isFiatExchangeRatesLoading) return;
|
|
2811
|
+
const targetCurrency = currency.toLowerCase();
|
|
2812
|
+
if (targetCurrency !== "usd") {
|
|
2813
|
+
setCurrency("usd");
|
|
2814
|
+
}
|
|
2815
|
+
return;
|
|
2816
|
+
}
|
|
2817
|
+
setAmount(convertedAmount);
|
|
2818
|
+
setHasManualAmountEntry(true);
|
|
2819
|
+
}, [
|
|
2820
|
+
cleanedPrefilledAmountUsd,
|
|
2821
|
+
currency,
|
|
2822
|
+
getConvertedPrefilledAmount,
|
|
2823
|
+
isFiatExchangeRatesLoading
|
|
2824
|
+
]);
|
|
2661
2825
|
const depositWalletId = defaultToken ? getWalletByChainType(wallets, defaultToken.destination_token_metadata.chain_type)?.id : void 0;
|
|
2662
2826
|
const { executions, isPolling, showWaitingUi } = useDepositPolling({
|
|
2663
2827
|
userId,
|
|
@@ -2688,6 +2852,7 @@ function BuyWithCard({
|
|
|
2688
2852
|
}, [publishableKey]);
|
|
2689
2853
|
useEffect6(() => {
|
|
2690
2854
|
if (hasManualCurrencySelection) return;
|
|
2855
|
+
if (hasManualAmountEntry && !shouldAutoConvertPrefilledRef.current) return;
|
|
2691
2856
|
if (fiatCurrencies.length === 0 || !userIpInfo?.alpha2) return;
|
|
2692
2857
|
const userCountryCode = userIpInfo.alpha2;
|
|
2693
2858
|
const matchingCurrency = fiatCurrencies.find((c) => c.country_codes.includes(userCountryCode));
|
|
@@ -2706,7 +2871,15 @@ function BuyWithCard({
|
|
|
2706
2871
|
const prevCurrencyRef = useRef2(null);
|
|
2707
2872
|
useEffect6(() => {
|
|
2708
2873
|
if (fiatCurrencies.length === 0) return;
|
|
2874
|
+
if (shouldAutoConvertPrefilledRef.current) {
|
|
2875
|
+
prevCurrencyRef.current = currency;
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2709
2878
|
if (prevCurrencyRef.current !== null && prevCurrencyRef.current !== currency) {
|
|
2879
|
+
if (hasManualAmountEntry) {
|
|
2880
|
+
prevCurrencyRef.current = currency;
|
|
2881
|
+
return;
|
|
2882
|
+
}
|
|
2710
2883
|
const currentCurrency = fiatCurrencies.find(
|
|
2711
2884
|
(c) => c.currency_code.toLowerCase() === currency.toLowerCase()
|
|
2712
2885
|
);
|
|
@@ -2715,7 +2888,7 @@ function BuyWithCard({
|
|
|
2715
2888
|
}
|
|
2716
2889
|
}
|
|
2717
2890
|
prevCurrencyRef.current = currency;
|
|
2718
|
-
}, [currency]);
|
|
2891
|
+
}, [currency, fiatCurrencies, hasManualAmountEntry]);
|
|
2719
2892
|
useEffect6(() => {
|
|
2720
2893
|
async function fetchDestinationToken() {
|
|
2721
2894
|
try {
|
|
@@ -2892,6 +3065,7 @@ function BuyWithCard({
|
|
|
2892
3065
|
return () => clearInterval(timer);
|
|
2893
3066
|
}, [quotes.length, amount]);
|
|
2894
3067
|
const handleAmountChange = (value) => {
|
|
3068
|
+
shouldAutoConvertPrefilledRef.current = false;
|
|
2895
3069
|
if (value === "") {
|
|
2896
3070
|
setAmount(value);
|
|
2897
3071
|
setHasManualAmountEntry(true);
|
|
@@ -2905,6 +3079,7 @@ function BuyWithCard({
|
|
|
2905
3079
|
}
|
|
2906
3080
|
};
|
|
2907
3081
|
const handleQuickAmount = (quickAmount) => {
|
|
3082
|
+
shouldAutoConvertPrefilledRef.current = false;
|
|
2908
3083
|
setAmount(quickAmount.toString());
|
|
2909
3084
|
setHasManualAmountEntry(true);
|
|
2910
3085
|
};
|
|
@@ -3508,8 +3683,43 @@ function BuyWithCard({
|
|
|
3508
3683
|
preferredCurrencyCodes,
|
|
3509
3684
|
selectedCurrency: currency,
|
|
3510
3685
|
onSelectCurrency: (currencyCode) => {
|
|
3511
|
-
|
|
3686
|
+
const nextCurrency = currencyCode.toLowerCase();
|
|
3687
|
+
if (nextCurrency === currency.toLowerCase()) {
|
|
3688
|
+
setHasManualCurrencySelection(true);
|
|
3689
|
+
return;
|
|
3690
|
+
}
|
|
3691
|
+
const currentCurrency = currency;
|
|
3512
3692
|
setHasManualCurrencySelection(true);
|
|
3693
|
+
if (shouldAutoConvertPrefilledRef.current) {
|
|
3694
|
+
const convertedAmount = getConvertedPrefilledAmount(nextCurrency);
|
|
3695
|
+
if (convertedAmount) {
|
|
3696
|
+
setCurrency(nextCurrency);
|
|
3697
|
+
setAmount(convertedAmount);
|
|
3698
|
+
setHasManualAmountEntry(true);
|
|
3699
|
+
} else {
|
|
3700
|
+
if (isFiatExchangeRatesLoading) return;
|
|
3701
|
+
const fallbackUsdAmount = getConvertedPrefilledAmount("usd");
|
|
3702
|
+
setCurrency("usd");
|
|
3703
|
+
if (fallbackUsdAmount) {
|
|
3704
|
+
setAmount(fallbackUsdAmount);
|
|
3705
|
+
setHasManualAmountEntry(true);
|
|
3706
|
+
}
|
|
3707
|
+
}
|
|
3708
|
+
return;
|
|
3709
|
+
}
|
|
3710
|
+
if (hasManualAmountEntry && amount) {
|
|
3711
|
+
const convertedAmount = convertAmountBetweenCurrencies(
|
|
3712
|
+
amount,
|
|
3713
|
+
currentCurrency,
|
|
3714
|
+
nextCurrency
|
|
3715
|
+
);
|
|
3716
|
+
if (convertedAmount) {
|
|
3717
|
+
setCurrency(nextCurrency);
|
|
3718
|
+
setAmount(convertedAmount);
|
|
3719
|
+
}
|
|
3720
|
+
return;
|
|
3721
|
+
}
|
|
3722
|
+
setCurrency(nextCurrency);
|
|
3513
3723
|
},
|
|
3514
3724
|
themeClass
|
|
3515
3725
|
}
|
|
@@ -3528,8 +3738,8 @@ function BuyWithCard({
|
|
|
3528
3738
|
}
|
|
3529
3739
|
|
|
3530
3740
|
// src/components/deposits/BuyWithApplePay.tsx
|
|
3531
|
-
import * as
|
|
3532
|
-
import { useCallback, useEffect as useEffect7, useMemo as
|
|
3741
|
+
import * as React6 from "react";
|
|
3742
|
+
import { useCallback as useCallback2, useEffect as useEffect7, useMemo as useMemo4, useRef as useRef3, useState as useState11 } from "react";
|
|
3533
3743
|
import { Loader2 as Loader22 } from "lucide-react";
|
|
3534
3744
|
import {
|
|
3535
3745
|
createCoinbaseApplePaySession,
|
|
@@ -3586,13 +3796,13 @@ function isOnrampTokenFresh(contact) {
|
|
|
3586
3796
|
}
|
|
3587
3797
|
|
|
3588
3798
|
// src/hooks/use-coinbase-legal-agreements.ts
|
|
3589
|
-
import { useQuery as
|
|
3799
|
+
import { useQuery as useQuery4 } from "@tanstack/react-query";
|
|
3590
3800
|
import { getCoinbaseLegalAgreements } from "@unifold/core";
|
|
3591
3801
|
function useCoinbaseLegalAgreements({
|
|
3592
3802
|
publishableKey,
|
|
3593
3803
|
enabled = true
|
|
3594
3804
|
}) {
|
|
3595
|
-
return
|
|
3805
|
+
return useQuery4({
|
|
3596
3806
|
queryKey: ["unifold", "coinbaseLegalAgreements", publishableKey],
|
|
3597
3807
|
queryFn: () => getCoinbaseLegalAgreements(publishableKey),
|
|
3598
3808
|
enabled: enabled && !!publishableKey,
|
|
@@ -3605,10 +3815,10 @@ function useCoinbaseLegalAgreements({
|
|
|
3605
3815
|
}
|
|
3606
3816
|
|
|
3607
3817
|
// src/hooks/use-apple-pay-initial-screen.ts
|
|
3608
|
-
import { useMemo as
|
|
3818
|
+
import { useMemo as useMemo3 } from "react";
|
|
3609
3819
|
|
|
3610
3820
|
// src/hooks/use-apple-pay-limits.ts
|
|
3611
|
-
import { useQuery as
|
|
3821
|
+
import { useQuery as useQuery5 } from "@tanstack/react-query";
|
|
3612
3822
|
import { getCoinbaseApplePayLimits } from "@unifold/core";
|
|
3613
3823
|
var US_E164_REGEX = /^\+1\d{10}$/;
|
|
3614
3824
|
function useApplePayLimits({
|
|
@@ -3617,7 +3827,7 @@ function useApplePayLimits({
|
|
|
3617
3827
|
enabled = true
|
|
3618
3828
|
}) {
|
|
3619
3829
|
const phoneValid = US_E164_REGEX.test(phone);
|
|
3620
|
-
return
|
|
3830
|
+
return useQuery5({
|
|
3621
3831
|
queryKey: ["unifold", "applePayLimits", phone, publishableKey],
|
|
3622
3832
|
queryFn: ({ signal }) => getCoinbaseApplePayLimits(phone, publishableKey, signal),
|
|
3623
3833
|
enabled: enabled && phoneValid && !!publishableKey,
|
|
@@ -3658,7 +3868,7 @@ function useApplePayInitialScreen({
|
|
|
3658
3868
|
sessionPhoneVerified,
|
|
3659
3869
|
isWaiting
|
|
3660
3870
|
}) {
|
|
3661
|
-
const initialStoredSession =
|
|
3871
|
+
const initialStoredSession = useMemo3(() => getStoredApplePaySession(userId), [userId]);
|
|
3662
3872
|
const phoneVerified = PHONE_REGEX.test(normalizedPhone) && (sessionPhoneVerified || initialStoredSession?.phone === normalizedPhone && !!initialStoredSession?.phoneVerifiedAt);
|
|
3663
3873
|
const {
|
|
3664
3874
|
data: applePayLimits,
|
|
@@ -3669,7 +3879,7 @@ function useApplePayInitialScreen({
|
|
|
3669
3879
|
publishableKey,
|
|
3670
3880
|
enabled: phoneVerified
|
|
3671
3881
|
});
|
|
3672
|
-
const action =
|
|
3882
|
+
const action = useMemo3(() => {
|
|
3673
3883
|
if (isWaiting || applePayLimitsLoading) return { kind: "pending" };
|
|
3674
3884
|
const stored = initialStoredSession;
|
|
3675
3885
|
const hasUserEmail = !!userEmail && EMAIL_REGEX.test(userEmail);
|
|
@@ -3707,7 +3917,7 @@ function useApplePayInitialScreen({
|
|
|
3707
3917
|
}
|
|
3708
3918
|
|
|
3709
3919
|
// src/hooks/use-default-onramp-token.ts
|
|
3710
|
-
import { useQuery as
|
|
3920
|
+
import { useQuery as useQuery6 } from "@tanstack/react-query";
|
|
3711
3921
|
import { getDefaultOnrampToken as getDefaultOnrampToken2 } from "@unifold/core";
|
|
3712
3922
|
function useDefaultOnrampToken({
|
|
3713
3923
|
publishableKey,
|
|
@@ -3723,7 +3933,7 @@ function useDefaultOnrampToken({
|
|
|
3723
3933
|
isLoading,
|
|
3724
3934
|
isError,
|
|
3725
3935
|
error
|
|
3726
|
-
} =
|
|
3936
|
+
} = useQuery6({
|
|
3727
3937
|
queryKey: [
|
|
3728
3938
|
"unifold",
|
|
3729
3939
|
"defaultOnrampToken",
|
|
@@ -3800,7 +4010,7 @@ function parseCoinbasePostMessage(raw) {
|
|
|
3800
4010
|
} : void 0
|
|
3801
4011
|
};
|
|
3802
4012
|
}
|
|
3803
|
-
var BuyWithApplePay =
|
|
4013
|
+
var BuyWithApplePay = React6.forwardRef(
|
|
3804
4014
|
function BuyWithApplePay2({
|
|
3805
4015
|
userId,
|
|
3806
4016
|
publishableKey,
|
|
@@ -3871,7 +4081,7 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
3871
4081
|
countryCode: userIpInfo?.alpha2,
|
|
3872
4082
|
subdivisionCode: userIpInfo?.subdivisionCode ?? void 0
|
|
3873
4083
|
});
|
|
3874
|
-
const depositWallet =
|
|
4084
|
+
const depositWallet = useMemo4(() => {
|
|
3875
4085
|
const routingChainType = defaultToken?.destination_token_metadata?.chain_type;
|
|
3876
4086
|
if (!routingChainType) return void 0;
|
|
3877
4087
|
return getWalletByChainType2(depositWallets ?? [], routingChainType);
|
|
@@ -3959,7 +4169,7 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
3959
4169
|
popupRef.current = null;
|
|
3960
4170
|
};
|
|
3961
4171
|
}, []);
|
|
3962
|
-
|
|
4172
|
+
React6.useImperativeHandle(
|
|
3963
4173
|
ref,
|
|
3964
4174
|
() => ({
|
|
3965
4175
|
requestBack: () => {
|
|
@@ -4001,9 +4211,9 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
4001
4211
|
}),
|
|
4002
4212
|
[view, emailLocked]
|
|
4003
4213
|
);
|
|
4004
|
-
const normalizedPhone =
|
|
4214
|
+
const normalizedPhone = useMemo4(() => formatPhoneInput(phoneInput), [phoneInput]);
|
|
4005
4215
|
const isContactValid = EMAIL_REGEX2.test(email) && PHONE_REGEX2.test(normalizedPhone);
|
|
4006
|
-
const storeApplePaySession =
|
|
4216
|
+
const storeApplePaySession = useCallback2(
|
|
4007
4217
|
(patch = {}) => {
|
|
4008
4218
|
const session = {
|
|
4009
4219
|
email,
|
|
@@ -4015,7 +4225,7 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
4015
4225
|
},
|
|
4016
4226
|
[email, normalizedPhone, userId]
|
|
4017
4227
|
);
|
|
4018
|
-
const createSessionAndSendOtp =
|
|
4228
|
+
const createSessionAndSendOtp = useCallback2(async () => {
|
|
4019
4229
|
setView("submitting_session");
|
|
4020
4230
|
setErrorMessage("");
|
|
4021
4231
|
try {
|
|
@@ -4043,7 +4253,7 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
4043
4253
|
setView("phone_input");
|
|
4044
4254
|
}
|
|
4045
4255
|
}, [email, normalizedPhone, publishableKey, storeApplePaySession]);
|
|
4046
|
-
const clearUpgradeFields =
|
|
4256
|
+
const clearUpgradeFields = useCallback2(() => {
|
|
4047
4257
|
setSsnLast4("");
|
|
4048
4258
|
setDobInput("");
|
|
4049
4259
|
}, []);
|
|
@@ -4055,7 +4265,7 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
4055
4265
|
sessionPhoneVerified: verificationSession?.phone?.status === "verified",
|
|
4056
4266
|
isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
|
|
4057
4267
|
});
|
|
4058
|
-
const pollLimitUpgradeStatus =
|
|
4268
|
+
const pollLimitUpgradeStatus = useCallback2(
|
|
4059
4269
|
async (signal) => {
|
|
4060
4270
|
const POLL_INTERVAL_MS4 = 1500;
|
|
4061
4271
|
const POLL_TIMEOUT_MS = 3e4;
|
|
@@ -4117,7 +4327,7 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
4117
4327
|
clearUpgradeFields
|
|
4118
4328
|
]
|
|
4119
4329
|
);
|
|
4120
|
-
const startUpgradePolling =
|
|
4330
|
+
const startUpgradePolling = useCallback2(async () => {
|
|
4121
4331
|
upgradeFlowAbortRef.current?.abort();
|
|
4122
4332
|
const controller = new AbortController();
|
|
4123
4333
|
upgradeFlowAbortRef.current = controller;
|
|
@@ -4129,7 +4339,7 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
4129
4339
|
}
|
|
4130
4340
|
}
|
|
4131
4341
|
}, [pollLimitUpgradeStatus]);
|
|
4132
|
-
const applyLimitRouting =
|
|
4342
|
+
const applyLimitRouting = useCallback2(
|
|
4133
4343
|
(nextView, status) => {
|
|
4134
4344
|
if (nextView === "limit_upgrade_form" && status === "resubmit") {
|
|
4135
4345
|
setLimitUpgradeError(
|
|
@@ -4166,11 +4376,11 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
4166
4376
|
break;
|
|
4167
4377
|
}
|
|
4168
4378
|
}, [initialAction, applyLimitRouting, createSessionAndSendOtp]);
|
|
4169
|
-
const startVerification =
|
|
4379
|
+
const startVerification = useCallback2(async () => {
|
|
4170
4380
|
if (!isContactValid) return;
|
|
4171
4381
|
await createSessionAndSendOtp();
|
|
4172
4382
|
}, [isContactValid, createSessionAndSendOtp]);
|
|
4173
|
-
const submitLimitUpgrade =
|
|
4383
|
+
const submitLimitUpgrade = useCallback2(async () => {
|
|
4174
4384
|
if (upgradeSubmitting) return;
|
|
4175
4385
|
try {
|
|
4176
4386
|
const dob = parseDobInput(dobInput);
|
|
@@ -4220,7 +4430,7 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
4220
4430
|
startUpgradePolling,
|
|
4221
4431
|
clearUpgradeFields
|
|
4222
4432
|
]);
|
|
4223
|
-
const submitPhoneOtp =
|
|
4433
|
+
const submitPhoneOtp = useCallback2(async () => {
|
|
4224
4434
|
if (!verificationSession || !clientSecret || phoneCode.length !== 6) return;
|
|
4225
4435
|
if (otpSubmitting) return;
|
|
4226
4436
|
setOtpError(null);
|
|
@@ -4288,7 +4498,7 @@ var BuyWithApplePay = React5.forwardRef(
|
|
|
4288
4498
|
getViewForLimitStatus,
|
|
4289
4499
|
applyLimitRouting
|
|
4290
4500
|
]);
|
|
4291
|
-
const prepareSession =
|
|
4501
|
+
const prepareSession = useCallback2(
|
|
4292
4502
|
async (token, amt) => {
|
|
4293
4503
|
setErrorMessage("");
|
|
4294
4504
|
if (!destinationChainType || !destinationChainId) {
|
|
@@ -5269,7 +5479,7 @@ function LegalDisclaimer({ legalAgreements, loading }) {
|
|
|
5269
5479
|
children: [
|
|
5270
5480
|
"By continuing, you agree to Coinbase's",
|
|
5271
5481
|
" ",
|
|
5272
|
-
agreements.map((a, idx, arr) => /* @__PURE__ */ jsxs11(
|
|
5482
|
+
agreements.map((a, idx, arr) => /* @__PURE__ */ jsxs11(React6.Fragment, { children: [
|
|
5273
5483
|
/* @__PURE__ */ jsx13(
|
|
5274
5484
|
"a",
|
|
5275
5485
|
{
|
|
@@ -5545,7 +5755,7 @@ function PayWithExchange({
|
|
|
5545
5755
|
}
|
|
5546
5756
|
|
|
5547
5757
|
// src/components/deposits/PayWithCashApp.tsx
|
|
5548
|
-
import { useState as useState15, useEffect as useEffect10, useCallback as
|
|
5758
|
+
import { useState as useState15, useEffect as useEffect10, useCallback as useCallback3 } from "react";
|
|
5549
5759
|
import { Copy, Check as Check3, Clock, RefreshCw, Loader2 as Loader23 } from "lucide-react";
|
|
5550
5760
|
import {
|
|
5551
5761
|
createCashAppSession,
|
|
@@ -5555,7 +5765,7 @@ import {
|
|
|
5555
5765
|
} from "@unifold/core";
|
|
5556
5766
|
|
|
5557
5767
|
// src/components/deposits/StyledQRCode.tsx
|
|
5558
|
-
import { useEffect as useEffect8, useRef as useRef4, useState as useState13, useMemo as
|
|
5768
|
+
import { useEffect as useEffect8, useRef as useRef4, useState as useState13, useMemo as useMemo5 } from "react";
|
|
5559
5769
|
import QRCodeStyling from "qr-code-styling";
|
|
5560
5770
|
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5561
5771
|
function createQRConfig(value, size, imageUrl, imageSize, darkMode) {
|
|
@@ -5608,7 +5818,7 @@ function QRCodeSkeleton({ size = 180, darkMode = false }) {
|
|
|
5608
5818
|
const spacing = size / gridCount;
|
|
5609
5819
|
const fillColor = darkMode ? "rgba(255,255,255,0.10)" : "rgba(0,0,0,0.08)";
|
|
5610
5820
|
const cornerColor = darkMode ? "rgba(255,255,255,0.14)" : "rgba(0,0,0,0.12)";
|
|
5611
|
-
const dots =
|
|
5821
|
+
const dots = useMemo5(() => {
|
|
5612
5822
|
const result = [];
|
|
5613
5823
|
const cornerSize = 7;
|
|
5614
5824
|
const centerStart = Math.floor(gridCount / 2) - 2;
|
|
@@ -5712,10 +5922,10 @@ function useIsMobileViewport() {
|
|
|
5712
5922
|
}
|
|
5713
5923
|
|
|
5714
5924
|
// src/hooks/use-cashapp-limits.ts
|
|
5715
|
-
import { useQuery as
|
|
5925
|
+
import { useQuery as useQuery7 } from "@tanstack/react-query";
|
|
5716
5926
|
import { getCashAppLimits } from "@unifold/core";
|
|
5717
5927
|
function useCashAppLimits({ publishableKey, currency = "usd" }) {
|
|
5718
|
-
return
|
|
5928
|
+
return useQuery7({
|
|
5719
5929
|
queryKey: ["unifold", "cashAppLimits", currency, publishableKey],
|
|
5720
5930
|
queryFn: () => getCashAppLimits(currency, publishableKey),
|
|
5721
5931
|
enabled: !!publishableKey,
|
|
@@ -5731,6 +5941,7 @@ var POLL_INTERVAL_MS2 = 5e3;
|
|
|
5731
5941
|
var FALLBACK_MIN_USD = 5;
|
|
5732
5942
|
var SUGGESTED_AMOUNTS = [25, 50, 100];
|
|
5733
5943
|
var t3 = i18n.depositModal.cashApp;
|
|
5944
|
+
var sanitizePrefilledUsd = (value) => value?.replace(/[^0-9.]/g, "") ?? "";
|
|
5734
5945
|
function PayWithCashApp({
|
|
5735
5946
|
userId,
|
|
5736
5947
|
publishableKey,
|
|
@@ -5745,6 +5956,7 @@ function PayWithCashApp({
|
|
|
5745
5956
|
onEvent,
|
|
5746
5957
|
onDepositSuccess,
|
|
5747
5958
|
onDepositError,
|
|
5959
|
+
prefilledAmountUsd,
|
|
5748
5960
|
wallets = []
|
|
5749
5961
|
}) {
|
|
5750
5962
|
const { colors: colors2, fonts, components } = useTheme();
|
|
@@ -5760,14 +5972,14 @@ function PayWithCashApp({
|
|
|
5760
5972
|
const { data: limits, isLoading: limitsLoading } = useCashAppLimits({ publishableKey });
|
|
5761
5973
|
const minUsd = limits?.minimum_amount ?? FALLBACK_MIN_USD;
|
|
5762
5974
|
const maxUsd = limits?.maximum_amount ?? null;
|
|
5763
|
-
const [amount, setAmount] = useState15(
|
|
5975
|
+
const [amount, setAmount] = useState15(() => sanitizePrefilledUsd(prefilledAmountUsd));
|
|
5764
5976
|
const [loading, setLoading] = useState15(false);
|
|
5765
5977
|
const [session, setSession] = useState15(null);
|
|
5766
5978
|
const [status, setStatus] = useState15("pending");
|
|
5767
5979
|
const [error, setError] = useState15(null);
|
|
5768
5980
|
const [copied, setCopied] = useState15(false);
|
|
5769
5981
|
const [view, setViewInternal] = useState15(controlledView ?? "amount");
|
|
5770
|
-
const setView =
|
|
5982
|
+
const setView = useCallback3(
|
|
5771
5983
|
(v) => {
|
|
5772
5984
|
setViewInternal(v);
|
|
5773
5985
|
onViewChange?.(v);
|
|
@@ -5797,7 +6009,7 @@ function PayWithCashApp({
|
|
|
5797
6009
|
onDepositSuccess,
|
|
5798
6010
|
onDepositError
|
|
5799
6011
|
});
|
|
5800
|
-
const handleAmountChange =
|
|
6012
|
+
const handleAmountChange = useCallback3(
|
|
5801
6013
|
(raw) => {
|
|
5802
6014
|
const cleaned = raw.replace(/[^0-9.]/g, "");
|
|
5803
6015
|
const parts = cleaned.split(".");
|
|
@@ -5809,7 +6021,7 @@ function PayWithCashApp({
|
|
|
5809
6021
|
},
|
|
5810
6022
|
[onAmountChange]
|
|
5811
6023
|
);
|
|
5812
|
-
const handleCreateSession =
|
|
6024
|
+
const handleCreateSession = useCallback3(async () => {
|
|
5813
6025
|
if (!amount || !recipientAddress || !destinationChainType || !destinationChainId || !destinationTokenAddress) {
|
|
5814
6026
|
setError("Missing required fields");
|
|
5815
6027
|
return;
|
|
@@ -5883,6 +6095,13 @@ function PayWithCashApp({
|
|
|
5883
6095
|
return () => clearInterval(interval);
|
|
5884
6096
|
}, [session, view, status, publishableKey, onDepositSuccess, onDepositError]);
|
|
5885
6097
|
const [softExpired, setSoftExpired] = useState15(false);
|
|
6098
|
+
useEffect10(() => {
|
|
6099
|
+
if (!prefilledAmountUsd) return;
|
|
6100
|
+
const cleaned = sanitizePrefilledUsd(prefilledAmountUsd);
|
|
6101
|
+
if (!cleaned) return;
|
|
6102
|
+
setAmount(cleaned);
|
|
6103
|
+
onAmountChange?.(cleaned);
|
|
6104
|
+
}, [prefilledAmountUsd, onAmountChange]);
|
|
5886
6105
|
useEffect10(() => {
|
|
5887
6106
|
if (!session?.expires_at || view !== "payment") return;
|
|
5888
6107
|
const expiresMs = new Date(session.expires_at).getTime();
|
|
@@ -5897,12 +6116,12 @@ function PayWithCashApp({
|
|
|
5897
6116
|
const interval = setInterval(tick, 1e3);
|
|
5898
6117
|
return () => clearInterval(interval);
|
|
5899
6118
|
}, [session, view, status]);
|
|
5900
|
-
const handleCopy =
|
|
6119
|
+
const handleCopy = useCallback3(async (text) => {
|
|
5901
6120
|
await navigator.clipboard.writeText(text);
|
|
5902
6121
|
setCopied(true);
|
|
5903
6122
|
setTimeout(() => setCopied(false), 2e3);
|
|
5904
6123
|
}, []);
|
|
5905
|
-
const handleRecreate =
|
|
6124
|
+
const handleRecreate = useCallback3(() => {
|
|
5906
6125
|
setSession(null);
|
|
5907
6126
|
setStatus("pending");
|
|
5908
6127
|
setError(null);
|
|
@@ -6233,18 +6452,19 @@ function PayWithCashApp({
|
|
|
6233
6452
|
}
|
|
6234
6453
|
|
|
6235
6454
|
// src/components/deposits/BankTransfer.tsx
|
|
6236
|
-
import { useEffect as useEffect11, useMemo as
|
|
6455
|
+
import { useCallback as useCallback4, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef5, useState as useState16 } from "react";
|
|
6237
6456
|
import { ChevronRight as ChevronRight3, ExternalLink as ExternalLink3, Landmark } from "lucide-react";
|
|
6238
6457
|
import {
|
|
6239
6458
|
DepositEventType as DepositEventType5,
|
|
6240
6459
|
getIconUrlWithCdn as getIconUrlWithCdn2,
|
|
6241
6460
|
getOnrampSessionStartUrl as getOnrampSessionStartUrl2,
|
|
6461
|
+
getFiatExchangeRates as getFiatExchangeRates2,
|
|
6242
6462
|
getWalletByChainType as getWalletByChainType3,
|
|
6243
6463
|
generatePrefixedKSUID as generatePrefixedKSUID5
|
|
6244
6464
|
} from "@unifold/core";
|
|
6245
6465
|
|
|
6246
6466
|
// src/hooks/use-bank-transfer-providers.ts
|
|
6247
|
-
import { useQuery as
|
|
6467
|
+
import { useQuery as useQuery8 } from "@tanstack/react-query";
|
|
6248
6468
|
import { getBankTransferProviders } from "@unifold/core";
|
|
6249
6469
|
function useBankTransferProviders({
|
|
6250
6470
|
publishableKey,
|
|
@@ -6252,7 +6472,7 @@ function useBankTransferProviders({
|
|
|
6252
6472
|
countryCode
|
|
6253
6473
|
}) {
|
|
6254
6474
|
const normalizedCountry = countryCode?.toUpperCase();
|
|
6255
|
-
const { data: providers, isLoading } =
|
|
6475
|
+
const { data: providers, isLoading } = useQuery8({
|
|
6256
6476
|
queryKey: ["unifold", "bankTransferProviders", publishableKey, normalizedCountry ?? null],
|
|
6257
6477
|
queryFn: () => getBankTransferProviders(publishableKey, { countryCode: normalizedCountry }),
|
|
6258
6478
|
enabled,
|
|
@@ -6293,7 +6513,8 @@ function BankTransfer({
|
|
|
6293
6513
|
assetCdnUrl,
|
|
6294
6514
|
onDepositSuccess,
|
|
6295
6515
|
onEvent,
|
|
6296
|
-
onDepositError
|
|
6516
|
+
onDepositError,
|
|
6517
|
+
prefilledAmountUsd
|
|
6297
6518
|
}) {
|
|
6298
6519
|
const { colors: colors2, fonts, components } = useTheme();
|
|
6299
6520
|
const [internalView, setInternalView] = useState16("providers");
|
|
@@ -6303,6 +6524,10 @@ function BankTransfer({
|
|
|
6303
6524
|
const [requestBase, setRequestBase] = useState16(null);
|
|
6304
6525
|
const [activeRequest, setActiveRequest] = useState16(null);
|
|
6305
6526
|
const [amount, setAmount] = useState16("");
|
|
6527
|
+
const [fiatExchangeRates, setFiatExchangeRates] = useState16({
|
|
6528
|
+
usd: 1
|
|
6529
|
+
});
|
|
6530
|
+
const providerSelectionRequestIdRef = useRef5(0);
|
|
6306
6531
|
const currentView = externalView ?? internalView;
|
|
6307
6532
|
const setView = (v) => {
|
|
6308
6533
|
setInternalView(v);
|
|
@@ -6327,7 +6552,7 @@ function BankTransfer({
|
|
|
6327
6552
|
countryCode: userIpInfo?.alpha2
|
|
6328
6553
|
});
|
|
6329
6554
|
const providers = providersResponse?.data ?? [];
|
|
6330
|
-
const pollingWalletId =
|
|
6555
|
+
const pollingWalletId = useMemo6(() => {
|
|
6331
6556
|
if (!defaultToken) return void 0;
|
|
6332
6557
|
return getWalletByChainType3(
|
|
6333
6558
|
wallets,
|
|
@@ -6348,11 +6573,42 @@ function BankTransfer({
|
|
|
6348
6573
|
const currencySymbol = getCurrencySymbol2(sourceCurrency);
|
|
6349
6574
|
const parsedAmount = parseFloat(amount);
|
|
6350
6575
|
const amountValid = !!amount && Number.isFinite(parsedAmount) && parsedAmount >= MIN_AMOUNT;
|
|
6351
|
-
const displayTokenSymbol =
|
|
6576
|
+
const displayTokenSymbol = useMemo6(
|
|
6352
6577
|
() => destinationTokenSymbol?.toUpperCase() ?? defaultToken?.destination_token_metadata?.symbol?.toUpperCase() ?? defaultToken?.destination_currency?.toUpperCase() ?? "USDC",
|
|
6353
6578
|
[destinationTokenSymbol, defaultToken]
|
|
6354
6579
|
);
|
|
6355
|
-
const
|
|
6580
|
+
const resolvePrefilledSourceAmount = useCallback4(
|
|
6581
|
+
async (sourceCurrencyCode) => {
|
|
6582
|
+
const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
|
|
6583
|
+
if (!cleanedPrefilled) return "";
|
|
6584
|
+
const prefilledUsd = parseFloat(cleanedPrefilled);
|
|
6585
|
+
if (!Number.isFinite(prefilledUsd) || prefilledUsd <= 0) return "";
|
|
6586
|
+
const sourceCurrency2 = sourceCurrencyCode.toLowerCase();
|
|
6587
|
+
let rate = sourceCurrency2 === "usd" ? 1 : fiatExchangeRates[sourceCurrency2];
|
|
6588
|
+
if ((!rate || rate <= 0) && sourceCurrency2 !== "usd") {
|
|
6589
|
+
try {
|
|
6590
|
+
const response = await getFiatExchangeRates2({}, publishableKey);
|
|
6591
|
+
if (response?.rates) {
|
|
6592
|
+
setFiatExchangeRates((prev) => ({
|
|
6593
|
+
...prev,
|
|
6594
|
+
...response.rates,
|
|
6595
|
+
usd: 1
|
|
6596
|
+
}));
|
|
6597
|
+
}
|
|
6598
|
+
const fetchedRate = response.rates?.[sourceCurrency2];
|
|
6599
|
+
if (Number.isFinite(fetchedRate) && fetchedRate > 0) {
|
|
6600
|
+
rate = fetchedRate;
|
|
6601
|
+
}
|
|
6602
|
+
} catch (error) {
|
|
6603
|
+
console.error("Error fetching fiat exchange rates for bank transfer:", error);
|
|
6604
|
+
}
|
|
6605
|
+
}
|
|
6606
|
+
if (!rate || rate <= 0) return sourceCurrency2 === "usd" ? cleanedPrefilled : "";
|
|
6607
|
+
return parseFloat((prefilledUsd * rate).toFixed(2)).toString();
|
|
6608
|
+
},
|
|
6609
|
+
[fiatExchangeRates, prefilledAmountUsd, publishableKey]
|
|
6610
|
+
);
|
|
6611
|
+
const handleProviderClick = async (provider) => {
|
|
6356
6612
|
if (!provider.enabled) return;
|
|
6357
6613
|
setSessionError(null);
|
|
6358
6614
|
if (!defaultToken) {
|
|
@@ -6371,6 +6627,7 @@ function BankTransfer({
|
|
|
6371
6627
|
});
|
|
6372
6628
|
return;
|
|
6373
6629
|
}
|
|
6630
|
+
const requestId = ++providerSelectionRequestIdRef.current;
|
|
6374
6631
|
setRequestBase({
|
|
6375
6632
|
service_provider: provider.service_provider,
|
|
6376
6633
|
country_code: (userIpInfo?.alpha2 || "DE").toUpperCase(),
|
|
@@ -6384,7 +6641,10 @@ function BankTransfer({
|
|
|
6384
6641
|
payment_method: provider.payment_methods[0]
|
|
6385
6642
|
});
|
|
6386
6643
|
setActiveProvider(provider);
|
|
6387
|
-
|
|
6644
|
+
const convertedPrefilled = await resolvePrefilledSourceAmount(provider.source_currency);
|
|
6645
|
+
if (requestId !== providerSelectionRequestIdRef.current) return;
|
|
6646
|
+
const hasPrefilledAmount = !!prefilledAmountUsd?.replace(/[^0-9.]/g, "");
|
|
6647
|
+
setAmount(hasPrefilledAmount ? convertedPrefilled : "100");
|
|
6388
6648
|
setView("amount");
|
|
6389
6649
|
};
|
|
6390
6650
|
const handleAmountChange = (value) => {
|
|
@@ -6482,7 +6742,7 @@ function BankTransfer({
|
|
|
6482
6742
|
return /* @__PURE__ */ jsxs15(
|
|
6483
6743
|
"button",
|
|
6484
6744
|
{
|
|
6485
|
-
onClick: () => handleProviderClick(provider),
|
|
6745
|
+
onClick: () => void handleProviderClick(provider),
|
|
6486
6746
|
onMouseEnter: () => !disabled && setHoveredId(provider.service_provider),
|
|
6487
6747
|
onMouseLeave: () => setHoveredId(null),
|
|
6488
6748
|
disabled,
|
|
@@ -7051,7 +7311,7 @@ function DepositExecutionItem({ execution, onClick }) {
|
|
|
7051
7311
|
}
|
|
7052
7312
|
|
|
7053
7313
|
// src/components/deposits/buttons/TransferCryptoButton.tsx
|
|
7054
|
-
import * as
|
|
7314
|
+
import * as React7 from "react";
|
|
7055
7315
|
import { Zap, ChevronRight as ChevronRight5 } from "lucide-react";
|
|
7056
7316
|
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
7057
7317
|
function TransferCryptoButton({
|
|
@@ -7061,9 +7321,9 @@ function TransferCryptoButton({
|
|
|
7061
7321
|
featuredTokens
|
|
7062
7322
|
}) {
|
|
7063
7323
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7064
|
-
const [isHovered, setIsHovered] =
|
|
7065
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
7066
|
-
|
|
7324
|
+
const [isHovered, setIsHovered] = React7.useState(false);
|
|
7325
|
+
const [isTouchDevice, setIsTouchDevice] = React7.useState(false);
|
|
7326
|
+
React7.useEffect(() => {
|
|
7067
7327
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
7068
7328
|
}, []);
|
|
7069
7329
|
const sortedTokens = featuredTokens ? [...featuredTokens].sort((a, b) => a.position - b.position) : [];
|
|
@@ -7138,7 +7398,7 @@ function TransferCryptoButton({
|
|
|
7138
7398
|
}
|
|
7139
7399
|
|
|
7140
7400
|
// src/components/deposits/buttons/DepositWithCardButton.tsx
|
|
7141
|
-
import * as
|
|
7401
|
+
import * as React8 from "react";
|
|
7142
7402
|
import { CreditCard, ChevronRight as ChevronRight6 } from "lucide-react";
|
|
7143
7403
|
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
7144
7404
|
function DepositWithCardButton({
|
|
@@ -7148,9 +7408,9 @@ function DepositWithCardButton({
|
|
|
7148
7408
|
paymentNetworks
|
|
7149
7409
|
}) {
|
|
7150
7410
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7151
|
-
const [isHovered, setIsHovered] =
|
|
7152
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
7153
|
-
|
|
7411
|
+
const [isHovered, setIsHovered] = React8.useState(false);
|
|
7412
|
+
const [isTouchDevice, setIsTouchDevice] = React8.useState(false);
|
|
7413
|
+
React8.useEffect(() => {
|
|
7154
7414
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
7155
7415
|
}, []);
|
|
7156
7416
|
return /* @__PURE__ */ jsxs18(
|
|
@@ -7223,7 +7483,7 @@ function DepositWithCardButton({
|
|
|
7223
7483
|
}
|
|
7224
7484
|
|
|
7225
7485
|
// src/components/deposits/buttons/PayWithExchangeButton.tsx
|
|
7226
|
-
import * as
|
|
7486
|
+
import * as React9 from "react";
|
|
7227
7487
|
import { ArrowLeftRight, ChevronRight as ChevronRight7 } from "lucide-react";
|
|
7228
7488
|
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
7229
7489
|
function PayWithExchangeButton({
|
|
@@ -7234,9 +7494,9 @@ function PayWithExchangeButton({
|
|
|
7234
7494
|
loading = false
|
|
7235
7495
|
}) {
|
|
7236
7496
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7237
|
-
const [isHovered, setIsHovered] =
|
|
7238
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
7239
|
-
|
|
7497
|
+
const [isHovered, setIsHovered] = React9.useState(false);
|
|
7498
|
+
const [isTouchDevice, setIsTouchDevice] = React9.useState(false);
|
|
7499
|
+
React9.useEffect(() => {
|
|
7240
7500
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
7241
7501
|
}, []);
|
|
7242
7502
|
if (loading) {
|
|
@@ -7315,11 +7575,11 @@ function PayWithExchangeButton({
|
|
|
7315
7575
|
}
|
|
7316
7576
|
|
|
7317
7577
|
// src/components/deposits/buttons/ConnectExchangeButton.tsx
|
|
7318
|
-
import * as
|
|
7578
|
+
import * as React11 from "react";
|
|
7319
7579
|
import { Link2, ChevronRight as ChevronRight8 } from "lucide-react";
|
|
7320
7580
|
|
|
7321
7581
|
// src/components/shared/button.tsx
|
|
7322
|
-
import * as
|
|
7582
|
+
import * as React10 from "react";
|
|
7323
7583
|
import { Slot } from "@radix-ui/react-slot";
|
|
7324
7584
|
import { cva } from "class-variance-authority";
|
|
7325
7585
|
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
@@ -7348,11 +7608,11 @@ var buttonVariants = cva(
|
|
|
7348
7608
|
}
|
|
7349
7609
|
}
|
|
7350
7610
|
);
|
|
7351
|
-
var Button =
|
|
7611
|
+
var Button = React10.forwardRef(
|
|
7352
7612
|
({ className, variant, size, asChild = false, style, ...props }, ref) => {
|
|
7353
7613
|
const Comp = asChild ? Slot : "button";
|
|
7354
7614
|
const { components, fonts } = useTheme();
|
|
7355
|
-
const themeStyle =
|
|
7615
|
+
const themeStyle = React10.useMemo(() => {
|
|
7356
7616
|
const baseStyle = { ...style };
|
|
7357
7617
|
if (variant === "default" || !variant) {
|
|
7358
7618
|
baseStyle.backgroundColor = components.button.primaryBackground;
|
|
@@ -7390,9 +7650,9 @@ function ConnectExchangeButton({
|
|
|
7390
7650
|
connectedExchange
|
|
7391
7651
|
}) {
|
|
7392
7652
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7393
|
-
const [isHovered, setIsHovered] =
|
|
7394
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
7395
|
-
|
|
7653
|
+
const [isHovered, setIsHovered] = React11.useState(false);
|
|
7654
|
+
const [isTouchDevice, setIsTouchDevice] = React11.useState(false);
|
|
7655
|
+
React11.useEffect(() => {
|
|
7396
7656
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
7397
7657
|
}, []);
|
|
7398
7658
|
const isConnected = connectedExchange != null;
|
|
@@ -7532,7 +7792,7 @@ function ConnectExchangeButton({
|
|
|
7532
7792
|
}
|
|
7533
7793
|
|
|
7534
7794
|
// src/components/deposits/buttons/DepositTrackerButton.tsx
|
|
7535
|
-
import * as
|
|
7795
|
+
import * as React12 from "react";
|
|
7536
7796
|
import { Clock as Clock2, ChevronRight as ChevronRight9 } from "lucide-react";
|
|
7537
7797
|
import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
7538
7798
|
function DepositTrackerButton({
|
|
@@ -7542,9 +7802,9 @@ function DepositTrackerButton({
|
|
|
7542
7802
|
badge
|
|
7543
7803
|
}) {
|
|
7544
7804
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7545
|
-
const [isHovered, setIsHovered] =
|
|
7546
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
7547
|
-
|
|
7805
|
+
const [isHovered, setIsHovered] = React12.useState(false);
|
|
7806
|
+
const [isTouchDevice, setIsTouchDevice] = React12.useState(false);
|
|
7807
|
+
React12.useEffect(() => {
|
|
7548
7808
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
7549
7809
|
}, []);
|
|
7550
7810
|
return /* @__PURE__ */ jsxs21(
|
|
@@ -7615,14 +7875,14 @@ function DepositTrackerButton({
|
|
|
7615
7875
|
}
|
|
7616
7876
|
|
|
7617
7877
|
// src/components/deposits/buttons/CashAppButton.tsx
|
|
7618
|
-
import * as
|
|
7878
|
+
import * as React13 from "react";
|
|
7619
7879
|
import { ChevronRight as ChevronRight10 } from "lucide-react";
|
|
7620
7880
|
import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
7621
7881
|
function CashAppButton({ onClick, title, subtitle, iconUrl }) {
|
|
7622
7882
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7623
|
-
const [isHovered, setIsHovered] =
|
|
7624
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
7625
|
-
|
|
7883
|
+
const [isHovered, setIsHovered] = React13.useState(false);
|
|
7884
|
+
const [isTouchDevice, setIsTouchDevice] = React13.useState(false);
|
|
7885
|
+
React13.useEffect(() => {
|
|
7626
7886
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
7627
7887
|
}, []);
|
|
7628
7888
|
return /* @__PURE__ */ jsxs22(
|
|
@@ -7686,7 +7946,7 @@ function CashAppButton({ onClick, title, subtitle, iconUrl }) {
|
|
|
7686
7946
|
}
|
|
7687
7947
|
|
|
7688
7948
|
// src/components/deposits/buttons/ApplePayButton.tsx
|
|
7689
|
-
import * as
|
|
7949
|
+
import * as React14 from "react";
|
|
7690
7950
|
import { ChevronRight as ChevronRight11 } from "lucide-react";
|
|
7691
7951
|
import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
7692
7952
|
function AppleLogo({ className, style }) {
|
|
@@ -7709,11 +7969,11 @@ function AppleLogo({ className, style }) {
|
|
|
7709
7969
|
}
|
|
7710
7970
|
);
|
|
7711
7971
|
}
|
|
7712
|
-
function ApplePayButton({ onClick, title, subtitle }) {
|
|
7972
|
+
function ApplePayButton({ onClick, title, subtitle, iconUrl }) {
|
|
7713
7973
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7714
|
-
const [isHovered, setIsHovered] =
|
|
7715
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
7716
|
-
|
|
7974
|
+
const [isHovered, setIsHovered] = React14.useState(false);
|
|
7975
|
+
const [isTouchDevice, setIsTouchDevice] = React14.useState(false);
|
|
7976
|
+
React14.useEffect(() => {
|
|
7717
7977
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
7718
7978
|
}, []);
|
|
7719
7979
|
return /* @__PURE__ */ jsxs23(
|
|
@@ -7731,7 +7991,14 @@ function ApplePayButton({ onClick, title, subtitle }) {
|
|
|
7731
7991
|
},
|
|
7732
7992
|
children: [
|
|
7733
7993
|
/* @__PURE__ */ jsxs23("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
|
|
7734
|
-
/* @__PURE__ */ jsx26("div", { className: "uf-rounded-lg uf-
|
|
7994
|
+
/* @__PURE__ */ jsx26("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__ */ jsx26("img", { src: iconUrl, alt: "Apple Pay", width: 36, height: 36, className: "uf-rounded-lg" }) : /* @__PURE__ */ jsx26(
|
|
7995
|
+
"div",
|
|
7996
|
+
{
|
|
7997
|
+
className: "uf-w-9 uf-h-9 uf-rounded-lg uf-flex uf-items-center uf-justify-center",
|
|
7998
|
+
style: { backgroundColor: "#000" },
|
|
7999
|
+
children: /* @__PURE__ */ jsx26(AppleLogo, { className: "uf-w-5 uf-h-5", style: { color: "#fff" } })
|
|
8000
|
+
}
|
|
8001
|
+
) }),
|
|
7735
8002
|
/* @__PURE__ */ jsxs23("div", { className: "uf-text-left", children: [
|
|
7736
8003
|
/* @__PURE__ */ jsx26(
|
|
7737
8004
|
"div",
|
|
@@ -7770,7 +8037,7 @@ function ApplePayButton({ onClick, title, subtitle }) {
|
|
|
7770
8037
|
}
|
|
7771
8038
|
|
|
7772
8039
|
// src/components/deposits/buttons/BankTransferButton.tsx
|
|
7773
|
-
import * as
|
|
8040
|
+
import * as React15 from "react";
|
|
7774
8041
|
import { Landmark as Landmark2, ChevronRight as ChevronRight12 } from "lucide-react";
|
|
7775
8042
|
import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
7776
8043
|
function BankTransferButton({
|
|
@@ -7780,9 +8047,9 @@ function BankTransferButton({
|
|
|
7780
8047
|
comingSoon = false
|
|
7781
8048
|
}) {
|
|
7782
8049
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7783
|
-
const [isHovered, setIsHovered] =
|
|
7784
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
7785
|
-
|
|
8050
|
+
const [isHovered, setIsHovered] = React15.useState(false);
|
|
8051
|
+
const [isTouchDevice, setIsTouchDevice] = React15.useState(false);
|
|
8052
|
+
React15.useEffect(() => {
|
|
7786
8053
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
7787
8054
|
}, []);
|
|
7788
8055
|
return /* @__PURE__ */ jsxs24(
|
|
@@ -7840,7 +8107,7 @@ function BankTransferButton({
|
|
|
7840
8107
|
}
|
|
7841
8108
|
|
|
7842
8109
|
// src/components/deposits/buttons/BrowserWalletButton.tsx
|
|
7843
|
-
import * as
|
|
8110
|
+
import * as React29 from "react";
|
|
7844
8111
|
import { Wallet, ChevronRight as ChevronRight13, Loader2 as Loader24 } from "lucide-react";
|
|
7845
8112
|
import { getAddressBalances } from "@unifold/core";
|
|
7846
8113
|
|
|
@@ -7895,7 +8162,7 @@ function collectAllEip6963EthProviders() {
|
|
|
7895
8162
|
}
|
|
7896
8163
|
|
|
7897
8164
|
// src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
|
|
7898
|
-
import * as
|
|
8165
|
+
import * as React16 from "react";
|
|
7899
8166
|
|
|
7900
8167
|
// src/components/deposits/browser-wallets/detectConnectedWallet.ts
|
|
7901
8168
|
function identifyEthWallet(provider, hint) {
|
|
@@ -7965,13 +8232,6 @@ function solanaCandidate(provider, type, name, icon) {
|
|
|
7965
8232
|
if (provider.isConnected && provider.publicKey) {
|
|
7966
8233
|
return { type, name, address: provider.publicKey.toString(), icon };
|
|
7967
8234
|
}
|
|
7968
|
-
try {
|
|
7969
|
-
const resp = await provider.connect({ onlyIfTrusted: true });
|
|
7970
|
-
if (resp.publicKey) {
|
|
7971
|
-
return { type, name, address: resp.publicKey.toString(), icon };
|
|
7972
|
-
}
|
|
7973
|
-
} catch {
|
|
7974
|
-
}
|
|
7975
8235
|
return null;
|
|
7976
8236
|
}
|
|
7977
8237
|
};
|
|
@@ -8046,18 +8306,18 @@ async function detectConnectedBrowserWallet(chainType) {
|
|
|
8046
8306
|
// src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
|
|
8047
8307
|
function useDetectedBrowserWallet(opts = {}) {
|
|
8048
8308
|
const { chainType, enabled = true, onDisconnect } = opts;
|
|
8049
|
-
const [wallet, setWallet] =
|
|
8050
|
-
const [isLoading, setIsLoading] =
|
|
8051
|
-
const [eip6963ProviderCount, setEip6963ProviderCount] =
|
|
8052
|
-
const onDisconnectRef =
|
|
8309
|
+
const [wallet, setWallet] = React16.useState(null);
|
|
8310
|
+
const [isLoading, setIsLoading] = React16.useState(enabled);
|
|
8311
|
+
const [eip6963ProviderCount, setEip6963ProviderCount] = React16.useState(0);
|
|
8312
|
+
const onDisconnectRef = React16.useRef(onDisconnect);
|
|
8053
8313
|
onDisconnectRef.current = onDisconnect;
|
|
8054
|
-
|
|
8314
|
+
React16.useEffect(() => {
|
|
8055
8315
|
const store = getEip6963Store();
|
|
8056
8316
|
if (!store) return;
|
|
8057
8317
|
setEip6963ProviderCount(store.getProviders().length);
|
|
8058
8318
|
return store.subscribe((providers) => setEip6963ProviderCount(providers.length));
|
|
8059
8319
|
}, []);
|
|
8060
|
-
|
|
8320
|
+
React16.useEffect(() => {
|
|
8061
8321
|
if (!enabled) {
|
|
8062
8322
|
setWallet(null);
|
|
8063
8323
|
setIsLoading(false);
|
|
@@ -8194,17 +8454,191 @@ async function disconnectInjectedBrowserWallet(wallet) {
|
|
|
8194
8454
|
await disconnectSolanaProvider(wallet.type, win);
|
|
8195
8455
|
return;
|
|
8196
8456
|
}
|
|
8197
|
-
await disconnectEthereumMatchingAddress(
|
|
8198
|
-
wallet.address,
|
|
8199
|
-
collectEthereumProvidersForDisconnect(window)
|
|
8200
|
-
);
|
|
8457
|
+
await disconnectEthereumMatchingAddress(
|
|
8458
|
+
wallet.address,
|
|
8459
|
+
collectEthereumProvidersForDisconnect(window)
|
|
8460
|
+
);
|
|
8461
|
+
}
|
|
8462
|
+
|
|
8463
|
+
// src/components/deposits/browser-wallets/providerResolvers.ts
|
|
8464
|
+
var STORED_TYPE_TO_EIP6963_WALLET_ID = {
|
|
8465
|
+
metamask: "metamask",
|
|
8466
|
+
"phantom-ethereum": "phantom",
|
|
8467
|
+
coinbase: "coinbase",
|
|
8468
|
+
trust: "trust",
|
|
8469
|
+
rainbow: "rainbow",
|
|
8470
|
+
rabby: "rabby",
|
|
8471
|
+
okx: "okx"
|
|
8472
|
+
};
|
|
8473
|
+
var EIP6963_WALLET_ID_TO_INFO = {
|
|
8474
|
+
metamask: { walletType: "metamask", name: "MetaMask", icon: "metamask" },
|
|
8475
|
+
phantom: { walletType: "phantom-ethereum", name: "Phantom", icon: "phantom" },
|
|
8476
|
+
coinbase: { walletType: "coinbase", name: "Coinbase Wallet", icon: "coinbase" },
|
|
8477
|
+
trust: { walletType: "trust", name: "Trust Wallet", icon: "trust" },
|
|
8478
|
+
rainbow: { walletType: "rainbow", name: "Rainbow", icon: "rainbow" },
|
|
8479
|
+
rabby: { walletType: "rabby", name: "Rabby", icon: "rabby" },
|
|
8480
|
+
okx: { walletType: "okx", name: "OKX Wallet", icon: "okx" }
|
|
8481
|
+
};
|
|
8482
|
+
var WALLET_ID_TO_WALLET_TYPE = {
|
|
8483
|
+
phantom: "phantom-ethereum",
|
|
8484
|
+
coinbase: "coinbase",
|
|
8485
|
+
trust: "trust",
|
|
8486
|
+
rainbow: "rainbow",
|
|
8487
|
+
rabby: "rabby",
|
|
8488
|
+
okx: "okx",
|
|
8489
|
+
metamask: "metamask"
|
|
8490
|
+
};
|
|
8491
|
+
var WALLET_TYPE_TO_WALLET_ID = {
|
|
8492
|
+
"phantom-ethereum": "phantom",
|
|
8493
|
+
coinbase: "coinbase",
|
|
8494
|
+
trust: "trust",
|
|
8495
|
+
okx: "okx",
|
|
8496
|
+
rainbow: "rainbow",
|
|
8497
|
+
rabby: "rabby",
|
|
8498
|
+
metamask: "metamask"
|
|
8499
|
+
};
|
|
8500
|
+
function isWalletType(value) {
|
|
8501
|
+
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";
|
|
8502
|
+
}
|
|
8503
|
+
function walletIdToWalletType(walletId) {
|
|
8504
|
+
return WALLET_ID_TO_WALLET_TYPE[walletId] || "metamask";
|
|
8505
|
+
}
|
|
8506
|
+
function walletTypeToWalletId(walletType) {
|
|
8507
|
+
return WALLET_TYPE_TO_WALLET_ID[walletType] || walletType;
|
|
8508
|
+
}
|
|
8509
|
+
function getLegacyEvmProviders(win) {
|
|
8510
|
+
if (!win) return {};
|
|
8511
|
+
const anyWin = win;
|
|
8512
|
+
return {
|
|
8513
|
+
ethereum: anyWin.ethereum,
|
|
8514
|
+
phantomEthereum: anyWin.phantom?.ethereum,
|
|
8515
|
+
coinbaseEthereum: anyWin.coinbaseWalletExtension,
|
|
8516
|
+
trustEthereum: anyWin.trustwallet?.ethereum,
|
|
8517
|
+
okxEthereum: anyWin.okxwallet
|
|
8518
|
+
};
|
|
8519
|
+
}
|
|
8520
|
+
function getInjectedSolanaProviders(win) {
|
|
8521
|
+
if (!win) return {};
|
|
8522
|
+
const anyWin = win;
|
|
8523
|
+
return {
|
|
8524
|
+
phantomSolana: anyWin.phantom?.solana,
|
|
8525
|
+
solflare: anyWin.solflare,
|
|
8526
|
+
backpack: anyWin.backpack,
|
|
8527
|
+
glow: anyWin.glow,
|
|
8528
|
+
coinbaseSolana: anyWin.coinbaseSolana || anyWin.coinbaseWalletExtension?.solana,
|
|
8529
|
+
trustSolana: anyWin.trustwallet?.solana
|
|
8530
|
+
};
|
|
8531
|
+
}
|
|
8532
|
+
function describeEip6963Provider(wp) {
|
|
8533
|
+
const mapped = EIP6963_WALLET_ID_TO_INFO[wp.walletId];
|
|
8534
|
+
return {
|
|
8535
|
+
provider: wp.provider,
|
|
8536
|
+
walletType: mapped?.walletType ?? "metamask",
|
|
8537
|
+
name: mapped?.name ?? wp.info.name,
|
|
8538
|
+
icon: mapped?.icon ?? wp.info.icon
|
|
8539
|
+
};
|
|
8540
|
+
}
|
|
8541
|
+
function resolveQuickConnectEvmProvider(win) {
|
|
8542
|
+
const eip6963Providers = getEip6963Providers();
|
|
8543
|
+
if (eip6963Providers.length > 0) {
|
|
8544
|
+
const stored = getStoredWalletState();
|
|
8545
|
+
const preferredWalletId = stored?.walletType && isWalletType(stored.walletType) ? STORED_TYPE_TO_EIP6963_WALLET_ID[stored.walletType] : void 0;
|
|
8546
|
+
if (preferredWalletId) {
|
|
8547
|
+
const preferred = findProviderByWalletId(preferredWalletId);
|
|
8548
|
+
if (preferred) return describeEip6963Provider(preferred);
|
|
8549
|
+
}
|
|
8550
|
+
if (eip6963Providers.length === 1) {
|
|
8551
|
+
return describeEip6963Provider(eip6963Providers[0]);
|
|
8552
|
+
}
|
|
8553
|
+
return void 0;
|
|
8554
|
+
}
|
|
8555
|
+
const anyWin = win;
|
|
8556
|
+
const legacy = anyWin.phantom?.ethereum || anyWin.ethereum;
|
|
8557
|
+
if (!legacy) return void 0;
|
|
8558
|
+
const isPhantom = legacy.isPhantom;
|
|
8559
|
+
return {
|
|
8560
|
+
provider: legacy,
|
|
8561
|
+
walletType: isPhantom ? "phantom-ethereum" : "metamask",
|
|
8562
|
+
name: isPhantom ? "Phantom" : "MetaMask",
|
|
8563
|
+
icon: isPhantom ? "phantom" : "metamask"
|
|
8564
|
+
};
|
|
8565
|
+
}
|
|
8566
|
+
function resolveSolanaPublicKey(provider, response) {
|
|
8567
|
+
if (response?.publicKey) return { publicKey: response.publicKey };
|
|
8568
|
+
if (provider.publicKey) return { publicKey: provider.publicKey };
|
|
8569
|
+
return null;
|
|
8570
|
+
}
|
|
8571
|
+
function isUserRejectedSolanaConnectError(error) {
|
|
8572
|
+
if (!error || typeof error !== "object") return false;
|
|
8573
|
+
const maybeCode = "code" in error ? error.code : void 0;
|
|
8574
|
+
if (maybeCode === 4001) return true;
|
|
8575
|
+
const msg = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
|
|
8576
|
+
return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("rejected the request") || msg.includes("declined");
|
|
8577
|
+
}
|
|
8578
|
+
function isSolanaConnectTimeoutError(error) {
|
|
8579
|
+
return error instanceof Error && error.message.toLowerCase().includes("did not respond to the connection request");
|
|
8580
|
+
}
|
|
8581
|
+
async function connectSolanaProviderWithRecovery(provider, walletId, walletName) {
|
|
8582
|
+
if (provider.isConnected && provider.publicKey) {
|
|
8583
|
+
return { publicKey: provider.publicKey };
|
|
8584
|
+
}
|
|
8585
|
+
const connectOnce = () => provider.connect(walletId === "solflare" ? { onlyIfTrusted: false } : void 0);
|
|
8586
|
+
const withTimeout = async (ms = 2e4) => await Promise.race([
|
|
8587
|
+
connectOnce(),
|
|
8588
|
+
new Promise(
|
|
8589
|
+
(resolve, reject) => setTimeout(() => {
|
|
8590
|
+
const connected = resolveSolanaPublicKey(provider);
|
|
8591
|
+
if (connected) {
|
|
8592
|
+
resolve(connected);
|
|
8593
|
+
return;
|
|
8594
|
+
}
|
|
8595
|
+
reject(
|
|
8596
|
+
new Error(
|
|
8597
|
+
`${walletName} did not respond to the connection request. Please unlock the wallet and try again.`
|
|
8598
|
+
)
|
|
8599
|
+
);
|
|
8600
|
+
}, ms)
|
|
8601
|
+
)
|
|
8602
|
+
]);
|
|
8603
|
+
if (walletId === "solflare") {
|
|
8604
|
+
await provider.disconnect?.().catch(() => {
|
|
8605
|
+
});
|
|
8606
|
+
}
|
|
8607
|
+
const connectAndResolve = async () => {
|
|
8608
|
+
try {
|
|
8609
|
+
const response = await withTimeout();
|
|
8610
|
+
const resolved = resolveSolanaPublicKey(provider, response);
|
|
8611
|
+
if (resolved) return resolved;
|
|
8612
|
+
await new Promise((resolve) => setTimeout(resolve, 120));
|
|
8613
|
+
const delayedResolved = resolveSolanaPublicKey(provider);
|
|
8614
|
+
if (delayedResolved) return delayedResolved;
|
|
8615
|
+
throw new Error(`${walletName} connected but did not expose a public key.`);
|
|
8616
|
+
} catch (error) {
|
|
8617
|
+
const connected = resolveSolanaPublicKey(provider);
|
|
8618
|
+
if (connected) return connected;
|
|
8619
|
+
throw error;
|
|
8620
|
+
}
|
|
8621
|
+
};
|
|
8622
|
+
try {
|
|
8623
|
+
return await connectAndResolve();
|
|
8624
|
+
} catch (err) {
|
|
8625
|
+
if (isUserRejectedSolanaConnectError(err)) throw err;
|
|
8626
|
+
if (isSolanaConnectTimeoutError(err)) throw err;
|
|
8627
|
+
if (walletId === "solflare") {
|
|
8628
|
+
await provider.disconnect?.().catch(() => {
|
|
8629
|
+
});
|
|
8630
|
+
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
8631
|
+
return await connectAndResolve();
|
|
8632
|
+
}
|
|
8633
|
+
throw err;
|
|
8634
|
+
}
|
|
8201
8635
|
}
|
|
8202
8636
|
|
|
8203
8637
|
// src/resources/icons/MetamaskIcon.tsx
|
|
8204
|
-
import * as
|
|
8638
|
+
import * as React17 from "react";
|
|
8205
8639
|
import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
8206
8640
|
function MetamaskIcon({ size = 24, className, variant = "color" }) {
|
|
8207
|
-
const id =
|
|
8641
|
+
const id = React17.useId();
|
|
8208
8642
|
if (variant === "light" || variant === "dark") {
|
|
8209
8643
|
return /* @__PURE__ */ jsxs25(
|
|
8210
8644
|
"svg",
|
|
@@ -8326,10 +8760,10 @@ function MetamaskIcon({ size = 24, className, variant = "color" }) {
|
|
|
8326
8760
|
}
|
|
8327
8761
|
|
|
8328
8762
|
// src/resources/icons/PhantomIcon.tsx
|
|
8329
|
-
import * as
|
|
8763
|
+
import * as React18 from "react";
|
|
8330
8764
|
import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
8331
8765
|
function PhantomIcon({ size = 24, className, variant = "color" }) {
|
|
8332
|
-
const id =
|
|
8766
|
+
const id = React18.useId();
|
|
8333
8767
|
if (variant === "light") {
|
|
8334
8768
|
return /* @__PURE__ */ jsx29(
|
|
8335
8769
|
"svg",
|
|
@@ -8397,10 +8831,10 @@ function PhantomIcon({ size = 24, className, variant = "color" }) {
|
|
|
8397
8831
|
}
|
|
8398
8832
|
|
|
8399
8833
|
// src/resources/icons/CoinbaseIcon.tsx
|
|
8400
|
-
import * as
|
|
8834
|
+
import * as React19 from "react";
|
|
8401
8835
|
import { jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
8402
8836
|
function CoinbaseIcon({ size = 24, className, variant = "color" }) {
|
|
8403
|
-
const id =
|
|
8837
|
+
const id = React19.useId();
|
|
8404
8838
|
if (variant === "light") {
|
|
8405
8839
|
return /* @__PURE__ */ jsxs27(
|
|
8406
8840
|
"svg",
|
|
@@ -8481,10 +8915,10 @@ function CoinbaseIcon({ size = 24, className, variant = "color" }) {
|
|
|
8481
8915
|
}
|
|
8482
8916
|
|
|
8483
8917
|
// src/resources/icons/RabbyIcon.tsx
|
|
8484
|
-
import * as
|
|
8918
|
+
import * as React20 from "react";
|
|
8485
8919
|
import { jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
8486
8920
|
function RabbyIcon({ size = 24, className, variant = "color" }) {
|
|
8487
|
-
const id =
|
|
8921
|
+
const id = React20.useId();
|
|
8488
8922
|
if (variant === "light") {
|
|
8489
8923
|
return /* @__PURE__ */ jsxs28(
|
|
8490
8924
|
"svg",
|
|
@@ -8832,10 +9266,10 @@ function RabbyIcon({ size = 24, className, variant = "color" }) {
|
|
|
8832
9266
|
}
|
|
8833
9267
|
|
|
8834
9268
|
// src/resources/icons/RainbowIcon.tsx
|
|
8835
|
-
import * as
|
|
9269
|
+
import * as React21 from "react";
|
|
8836
9270
|
import { jsx as jsx32, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
8837
9271
|
function RainbowIcon({ size = 24, className, variant = "color" }) {
|
|
8838
|
-
const id =
|
|
9272
|
+
const id = React21.useId();
|
|
8839
9273
|
if (variant === "light") {
|
|
8840
9274
|
return /* @__PURE__ */ jsxs29(
|
|
8841
9275
|
"svg",
|
|
@@ -9250,10 +9684,10 @@ function RainbowIcon({ size = 24, className, variant = "color" }) {
|
|
|
9250
9684
|
}
|
|
9251
9685
|
|
|
9252
9686
|
// src/resources/icons/TrustIcon.tsx
|
|
9253
|
-
import * as
|
|
9687
|
+
import * as React22 from "react";
|
|
9254
9688
|
import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
9255
9689
|
function TrustIcon({ size = 24, className, variant = "color" }) {
|
|
9256
|
-
const id =
|
|
9690
|
+
const id = React22.useId();
|
|
9257
9691
|
if (variant === "light") {
|
|
9258
9692
|
return /* @__PURE__ */ jsx33(
|
|
9259
9693
|
"svg",
|
|
@@ -9337,10 +9771,10 @@ function TrustIcon({ size = 24, className, variant = "color" }) {
|
|
|
9337
9771
|
}
|
|
9338
9772
|
|
|
9339
9773
|
// src/resources/icons/OkxIcon.tsx
|
|
9340
|
-
import * as
|
|
9774
|
+
import * as React23 from "react";
|
|
9341
9775
|
import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
9342
9776
|
function OkxIcon({ size = 24, className, variant = "color" }) {
|
|
9343
|
-
const id =
|
|
9777
|
+
const id = React23.useId();
|
|
9344
9778
|
if (variant === "light") {
|
|
9345
9779
|
return /* @__PURE__ */ jsx34(
|
|
9346
9780
|
"svg",
|
|
@@ -9396,10 +9830,10 @@ function OkxIcon({ size = 24, className, variant = "color" }) {
|
|
|
9396
9830
|
}
|
|
9397
9831
|
|
|
9398
9832
|
// src/resources/icons/GlowIcon.tsx
|
|
9399
|
-
import * as
|
|
9833
|
+
import * as React24 from "react";
|
|
9400
9834
|
import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
9401
9835
|
function GlowIcon({ size = 24, className, variant = "color" }) {
|
|
9402
|
-
const id =
|
|
9836
|
+
const id = React24.useId();
|
|
9403
9837
|
if (variant === "light") {
|
|
9404
9838
|
return /* @__PURE__ */ jsx35(
|
|
9405
9839
|
"svg",
|
|
@@ -9501,10 +9935,10 @@ function GlowIcon({ size = 24, className, variant = "color" }) {
|
|
|
9501
9935
|
}
|
|
9502
9936
|
|
|
9503
9937
|
// src/resources/icons/BackpackIcon.tsx
|
|
9504
|
-
import * as
|
|
9938
|
+
import * as React25 from "react";
|
|
9505
9939
|
import { jsx as jsx36, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
9506
9940
|
function BackpackIcon({ size = 24, className, variant = "color" }) {
|
|
9507
|
-
const id =
|
|
9941
|
+
const id = React25.useId();
|
|
9508
9942
|
if (variant === "light") {
|
|
9509
9943
|
return /* @__PURE__ */ jsx36(
|
|
9510
9944
|
"svg",
|
|
@@ -9578,10 +10012,10 @@ function BackpackIcon({ size = 24, className, variant = "color" }) {
|
|
|
9578
10012
|
}
|
|
9579
10013
|
|
|
9580
10014
|
// src/resources/icons/SolflareIcon.tsx
|
|
9581
|
-
import * as
|
|
10015
|
+
import * as React26 from "react";
|
|
9582
10016
|
import { jsx as jsx37, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
9583
10017
|
function SolflareIcon({ size = 24, className, variant = "color" }) {
|
|
9584
|
-
const id =
|
|
10018
|
+
const id = React26.useId();
|
|
9585
10019
|
if (variant === "light") {
|
|
9586
10020
|
return /* @__PURE__ */ jsx37(
|
|
9587
10021
|
"svg",
|
|
@@ -9649,10 +10083,10 @@ function SolflareIcon({ size = 24, className, variant = "color" }) {
|
|
|
9649
10083
|
}
|
|
9650
10084
|
|
|
9651
10085
|
// src/resources/icons/EthereumIcon.tsx
|
|
9652
|
-
import * as
|
|
10086
|
+
import * as React27 from "react";
|
|
9653
10087
|
import { jsx as jsx38, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
9654
10088
|
function EthereumIcon({ size = 24, className, variant = "color" }) {
|
|
9655
|
-
const id =
|
|
10089
|
+
const id = React27.useId();
|
|
9656
10090
|
if (variant === "light") {
|
|
9657
10091
|
return /* @__PURE__ */ jsxs35(
|
|
9658
10092
|
"svg",
|
|
@@ -9777,10 +10211,10 @@ function EthereumIcon({ size = 24, className, variant = "color" }) {
|
|
|
9777
10211
|
}
|
|
9778
10212
|
|
|
9779
10213
|
// src/resources/icons/SolanaIcon.tsx
|
|
9780
|
-
import * as
|
|
10214
|
+
import * as React28 from "react";
|
|
9781
10215
|
import { jsx as jsx39, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
9782
10216
|
function SolanaIcon({ size = 24, className, variant = "color" }) {
|
|
9783
|
-
const id =
|
|
10217
|
+
const id = React28.useId();
|
|
9784
10218
|
if (variant === "light") {
|
|
9785
10219
|
return /* @__PURE__ */ jsx39(
|
|
9786
10220
|
"svg",
|
|
@@ -10031,19 +10465,19 @@ function BrowserWalletButton({
|
|
|
10031
10465
|
subtitle = i18n.depositModal.browserWallet.subtitle
|
|
10032
10466
|
}) {
|
|
10033
10467
|
const { colors: colors2, fonts, components } = useTheme();
|
|
10034
|
-
const [isHovered, setIsHovered] =
|
|
10035
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
10468
|
+
const [isHovered, setIsHovered] = React29.useState(false);
|
|
10469
|
+
const [isTouchDevice, setIsTouchDevice] = React29.useState(false);
|
|
10036
10470
|
const { wallet, isLoading, setWallet } = useDetectedBrowserWallet({ chainType, onDisconnect });
|
|
10037
|
-
const [isConnecting, setIsConnecting] =
|
|
10038
|
-
const [balanceText, setBalanceText] =
|
|
10039
|
-
const [isLoadingBalance, setIsLoadingBalance] =
|
|
10040
|
-
const [isDisconnecting, setIsDisconnecting] =
|
|
10041
|
-
const onDisconnectRef =
|
|
10471
|
+
const [isConnecting, setIsConnecting] = React29.useState(false);
|
|
10472
|
+
const [balanceText, setBalanceText] = React29.useState(null);
|
|
10473
|
+
const [isLoadingBalance, setIsLoadingBalance] = React29.useState(false);
|
|
10474
|
+
const [isDisconnecting, setIsDisconnecting] = React29.useState(false);
|
|
10475
|
+
const onDisconnectRef = React29.useRef(onDisconnect);
|
|
10042
10476
|
onDisconnectRef.current = onDisconnect;
|
|
10043
|
-
|
|
10477
|
+
React29.useEffect(() => {
|
|
10044
10478
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
10045
10479
|
}, []);
|
|
10046
|
-
|
|
10480
|
+
React29.useEffect(() => {
|
|
10047
10481
|
if (!wallet || !publishableKey) {
|
|
10048
10482
|
setBalanceText(null);
|
|
10049
10483
|
return;
|
|
@@ -10112,21 +10546,19 @@ function BrowserWalletButton({
|
|
|
10112
10546
|
}
|
|
10113
10547
|
}
|
|
10114
10548
|
if (!chainType || chainType === "ethereum") {
|
|
10115
|
-
const
|
|
10116
|
-
if (
|
|
10117
|
-
const accounts = await
|
|
10549
|
+
const resolved = resolveQuickConnectEvmProvider(window);
|
|
10550
|
+
if (resolved) {
|
|
10551
|
+
const accounts = await resolved.provider.request({
|
|
10118
10552
|
method: "eth_requestAccounts"
|
|
10119
10553
|
});
|
|
10120
10554
|
if (accounts && accounts.length > 0) {
|
|
10121
10555
|
setUserDisconnectedWallet(false);
|
|
10122
|
-
|
|
10123
|
-
const walletType = isPhantom ? "phantom-ethereum" : "metamask";
|
|
10124
|
-
setStoredWalletState(walletType);
|
|
10556
|
+
setStoredWalletState(resolved.walletType);
|
|
10125
10557
|
setWallet({
|
|
10126
|
-
type: walletType,
|
|
10127
|
-
name:
|
|
10558
|
+
type: resolved.walletType,
|
|
10559
|
+
name: resolved.name,
|
|
10128
10560
|
address: accounts[0],
|
|
10129
|
-
icon:
|
|
10561
|
+
icon: resolved.icon
|
|
10130
10562
|
});
|
|
10131
10563
|
}
|
|
10132
10564
|
}
|
|
@@ -10160,7 +10592,10 @@ function BrowserWalletButton({
|
|
|
10160
10592
|
if (isLoading) {
|
|
10161
10593
|
return null;
|
|
10162
10594
|
}
|
|
10163
|
-
const
|
|
10595
|
+
const eip6963EvmProviderCount = getEip6963Providers().length;
|
|
10596
|
+
const legacyEvmProviders = getLegacyEvmProviders(window);
|
|
10597
|
+
const hasLegacyEvmProvider = eip6963EvmProviderCount === 0 && !!(legacyEvmProviders.ethereum || legacyEvmProviders.phantomEthereum || legacyEvmProviders.coinbaseEthereum || legacyEvmProviders.trustEthereum || legacyEvmProviders.okxEthereum);
|
|
10598
|
+
const hasWalletExtension = (!chainType || chainType === "ethereum") && eip6963EvmProviderCount > 0 || (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) || (!chainType || chainType === "ethereum") && hasLegacyEvmProvider;
|
|
10164
10599
|
if (!onConnectClick && !wallet && !hasWalletExtension) {
|
|
10165
10600
|
return null;
|
|
10166
10601
|
}
|
|
@@ -10170,11 +10605,25 @@ function BrowserWalletButton({
|
|
|
10170
10605
|
border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
|
|
10171
10606
|
};
|
|
10172
10607
|
const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
|
|
10173
|
-
const
|
|
10608
|
+
const isImageIcon = !!wallet && (wallet.icon.startsWith("data:") || wallet.icon.startsWith("http"));
|
|
10609
|
+
const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React29.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
|
|
10174
10610
|
size: 36,
|
|
10175
10611
|
className: "uf-rounded-lg",
|
|
10176
10612
|
variant: "color"
|
|
10177
|
-
}) :
|
|
10613
|
+
}) : isImageIcon ? (
|
|
10614
|
+
// Wallet announced via EIP-6963 with no internal icon component: render its
|
|
10615
|
+
// own advertised icon (`info.icon`) rather than a generic placeholder.
|
|
10616
|
+
/* @__PURE__ */ jsx41(
|
|
10617
|
+
"img",
|
|
10618
|
+
{
|
|
10619
|
+
src: wallet.icon,
|
|
10620
|
+
alt: wallet.name,
|
|
10621
|
+
width: 36,
|
|
10622
|
+
height: 36,
|
|
10623
|
+
className: "uf-rounded-lg uf-w-9 uf-h-9"
|
|
10624
|
+
}
|
|
10625
|
+
)
|
|
10626
|
+
) : /* @__PURE__ */ jsx41("div", { className: "uf-w-9 uf-h-9 uf-rounded-lg uf-bg-gray-500" }) : /* @__PURE__ */ jsx41("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ jsx41(Wallet, { className: "uf-w-5 uf-h-5", style: { color: components.card.iconColor } }) });
|
|
10178
10627
|
const titleSubtitleBlock = /* @__PURE__ */ jsxs38("div", { className: "uf-text-left uf-min-w-0", children: [
|
|
10179
10628
|
/* @__PURE__ */ jsx41(
|
|
10180
10629
|
"div",
|
|
@@ -10315,7 +10764,7 @@ function BrowserWalletButton({
|
|
|
10315
10764
|
}
|
|
10316
10765
|
|
|
10317
10766
|
// src/components/deposits/buttons/StripeLinkButton.tsx
|
|
10318
|
-
import * as
|
|
10767
|
+
import * as React30 from "react";
|
|
10319
10768
|
import { ChevronRight as ChevronRight14 } from "lucide-react";
|
|
10320
10769
|
import { jsx as jsx42, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
10321
10770
|
var t4 = i18n.depositModal.stripeLink;
|
|
@@ -10326,9 +10775,9 @@ function StripeLinkButton({
|
|
|
10326
10775
|
iconUrl
|
|
10327
10776
|
}) {
|
|
10328
10777
|
const { colors: colors2, fonts, components } = useTheme();
|
|
10329
|
-
const [isHovered, setIsHovered] =
|
|
10330
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
10331
|
-
|
|
10778
|
+
const [isHovered, setIsHovered] = React30.useState(false);
|
|
10779
|
+
const [isTouchDevice, setIsTouchDevice] = React30.useState(false);
|
|
10780
|
+
React30.useEffect(() => {
|
|
10332
10781
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
10333
10782
|
}, []);
|
|
10334
10783
|
return /* @__PURE__ */ jsxs39(
|
|
@@ -10398,12 +10847,12 @@ function StripeLinkButton({
|
|
|
10398
10847
|
}
|
|
10399
10848
|
|
|
10400
10849
|
// src/components/deposits/stripe-link/PayWithStripeLink.tsx
|
|
10401
|
-
import { useState as useState29, useEffect as useEffect24, useCallback as
|
|
10850
|
+
import { useState as useState29, useEffect as useEffect24, useCallback as useCallback6, useRef as useRef9 } from "react";
|
|
10402
10851
|
import {
|
|
10403
10852
|
Loader2 as Loader25,
|
|
10404
10853
|
CreditCard as CreditCard3,
|
|
10405
10854
|
CheckCircle2 as CheckCircle22,
|
|
10406
|
-
AlertTriangle,
|
|
10855
|
+
AlertTriangle as AlertTriangle2,
|
|
10407
10856
|
ArrowRight,
|
|
10408
10857
|
Zap as Zap2,
|
|
10409
10858
|
ChevronDown as ChevronDown3
|
|
@@ -10635,17 +11084,17 @@ import {
|
|
|
10635
11084
|
} from "@unifold/core";
|
|
10636
11085
|
|
|
10637
11086
|
// src/components/deposits/stripe-link/use-stripe-onramp.ts
|
|
10638
|
-
import { useState as useState28, useEffect as useEffect23, useRef as
|
|
11087
|
+
import { useState as useState28, useEffect as useEffect23, useRef as useRef8, useCallback as useCallback5 } from "react";
|
|
10639
11088
|
function useStripeOnramp(stripePublishableKey, isDark = false) {
|
|
10640
11089
|
const [coordinator, setCoordinator] = useState28(null);
|
|
10641
11090
|
const [isLoading, setIsLoading] = useState28(false);
|
|
10642
11091
|
const [error, setError] = useState28(null);
|
|
10643
|
-
const coordinatorRef =
|
|
10644
|
-
const coordinatorThemeRef =
|
|
10645
|
-
const initPromiseRef =
|
|
10646
|
-
const isDarkRef =
|
|
11092
|
+
const coordinatorRef = useRef8(null);
|
|
11093
|
+
const coordinatorThemeRef = useRef8(null);
|
|
11094
|
+
const initPromiseRef = useRef8(null);
|
|
11095
|
+
const isDarkRef = useRef8(isDark);
|
|
10647
11096
|
isDarkRef.current = isDark;
|
|
10648
|
-
const initialize =
|
|
11097
|
+
const initialize = useCallback5(() => {
|
|
10649
11098
|
if (coordinatorRef.current) return Promise.resolve(coordinatorRef.current);
|
|
10650
11099
|
if (initPromiseRef.current) return initPromiseRef.current;
|
|
10651
11100
|
if (!stripePublishableKey) return Promise.resolve(null);
|
|
@@ -10858,6 +11307,8 @@ function PayWithStripeLink({
|
|
|
10858
11307
|
destinationChainType,
|
|
10859
11308
|
destinationChainId,
|
|
10860
11309
|
destinationTokenAddress,
|
|
11310
|
+
countryCode,
|
|
11311
|
+
subdivisionCode,
|
|
10861
11312
|
wallets: externalWallets,
|
|
10862
11313
|
email: emailProp,
|
|
10863
11314
|
iconUrl,
|
|
@@ -10869,14 +11320,14 @@ function PayWithStripeLink({
|
|
|
10869
11320
|
}) {
|
|
10870
11321
|
const { colors: colors2, fonts, components, isDark } = useTheme();
|
|
10871
11322
|
const [step, setStepInternal] = useState29(controlledStep ?? "amount");
|
|
10872
|
-
const setStep =
|
|
11323
|
+
const setStep = useCallback6(
|
|
10873
11324
|
(s) => {
|
|
10874
11325
|
setStepInternal(s);
|
|
10875
11326
|
onStepChange?.(s);
|
|
10876
11327
|
},
|
|
10877
11328
|
[onStepChange]
|
|
10878
11329
|
);
|
|
10879
|
-
const stepRef =
|
|
11330
|
+
const stepRef = useRef9(step);
|
|
10880
11331
|
stepRef.current = step;
|
|
10881
11332
|
useEffect24(() => {
|
|
10882
11333
|
if (controlledStep && controlledStep !== step) {
|
|
@@ -10967,20 +11418,20 @@ function PayWithStripeLink({
|
|
|
10967
11418
|
const [restoring, setRestoring] = useState29(true);
|
|
10968
11419
|
const [errorReturnStep, setErrorReturnStep] = useState29("email");
|
|
10969
11420
|
const [authIntentId, setAuthIntentId] = useState29(null);
|
|
10970
|
-
const sdkAuthenticatedRef =
|
|
10971
|
-
const everAuthenticatedRef =
|
|
10972
|
-
const reauthReturnStepRef =
|
|
10973
|
-
const attemptedWalletReauthRef =
|
|
10974
|
-
const pendingAddPaymentRef =
|
|
10975
|
-
const autoOpenedAddPaymentRef =
|
|
10976
|
-
const checkoutGenRef =
|
|
11421
|
+
const sdkAuthenticatedRef = useRef9(false);
|
|
11422
|
+
const everAuthenticatedRef = useRef9(false);
|
|
11423
|
+
const reauthReturnStepRef = useRef9(null);
|
|
11424
|
+
const attemptedWalletReauthRef = useRef9(false);
|
|
11425
|
+
const pendingAddPaymentRef = useRef9(false);
|
|
11426
|
+
const autoOpenedAddPaymentRef = useRef9(false);
|
|
11427
|
+
const checkoutGenRef = useRef9(0);
|
|
10977
11428
|
const [stripePaymentUIReady, setStripePaymentUIReady] = useState29(false);
|
|
10978
11429
|
const [oauthToken, setOauthToken] = useState29(null);
|
|
10979
11430
|
const [refreshTokenValue, setRefreshTokenValue] = useState29(null);
|
|
10980
11431
|
const [customerId, setCustomerId] = useState29(null);
|
|
10981
|
-
const accessTokenRef =
|
|
10982
|
-
const refreshTokenRef =
|
|
10983
|
-
const persistSession =
|
|
11432
|
+
const accessTokenRef = useRef9("");
|
|
11433
|
+
const refreshTokenRef = useRef9("");
|
|
11434
|
+
const persistSession = useCallback6(
|
|
10984
11435
|
(cid, token, refresh, expiresIn, loginEmail) => {
|
|
10985
11436
|
accessTokenRef.current = token;
|
|
10986
11437
|
refreshTokenRef.current = refresh;
|
|
@@ -10994,8 +11445,8 @@ function PayWithStripeLink({
|
|
|
10994
11445
|
},
|
|
10995
11446
|
[userId, email]
|
|
10996
11447
|
);
|
|
10997
|
-
const refreshInFlightRef =
|
|
10998
|
-
const tryRefreshToken =
|
|
11448
|
+
const refreshInFlightRef = useRef9(null);
|
|
11449
|
+
const tryRefreshToken = useCallback6(async () => {
|
|
10999
11450
|
if (refreshInFlightRef.current) return refreshInFlightRef.current;
|
|
11000
11451
|
const rt = refreshTokenRef.current;
|
|
11001
11452
|
if (!rt) return null;
|
|
@@ -11025,7 +11476,7 @@ function PayWithStripeLink({
|
|
|
11025
11476
|
refreshInFlightRef.current = doRefresh();
|
|
11026
11477
|
return refreshInFlightRef.current;
|
|
11027
11478
|
}, [publishableKey, customerId, persistSession, userId]);
|
|
11028
|
-
const withTokenRefresh =
|
|
11479
|
+
const withTokenRefresh = useCallback6(
|
|
11029
11480
|
async (fn) => {
|
|
11030
11481
|
const token = accessTokenRef.current;
|
|
11031
11482
|
if (!token) {
|
|
@@ -11187,8 +11638,8 @@ function PayWithStripeLink({
|
|
|
11187
11638
|
);
|
|
11188
11639
|
const [selectedPaymentToken, setSelectedPaymentToken] = useState29(null);
|
|
11189
11640
|
const [paymentDisplay, setPaymentDisplay] = useState29(null);
|
|
11190
|
-
const selectedTokenSingleUseRef =
|
|
11191
|
-
const selectPaymentToken =
|
|
11641
|
+
const selectedTokenSingleUseRef = useRef9(false);
|
|
11642
|
+
const selectPaymentToken = useCallback6(
|
|
11192
11643
|
(token) => {
|
|
11193
11644
|
selectedTokenSingleUseRef.current = !!token.singleUse;
|
|
11194
11645
|
setSelectedPaymentToken(token.id);
|
|
@@ -11200,7 +11651,7 @@ function PayWithStripeLink({
|
|
|
11200
11651
|
},
|
|
11201
11652
|
[customerId]
|
|
11202
11653
|
);
|
|
11203
|
-
const clearSelectedPaymentToken =
|
|
11654
|
+
const clearSelectedPaymentToken = useCallback6(() => {
|
|
11204
11655
|
selectedTokenSingleUseRef.current = false;
|
|
11205
11656
|
const persisted = customerId ? getStoredSelectedToken(customerId) : null;
|
|
11206
11657
|
if (persisted && !persisted.singleUse) {
|
|
@@ -11252,7 +11703,9 @@ function PayWithStripeLink({
|
|
|
11252
11703
|
{
|
|
11253
11704
|
tokenAddress: destinationTokenAddress,
|
|
11254
11705
|
chainId: destinationChainId,
|
|
11255
|
-
chainType: destinationChainType
|
|
11706
|
+
chainType: destinationChainType,
|
|
11707
|
+
countryCode,
|
|
11708
|
+
subdivisionCode
|
|
11256
11709
|
},
|
|
11257
11710
|
publishableKey
|
|
11258
11711
|
).then((token) => {
|
|
@@ -11271,10 +11724,17 @@ function PayWithStripeLink({
|
|
|
11271
11724
|
return () => {
|
|
11272
11725
|
cancelled = true;
|
|
11273
11726
|
};
|
|
11274
|
-
}, [
|
|
11727
|
+
}, [
|
|
11728
|
+
publishableKey,
|
|
11729
|
+
destinationTokenAddress,
|
|
11730
|
+
destinationChainId,
|
|
11731
|
+
destinationChainType,
|
|
11732
|
+
countryCode,
|
|
11733
|
+
subdivisionCode
|
|
11734
|
+
]);
|
|
11275
11735
|
const destinationCurrency = stripeDestCurrency;
|
|
11276
|
-
const authInnerRef =
|
|
11277
|
-
const paymentInnerRef =
|
|
11736
|
+
const authInnerRef = useRef9(null);
|
|
11737
|
+
const paymentInnerRef = useRef9(null);
|
|
11278
11738
|
const [authReady, setAuthReady] = useState29(false);
|
|
11279
11739
|
if (typeof document !== "undefined" && !authInnerRef.current) {
|
|
11280
11740
|
authInnerRef.current = document.createElement("div");
|
|
@@ -11282,12 +11742,12 @@ function PayWithStripeLink({
|
|
|
11282
11742
|
if (typeof document !== "undefined" && !paymentInnerRef.current) {
|
|
11283
11743
|
paymentInnerRef.current = document.createElement("div");
|
|
11284
11744
|
}
|
|
11285
|
-
const authMountRef =
|
|
11745
|
+
const authMountRef = useCallback6((node) => {
|
|
11286
11746
|
if (node && !node.contains(authInnerRef.current)) {
|
|
11287
11747
|
node.appendChild(authInnerRef.current);
|
|
11288
11748
|
}
|
|
11289
11749
|
}, []);
|
|
11290
|
-
const paymentMountRef =
|
|
11750
|
+
const paymentMountRef = useCallback6((node) => {
|
|
11291
11751
|
if (node && !node.contains(paymentInnerRef.current)) {
|
|
11292
11752
|
node.appendChild(paymentInnerRef.current);
|
|
11293
11753
|
}
|
|
@@ -11338,8 +11798,8 @@ function PayWithStripeLink({
|
|
|
11338
11798
|
});
|
|
11339
11799
|
const [confirmedSessionId, setConfirmedSessionId] = useState29(null);
|
|
11340
11800
|
const [sessionStatus, setSessionStatus] = useState29(null);
|
|
11341
|
-
const handledTerminalSessionRef =
|
|
11342
|
-
const executionReconciledSessionRef =
|
|
11801
|
+
const handledTerminalSessionRef = useRef9(null);
|
|
11802
|
+
const executionReconciledSessionRef = useRef9(null);
|
|
11343
11803
|
const hasExecution = executions.length > 0;
|
|
11344
11804
|
const isSessionFulfilled = sessionStatus === STRIPE_SESSION_STATUS.FULFILLMENT_COMPLETE || hasExecution;
|
|
11345
11805
|
const isSessionFailed = !hasExecution && (sessionStatus === STRIPE_SESSION_STATUS.REJECTED || sessionStatus === STRIPE_SESSION_STATUS.EXPIRED);
|
|
@@ -11457,7 +11917,7 @@ function PayWithStripeLink({
|
|
|
11457
11917
|
sdkAuthenticatedRef.current = false;
|
|
11458
11918
|
attemptedWalletReauthRef.current = false;
|
|
11459
11919
|
}, [coordinator]);
|
|
11460
|
-
const handleAuthInterrupted =
|
|
11920
|
+
const handleAuthInterrupted = useCallback6(
|
|
11461
11921
|
(message) => {
|
|
11462
11922
|
const alreadySignedIn = !!accessTokenRef.current;
|
|
11463
11923
|
if (alreadySignedIn || emailProp) {
|
|
@@ -11470,7 +11930,7 @@ function PayWithStripeLink({
|
|
|
11470
11930
|
},
|
|
11471
11931
|
[emailProp, setStep]
|
|
11472
11932
|
);
|
|
11473
|
-
const reauthenticateSdk =
|
|
11933
|
+
const reauthenticateSdk = useCallback6(async () => {
|
|
11474
11934
|
const current = stepRef.current;
|
|
11475
11935
|
const preAuthSteps = ["email", "register", "auth"];
|
|
11476
11936
|
reauthReturnStepRef.current = preAuthSteps.includes(current) ? null : current;
|
|
@@ -12169,14 +12629,14 @@ function PayWithStripeLink({
|
|
|
12169
12629
|
};
|
|
12170
12630
|
const [quote, setQuote] = useState29(null);
|
|
12171
12631
|
const [quoteLoading, setQuoteLoading] = useState29(false);
|
|
12172
|
-
const quoteTimerRef =
|
|
12632
|
+
const quoteTimerRef = useRef9(null);
|
|
12173
12633
|
const [sessionForCheckout, setSessionForCheckoutState] = useState29(null);
|
|
12174
|
-
const sessionForCheckoutRef =
|
|
12634
|
+
const sessionForCheckoutRef = useRef9(sessionForCheckout);
|
|
12175
12635
|
const setSessionForCheckout = (s) => {
|
|
12176
12636
|
sessionForCheckoutRef.current = s;
|
|
12177
12637
|
setSessionForCheckoutState(s);
|
|
12178
12638
|
};
|
|
12179
|
-
const loadAndSelectPreferredToken =
|
|
12639
|
+
const loadAndSelectPreferredToken = useCallback6(async () => {
|
|
12180
12640
|
if (!customerId) return;
|
|
12181
12641
|
try {
|
|
12182
12642
|
const existing = await withTokenRefresh(
|
|
@@ -12206,7 +12666,7 @@ function PayWithStripeLink({
|
|
|
12206
12666
|
};
|
|
12207
12667
|
const [quoteError, setQuoteError] = useState29(null);
|
|
12208
12668
|
const [quoteNonce, setQuoteNonce] = useState29(0);
|
|
12209
|
-
const quoteNonceAtReviewRef =
|
|
12669
|
+
const quoteNonceAtReviewRef = useRef9(quoteNonce);
|
|
12210
12670
|
const [purchaseLimit, setPurchaseLimit] = useState29(null);
|
|
12211
12671
|
const [limitReachedAmount, setLimitReachedAmount] = useState29(null);
|
|
12212
12672
|
const [requiredStepUp, setRequiredStepUp] = useState29(null);
|
|
@@ -12438,7 +12898,7 @@ function PayWithStripeLink({
|
|
|
12438
12898
|
};
|
|
12439
12899
|
if (configError) {
|
|
12440
12900
|
return /* @__PURE__ */ jsxs41("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-12 uf-px-4", children: [
|
|
12441
|
-
/* @__PURE__ */ jsx44(
|
|
12901
|
+
/* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10 uf-mb-3", style: { color: colors2.error } }),
|
|
12442
12902
|
/* @__PURE__ */ jsx44(
|
|
12443
12903
|
"p",
|
|
12444
12904
|
{
|
|
@@ -12452,7 +12912,7 @@ function PayWithStripeLink({
|
|
|
12452
12912
|
if (step === "kyc" || step === "wallet") {
|
|
12453
12913
|
if (error && !loading) {
|
|
12454
12914
|
return /* @__PURE__ */ jsxs41("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-12 uf-px-4", children: [
|
|
12455
|
-
/* @__PURE__ */ jsx44(
|
|
12915
|
+
/* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10 uf-mb-3", style: { color: colors2.error } }),
|
|
12456
12916
|
/* @__PURE__ */ jsx44(
|
|
12457
12917
|
"p",
|
|
12458
12918
|
{
|
|
@@ -12591,7 +13051,7 @@ function PayWithStripeLink({
|
|
|
12591
13051
|
},
|
|
12592
13052
|
children: [
|
|
12593
13053
|
/* @__PURE__ */ jsx44(
|
|
12594
|
-
|
|
13054
|
+
AlertTriangle2,
|
|
12595
13055
|
{
|
|
12596
13056
|
className: "uf-w-4 uf-h-4 uf-mt-0.5 uf-shrink-0",
|
|
12597
13057
|
style: { color: colors2.error }
|
|
@@ -13496,7 +13956,7 @@ function PayWithStripeLink({
|
|
|
13496
13956
|
const fatalError = sdkError || configError;
|
|
13497
13957
|
if (fatalError) {
|
|
13498
13958
|
return /* @__PURE__ */ jsxs41("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-12 uf-px-4", children: [
|
|
13499
|
-
/* @__PURE__ */ jsx44(
|
|
13959
|
+
/* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10 uf-mb-3", style: { color: colors2.error } }),
|
|
13500
13960
|
/* @__PURE__ */ jsx44(
|
|
13501
13961
|
"p",
|
|
13502
13962
|
{
|
|
@@ -14051,7 +14511,7 @@ function PayWithStripeLink({
|
|
|
14051
14511
|
backgroundColor: isSessionFulfilled ? colors2.success : isSessionFailed ? colors2.error : "#f59e0b",
|
|
14052
14512
|
border: `2px solid ${colors2.background}`
|
|
14053
14513
|
},
|
|
14054
|
-
children: isSessionFulfilled ? /* @__PURE__ */ jsx44(CheckCircle22, { className: "uf-w-4 uf-h-4 uf-text-white" }) : isSessionFailed ? /* @__PURE__ */ jsx44(
|
|
14514
|
+
children: isSessionFulfilled ? /* @__PURE__ */ jsx44(CheckCircle22, { className: "uf-w-4 uf-h-4 uf-text-white" }) : isSessionFailed ? /* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-3.5 uf-h-3.5 uf-text-white" }) : /* @__PURE__ */ jsx44(Loader25, { className: "uf-w-3.5 uf-h-3.5 uf-text-white uf-animate-spin" })
|
|
14055
14515
|
}
|
|
14056
14516
|
)
|
|
14057
14517
|
] }),
|
|
@@ -14080,7 +14540,7 @@ function PayWithStripeLink({
|
|
|
14080
14540
|
{
|
|
14081
14541
|
className: "uf-w-20 uf-h-20 uf-rounded-full uf-flex uf-items-center uf-justify-center uf-mb-6",
|
|
14082
14542
|
style: { backgroundColor: `${colors2.error}20` },
|
|
14083
|
-
children: /* @__PURE__ */ jsx44(
|
|
14543
|
+
children: /* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10", style: { color: colors2.error } })
|
|
14084
14544
|
}
|
|
14085
14545
|
),
|
|
14086
14546
|
/* @__PURE__ */ jsx44(
|
|
@@ -14121,7 +14581,7 @@ function PayWithStripeLink({
|
|
|
14121
14581
|
}
|
|
14122
14582
|
|
|
14123
14583
|
// src/components/deposits/CoinbaseConnect.tsx
|
|
14124
|
-
import { useState as useState30, useEffect as useEffect25, useCallback as
|
|
14584
|
+
import { useState as useState30, useEffect as useEffect25, useCallback as useCallback7, useMemo as useMemo8, useRef as useRef10 } from "react";
|
|
14125
14585
|
import {
|
|
14126
14586
|
ChevronRight as ChevronRight15,
|
|
14127
14587
|
ChevronDown as ChevronDown4,
|
|
@@ -14144,7 +14604,7 @@ import {
|
|
|
14144
14604
|
} from "@unifold/core";
|
|
14145
14605
|
|
|
14146
14606
|
// src/hooks/use-project-config.ts
|
|
14147
|
-
import { useQuery as
|
|
14607
|
+
import { useQuery as useQuery9, keepPreviousData } from "@tanstack/react-query";
|
|
14148
14608
|
import { getProjectConfig } from "@unifold/core";
|
|
14149
14609
|
function useProjectConfig({
|
|
14150
14610
|
publishableKey,
|
|
@@ -14156,7 +14616,7 @@ function useProjectConfig({
|
|
|
14156
14616
|
data: projectConfig,
|
|
14157
14617
|
isLoading,
|
|
14158
14618
|
error
|
|
14159
|
-
} =
|
|
14619
|
+
} = useQuery9({
|
|
14160
14620
|
// Country is part of the key so a region change refetches the region-aware
|
|
14161
14621
|
// config. Omitted when undefined so callers that don't pass a country keep
|
|
14162
14622
|
// sharing the base cache entry.
|
|
@@ -14175,7 +14635,7 @@ function useProjectConfig({
|
|
|
14175
14635
|
}
|
|
14176
14636
|
|
|
14177
14637
|
// src/hooks/use-supported-deposit-tokens.ts
|
|
14178
|
-
import { useQuery as
|
|
14638
|
+
import { useQuery as useQuery10 } from "@tanstack/react-query";
|
|
14179
14639
|
import {
|
|
14180
14640
|
getSupportedDepositTokens
|
|
14181
14641
|
} from "@unifold/core";
|
|
@@ -14190,7 +14650,7 @@ function useSupportedDepositTokens(publishableKey, options) {
|
|
|
14190
14650
|
...options?.product_type ? { product_type: options.product_type } : {}
|
|
14191
14651
|
};
|
|
14192
14652
|
const hasFilteredOptions = Object.keys(filteredOptions).length > 0;
|
|
14193
|
-
return
|
|
14653
|
+
return useQuery10({
|
|
14194
14654
|
queryKey: [
|
|
14195
14655
|
"unifold",
|
|
14196
14656
|
"supportedDepositTokens",
|
|
@@ -14211,7 +14671,7 @@ function useSupportedDepositTokens(publishableKey, options) {
|
|
|
14211
14671
|
}
|
|
14212
14672
|
|
|
14213
14673
|
// src/hooks/use-integration-transfer-default-token.ts
|
|
14214
|
-
import { useQuery as
|
|
14674
|
+
import { useQuery as useQuery11 } from "@tanstack/react-query";
|
|
14215
14675
|
import {
|
|
14216
14676
|
getIntegrationTransferDefaultToken
|
|
14217
14677
|
} from "@unifold/core";
|
|
@@ -14220,7 +14680,7 @@ function useIntegrationTransferDefaultToken({
|
|
|
14220
14680
|
publishableKey,
|
|
14221
14681
|
enabled = true
|
|
14222
14682
|
}) {
|
|
14223
|
-
return
|
|
14683
|
+
return useQuery11({
|
|
14224
14684
|
queryKey: [
|
|
14225
14685
|
"unifold",
|
|
14226
14686
|
"integrationTransferDefaultToken",
|
|
@@ -14291,7 +14751,8 @@ function CoinbaseConnect({
|
|
|
14291
14751
|
defaultSourceChainType,
|
|
14292
14752
|
defaultSourceChainId,
|
|
14293
14753
|
defaultSourceTokenAddress,
|
|
14294
|
-
defaultSourceSymbol
|
|
14754
|
+
defaultSourceSymbol,
|
|
14755
|
+
prefilledAmountUsd
|
|
14295
14756
|
}) {
|
|
14296
14757
|
const { colors: colors2, fonts, components } = useTheme();
|
|
14297
14758
|
const { projectConfig } = useProjectConfig({ publishableKey });
|
|
@@ -14301,12 +14762,12 @@ function CoinbaseConnect({
|
|
|
14301
14762
|
destination_chain_id: destinationChainId,
|
|
14302
14763
|
destination_chain_type: destinationChainType
|
|
14303
14764
|
});
|
|
14304
|
-
const supportedSymbols =
|
|
14765
|
+
const supportedSymbols = useMemo8(() => {
|
|
14305
14766
|
const set = /* @__PURE__ */ new Set();
|
|
14306
14767
|
supportedTokensData?.data.forEach((token) => set.add(token.symbol.toLowerCase()));
|
|
14307
14768
|
return set;
|
|
14308
14769
|
}, [supportedTokensData]);
|
|
14309
|
-
const stablecoinSymbols =
|
|
14770
|
+
const stablecoinSymbols = useMemo8(() => {
|
|
14310
14771
|
const set = /* @__PURE__ */ new Set();
|
|
14311
14772
|
supportedTokensData?.data.forEach((token) => {
|
|
14312
14773
|
if (token.is_stablecoin) set.add(token.symbol.toLowerCase());
|
|
@@ -14339,12 +14800,12 @@ function CoinbaseConnect({
|
|
|
14339
14800
|
const [transferDepositWalletId, setTransferDepositWalletId] = useState30(
|
|
14340
14801
|
void 0
|
|
14341
14802
|
);
|
|
14342
|
-
const exchangeSupportedCurrencies =
|
|
14803
|
+
const exchangeSupportedCurrencies = useMemo8(() => {
|
|
14343
14804
|
const set = /* @__PURE__ */ new Set();
|
|
14344
14805
|
selectedExchange?.supported_currencies.forEach((c) => set.add(c.toLowerCase()));
|
|
14345
14806
|
return set;
|
|
14346
14807
|
}, [selectedExchange]);
|
|
14347
|
-
const defaultTokenParams =
|
|
14808
|
+
const defaultTokenParams = useMemo8(
|
|
14348
14809
|
() => selectedAsset ? {
|
|
14349
14810
|
integration_provider: IntegrationProvider.COINBASE,
|
|
14350
14811
|
source_currency: selectedAsset.currency.toLowerCase(),
|
|
@@ -14367,7 +14828,7 @@ function CoinbaseConnect({
|
|
|
14367
14828
|
params: defaultTokenParams,
|
|
14368
14829
|
publishableKey
|
|
14369
14830
|
});
|
|
14370
|
-
const defaultSourceCurrency =
|
|
14831
|
+
const defaultSourceCurrency = useMemo8(
|
|
14371
14832
|
() => resolveDefaultSourceSymbol(supportedTokensData?.data, {
|
|
14372
14833
|
defaultSourceChainType,
|
|
14373
14834
|
defaultSourceChainId,
|
|
@@ -14382,7 +14843,7 @@ function CoinbaseConnect({
|
|
|
14382
14843
|
defaultSourceSymbol
|
|
14383
14844
|
]
|
|
14384
14845
|
);
|
|
14385
|
-
const sortedHoldings =
|
|
14846
|
+
const sortedHoldings = useMemo8(() => {
|
|
14386
14847
|
const supported = [];
|
|
14387
14848
|
const unsupported = [];
|
|
14388
14849
|
holdings.forEach((account) => {
|
|
@@ -14402,7 +14863,7 @@ function CoinbaseConnect({
|
|
|
14402
14863
|
}
|
|
14403
14864
|
return [...supported, ...unsupported];
|
|
14404
14865
|
}, [holdings, supportedSymbols, exchangeSupportedCurrencies, defaultSourceCurrency]);
|
|
14405
|
-
const selectedHoldingIsSupported =
|
|
14866
|
+
const selectedHoldingIsSupported = useMemo8(() => {
|
|
14406
14867
|
if (!selectedHolding) return false;
|
|
14407
14868
|
const currencyLower = selectedHolding.currency.toLowerCase();
|
|
14408
14869
|
return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
|
|
@@ -14446,10 +14907,10 @@ function CoinbaseConnect({
|
|
|
14446
14907
|
useEffect25(() => {
|
|
14447
14908
|
onExecutionsChange?.(depositExecutions);
|
|
14448
14909
|
}, [depositExecutions, onExecutionsChange]);
|
|
14449
|
-
const pollRef =
|
|
14450
|
-
const popupRef =
|
|
14451
|
-
const viewRef =
|
|
14452
|
-
const transitionTo =
|
|
14910
|
+
const pollRef = useRef10(null);
|
|
14911
|
+
const popupRef = useRef10(null);
|
|
14912
|
+
const viewRef = useRef10(initialView);
|
|
14913
|
+
const transitionTo = useCallback7((nextView) => {
|
|
14453
14914
|
if (nextView === viewRef.current) return;
|
|
14454
14915
|
setIsTransitioning(true);
|
|
14455
14916
|
setTimeout(() => {
|
|
@@ -14459,7 +14920,7 @@ function CoinbaseConnect({
|
|
|
14459
14920
|
setIsTransitioning(false);
|
|
14460
14921
|
}, 150);
|
|
14461
14922
|
}, []);
|
|
14462
|
-
const tryRefreshToken =
|
|
14923
|
+
const tryRefreshToken = useCallback7(
|
|
14463
14924
|
async (currentToken) => {
|
|
14464
14925
|
try {
|
|
14465
14926
|
const result = await refreshIntegrationToken(currentToken, publishableKey);
|
|
@@ -14497,7 +14958,7 @@ function CoinbaseConnect({
|
|
|
14497
14958
|
}
|
|
14498
14959
|
}
|
|
14499
14960
|
}, []);
|
|
14500
|
-
const loadHoldings =
|
|
14961
|
+
const loadHoldings = useCallback7(
|
|
14501
14962
|
async (token) => {
|
|
14502
14963
|
setIsLoading(true);
|
|
14503
14964
|
try {
|
|
@@ -14549,7 +15010,7 @@ function CoinbaseConnect({
|
|
|
14549
15010
|
if (pollRef.current) clearInterval(pollRef.current);
|
|
14550
15011
|
};
|
|
14551
15012
|
}, []);
|
|
14552
|
-
const minDepositUsd =
|
|
15013
|
+
const minDepositUsd = useMemo8(() => {
|
|
14553
15014
|
if (!selectedAsset || !defaultTokenData) return 0;
|
|
14554
15015
|
const supportedToken = supportedTokensData?.data.find(
|
|
14555
15016
|
(t14) => t14.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
|
|
@@ -14560,7 +15021,7 @@ function CoinbaseConnect({
|
|
|
14560
15021
|
);
|
|
14561
15022
|
return matchingChain?.minimum_deposit_amount_usd ?? Math.min(...supportedToken.chains.map((c) => c.minimum_deposit_amount_usd));
|
|
14562
15023
|
}, [selectedAsset, supportedTokensData, defaultTokenData]);
|
|
14563
|
-
const estimatedProcessingTime =
|
|
15024
|
+
const estimatedProcessingTime = useMemo8(() => {
|
|
14564
15025
|
if (!selectedAsset || !defaultTokenData) return null;
|
|
14565
15026
|
const supportedToken = supportedTokensData?.data.find(
|
|
14566
15027
|
(t14) => t14.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
|
|
@@ -14614,7 +15075,8 @@ function CoinbaseConnect({
|
|
|
14614
15075
|
};
|
|
14615
15076
|
const handleSelectAsset = (asset) => {
|
|
14616
15077
|
setSelectedAsset(asset);
|
|
14617
|
-
|
|
15078
|
+
const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
|
|
15079
|
+
setSendAmount(cleanedPrefilled);
|
|
14618
15080
|
transitionTo("enter_amount");
|
|
14619
15081
|
};
|
|
14620
15082
|
const handleCreateTransfer = async () => {
|
|
@@ -16200,13 +16662,13 @@ function CoinbaseConnect({
|
|
|
16200
16662
|
CoinbaseConnect.displayName = "CoinbaseConnect";
|
|
16201
16663
|
|
|
16202
16664
|
// src/hooks/use-exchanges.ts
|
|
16203
|
-
import { useQuery as
|
|
16665
|
+
import { useQuery as useQuery12 } from "@tanstack/react-query";
|
|
16204
16666
|
import { getExchanges } from "@unifold/core";
|
|
16205
16667
|
function useExchanges({
|
|
16206
16668
|
publishableKey,
|
|
16207
16669
|
enabled = true
|
|
16208
16670
|
}) {
|
|
16209
|
-
const { data: exchanges = [], isLoading } =
|
|
16671
|
+
const { data: exchanges = [], isLoading } = useQuery12({
|
|
16210
16672
|
queryKey: ["unifold", "exchanges", publishableKey],
|
|
16211
16673
|
queryFn: () => getExchanges(void 0, publishableKey).then((res) => res.data),
|
|
16212
16674
|
enabled,
|
|
@@ -16217,14 +16679,36 @@ function useExchanges({
|
|
|
16217
16679
|
return { exchanges, isLoading };
|
|
16218
16680
|
}
|
|
16219
16681
|
|
|
16682
|
+
// src/hooks/use-public-incident.ts
|
|
16683
|
+
import { useQuery as useQuery13 } from "@tanstack/react-query";
|
|
16684
|
+
import { getPublicIncident } from "@unifold/core";
|
|
16685
|
+
function usePublicIncident({
|
|
16686
|
+
publishableKey,
|
|
16687
|
+
enabled = true
|
|
16688
|
+
}) {
|
|
16689
|
+
const {
|
|
16690
|
+
data: incident,
|
|
16691
|
+
isLoading,
|
|
16692
|
+
error
|
|
16693
|
+
} = useQuery13({
|
|
16694
|
+
queryKey: ["unifold", "publicIncident", publishableKey],
|
|
16695
|
+
queryFn: () => getPublicIncident(publishableKey),
|
|
16696
|
+
enabled,
|
|
16697
|
+
staleTime: 1e3 * 30,
|
|
16698
|
+
refetchInterval: 1e3 * 30,
|
|
16699
|
+
refetchOnWindowFocus: true
|
|
16700
|
+
});
|
|
16701
|
+
return { incident, isLoading, error: error ?? null };
|
|
16702
|
+
}
|
|
16703
|
+
|
|
16220
16704
|
// src/hooks/use-apple-pay-providers.ts
|
|
16221
|
-
import { useQuery as
|
|
16705
|
+
import { useQuery as useQuery14 } from "@tanstack/react-query";
|
|
16222
16706
|
import { getApplePayProviders } from "@unifold/core";
|
|
16223
16707
|
function useApplePayProviders({
|
|
16224
16708
|
publishableKey,
|
|
16225
16709
|
enabled = true
|
|
16226
16710
|
}) {
|
|
16227
|
-
const { data: providers, isLoading } =
|
|
16711
|
+
const { data: providers, isLoading } = useQuery14({
|
|
16228
16712
|
queryKey: ["unifold", "applePayProviders", publishableKey],
|
|
16229
16713
|
queryFn: () => getApplePayProviders(publishableKey),
|
|
16230
16714
|
enabled,
|
|
@@ -16243,7 +16727,8 @@ import {
|
|
|
16243
16727
|
refreshIntegrationToken as refreshIntegrationToken2,
|
|
16244
16728
|
revokeIntegrationToken,
|
|
16245
16729
|
IntegrationProvider as IntegrationProvider2,
|
|
16246
|
-
ActionType as ActionType3
|
|
16730
|
+
ActionType as ActionType3,
|
|
16731
|
+
isDepositAddressValidationError as isDepositAddressValidationError2
|
|
16247
16732
|
} from "@unifold/core";
|
|
16248
16733
|
|
|
16249
16734
|
// src/hooks/use-allowed-country.ts
|
|
@@ -16289,7 +16774,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
16289
16774
|
}
|
|
16290
16775
|
|
|
16291
16776
|
// src/hooks/use-address-validation.ts
|
|
16292
|
-
import { useQuery as
|
|
16777
|
+
import { useQuery as useQuery15 } from "@tanstack/react-query";
|
|
16293
16778
|
import {
|
|
16294
16779
|
verifyRecipientAddress
|
|
16295
16780
|
} from "@unifold/core";
|
|
@@ -16303,7 +16788,7 @@ function useAddressValidation({
|
|
|
16303
16788
|
refetchOnMount = false
|
|
16304
16789
|
}) {
|
|
16305
16790
|
const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
16306
|
-
const { data, isLoading, error } =
|
|
16791
|
+
const { data, isLoading, error } = useQuery15({
|
|
16307
16792
|
queryKey: [
|
|
16308
16793
|
"unifold",
|
|
16309
16794
|
"addressValidation",
|
|
@@ -16334,6 +16819,7 @@ function useAddressValidation({
|
|
|
16334
16819
|
return {
|
|
16335
16820
|
isValid: null,
|
|
16336
16821
|
failureCode: null,
|
|
16822
|
+
message: null,
|
|
16337
16823
|
metadata: null,
|
|
16338
16824
|
isLoading: false,
|
|
16339
16825
|
error: null
|
|
@@ -16342,6 +16828,7 @@ function useAddressValidation({
|
|
|
16342
16828
|
return {
|
|
16343
16829
|
isValid: data?.valid ?? null,
|
|
16344
16830
|
failureCode: data?.failure_code ?? null,
|
|
16831
|
+
message: data?.message ?? null,
|
|
16345
16832
|
metadata: data?.metadata ?? null,
|
|
16346
16833
|
isLoading,
|
|
16347
16834
|
error: error ?? null
|
|
@@ -16349,11 +16836,11 @@ function useAddressValidation({
|
|
|
16349
16836
|
}
|
|
16350
16837
|
|
|
16351
16838
|
// src/components/deposits/TransferCryptoSingleInput.tsx
|
|
16352
|
-
import { useState as useState36, useEffect as useEffect30, useMemo as
|
|
16839
|
+
import { useState as useState36, useEffect as useEffect30, useMemo as useMemo11 } from "react";
|
|
16353
16840
|
import {
|
|
16354
16841
|
ChevronDown as ChevronDown5,
|
|
16355
16842
|
ChevronUp as ChevronUp3,
|
|
16356
|
-
Info,
|
|
16843
|
+
Info as Info2,
|
|
16357
16844
|
Check as Check4,
|
|
16358
16845
|
DollarSign,
|
|
16359
16846
|
ShieldCheck,
|
|
@@ -16367,14 +16854,14 @@ import {
|
|
|
16367
16854
|
import { useEffect as useEffect27, useState as useState31 } from "react";
|
|
16368
16855
|
|
|
16369
16856
|
// src/components/shared/ThemeStyleInjector.tsx
|
|
16370
|
-
import * as
|
|
16857
|
+
import * as React32 from "react";
|
|
16371
16858
|
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
16372
16859
|
function ThemeStyleInjector({
|
|
16373
16860
|
children,
|
|
16374
16861
|
className
|
|
16375
16862
|
}) {
|
|
16376
16863
|
const { colors: colors2, fonts, mode } = useTheme();
|
|
16377
|
-
const cssVars =
|
|
16864
|
+
const cssVars = React32.useMemo(() => {
|
|
16378
16865
|
const hexToHSL = (hex) => {
|
|
16379
16866
|
hex = hex.replace("#", "");
|
|
16380
16867
|
const r = parseInt(hex.slice(0, 2), 16) / 255;
|
|
@@ -16434,7 +16921,7 @@ function ThemeStyleInjector({
|
|
|
16434
16921
|
...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
|
|
16435
16922
|
};
|
|
16436
16923
|
}, [colors2, fonts.regular]);
|
|
16437
|
-
|
|
16924
|
+
React32.useEffect(() => {
|
|
16438
16925
|
if (typeof document === "undefined") return;
|
|
16439
16926
|
if (fonts.regular) {
|
|
16440
16927
|
document.documentElement.style.setProperty("--uf-font-family", fonts.regular);
|
|
@@ -16708,7 +17195,7 @@ function DepositsModal({
|
|
|
16708
17195
|
}
|
|
16709
17196
|
|
|
16710
17197
|
// src/components/deposits/TokenSelectorSheet.tsx
|
|
16711
|
-
import { useState as useState32, useMemo as
|
|
17198
|
+
import { useState as useState32, useMemo as useMemo10, useEffect as useEffect28 } from "react";
|
|
16712
17199
|
import { ArrowLeft as ArrowLeft2, X as X4 } from "lucide-react";
|
|
16713
17200
|
import Fuse from "fuse.js";
|
|
16714
17201
|
import { jsx as jsx49, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
@@ -16775,7 +17262,7 @@ function TokenSelectorSheet({
|
|
|
16775
17262
|
useEffect28(() => {
|
|
16776
17263
|
setRecentTokens(getRecentTokens());
|
|
16777
17264
|
}, []);
|
|
16778
|
-
const allOptions =
|
|
17265
|
+
const allOptions = useMemo10(() => {
|
|
16779
17266
|
const options = [];
|
|
16780
17267
|
tokens.forEach((token) => {
|
|
16781
17268
|
token.chains.forEach((chain) => {
|
|
@@ -16784,7 +17271,7 @@ function TokenSelectorSheet({
|
|
|
16784
17271
|
});
|
|
16785
17272
|
return options;
|
|
16786
17273
|
}, [tokens]);
|
|
16787
|
-
const quickSelectOptions =
|
|
17274
|
+
const quickSelectOptions = useMemo10(() => {
|
|
16788
17275
|
const result = [];
|
|
16789
17276
|
const seen = /* @__PURE__ */ new Set();
|
|
16790
17277
|
const addOption = (symbol, chainType, chainId, isRecent) => {
|
|
@@ -16816,7 +17303,7 @@ function TokenSelectorSheet({
|
|
|
16816
17303
|
});
|
|
16817
17304
|
setRecentTokens(updated);
|
|
16818
17305
|
};
|
|
16819
|
-
const fuse =
|
|
17306
|
+
const fuse = useMemo10(
|
|
16820
17307
|
() => new Fuse(allOptions, {
|
|
16821
17308
|
keys: [
|
|
16822
17309
|
{ name: "token.symbol", weight: 2 },
|
|
@@ -16829,7 +17316,7 @@ function TokenSelectorSheet({
|
|
|
16829
17316
|
}),
|
|
16830
17317
|
[allOptions]
|
|
16831
17318
|
);
|
|
16832
|
-
const filteredOptions =
|
|
17319
|
+
const filteredOptions = useMemo10(() => {
|
|
16833
17320
|
if (!searchQuery.trim()) return allOptions;
|
|
16834
17321
|
const query = searchQuery.trim();
|
|
16835
17322
|
const results = fuse.search(query);
|
|
@@ -17201,10 +17688,41 @@ function TokenSelectorSheet({
|
|
|
17201
17688
|
}
|
|
17202
17689
|
|
|
17203
17690
|
// src/hooks/use-default-token.ts
|
|
17204
|
-
import { useState as useState33, useEffect as useEffect29, useRef as
|
|
17691
|
+
import { useState as useState33, useEffect as useEffect29, useRef as useRef11, useCallback as useCallback8 } from "react";
|
|
17205
17692
|
var getChainKey = (chainId, chainType) => {
|
|
17206
17693
|
return `${chainType}:${chainId}`;
|
|
17207
17694
|
};
|
|
17695
|
+
function getStoredSelection(key) {
|
|
17696
|
+
if (typeof window === "undefined") return null;
|
|
17697
|
+
try {
|
|
17698
|
+
const raw = localStorage.getItem(key);
|
|
17699
|
+
if (!raw) return null;
|
|
17700
|
+
const parsed = JSON.parse(raw);
|
|
17701
|
+
if (parsed && typeof parsed.symbol === "string" && typeof parsed.chainType === "string" && typeof parsed.chainId === "string") {
|
|
17702
|
+
return parsed;
|
|
17703
|
+
}
|
|
17704
|
+
} catch {
|
|
17705
|
+
}
|
|
17706
|
+
return null;
|
|
17707
|
+
}
|
|
17708
|
+
function saveStoredSelection(key, symbol, chainType, chainId) {
|
|
17709
|
+
if (typeof window === "undefined") return;
|
|
17710
|
+
try {
|
|
17711
|
+
localStorage.setItem(key, JSON.stringify({ symbol, chainType, chainId }));
|
|
17712
|
+
} catch {
|
|
17713
|
+
}
|
|
17714
|
+
}
|
|
17715
|
+
function resolveFromStorage(tokens, stored) {
|
|
17716
|
+
for (const t13 of tokens) {
|
|
17717
|
+
if (t13.symbol !== stored.symbol) continue;
|
|
17718
|
+
const matchedChain = t13.chains.find(
|
|
17719
|
+
(c) => c.chain_type === stored.chainType && c.chain_id === stored.chainId
|
|
17720
|
+
);
|
|
17721
|
+
if (matchedChain) return { token: t13, chain: matchedChain };
|
|
17722
|
+
if (t13.chains.length > 0) return { token: t13, chain: t13.chains[0] };
|
|
17723
|
+
}
|
|
17724
|
+
return null;
|
|
17725
|
+
}
|
|
17208
17726
|
function resolveToken(tokens, defaultChainType, defaultChainId, defaultTokenAddress, defaultSymbol) {
|
|
17209
17727
|
if (!tokens.length) return null;
|
|
17210
17728
|
let selectedToken;
|
|
@@ -17254,27 +17772,73 @@ function useDefaultToken({
|
|
|
17254
17772
|
defaultChainType,
|
|
17255
17773
|
defaultChainId,
|
|
17256
17774
|
defaultTokenAddress,
|
|
17257
|
-
defaultSymbol
|
|
17775
|
+
defaultSymbol,
|
|
17776
|
+
storageKey: storageKey2
|
|
17258
17777
|
}) {
|
|
17259
|
-
const [token,
|
|
17260
|
-
const [chain,
|
|
17778
|
+
const [token, setTokenState] = useState33(null);
|
|
17779
|
+
const [chain, setChainState] = useState33(null);
|
|
17261
17780
|
const [initialSelectionDone, setInitialSelectionDone] = useState33(false);
|
|
17262
|
-
const appliedDefaultsRef =
|
|
17781
|
+
const appliedDefaultsRef = useRef11("");
|
|
17782
|
+
const tokenRef = useRef11(null);
|
|
17783
|
+
const chainRef = useRef11(null);
|
|
17784
|
+
tokenRef.current = token;
|
|
17785
|
+
chainRef.current = chain;
|
|
17786
|
+
const setToken = useCallback8(
|
|
17787
|
+
(newToken) => {
|
|
17788
|
+
tokenRef.current = newToken;
|
|
17789
|
+
setTokenState(newToken);
|
|
17790
|
+
if (storageKey2 && chainRef.current) {
|
|
17791
|
+
const [chainType, chainId] = chainRef.current.split(":");
|
|
17792
|
+
saveStoredSelection(storageKey2, newToken, chainType, chainId);
|
|
17793
|
+
}
|
|
17794
|
+
},
|
|
17795
|
+
[storageKey2]
|
|
17796
|
+
);
|
|
17797
|
+
const setChain = useCallback8(
|
|
17798
|
+
(newChain) => {
|
|
17799
|
+
chainRef.current = newChain;
|
|
17800
|
+
setChainState(newChain);
|
|
17801
|
+
if (storageKey2 && tokenRef.current) {
|
|
17802
|
+
const [chainType, chainId] = newChain.split(":");
|
|
17803
|
+
saveStoredSelection(storageKey2, tokenRef.current, chainType, chainId);
|
|
17804
|
+
}
|
|
17805
|
+
},
|
|
17806
|
+
[storageKey2]
|
|
17807
|
+
);
|
|
17263
17808
|
useEffect29(() => {
|
|
17264
17809
|
if (!tokens.length) return;
|
|
17265
17810
|
const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
|
|
17266
17811
|
const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
|
|
17267
17812
|
if (initialSelectionDone && !defaultsChanged) return;
|
|
17268
|
-
const
|
|
17269
|
-
|
|
17270
|
-
|
|
17271
|
-
|
|
17272
|
-
|
|
17273
|
-
|
|
17274
|
-
|
|
17813
|
+
const hasExplicitDefaults = defaultTokenAddress && defaultChainType && defaultChainId || defaultSymbol && defaultChainType && defaultChainId;
|
|
17814
|
+
let result = null;
|
|
17815
|
+
if (hasExplicitDefaults) {
|
|
17816
|
+
result = resolveToken(
|
|
17817
|
+
tokens,
|
|
17818
|
+
defaultChainType,
|
|
17819
|
+
defaultChainId,
|
|
17820
|
+
defaultTokenAddress,
|
|
17821
|
+
defaultSymbol
|
|
17822
|
+
);
|
|
17823
|
+
if (result) {
|
|
17824
|
+
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;
|
|
17825
|
+
if (!matched) {
|
|
17826
|
+
result = null;
|
|
17827
|
+
}
|
|
17828
|
+
}
|
|
17829
|
+
}
|
|
17830
|
+
if (!result && storageKey2) {
|
|
17831
|
+
const stored = getStoredSelection(storageKey2);
|
|
17832
|
+
if (stored) {
|
|
17833
|
+
result = resolveFromStorage(tokens, stored);
|
|
17834
|
+
}
|
|
17835
|
+
}
|
|
17836
|
+
if (!result) {
|
|
17837
|
+
result = resolveToken(tokens);
|
|
17838
|
+
}
|
|
17275
17839
|
if (result) {
|
|
17276
|
-
|
|
17277
|
-
|
|
17840
|
+
setTokenState(result.token.symbol);
|
|
17841
|
+
setChainState(getChainKey(result.chain.chain_id, result.chain.chain_type));
|
|
17278
17842
|
appliedDefaultsRef.current = defaultsKey;
|
|
17279
17843
|
setInitialSelectionDone(true);
|
|
17280
17844
|
}
|
|
@@ -17284,7 +17848,8 @@ function useDefaultToken({
|
|
|
17284
17848
|
defaultSymbol,
|
|
17285
17849
|
defaultChainType,
|
|
17286
17850
|
defaultChainId,
|
|
17287
|
-
initialSelectionDone
|
|
17851
|
+
initialSelectionDone,
|
|
17852
|
+
storageKey2
|
|
17288
17853
|
]);
|
|
17289
17854
|
useEffect29(() => {
|
|
17290
17855
|
if (!tokens.length || !token) return;
|
|
@@ -17295,13 +17860,14 @@ function useDefaultToken({
|
|
|
17295
17860
|
});
|
|
17296
17861
|
if (!isChainAvailable) {
|
|
17297
17862
|
const firstChain = currentToken.chains[0];
|
|
17298
|
-
|
|
17863
|
+
setChainState(getChainKey(firstChain.chain_id, firstChain.chain_type));
|
|
17299
17864
|
}
|
|
17300
17865
|
}, [token, tokens, chain]);
|
|
17301
17866
|
return { token, chain, setToken, setChain, initialSelectionDone };
|
|
17302
17867
|
}
|
|
17303
17868
|
|
|
17304
17869
|
// src/hooks/use-default-source-token.ts
|
|
17870
|
+
var STORAGE_KEY2 = "unifold_last_deposit_from_token";
|
|
17305
17871
|
function useDefaultSourceToken({
|
|
17306
17872
|
supportedTokens,
|
|
17307
17873
|
defaultSourceChainType,
|
|
@@ -17314,7 +17880,8 @@ function useDefaultSourceToken({
|
|
|
17314
17880
|
defaultChainType: defaultSourceChainType,
|
|
17315
17881
|
defaultChainId: defaultSourceChainId,
|
|
17316
17882
|
defaultTokenAddress: defaultSourceTokenAddress,
|
|
17317
|
-
defaultSymbol: defaultSourceSymbol
|
|
17883
|
+
defaultSymbol: defaultSourceSymbol,
|
|
17884
|
+
storageKey: STORAGE_KEY2
|
|
17318
17885
|
});
|
|
17319
17886
|
}
|
|
17320
17887
|
|
|
@@ -17608,7 +18175,7 @@ function useCopyAddress() {
|
|
|
17608
18175
|
}
|
|
17609
18176
|
|
|
17610
18177
|
// src/components/shared/tooltip.tsx
|
|
17611
|
-
import * as
|
|
18178
|
+
import * as React33 from "react";
|
|
17612
18179
|
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
17613
18180
|
import { jsx as jsx52 } from "react/jsx-runtime";
|
|
17614
18181
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
@@ -17616,20 +18183,20 @@ function Tooltip({
|
|
|
17616
18183
|
children,
|
|
17617
18184
|
...props
|
|
17618
18185
|
}) {
|
|
17619
|
-
const [open, setOpen] =
|
|
18186
|
+
const [open, setOpen] = React33.useState(props.defaultOpen ?? false);
|
|
17620
18187
|
const isControlled = props.open !== void 0;
|
|
17621
18188
|
const isOpen = isControlled ? props.open : open;
|
|
17622
18189
|
const onOpenChange = isControlled ? props.onOpenChange : (nextOpen) => setOpen(nextOpen);
|
|
17623
18190
|
return /* @__PURE__ */ jsx52(TooltipContext.Provider, { value: { open: isOpen, onOpenChange }, children: /* @__PURE__ */ jsx52(TooltipPrimitive.Root, { ...props, open: isOpen, onOpenChange, children }) });
|
|
17624
18191
|
}
|
|
17625
|
-
var TooltipContext =
|
|
18192
|
+
var TooltipContext = React33.createContext({
|
|
17626
18193
|
open: false,
|
|
17627
18194
|
onOpenChange: () => {
|
|
17628
18195
|
}
|
|
17629
18196
|
});
|
|
17630
|
-
var TooltipTrigger =
|
|
17631
|
-
const { open, onOpenChange } =
|
|
17632
|
-
const handleClick =
|
|
18197
|
+
var TooltipTrigger = React33.forwardRef(({ onClick, ...props }, ref) => {
|
|
18198
|
+
const { open, onOpenChange } = React33.useContext(TooltipContext);
|
|
18199
|
+
const handleClick = React33.useCallback(
|
|
17633
18200
|
(e) => {
|
|
17634
18201
|
onOpenChange(!open);
|
|
17635
18202
|
onClick?.(e);
|
|
@@ -17639,7 +18206,7 @@ var TooltipTrigger = React32.forwardRef(({ onClick, ...props }, ref) => {
|
|
|
17639
18206
|
return /* @__PURE__ */ jsx52(TooltipPrimitive.Trigger, { ref, onClick: handleClick, ...props });
|
|
17640
18207
|
});
|
|
17641
18208
|
TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
|
|
17642
|
-
var TooltipContent =
|
|
18209
|
+
var TooltipContent = React33.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
|
|
17643
18210
|
const { themeClass, colors: colors2 } = useTheme();
|
|
17644
18211
|
return /* @__PURE__ */ jsx52(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx52(
|
|
17645
18212
|
TooltipPrimitive.Content,
|
|
@@ -17665,7 +18232,7 @@ import {
|
|
|
17665
18232
|
} from "@unifold/core";
|
|
17666
18233
|
|
|
17667
18234
|
// src/hooks/use-hypercore-activation.ts
|
|
17668
|
-
import { useQuery as
|
|
18235
|
+
import { useQuery as useQuery16 } from "@tanstack/react-query";
|
|
17669
18236
|
import { checkHypercoreActivation } from "@unifold/core";
|
|
17670
18237
|
|
|
17671
18238
|
// src/lib/constants.ts
|
|
@@ -17684,7 +18251,7 @@ function useHypercoreActivation(params) {
|
|
|
17684
18251
|
const recipient = recipientAddress?.trim() ?? "";
|
|
17685
18252
|
const source = sourceAddress?.trim() ?? "";
|
|
17686
18253
|
const hasAddresses = !!recipient && !!source;
|
|
17687
|
-
const { data, isLoading } =
|
|
18254
|
+
const { data, isLoading } = useQuery16({
|
|
17688
18255
|
queryKey: ["unifold", "hypercoreActivation", source, recipient, publishableKey],
|
|
17689
18256
|
queryFn: () => checkHypercoreActivation(
|
|
17690
18257
|
{
|
|
@@ -17712,7 +18279,7 @@ function useHypercoreActivation(params) {
|
|
|
17712
18279
|
}
|
|
17713
18280
|
|
|
17714
18281
|
// src/components/shared/HypercoreActivationWarning.tsx
|
|
17715
|
-
import { AlertTriangle as
|
|
18282
|
+
import { AlertTriangle as AlertTriangle3 } from "lucide-react";
|
|
17716
18283
|
import { jsx as jsx53, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
17717
18284
|
function HypercoreActivationWarning({
|
|
17718
18285
|
activationFee,
|
|
@@ -17730,7 +18297,7 @@ function HypercoreActivationWarning({
|
|
|
17730
18297
|
},
|
|
17731
18298
|
children: [
|
|
17732
18299
|
/* @__PURE__ */ jsx53(
|
|
17733
|
-
|
|
18300
|
+
AlertTriangle3,
|
|
17734
18301
|
{
|
|
17735
18302
|
className: "uf-w-4 uf-h-4 uf-flex-shrink-0 uf-mt-0.5",
|
|
17736
18303
|
style: { color: colors2.warning }
|
|
@@ -17770,6 +18337,7 @@ function TransferCryptoSingleInput({
|
|
|
17770
18337
|
onDepositError,
|
|
17771
18338
|
wallets: externalWallets,
|
|
17772
18339
|
onSourceTokenChange,
|
|
18340
|
+
prefilledAmountUsd,
|
|
17773
18341
|
checkoutQuote,
|
|
17774
18342
|
isCheckoutQuoteLoading = false,
|
|
17775
18343
|
persistCheckingIndicator = false,
|
|
@@ -17817,7 +18385,7 @@ function TransferCryptoSingleInput({
|
|
|
17817
18385
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
17818
18386
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
17819
18387
|
const error = walletsError?.message ?? null;
|
|
17820
|
-
const allAvailableChains =
|
|
18388
|
+
const allAvailableChains = useMemo11(() => {
|
|
17821
18389
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
17822
18390
|
supportedTokens.forEach((t13) => {
|
|
17823
18391
|
t13.chains.forEach((c) => {
|
|
@@ -17913,6 +18481,22 @@ function TransferCryptoSingleInput({
|
|
|
17913
18481
|
const maxSlippage = currentChainFromBackend?.max_slippage_percent ?? 0.25;
|
|
17914
18482
|
const processingTime = currentChainFromBackend?.estimated_processing_time ?? null;
|
|
17915
18483
|
const minDepositUsd = currentChainFromBackend?.minimum_deposit_amount_usd ?? 3;
|
|
18484
|
+
const parsedPrefilledUsd = useMemo11(() => {
|
|
18485
|
+
const value = parseFloat(prefilledAmountUsd ?? "");
|
|
18486
|
+
return Number.isFinite(value) && value > 0 ? value : null;
|
|
18487
|
+
}, [prefilledAmountUsd]);
|
|
18488
|
+
const effectivePrefilledUsd = useMemo11(() => {
|
|
18489
|
+
if (parsedPrefilledUsd === null) return null;
|
|
18490
|
+
return Math.max(parsedPrefilledUsd, minDepositUsd);
|
|
18491
|
+
}, [parsedPrefilledUsd, minDepositUsd]);
|
|
18492
|
+
const prefillDisplay = useMemo11(() => {
|
|
18493
|
+
if (effectivePrefilledUsd === null) return null;
|
|
18494
|
+
const usdLabel = `$${effectivePrefilledUsd.toFixed(2)}`;
|
|
18495
|
+
if (selectedToken?.is_stablecoin) {
|
|
18496
|
+
return `${effectivePrefilledUsd.toFixed(2)} ${selectedToken.symbol} (${usdLabel})`;
|
|
18497
|
+
}
|
|
18498
|
+
return `${usdLabel} USD`;
|
|
18499
|
+
}, [effectivePrefilledUsd, selectedToken]);
|
|
17916
18500
|
return /* @__PURE__ */ jsx54(TooltipProvider, { delayDuration: 0, skipDelayDuration: 0, children: /* @__PURE__ */ jsxs49(
|
|
17917
18501
|
"div",
|
|
17918
18502
|
{
|
|
@@ -18028,7 +18612,7 @@ function TransferCryptoSingleInput({
|
|
|
18028
18612
|
),
|
|
18029
18613
|
error && !loading && /* @__PURE__ */ jsxs49("div", { className: "uf-bg-destructive/10 uf-border uf-border-destructive/20 uf-rounded-xl uf-p-3 uf-space-y-2", children: [
|
|
18030
18614
|
/* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-start uf-gap-2", children: [
|
|
18031
|
-
/* @__PURE__ */ jsx54(
|
|
18615
|
+
/* @__PURE__ */ jsx54(Info2, { className: "uf-w-4 uf-h-4 uf-text-destructive uf-flex-shrink-0 uf-mt-0.5" }),
|
|
18032
18616
|
/* @__PURE__ */ jsxs49("div", { className: "uf-flex-1 uf-min-w-0", children: [
|
|
18033
18617
|
/* @__PURE__ */ jsx54("div", { className: "uf-text-xs uf-font-medium uf-text-destructive uf-mb-1", children: "Failed to create deposit address" }),
|
|
18034
18618
|
/* @__PURE__ */ jsx54("div", { className: "uf-text-xs uf-text-muted-foreground", children: error })
|
|
@@ -18039,7 +18623,7 @@ function TransferCryptoSingleInput({
|
|
|
18039
18623
|
/* @__PURE__ */ jsx54("span", { children: "Retrying automatically every 5 seconds..." })
|
|
18040
18624
|
] })
|
|
18041
18625
|
] }),
|
|
18042
|
-
(checkoutQuote || isCheckoutQuoteLoading) && /* @__PURE__ */ jsxs49(
|
|
18626
|
+
(checkoutQuote || isCheckoutQuoteLoading || prefillDisplay) && /* @__PURE__ */ jsxs49(
|
|
18043
18627
|
"div",
|
|
18044
18628
|
{
|
|
18045
18629
|
className: "uf-rounded-xl uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
|
|
@@ -18083,6 +18667,13 @@ function TransferCryptoSingleInput({
|
|
|
18083
18667
|
)
|
|
18084
18668
|
]
|
|
18085
18669
|
}
|
|
18670
|
+
) : prefillDisplay ? /* @__PURE__ */ jsx54(
|
|
18671
|
+
"span",
|
|
18672
|
+
{
|
|
18673
|
+
className: "uf-text-sm uf-font-semibold",
|
|
18674
|
+
style: { color: components.card.titleColor, fontFamily: fonts.semibold },
|
|
18675
|
+
children: prefillDisplay
|
|
18676
|
+
}
|
|
18086
18677
|
) : /* @__PURE__ */ jsx54(
|
|
18087
18678
|
"div",
|
|
18088
18679
|
{
|
|
@@ -18412,11 +19003,11 @@ function TransferCryptoSingleInput({
|
|
|
18412
19003
|
}
|
|
18413
19004
|
|
|
18414
19005
|
// src/components/deposits/TransferCryptoDoubleInput.tsx
|
|
18415
|
-
import { useState as useState37, useEffect as useEffect31, useMemo as
|
|
19006
|
+
import { useState as useState37, useEffect as useEffect31, useMemo as useMemo12 } from "react";
|
|
18416
19007
|
import {
|
|
18417
19008
|
ChevronDown as ChevronDown7,
|
|
18418
19009
|
ChevronUp as ChevronUp5,
|
|
18419
|
-
Info as
|
|
19010
|
+
Info as Info3,
|
|
18420
19011
|
Check as Check6,
|
|
18421
19012
|
DollarSign as DollarSign2,
|
|
18422
19013
|
ShieldCheck as ShieldCheck2,
|
|
@@ -18427,14 +19018,14 @@ import {
|
|
|
18427
19018
|
} from "lucide-react";
|
|
18428
19019
|
|
|
18429
19020
|
// src/components/shared/select.tsx
|
|
18430
|
-
import * as
|
|
19021
|
+
import * as React34 from "react";
|
|
18431
19022
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
18432
19023
|
import { Check as Check5, ChevronDown as ChevronDown6, ChevronUp as ChevronUp4 } from "lucide-react";
|
|
18433
19024
|
import { jsx as jsx55, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
18434
19025
|
var Select = SelectPrimitive.Root;
|
|
18435
19026
|
var SelectGroup = SelectPrimitive.Group;
|
|
18436
19027
|
var SelectValue = SelectPrimitive.Value;
|
|
18437
|
-
var SelectTrigger =
|
|
19028
|
+
var SelectTrigger = React34.forwardRef(({ className, style, children, ...props }, ref) => {
|
|
18438
19029
|
const { components } = useTheme();
|
|
18439
19030
|
return /* @__PURE__ */ jsxs50(
|
|
18440
19031
|
SelectPrimitive.Trigger,
|
|
@@ -18458,7 +19049,7 @@ var SelectTrigger = React33.forwardRef(({ className, style, children, ...props }
|
|
|
18458
19049
|
);
|
|
18459
19050
|
});
|
|
18460
19051
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
18461
|
-
var SelectScrollUpButton =
|
|
19052
|
+
var SelectScrollUpButton = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx55(
|
|
18462
19053
|
SelectPrimitive.ScrollUpButton,
|
|
18463
19054
|
{
|
|
18464
19055
|
ref,
|
|
@@ -18468,7 +19059,7 @@ var SelectScrollUpButton = React33.forwardRef(({ className, ...props }, ref) =>
|
|
|
18468
19059
|
}
|
|
18469
19060
|
));
|
|
18470
19061
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
18471
|
-
var SelectScrollDownButton =
|
|
19062
|
+
var SelectScrollDownButton = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx55(
|
|
18472
19063
|
SelectPrimitive.ScrollDownButton,
|
|
18473
19064
|
{
|
|
18474
19065
|
ref,
|
|
@@ -18478,7 +19069,7 @@ var SelectScrollDownButton = React33.forwardRef(({ className, ...props }, ref) =
|
|
|
18478
19069
|
}
|
|
18479
19070
|
));
|
|
18480
19071
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
18481
|
-
var SelectContent =
|
|
19072
|
+
var SelectContent = React34.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
|
|
18482
19073
|
const { themeClass, colors: colors2, components } = useTheme();
|
|
18483
19074
|
return /* @__PURE__ */ jsx55(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs50(
|
|
18484
19075
|
SelectPrimitive.Content,
|
|
@@ -18516,7 +19107,7 @@ var SelectContent = React33.forwardRef(({ className, style, children, position =
|
|
|
18516
19107
|
) });
|
|
18517
19108
|
});
|
|
18518
19109
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
18519
|
-
var SelectLabel =
|
|
19110
|
+
var SelectLabel = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx55(
|
|
18520
19111
|
SelectPrimitive.Label,
|
|
18521
19112
|
{
|
|
18522
19113
|
ref,
|
|
@@ -18525,7 +19116,7 @@ var SelectLabel = React33.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
18525
19116
|
}
|
|
18526
19117
|
));
|
|
18527
19118
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
18528
|
-
var SelectItem =
|
|
19119
|
+
var SelectItem = React34.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs50(
|
|
18529
19120
|
SelectPrimitive.Item,
|
|
18530
19121
|
{
|
|
18531
19122
|
ref,
|
|
@@ -18541,7 +19132,7 @@ var SelectItem = React33.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
18541
19132
|
}
|
|
18542
19133
|
));
|
|
18543
19134
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
18544
|
-
var SelectSeparator =
|
|
19135
|
+
var SelectSeparator = React34.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx55(
|
|
18545
19136
|
SelectPrimitive.Separator,
|
|
18546
19137
|
{
|
|
18547
19138
|
ref,
|
|
@@ -18575,6 +19166,7 @@ function TransferCryptoDoubleInput({
|
|
|
18575
19166
|
defaultSourceChainId,
|
|
18576
19167
|
defaultSourceTokenAddress,
|
|
18577
19168
|
defaultSourceSymbol,
|
|
19169
|
+
prefilledAmountUsd,
|
|
18578
19170
|
depositConfirmationMode = "auto_ui",
|
|
18579
19171
|
onExecutionsChange,
|
|
18580
19172
|
onDepositSuccess,
|
|
@@ -18621,7 +19213,7 @@ function TransferCryptoDoubleInput({
|
|
|
18621
19213
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
18622
19214
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
18623
19215
|
const error = walletsError?.message ?? null;
|
|
18624
|
-
const allAvailableChains =
|
|
19216
|
+
const allAvailableChains = useMemo12(() => {
|
|
18625
19217
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
18626
19218
|
supportedTokens.forEach((t13) => {
|
|
18627
19219
|
t13.chains.forEach((c) => {
|
|
@@ -18699,6 +19291,22 @@ function TransferCryptoDoubleInput({
|
|
|
18699
19291
|
const maxSlippage = currentChainFromBackend?.max_slippage_percent ?? 0.25;
|
|
18700
19292
|
const processingTime = currentChainFromBackend?.estimated_processing_time ?? null;
|
|
18701
19293
|
const minDepositUsd = currentChainFromBackend?.minimum_deposit_amount_usd ?? 3;
|
|
19294
|
+
const parsedPrefilledUsd = useMemo12(() => {
|
|
19295
|
+
const value = parseFloat(prefilledAmountUsd ?? "");
|
|
19296
|
+
return Number.isFinite(value) && value > 0 ? value : null;
|
|
19297
|
+
}, [prefilledAmountUsd]);
|
|
19298
|
+
const effectivePrefilledUsd = useMemo12(() => {
|
|
19299
|
+
if (parsedPrefilledUsd === null) return null;
|
|
19300
|
+
return Math.max(parsedPrefilledUsd, minDepositUsd);
|
|
19301
|
+
}, [parsedPrefilledUsd, minDepositUsd]);
|
|
19302
|
+
const prefillDisplay = useMemo12(() => {
|
|
19303
|
+
if (effectivePrefilledUsd === null) return null;
|
|
19304
|
+
const usdLabel = `$${effectivePrefilledUsd.toFixed(2)}`;
|
|
19305
|
+
if (selectedToken?.is_stablecoin) {
|
|
19306
|
+
return `${effectivePrefilledUsd.toFixed(2)} ${selectedToken.symbol} (${usdLabel})`;
|
|
19307
|
+
}
|
|
19308
|
+
return `${usdLabel} USD`;
|
|
19309
|
+
}, [effectivePrefilledUsd, selectedToken]);
|
|
18702
19310
|
const renderTokenItem = (tokenData) => {
|
|
18703
19311
|
return /* @__PURE__ */ jsxs51("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
|
|
18704
19312
|
/* @__PURE__ */ jsx56(
|
|
@@ -18868,7 +19476,7 @@ function TransferCryptoDoubleInput({
|
|
|
18868
19476
|
] }),
|
|
18869
19477
|
error && !loading && /* @__PURE__ */ jsxs51("div", { className: "uf-bg-destructive/10 uf-border uf-border-destructive/20 uf-rounded-xl uf-p-3 uf-space-y-2", children: [
|
|
18870
19478
|
/* @__PURE__ */ jsxs51("div", { className: "uf-flex uf-items-start uf-gap-2", children: [
|
|
18871
|
-
/* @__PURE__ */ jsx56(
|
|
19479
|
+
/* @__PURE__ */ jsx56(Info3, { className: "uf-w-4 uf-h-4 uf-text-destructive uf-flex-shrink-0 uf-mt-0.5" }),
|
|
18872
19480
|
/* @__PURE__ */ jsxs51("div", { className: "uf-flex-1 uf-min-w-0", children: [
|
|
18873
19481
|
/* @__PURE__ */ jsx56("div", { className: "uf-text-xs uf-font-medium uf-text-destructive uf-mb-1", children: "Failed to create deposit address" }),
|
|
18874
19482
|
/* @__PURE__ */ jsx56("div", { className: "uf-text-xs uf-text-muted-foreground", children: error })
|
|
@@ -18879,6 +19487,35 @@ function TransferCryptoDoubleInput({
|
|
|
18879
19487
|
/* @__PURE__ */ jsx56("span", { children: "Retrying automatically every 5 seconds..." })
|
|
18880
19488
|
] })
|
|
18881
19489
|
] }),
|
|
19490
|
+
prefillDisplay && /* @__PURE__ */ jsxs51(
|
|
19491
|
+
"div",
|
|
19492
|
+
{
|
|
19493
|
+
className: "uf-rounded-xl uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
|
|
19494
|
+
style: {
|
|
19495
|
+
backgroundColor: components.card.backgroundColor,
|
|
19496
|
+
border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
|
|
19497
|
+
borderRadius: components.card.borderRadius
|
|
19498
|
+
},
|
|
19499
|
+
children: [
|
|
19500
|
+
/* @__PURE__ */ jsx56(
|
|
19501
|
+
"span",
|
|
19502
|
+
{
|
|
19503
|
+
className: "uf-text-xs",
|
|
19504
|
+
style: { color: components.card.subtitleColor, fontFamily: fonts.regular },
|
|
19505
|
+
children: "You send"
|
|
19506
|
+
}
|
|
19507
|
+
),
|
|
19508
|
+
/* @__PURE__ */ jsx56(
|
|
19509
|
+
"span",
|
|
19510
|
+
{
|
|
19511
|
+
className: "uf-text-sm uf-font-semibold",
|
|
19512
|
+
style: { color: components.card.titleColor, fontFamily: fonts.semibold },
|
|
19513
|
+
children: prefillDisplay
|
|
19514
|
+
}
|
|
19515
|
+
)
|
|
19516
|
+
]
|
|
19517
|
+
}
|
|
19518
|
+
),
|
|
18882
19519
|
/* @__PURE__ */ jsxs51("div", { className: "uf-flex uf-flex-col uf-items-center uf-pt-2", children: [
|
|
18883
19520
|
/* @__PURE__ */ jsx56(
|
|
18884
19521
|
"div",
|
|
@@ -19161,7 +19798,7 @@ function TransferCryptoDoubleInput({
|
|
|
19161
19798
|
}
|
|
19162
19799
|
|
|
19163
19800
|
// src/components/deposits/WalletConnect.tsx
|
|
19164
|
-
import * as
|
|
19801
|
+
import * as React35 from "react";
|
|
19165
19802
|
import { ExternalLink as ExternalLink4, Loader2 as Loader210 } from "lucide-react";
|
|
19166
19803
|
import {
|
|
19167
19804
|
getAddressBalances as getAddressBalances2,
|
|
@@ -19213,7 +19850,7 @@ async function sendHypercoreEvmTransfer(params) {
|
|
|
19213
19850
|
}
|
|
19214
19851
|
|
|
19215
19852
|
// src/hooks/use-deposit-quote.ts
|
|
19216
|
-
import { useQuery as
|
|
19853
|
+
import { useQuery as useQuery17 } from "@tanstack/react-query";
|
|
19217
19854
|
import { getDepositQuote } from "@unifold/core";
|
|
19218
19855
|
function useDepositQuote(params) {
|
|
19219
19856
|
const {
|
|
@@ -19240,7 +19877,7 @@ function useDepositQuote(params) {
|
|
|
19240
19877
|
...adjustForSlippage ? { adjust_for_slippage: true } : {},
|
|
19241
19878
|
...stablecoinParity ? { stablecoin_parity: true } : {}
|
|
19242
19879
|
};
|
|
19243
|
-
return
|
|
19880
|
+
return useQuery17({
|
|
19244
19881
|
queryKey: [
|
|
19245
19882
|
"unifold",
|
|
19246
19883
|
"depositQuote",
|
|
@@ -19268,13 +19905,13 @@ function useDepositQuote(params) {
|
|
|
19268
19905
|
}
|
|
19269
19906
|
|
|
19270
19907
|
// src/hooks/use-external-wallets.ts
|
|
19271
|
-
import { useQuery as
|
|
19908
|
+
import { useQuery as useQuery18 } from "@tanstack/react-query";
|
|
19272
19909
|
import { getExternalWallets } from "@unifold/core";
|
|
19273
19910
|
function useExternalWallets({
|
|
19274
19911
|
publishableKey,
|
|
19275
19912
|
enabled = true
|
|
19276
19913
|
}) {
|
|
19277
|
-
const { data: wallets = [], isLoading } =
|
|
19914
|
+
const { data: wallets = [], isLoading } = useQuery18({
|
|
19278
19915
|
queryKey: ["unifold", "external-wallets", publishableKey],
|
|
19279
19916
|
queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
|
|
19280
19917
|
enabled: enabled && !!publishableKey,
|
|
@@ -20385,33 +21022,11 @@ function balancesRepresentSameToken(a, b) {
|
|
|
20385
21022
|
if (!tokenA || !tokenB) return false;
|
|
20386
21023
|
return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
|
|
20387
21024
|
}
|
|
20388
|
-
function getSolanaProviders() {
|
|
20389
|
-
if (typeof window === "undefined") return {};
|
|
20390
|
-
const win = window;
|
|
20391
|
-
return {
|
|
20392
|
-
phantomSolana: win.phantom?.solana,
|
|
20393
|
-
solflare: win.solflare,
|
|
20394
|
-
backpack: win.backpack,
|
|
20395
|
-
glow: win.glow,
|
|
20396
|
-
coinbaseSolana: win.coinbaseSolana || win.coinbaseWalletExtension?.solana
|
|
20397
|
-
};
|
|
20398
|
-
}
|
|
20399
|
-
function getLegacyEvmProviders() {
|
|
20400
|
-
if (typeof window === "undefined") return {};
|
|
20401
|
-
const win = window;
|
|
20402
|
-
return {
|
|
20403
|
-
ethereum: win.ethereum,
|
|
20404
|
-
phantomEthereum: win.phantom?.ethereum,
|
|
20405
|
-
coinbaseEthereum: win.coinbaseWalletExtension,
|
|
20406
|
-
trustEthereum: win.trustwallet?.ethereum,
|
|
20407
|
-
okxEthereum: win.okxwallet
|
|
20408
|
-
};
|
|
20409
|
-
}
|
|
20410
21025
|
function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
|
|
20411
|
-
const solProviders = getSolanaProviders();
|
|
20412
|
-
const legacyEvm = getLegacyEvmProviders();
|
|
20413
|
-
const eip6963List = getEip6963Providers();
|
|
20414
21026
|
const win = typeof window !== "undefined" ? window : null;
|
|
21027
|
+
const solProviders = getInjectedSolanaProviders(win);
|
|
21028
|
+
const legacyEvm = getLegacyEvmProviders(win);
|
|
21029
|
+
const eip6963List = getEip6963Providers();
|
|
20415
21030
|
const hasEip6963 = (walletId) => eip6963List.some((d) => {
|
|
20416
21031
|
const rdns = d.info?.rdns || "";
|
|
20417
21032
|
switch (walletId) {
|
|
@@ -20521,7 +21136,7 @@ function WalletConnect({
|
|
|
20521
21136
|
amountQuickSelect = "percentage",
|
|
20522
21137
|
onWalletDisconnect,
|
|
20523
21138
|
onWalletConnected,
|
|
20524
|
-
|
|
21139
|
+
prefilledAmountUsd,
|
|
20525
21140
|
checkoutAmountUsd,
|
|
20526
21141
|
checkoutReceivedUsd,
|
|
20527
21142
|
onNewDeposit,
|
|
@@ -20543,28 +21158,28 @@ function WalletConnect({
|
|
|
20543
21158
|
onExecutionsChange
|
|
20544
21159
|
}) {
|
|
20545
21160
|
const { colors: colors2, fonts, components, mode } = useTheme();
|
|
20546
|
-
const walletProvidedAtMount =
|
|
20547
|
-
const [activeWalletInfo, setActiveWalletInfo] =
|
|
21161
|
+
const walletProvidedAtMount = React35.useRef(!!initialWalletInfo && !!initialDepositWallet);
|
|
21162
|
+
const [activeWalletInfo, setActiveWalletInfo] = React35.useState(
|
|
20548
21163
|
initialWalletInfo ?? null
|
|
20549
21164
|
);
|
|
20550
|
-
const [activeDepositWallet, setActiveDepositWallet] =
|
|
21165
|
+
const [activeDepositWallet, setActiveDepositWallet] = React35.useState(
|
|
20551
21166
|
initialDepositWallet ?? null
|
|
20552
21167
|
);
|
|
20553
21168
|
const initialView = initialWalletInfo && initialDepositWallet ? "select_token" : "select_wallet";
|
|
20554
|
-
const [view, setView] =
|
|
20555
|
-
const [isTransitioning, setIsTransitioning] =
|
|
20556
|
-
const viewRef =
|
|
21169
|
+
const [view, setView] = React35.useState(initialView);
|
|
21170
|
+
const [isTransitioning, setIsTransitioning] = React35.useState(false);
|
|
21171
|
+
const viewRef = React35.useRef(initialView);
|
|
20557
21172
|
const standalone = !canGoBack && !walletProvidedAtMount.current;
|
|
20558
21173
|
const { wallet: detectedWallet, isLoading: detectingWallet } = useDetectedBrowserWallet({
|
|
20559
21174
|
enabled: standalone
|
|
20560
21175
|
});
|
|
20561
|
-
const [autoResolved, setAutoResolved] =
|
|
20562
|
-
const [selectedWalletDef, setSelectedWalletDef] =
|
|
20563
|
-
const [connectingNetwork, setConnectingNetwork] =
|
|
20564
|
-
const [walletError, setWalletError] =
|
|
20565
|
-
const [isWalletConnecting, setIsWalletConnecting] =
|
|
20566
|
-
const [eip6963ProviderCount, setEip6963ProviderCount] =
|
|
20567
|
-
|
|
21176
|
+
const [autoResolved, setAutoResolved] = React35.useState(false);
|
|
21177
|
+
const [selectedWalletDef, setSelectedWalletDef] = React35.useState(null);
|
|
21178
|
+
const [connectingNetwork, setConnectingNetwork] = React35.useState(null);
|
|
21179
|
+
const [walletError, setWalletError] = React35.useState(null);
|
|
21180
|
+
const [isWalletConnecting, setIsWalletConnecting] = React35.useState(false);
|
|
21181
|
+
const [eip6963ProviderCount, setEip6963ProviderCount] = React35.useState(0);
|
|
21182
|
+
React35.useEffect(() => {
|
|
20568
21183
|
const store = getEip6963Store();
|
|
20569
21184
|
if (!store) return;
|
|
20570
21185
|
setEip6963ProviderCount(store.getProviders().length);
|
|
@@ -20573,7 +21188,7 @@ function WalletConnect({
|
|
|
20573
21188
|
});
|
|
20574
21189
|
}, []);
|
|
20575
21190
|
const { wallets: backendWallets } = useExternalWallets({ publishableKey });
|
|
20576
|
-
const walletDefinitions =
|
|
21191
|
+
const walletDefinitions = React35.useMemo(
|
|
20577
21192
|
() => backendWallets.length > 0 ? backendWallets.map((w) => ({
|
|
20578
21193
|
id: w.id,
|
|
20579
21194
|
name: w.name,
|
|
@@ -20584,32 +21199,32 @@ function WalletConnect({
|
|
|
20584
21199
|
})) : FALLBACK_WALLET_DEFINITIONS,
|
|
20585
21200
|
[backendWallets]
|
|
20586
21201
|
);
|
|
20587
|
-
const [recentWalletId, setRecentWalletIdState] =
|
|
20588
|
-
|
|
21202
|
+
const [recentWalletId, setRecentWalletIdState] = React35.useState(getLastOpenedWallet);
|
|
21203
|
+
React35.useEffect(() => {
|
|
20589
21204
|
if (view === "select_wallet") {
|
|
20590
21205
|
setRecentWalletIdState(getLastOpenedWallet());
|
|
20591
21206
|
}
|
|
20592
21207
|
}, [view]);
|
|
20593
|
-
const availableWallets =
|
|
21208
|
+
const availableWallets = React35.useMemo(
|
|
20594
21209
|
() => detectAvailableWallets(walletDefinitions, recentWalletId),
|
|
20595
21210
|
[walletDefinitions, eip6963ProviderCount, recentWalletId]
|
|
20596
21211
|
);
|
|
20597
|
-
const [isMobile, setIsMobile] =
|
|
20598
|
-
|
|
21212
|
+
const [isMobile, setIsMobile] = React35.useState(false);
|
|
21213
|
+
React35.useEffect(() => {
|
|
20599
21214
|
setIsMobile(isMobileDevice());
|
|
20600
21215
|
}, []);
|
|
20601
|
-
const mobileDepositAddresses =
|
|
21216
|
+
const mobileDepositAddresses = React35.useMemo(
|
|
20602
21217
|
() => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
|
|
20603
21218
|
[depositWallets]
|
|
20604
21219
|
);
|
|
20605
|
-
const mobileDepositWalletIds =
|
|
21220
|
+
const mobileDepositWalletIds = React35.useMemo(
|
|
20606
21221
|
() => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
|
|
20607
21222
|
[depositWallets]
|
|
20608
21223
|
);
|
|
20609
|
-
const [mobileRedirect, setMobileRedirect] =
|
|
20610
|
-
const [pendingMobileWallet, setPendingMobileWallet] =
|
|
20611
|
-
const [awaitingMobileDeposit, setAwaitingMobileDeposit] =
|
|
20612
|
-
|
|
21224
|
+
const [mobileRedirect, setMobileRedirect] = React35.useState(null);
|
|
21225
|
+
const [pendingMobileWallet, setPendingMobileWallet] = React35.useState(null);
|
|
21226
|
+
const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React35.useState(false);
|
|
21227
|
+
React35.useEffect(() => {
|
|
20613
21228
|
if (!standalone || autoResolved || detectingWallet) return;
|
|
20614
21229
|
if (!detectedWallet) {
|
|
20615
21230
|
setAutoResolved(true);
|
|
@@ -20635,32 +21250,36 @@ function WalletConnect({
|
|
|
20635
21250
|
depositWallets,
|
|
20636
21251
|
depositWalletsLoading
|
|
20637
21252
|
]);
|
|
20638
|
-
|
|
21253
|
+
React35.useEffect(() => {
|
|
20639
21254
|
if (!standalone || autoResolved) return;
|
|
20640
21255
|
const t13 = setTimeout(() => setAutoResolved(true), 5e3);
|
|
20641
21256
|
return () => clearTimeout(t13);
|
|
20642
21257
|
}, [standalone, autoResolved]);
|
|
20643
|
-
const [balances, setBalances] =
|
|
20644
|
-
const [isLoading, setIsLoading] =
|
|
20645
|
-
const [selectedBalance, setSelectedBalance] =
|
|
20646
|
-
const [totalBalanceUsd, setTotalBalanceUsd] =
|
|
20647
|
-
const [error, setError] =
|
|
20648
|
-
const [isDisconnectingWallet, setIsDisconnectingWallet] =
|
|
20649
|
-
const [amountUsd, setAmountUsd] =
|
|
20650
|
-
const [isConfirming, setIsConfirming] =
|
|
20651
|
-
const [hasSignedTransaction, setHasSignedTransaction] =
|
|
20652
|
-
const [tokenChainDetails, setTokenChainDetails] =
|
|
20653
|
-
const [loadingTokenDetails, setLoadingTokenDetails] =
|
|
20654
|
-
const [showTransactionDetails, setShowTransactionDetails] =
|
|
20655
|
-
const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] =
|
|
21258
|
+
const [balances, setBalances] = React35.useState([]);
|
|
21259
|
+
const [isLoading, setIsLoading] = React35.useState(false);
|
|
21260
|
+
const [selectedBalance, setSelectedBalance] = React35.useState(null);
|
|
21261
|
+
const [totalBalanceUsd, setTotalBalanceUsd] = React35.useState(null);
|
|
21262
|
+
const [error, setError] = React35.useState(null);
|
|
21263
|
+
const [isDisconnectingWallet, setIsDisconnectingWallet] = React35.useState(false);
|
|
21264
|
+
const [amountUsd, setAmountUsd] = React35.useState(prefilledAmountUsd ?? "");
|
|
21265
|
+
const [isConfirming, setIsConfirming] = React35.useState(false);
|
|
21266
|
+
const [hasSignedTransaction, setHasSignedTransaction] = React35.useState(false);
|
|
21267
|
+
const [tokenChainDetails, setTokenChainDetails] = React35.useState(null);
|
|
21268
|
+
const [loadingTokenDetails, setLoadingTokenDetails] = React35.useState(false);
|
|
21269
|
+
const [showTransactionDetails, setShowTransactionDetails] = React35.useState(false);
|
|
21270
|
+
const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React35.useState(null);
|
|
20656
21271
|
const walletInfo = activeWalletInfo;
|
|
20657
21272
|
const depositWallet = activeDepositWallet;
|
|
20658
21273
|
const hasWallet = !!activeWalletInfo && !!activeDepositWallet;
|
|
21274
|
+
React35.useEffect(() => {
|
|
21275
|
+
const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
|
|
21276
|
+
setAmountUsd(cleanedPrefilled);
|
|
21277
|
+
}, [prefilledAmountUsd]);
|
|
20659
21278
|
const chainType = activeDepositWallet?.chain_type ?? "ethereum";
|
|
20660
21279
|
const recipientAddress = activeDepositWallet?.address ?? "";
|
|
20661
21280
|
const isCheckoutMode = !!checkoutAmountUsd;
|
|
20662
21281
|
const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
|
|
20663
|
-
const transitionTo =
|
|
21282
|
+
const transitionTo = React35.useCallback((nextView) => {
|
|
20664
21283
|
if (nextView === viewRef.current) return;
|
|
20665
21284
|
setIsTransitioning(true);
|
|
20666
21285
|
setTimeout(() => {
|
|
@@ -20676,10 +21295,13 @@ function WalletConnect({
|
|
|
20676
21295
|
};
|
|
20677
21296
|
const openMobileWalletBrowse = async (wallet, depositAddresses) => {
|
|
20678
21297
|
try {
|
|
21298
|
+
const cleanedAmountUsd = amountUsd?.replace(/[^0-9.]/g, "") ?? "";
|
|
21299
|
+
const forwardedAmountUsd = parseFloat(cleanedAmountUsd) > 0 ? cleanedAmountUsd : void 0;
|
|
20679
21300
|
const res = await getWalletMobileDeepLink(
|
|
20680
21301
|
wallet.id,
|
|
20681
21302
|
depositAddresses,
|
|
20682
|
-
publishableKey
|
|
21303
|
+
publishableKey,
|
|
21304
|
+
forwardedAmountUsd
|
|
20683
21305
|
);
|
|
20684
21306
|
if (res.deeplink) {
|
|
20685
21307
|
setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
|
|
@@ -20725,7 +21347,7 @@ function WalletConnect({
|
|
|
20725
21347
|
if (!selectedWalletDef) return;
|
|
20726
21348
|
handleConnectWallet(selectedWalletDef, network);
|
|
20727
21349
|
};
|
|
20728
|
-
|
|
21350
|
+
React35.useEffect(() => {
|
|
20729
21351
|
if (!pendingMobileWallet) return;
|
|
20730
21352
|
if (mobileDepositAddresses.length > 0) {
|
|
20731
21353
|
const wallet = pendingMobileWallet;
|
|
@@ -20768,7 +21390,7 @@ function WalletConnect({
|
|
|
20768
21390
|
const eip6963Match = findProviderByWalletId(wallet.id);
|
|
20769
21391
|
let provider = eip6963Match?.provider;
|
|
20770
21392
|
if (!provider) {
|
|
20771
|
-
const legacyEvm = getLegacyEvmProviders();
|
|
21393
|
+
const legacyEvm = getLegacyEvmProviders(win);
|
|
20772
21394
|
switch (wallet.id) {
|
|
20773
21395
|
case "metamask":
|
|
20774
21396
|
if (legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom)
|
|
@@ -20800,16 +21422,7 @@ function WalletConnect({
|
|
|
20800
21422
|
const accounts = await provider.request({ method: "eth_requestAccounts" });
|
|
20801
21423
|
if (!accounts?.length) throw new Error("No accounts returned from wallet");
|
|
20802
21424
|
setUserDisconnectedWallet(false);
|
|
20803
|
-
const
|
|
20804
|
-
phantom: "phantom-ethereum",
|
|
20805
|
-
coinbase: "coinbase",
|
|
20806
|
-
trust: "trust",
|
|
20807
|
-
rainbow: "rainbow",
|
|
20808
|
-
rabby: "rabby",
|
|
20809
|
-
okx: "okx",
|
|
20810
|
-
metamask: "metamask"
|
|
20811
|
-
};
|
|
20812
|
-
const walletType = walletIdToType[wallet.id] || "metamask";
|
|
21425
|
+
const walletType = walletIdToWalletType(wallet.id);
|
|
20813
21426
|
setStoredWalletState(walletType);
|
|
20814
21427
|
connectedInfo = {
|
|
20815
21428
|
type: walletType,
|
|
@@ -20818,7 +21431,7 @@ function WalletConnect({
|
|
|
20818
21431
|
icon: wallet.id
|
|
20819
21432
|
};
|
|
20820
21433
|
} else {
|
|
20821
|
-
const solProviders =
|
|
21434
|
+
const solProviders = getInjectedSolanaProviders(win);
|
|
20822
21435
|
let provider;
|
|
20823
21436
|
switch (wallet.id) {
|
|
20824
21437
|
case "phantom":
|
|
@@ -20837,11 +21450,11 @@ function WalletConnect({
|
|
|
20837
21450
|
provider = solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
|
|
20838
21451
|
break;
|
|
20839
21452
|
case "trust":
|
|
20840
|
-
provider =
|
|
21453
|
+
provider = solProviders.trustSolana;
|
|
20841
21454
|
break;
|
|
20842
21455
|
}
|
|
20843
21456
|
if (!provider) throw new Error(`${wallet.name} Solana wallet not found.`);
|
|
20844
|
-
const response = await provider.
|
|
21457
|
+
const response = await connectSolanaProviderWithRecovery(provider, wallet.id, wallet.name);
|
|
20845
21458
|
setUserDisconnectedWallet(false);
|
|
20846
21459
|
const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
|
|
20847
21460
|
setStoredWalletState(walletType);
|
|
@@ -20889,7 +21502,7 @@ function WalletConnect({
|
|
|
20889
21502
|
publishableKey,
|
|
20890
21503
|
enabled: !!activeWalletInfo && !!recipientAddress
|
|
20891
21504
|
});
|
|
20892
|
-
const effectiveDestinationAmount =
|
|
21505
|
+
const effectiveDestinationAmount = React35.useMemo(() => {
|
|
20893
21506
|
if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
|
|
20894
21507
|
if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
|
|
20895
21508
|
const remaining = BigInt(checkoutRemainingBaseUnits);
|
|
@@ -20917,7 +21530,7 @@ function WalletConnect({
|
|
|
20917
21530
|
stablecoinParity,
|
|
20918
21531
|
enabled: isCheckoutMode && !!selectedToken && !!checkoutDestination && effectiveDestinationAmount !== "0"
|
|
20919
21532
|
});
|
|
20920
|
-
const activeCheckoutQuote =
|
|
21533
|
+
const activeCheckoutQuote = React35.useMemo(() => {
|
|
20921
21534
|
if (!isCheckoutMode) return null;
|
|
20922
21535
|
if (walletCheckoutQuote)
|
|
20923
21536
|
return {
|
|
@@ -20947,10 +21560,10 @@ function WalletConnect({
|
|
|
20947
21560
|
onDepositSuccess,
|
|
20948
21561
|
onDepositError
|
|
20949
21562
|
});
|
|
20950
|
-
|
|
21563
|
+
React35.useEffect(() => {
|
|
20951
21564
|
onExecutionsChange?.(depositExecutions);
|
|
20952
21565
|
}, [depositExecutions, onExecutionsChange]);
|
|
20953
|
-
const latestDepositExecution =
|
|
21566
|
+
const latestDepositExecution = React35.useMemo(() => {
|
|
20954
21567
|
if (depositExecutions.length === 0) return null;
|
|
20955
21568
|
return [...depositExecutions].sort((a, b) => {
|
|
20956
21569
|
const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
|
|
@@ -20958,21 +21571,21 @@ function WalletConnect({
|
|
|
20958
21571
|
return tb - ta;
|
|
20959
21572
|
})[0];
|
|
20960
21573
|
}, [depositExecutions]);
|
|
20961
|
-
|
|
21574
|
+
React35.useEffect(() => {
|
|
20962
21575
|
if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
|
|
20963
21576
|
transitionTo("mobile_deposit_status");
|
|
20964
21577
|
}
|
|
20965
21578
|
}, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
|
|
20966
|
-
|
|
20967
|
-
if (!
|
|
21579
|
+
React35.useEffect(() => {
|
|
21580
|
+
if (!isCheckoutMode || !tokenChainDetails || view !== "enter_amount") return;
|
|
20968
21581
|
const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
|
|
20969
21582
|
const currentAmount = parseFloat(amountUsd) || 0;
|
|
20970
21583
|
if (currentAmount > 0 && currentAmount < minDeposit) setAmountUsd(minDeposit.toFixed(2));
|
|
20971
|
-
}, [tokenChainDetails, view,
|
|
20972
|
-
|
|
21584
|
+
}, [isCheckoutMode, tokenChainDetails, view, amountUsd]);
|
|
21585
|
+
React35.useEffect(() => {
|
|
20973
21586
|
if (view === "review") setShowTransactionDetails(false);
|
|
20974
21587
|
}, [view]);
|
|
20975
|
-
|
|
21588
|
+
React35.useEffect(() => {
|
|
20976
21589
|
if (view !== "enter_amount" && view !== "review" || !selectedBalance || !activeDepositWallet)
|
|
20977
21590
|
return;
|
|
20978
21591
|
let cancelled = false;
|
|
@@ -21009,7 +21622,7 @@ function WalletConnect({
|
|
|
21009
21622
|
cancelled = true;
|
|
21010
21623
|
};
|
|
21011
21624
|
}, [view, selectedBalance, publishableKey, activeDepositWallet]);
|
|
21012
|
-
|
|
21625
|
+
React35.useEffect(() => {
|
|
21013
21626
|
if (!activeWalletInfo || !activeDepositWallet) return;
|
|
21014
21627
|
let cancelled = false;
|
|
21015
21628
|
setIsLoading(true);
|
|
@@ -21074,21 +21687,21 @@ function WalletConnect({
|
|
|
21074
21687
|
defaultSourceTokenAddress,
|
|
21075
21688
|
defaultSourceSymbol
|
|
21076
21689
|
]);
|
|
21077
|
-
const usdToTokenRate =
|
|
21690
|
+
const usdToTokenRate = React35.useMemo(() => {
|
|
21078
21691
|
if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
|
|
21079
21692
|
const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
|
|
21080
21693
|
const balanceUsd = parseFloat(selectedBalance.amount_usd);
|
|
21081
21694
|
if (balanceAmount === 0 || balanceUsd === 0) return 0;
|
|
21082
21695
|
return balanceAmount / balanceUsd;
|
|
21083
21696
|
}, [selectedBalance, selectedToken]);
|
|
21084
|
-
const tokenAmount =
|
|
21697
|
+
const tokenAmount = React35.useMemo(() => {
|
|
21085
21698
|
if (isCheckoutMode && activeCheckoutQuote && selectedToken)
|
|
21086
21699
|
return Number(activeCheckoutQuote.sourceAmount) / 10 ** activeCheckoutQuote.sourceTokenDecimals;
|
|
21087
21700
|
const usdNum = parseFloat(amountUsd) || 0;
|
|
21088
21701
|
if (usdNum === 0 || usdToTokenRate === 0) return 0;
|
|
21089
21702
|
return usdNum * usdToTokenRate;
|
|
21090
21703
|
}, [amountUsd, usdToTokenRate, isCheckoutMode, activeCheckoutQuote, selectedToken]);
|
|
21091
|
-
|
|
21704
|
+
React35.useEffect(() => {
|
|
21092
21705
|
if (isCheckoutMode && activeCheckoutQuote?.sourceAmountUsd && view === "enter_amount")
|
|
21093
21706
|
setAmountUsd(activeCheckoutQuote.sourceAmountUsd);
|
|
21094
21707
|
}, [isCheckoutMode, activeCheckoutQuote, view]);
|
|
@@ -21097,7 +21710,7 @@ function WalletConnect({
|
|
|
21097
21710
|
const inputUsdNum = parseFloat(amountUsd) || 0;
|
|
21098
21711
|
const minDepositUsd = tokenChainDetails?.minimum_deposit_amount_usd || 0;
|
|
21099
21712
|
const isValidAmount = isCheckoutMode && activeCheckoutQuote ? tokenAmount > 0 && tokenAmount <= maxTokenAmount : inputUsdNum > 0 && inputUsdNum <= maxUsdAmount && inputUsdNum >= minDepositUsd;
|
|
21100
|
-
const formattedTokenAmount =
|
|
21713
|
+
const formattedTokenAmount = React35.useMemo(() => {
|
|
21101
21714
|
if (tokenAmount === 0 || !selectedToken) return null;
|
|
21102
21715
|
return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
|
|
21103
21716
|
}, [tokenAmount, selectedToken]);
|
|
@@ -21130,7 +21743,7 @@ function WalletConnect({
|
|
|
21130
21743
|
break;
|
|
21131
21744
|
case "enter_amount":
|
|
21132
21745
|
transitionTo("select_token");
|
|
21133
|
-
setAmountUsd(
|
|
21746
|
+
setAmountUsd(prefilledAmountUsd ?? "");
|
|
21134
21747
|
setTokenChainDetails(null);
|
|
21135
21748
|
break;
|
|
21136
21749
|
case "review":
|
|
@@ -21162,7 +21775,7 @@ function WalletConnect({
|
|
|
21162
21775
|
setSelectedBalance(null);
|
|
21163
21776
|
setBalances([]);
|
|
21164
21777
|
setTotalBalanceUsd(null);
|
|
21165
|
-
setAmountUsd(
|
|
21778
|
+
setAmountUsd(prefilledAmountUsd ?? "");
|
|
21166
21779
|
setError(null);
|
|
21167
21780
|
};
|
|
21168
21781
|
if (standalone) {
|
|
@@ -21192,16 +21805,7 @@ function WalletConnect({
|
|
|
21192
21805
|
return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
|
|
21193
21806
|
};
|
|
21194
21807
|
const resolveEvmProvider = () => {
|
|
21195
|
-
const
|
|
21196
|
-
"phantom-ethereum": "phantom",
|
|
21197
|
-
coinbase: "coinbase",
|
|
21198
|
-
trust: "trust",
|
|
21199
|
-
okx: "okx",
|
|
21200
|
-
rainbow: "rainbow",
|
|
21201
|
-
rabby: "rabby",
|
|
21202
|
-
metamask: "metamask"
|
|
21203
|
-
};
|
|
21204
|
-
const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
|
|
21808
|
+
const lookupId = walletTypeToWalletId(walletInfo.type);
|
|
21205
21809
|
const eip6963Match = findProviderByWalletId(lookupId);
|
|
21206
21810
|
let provider = eip6963Match?.provider;
|
|
21207
21811
|
if (!provider) {
|
|
@@ -21889,6 +22493,15 @@ function SkeletonButton({ variant = "default" }) {
|
|
|
21889
22493
|
] });
|
|
21890
22494
|
}
|
|
21891
22495
|
var t8 = i18n.depositModal;
|
|
22496
|
+
function normalizePrefilledUsdAmount(value) {
|
|
22497
|
+
if (!value) return void 0;
|
|
22498
|
+
const cleaned = value.replace(/[^0-9.]/g, "");
|
|
22499
|
+
if (!cleaned) return void 0;
|
|
22500
|
+
const normalizedNumeric = cleaned.replace(/(\..*)\./g, "$1");
|
|
22501
|
+
const parsed = parseFloat(normalizedNumeric);
|
|
22502
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return void 0;
|
|
22503
|
+
return parseFloat(parsed.toFixed(2)).toString();
|
|
22504
|
+
}
|
|
21892
22505
|
function depositTabForScreen(screen) {
|
|
21893
22506
|
return screen === "card" || screen === "cashapp" || screen === "bank_transfer" || screen === "stripe_link" || screen === "apple_pay" ? "cash" : "crypto";
|
|
21894
22507
|
}
|
|
@@ -21908,6 +22521,7 @@ function DepositModal({
|
|
|
21908
22521
|
defaultSourceChainId,
|
|
21909
22522
|
defaultSourceTokenAddress,
|
|
21910
22523
|
defaultSourceSymbol,
|
|
22524
|
+
prefilledAmountUsd,
|
|
21911
22525
|
hideDepositTracker,
|
|
21912
22526
|
showBalanceHeader = false,
|
|
21913
22527
|
transferInputVariant = "double_input",
|
|
@@ -21923,6 +22537,7 @@ function DepositModal({
|
|
|
21923
22537
|
applePayTitle = "Pay with Apple Pay",
|
|
21924
22538
|
applePaySubTitle = "Instant",
|
|
21925
22539
|
enableBankTransfer,
|
|
22540
|
+
enableIncidentBanner = false,
|
|
21926
22541
|
// No default: left undefined so the backend `stripe_link.enabled` can govern
|
|
21927
22542
|
// (via the `??` chain in showStripeLink) once a dashboard toggle exists.
|
|
21928
22543
|
enableStripeLink,
|
|
@@ -21943,7 +22558,11 @@ function DepositModal({
|
|
|
21943
22558
|
depositTrackerSubTitle = t8.depositTracker.subtitle
|
|
21944
22559
|
}) {
|
|
21945
22560
|
const { colors: colors2, fonts, components } = useTheme();
|
|
21946
|
-
const
|
|
22561
|
+
const normalizedPrefilledAmountUsd = useMemo14(
|
|
22562
|
+
() => normalizePrefilledUsdAmount(prefilledAmountUsd),
|
|
22563
|
+
[prefilledAmountUsd]
|
|
22564
|
+
);
|
|
22565
|
+
const onDepositSuccessFor = useCallback11(
|
|
21947
22566
|
(method) => onDepositSuccess || onEvent ? (data) => {
|
|
21948
22567
|
const payload = { ...data, method };
|
|
21949
22568
|
onDepositSuccess?.(payload);
|
|
@@ -21956,15 +22575,15 @@ function DepositModal({
|
|
|
21956
22575
|
} : void 0,
|
|
21957
22576
|
[onDepositSuccess, onEvent]
|
|
21958
22577
|
);
|
|
21959
|
-
const onDepositErrorFor =
|
|
22578
|
+
const onDepositErrorFor = useCallback11(
|
|
21960
22579
|
(method) => onDepositError ? (error) => onDepositError({ ...error, method }) : void 0,
|
|
21961
22580
|
[onDepositError]
|
|
21962
22581
|
);
|
|
21963
|
-
const effectiveInitialScreen =
|
|
22582
|
+
const effectiveInitialScreen = useMemo14(() => {
|
|
21964
22583
|
const s = initialScreen ?? "main";
|
|
21965
22584
|
if (s === "tracker" && hideDepositTracker === true) return "main";
|
|
21966
22585
|
if (s === "cashapp" && enableCashApp === false) return "main";
|
|
21967
|
-
if (s === "stripe_link" &&
|
|
22586
|
+
if (s === "stripe_link" && enableStripeLink === false) return "main";
|
|
21968
22587
|
if (s === "apple_pay" && enableApplePay === false) return "main";
|
|
21969
22588
|
if (s === "card" && enableFiatOnramp === false) return "main";
|
|
21970
22589
|
if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
|
|
@@ -21986,7 +22605,7 @@ function DepositModal({
|
|
|
21986
22605
|
enableStripeLink
|
|
21987
22606
|
]);
|
|
21988
22607
|
const [containerEl, setContainerEl] = useState40(null);
|
|
21989
|
-
const containerCallbackRef =
|
|
22608
|
+
const containerCallbackRef = useCallback11((el) => {
|
|
21990
22609
|
setContainerEl(el);
|
|
21991
22610
|
}, []);
|
|
21992
22611
|
const [view, setView] = useState40(effectiveInitialScreen);
|
|
@@ -21995,7 +22614,7 @@ function DepositModal({
|
|
|
21995
22614
|
const [depositTab, setDepositTab] = useState40(
|
|
21996
22615
|
() => depositTabForScreen(effectiveInitialScreen)
|
|
21997
22616
|
);
|
|
21998
|
-
const resetViewTimeoutRef =
|
|
22617
|
+
const resetViewTimeoutRef = useRef13(null);
|
|
21999
22618
|
const [cardView, setCardView] = useState40("amount");
|
|
22000
22619
|
const [exchangeView, setExchangeView] = useState40("providers");
|
|
22001
22620
|
const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState40(false);
|
|
@@ -22023,6 +22642,16 @@ function DepositModal({
|
|
|
22023
22642
|
const showApplePay = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
|
|
22024
22643
|
const showBankTransfer = enableBankTransfer ?? projectConfig?.bank_transfer?.enabled ?? true;
|
|
22025
22644
|
const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
|
|
22645
|
+
const { incident: publicIncident } = usePublicIncident({
|
|
22646
|
+
publishableKey,
|
|
22647
|
+
enabled: open && enableIncidentBanner
|
|
22648
|
+
});
|
|
22649
|
+
const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
|
|
22650
|
+
enabled: true,
|
|
22651
|
+
messages: publicIncident.messages,
|
|
22652
|
+
severity: publicIncident.severity,
|
|
22653
|
+
statusPageUrl: publicIncident.status_page_url
|
|
22654
|
+
} : void 0;
|
|
22026
22655
|
const [integrationExchanges, setIntegrationExchanges] = useState40([]);
|
|
22027
22656
|
useEffect34(() => {
|
|
22028
22657
|
if (!showConnectExchange || !open) return;
|
|
@@ -22089,7 +22718,11 @@ function DepositModal({
|
|
|
22089
22718
|
setConnectedExchange((prev) => prev ? { ...prev, iconUrl } : prev);
|
|
22090
22719
|
}
|
|
22091
22720
|
}, [integrationExchanges, connectedExchange]);
|
|
22092
|
-
const {
|
|
22721
|
+
const {
|
|
22722
|
+
data: depositAddressResponse,
|
|
22723
|
+
isLoading: walletsLoading,
|
|
22724
|
+
error: walletsError
|
|
22725
|
+
} = useDepositAddress({
|
|
22093
22726
|
userId,
|
|
22094
22727
|
publishableKey,
|
|
22095
22728
|
recipientAddress,
|
|
@@ -22222,6 +22855,7 @@ function DepositModal({
|
|
|
22222
22855
|
const {
|
|
22223
22856
|
isValid: isAddressValid,
|
|
22224
22857
|
failureCode: addressFailureCode,
|
|
22858
|
+
message: addressFailureMessage,
|
|
22225
22859
|
metadata: addressFailureMetadata,
|
|
22226
22860
|
isLoading: isAddressValidationLoading
|
|
22227
22861
|
} = useAddressValidation({
|
|
@@ -22235,17 +22869,31 @@ function DepositModal({
|
|
|
22235
22869
|
refetchOnMount: "always"
|
|
22236
22870
|
});
|
|
22237
22871
|
const addressValidationMessages = i18n.transferCrypto.addressValidation;
|
|
22238
|
-
const getAddressValidationErrorMessage = (code, metadata) => {
|
|
22872
|
+
const getAddressValidationErrorMessage = (message, code, metadata) => {
|
|
22873
|
+
if (message && message.trim().length > 0) return message;
|
|
22239
22874
|
if (!code) return addressValidationMessages.defaultError;
|
|
22240
22875
|
const errors = addressValidationMessages.errors;
|
|
22241
22876
|
const template = errors[code] ?? addressValidationMessages.defaultError;
|
|
22242
22877
|
return interpolate(template, metadata);
|
|
22243
22878
|
};
|
|
22879
|
+
const walletsRecipientError = isDepositAddressValidationError2(walletsError) ? walletsError.message : null;
|
|
22880
|
+
const isRecipientAddressInvalid = isAddressValid === false || walletsRecipientError !== null;
|
|
22881
|
+
const recipientInvalidMessage = getAddressValidationErrorMessage(
|
|
22882
|
+
addressFailureMessage ?? walletsRecipientError,
|
|
22883
|
+
addressFailureCode,
|
|
22884
|
+
addressFailureMetadata
|
|
22885
|
+
);
|
|
22244
22886
|
const openingScreen = effectiveInitialScreen;
|
|
22245
22887
|
const sessionOpenedFromMenu = openingScreen === "main";
|
|
22246
22888
|
const standaloneNeedsDepositPrereq = openingScreen !== "main" && (view === "transfer" || view === "card");
|
|
22247
22889
|
let depositPrerequisiteBody;
|
|
22248
|
-
if (
|
|
22890
|
+
if (isRecipientAddressInvalid) {
|
|
22891
|
+
depositPrerequisiteBody = /* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
22892
|
+
/* @__PURE__ */ jsx63("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__ */ jsx63(AlertTriangle4, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
22893
|
+
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
|
|
22894
|
+
/* @__PURE__ */ jsx63("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: recipientInvalidMessage })
|
|
22895
|
+
] });
|
|
22896
|
+
} else if (isCountryLoading || isAddressValidationLoading || tokensLoading || walletsLoading || !projectConfig || // Bank-transfer row visibility depends on the country-gated providers
|
|
22249
22897
|
// fetch — block the menu on it so the row never flashes in or out.
|
|
22250
22898
|
showBankTransfer && bankTransferProvidersLoading || // Same for Apple Pay: row visibility depends on the geo/platform-gated
|
|
22251
22899
|
// providers fetch — block the menu so the row doesn't pop in or out.
|
|
@@ -22257,7 +22905,7 @@ function DepositModal({
|
|
|
22257
22905
|
] });
|
|
22258
22906
|
} else if (countryError) {
|
|
22259
22907
|
depositPrerequisiteBody = /* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
22260
|
-
/* @__PURE__ */ jsx63("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__ */ jsx63(
|
|
22908
|
+
/* @__PURE__ */ jsx63("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__ */ jsx63(AlertTriangle4, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
22261
22909
|
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "Unable to Verify Location" }),
|
|
22262
22910
|
/* @__PURE__ */ jsx63("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: "We couldn't verify your location. Please check your connection and try again." })
|
|
22263
22911
|
] });
|
|
@@ -22267,12 +22915,6 @@ function DepositModal({
|
|
|
22267
22915
|
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "No Tokens Available" }),
|
|
22268
22916
|
/* @__PURE__ */ jsx63("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: "There are no supported tokens available from your current location." })
|
|
22269
22917
|
] });
|
|
22270
|
-
} else if (isAddressValid === false) {
|
|
22271
|
-
depositPrerequisiteBody = /* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
22272
|
-
/* @__PURE__ */ jsx63("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__ */ jsx63(AlertTriangle3, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
22273
|
-
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
|
|
22274
|
-
/* @__PURE__ */ jsx63("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: getAddressValidationErrorMessage(addressFailureCode, addressFailureMetadata) })
|
|
22275
|
-
] });
|
|
22276
22918
|
} else {
|
|
22277
22919
|
depositPrerequisiteBody = null;
|
|
22278
22920
|
}
|
|
@@ -22339,7 +22981,7 @@ function DepositModal({
|
|
|
22339
22981
|
);
|
|
22340
22982
|
const [cashAppView, setCashAppView] = useState40("amount");
|
|
22341
22983
|
const [stripeLinkStep, setStripeLinkStep] = useState40("amount");
|
|
22342
|
-
const stripeLinkBackRef =
|
|
22984
|
+
const stripeLinkBackRef = useRef13(null);
|
|
22343
22985
|
useEffect34(() => {
|
|
22344
22986
|
if (view === "stripe_link" && !showStripeLink && effectiveInitialScreen === "main") {
|
|
22345
22987
|
setView("main");
|
|
@@ -22348,7 +22990,7 @@ function DepositModal({
|
|
|
22348
22990
|
}, [view, showStripeLink, effectiveInitialScreen]);
|
|
22349
22991
|
const [cashAppAmount, setCashAppAmount] = useState40("");
|
|
22350
22992
|
const [applePayView, setApplePayView] = useState40("email_input");
|
|
22351
|
-
const applePayHandleRef =
|
|
22993
|
+
const applePayHandleRef = useRef13(null);
|
|
22352
22994
|
const applePayHeaderTitle = (() => {
|
|
22353
22995
|
switch (applePayView) {
|
|
22354
22996
|
case "email_input":
|
|
@@ -22766,6 +23408,7 @@ function DepositModal({
|
|
|
22766
23408
|
title: modalTitle || "Deposit",
|
|
22767
23409
|
showClose: !hideOverlay,
|
|
22768
23410
|
onClose: handleClose,
|
|
23411
|
+
incident: activeIncident,
|
|
22769
23412
|
showBalance: showBalanceHeader,
|
|
22770
23413
|
balanceAddress: recipientAddress,
|
|
22771
23414
|
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
|
|
@@ -22785,6 +23428,7 @@ function DepositModal({
|
|
|
22785
23428
|
showBack: showBackTransfer,
|
|
22786
23429
|
onBack: handleBack,
|
|
22787
23430
|
onClose: handleClose,
|
|
23431
|
+
incident: activeIncident,
|
|
22788
23432
|
showBalance: showBalanceHeader,
|
|
22789
23433
|
balanceAddress: recipientAddress,
|
|
22790
23434
|
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
|
|
@@ -22808,6 +23452,7 @@ function DepositModal({
|
|
|
22808
23452
|
defaultSourceChainId,
|
|
22809
23453
|
defaultSourceTokenAddress,
|
|
22810
23454
|
defaultSourceSymbol,
|
|
23455
|
+
prefilledAmountUsd: normalizedPrefilledAmountUsd,
|
|
22811
23456
|
depositConfirmationMode,
|
|
22812
23457
|
onExecutionsChange: setDepositExecutions,
|
|
22813
23458
|
onDepositSuccess: onDepositSuccessFor("transfer"),
|
|
@@ -22827,6 +23472,7 @@ function DepositModal({
|
|
|
22827
23472
|
defaultSourceChainId,
|
|
22828
23473
|
defaultSourceTokenAddress,
|
|
22829
23474
|
defaultSourceSymbol,
|
|
23475
|
+
prefilledAmountUsd: normalizedPrefilledAmountUsd,
|
|
22830
23476
|
depositConfirmationMode,
|
|
22831
23477
|
onExecutionsChange: setDepositExecutions,
|
|
22832
23478
|
onDepositSuccess: onDepositSuccessFor("transfer"),
|
|
@@ -22843,7 +23489,8 @@ function DepositModal({
|
|
|
22843
23489
|
title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
|
|
22844
23490
|
showBack: showBackTracker,
|
|
22845
23491
|
onBack: handleBack,
|
|
22846
|
-
onClose: handleClose
|
|
23492
|
+
onClose: handleClose,
|
|
23493
|
+
incident: activeIncident
|
|
22847
23494
|
}
|
|
22848
23495
|
),
|
|
22849
23496
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -22875,6 +23522,7 @@ function DepositModal({
|
|
|
22875
23522
|
showBack: showBackCard,
|
|
22876
23523
|
onBack: handleBack,
|
|
22877
23524
|
onClose: handleClose,
|
|
23525
|
+
incident: activeIncident,
|
|
22878
23526
|
badge: cardView === "quotes" ? { count: quotesCount } : void 0,
|
|
22879
23527
|
showBalance: showBalanceHeader,
|
|
22880
23528
|
balanceAddress: recipientAddress,
|
|
@@ -22911,7 +23559,8 @@ function DepositModal({
|
|
|
22911
23559
|
wallets,
|
|
22912
23560
|
assetCdnUrl: projectConfig?.asset_cdn_url,
|
|
22913
23561
|
hideDepositFlowInfo,
|
|
22914
|
-
hideDisplayDescription
|
|
23562
|
+
hideDisplayDescription,
|
|
23563
|
+
prefilledAmountUsd: normalizedPrefilledAmountUsd
|
|
22915
23564
|
}
|
|
22916
23565
|
),
|
|
22917
23566
|
depositPoweredByFooter
|
|
@@ -22923,7 +23572,8 @@ function DepositModal({
|
|
|
22923
23572
|
title: payWithExchangeTitle,
|
|
22924
23573
|
showBack: exchangeView === "pending" || sessionOpenedFromMenu,
|
|
22925
23574
|
onBack: handleBack,
|
|
22926
|
-
onClose: handleClose
|
|
23575
|
+
onClose: handleClose,
|
|
23576
|
+
incident: activeIncident
|
|
22927
23577
|
}
|
|
22928
23578
|
),
|
|
22929
23579
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -22976,7 +23626,8 @@ function DepositModal({
|
|
|
22976
23626
|
defaultSourceChainType,
|
|
22977
23627
|
defaultSourceChainId,
|
|
22978
23628
|
defaultSourceTokenAddress,
|
|
22979
|
-
defaultSourceSymbol
|
|
23629
|
+
defaultSourceSymbol,
|
|
23630
|
+
prefilledAmountUsd: normalizedPrefilledAmountUsd
|
|
22980
23631
|
}
|
|
22981
23632
|
),
|
|
22982
23633
|
depositPoweredByFooter
|
|
@@ -23008,6 +23659,7 @@ function DepositModal({
|
|
|
23008
23659
|
onDepositSuccess: onDepositSuccessFor("wallet_connect"),
|
|
23009
23660
|
onDepositError: onDepositErrorFor("wallet_connect"),
|
|
23010
23661
|
amountQuickSelect: browserWalletAmountQuickSelect,
|
|
23662
|
+
prefilledAmountUsd: normalizedPrefilledAmountUsd,
|
|
23011
23663
|
onWalletDisconnect: handleWalletDisconnect,
|
|
23012
23664
|
onWalletConnected: (info, dw) => {
|
|
23013
23665
|
setBrowserWalletInfo({ ...info, depositWallet: dw });
|
|
@@ -23035,7 +23687,8 @@ function DepositModal({
|
|
|
23035
23687
|
title: t8.bankTransfer.title,
|
|
23036
23688
|
showBack: bankTransferView !== "providers" || sessionOpenedFromMenu,
|
|
23037
23689
|
onBack: handleBack,
|
|
23038
|
-
onClose: handleClose
|
|
23690
|
+
onClose: handleClose,
|
|
23691
|
+
incident: activeIncident
|
|
23039
23692
|
}
|
|
23040
23693
|
),
|
|
23041
23694
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23056,7 +23709,8 @@ function DepositModal({
|
|
|
23056
23709
|
assetCdnUrl: projectConfig?.asset_cdn_url,
|
|
23057
23710
|
onEvent,
|
|
23058
23711
|
onDepositSuccess,
|
|
23059
|
-
onDepositError
|
|
23712
|
+
onDepositError,
|
|
23713
|
+
prefilledAmountUsd: normalizedPrefilledAmountUsd
|
|
23060
23714
|
}
|
|
23061
23715
|
),
|
|
23062
23716
|
depositPoweredByFooter
|
|
@@ -23068,26 +23722,24 @@ function DepositModal({
|
|
|
23068
23722
|
title: "Deposit with Link",
|
|
23069
23723
|
showBack: stripeLinkStep !== "checkout" && stripeLinkStep !== "success",
|
|
23070
23724
|
onBack: handleBack,
|
|
23071
|
-
|
|
23725
|
+
incident: activeIncident,
|
|
23726
|
+
showClose: stripeLinkStep !== "checkout" && stripeLinkStep !== "auth",
|
|
23072
23727
|
onClose: handleClose
|
|
23073
23728
|
}
|
|
23074
23729
|
),
|
|
23075
23730
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
23076
23731
|
isLoadingIp ? (
|
|
23077
|
-
//
|
|
23078
|
-
// PayWithStripeLink (which kicks off config/OAuth work) for a
|
|
23079
|
-
// deep-link user who turns out to be outside the US.
|
|
23732
|
+
// Wait for location so the first config fetch is region-aware.
|
|
23080
23733
|
/* @__PURE__ */ jsx63(SkeletonButton, { variant: "with-icons" })
|
|
23081
23734
|
) : !showStripeLink ? (
|
|
23082
|
-
//
|
|
23083
|
-
//
|
|
23084
|
-
//
|
|
23085
|
-
// the Link UI.
|
|
23735
|
+
// Direct opens (initialScreen="stripe_link") have no menu row
|
|
23736
|
+
// to fall back to, so render an unavailable state when backend
|
|
23737
|
+
// config resolves Stripe Link disabled/hidden.
|
|
23086
23738
|
/* @__PURE__ */ jsx63(
|
|
23087
23739
|
GeoRestrictionScreen,
|
|
23088
23740
|
{
|
|
23089
23741
|
methodName: t8.stripeLink.title,
|
|
23090
|
-
message:
|
|
23742
|
+
message: t8.stripeLink.unavailableInRegionMessage
|
|
23091
23743
|
}
|
|
23092
23744
|
)
|
|
23093
23745
|
) : /* @__PURE__ */ jsx63(
|
|
@@ -23099,6 +23751,8 @@ function DepositModal({
|
|
|
23099
23751
|
destinationChainType,
|
|
23100
23752
|
destinationChainId,
|
|
23101
23753
|
destinationTokenAddress,
|
|
23754
|
+
countryCode: userIpInfo?.alpha2,
|
|
23755
|
+
subdivisionCode: userIpInfo?.subdivisionCode ?? void 0,
|
|
23102
23756
|
wallets,
|
|
23103
23757
|
email: userEmail,
|
|
23104
23758
|
iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/link.svg` : void 0,
|
|
@@ -23118,7 +23772,8 @@ function DepositModal({
|
|
|
23118
23772
|
title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
|
|
23119
23773
|
showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
|
|
23120
23774
|
onBack: handleBack,
|
|
23121
|
-
onClose: handleClose
|
|
23775
|
+
onClose: handleClose,
|
|
23776
|
+
incident: activeIncident
|
|
23122
23777
|
}
|
|
23123
23778
|
),
|
|
23124
23779
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23138,6 +23793,7 @@ function DepositModal({
|
|
|
23138
23793
|
onEvent,
|
|
23139
23794
|
onDepositSuccess: onDepositSuccessFor("cashapp"),
|
|
23140
23795
|
onDepositError: onDepositErrorFor("cashapp"),
|
|
23796
|
+
prefilledAmountUsd: normalizedPrefilledAmountUsd,
|
|
23141
23797
|
wallets
|
|
23142
23798
|
}
|
|
23143
23799
|
),
|
|
@@ -23153,7 +23809,8 @@ function DepositModal({
|
|
|
23153
23809
|
const handled = applePayHandleRef.current?.requestBack() ?? false;
|
|
23154
23810
|
if (!handled) handleBack();
|
|
23155
23811
|
},
|
|
23156
|
-
onClose: handleClose
|
|
23812
|
+
onClose: handleClose,
|
|
23813
|
+
incident: activeIncident
|
|
23157
23814
|
}
|
|
23158
23815
|
),
|
|
23159
23816
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23195,16 +23852,16 @@ function DepositModal({
|
|
|
23195
23852
|
}
|
|
23196
23853
|
|
|
23197
23854
|
// src/components/checkout/CheckoutModal.tsx
|
|
23198
|
-
import { useState as useState41, useEffect as useEffect35, useLayoutEffect as useLayoutEffect3, useCallback as
|
|
23199
|
-
import { AlertTriangle as
|
|
23855
|
+
import { useState as useState41, useEffect as useEffect35, useLayoutEffect as useLayoutEffect3, useCallback as useCallback12, useRef as useRef14, useMemo as useMemo15 } from "react";
|
|
23856
|
+
import { AlertTriangle as AlertTriangle5, ChevronRight as ChevronRight19 } from "lucide-react";
|
|
23200
23857
|
|
|
23201
23858
|
// src/hooks/use-payment-intent.ts
|
|
23202
|
-
import { useQuery as
|
|
23859
|
+
import { useQuery as useQuery19 } from "@tanstack/react-query";
|
|
23203
23860
|
import { retrievePaymentIntent } from "@unifold/core";
|
|
23204
23861
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["succeeded", "expired", "refunded", "canceled"]);
|
|
23205
23862
|
function usePaymentIntent(params) {
|
|
23206
23863
|
const { clientSecret, publishableKey, enabled = true, pollingInterval = 3e3 } = params;
|
|
23207
|
-
return
|
|
23864
|
+
return useQuery19({
|
|
23208
23865
|
queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
|
|
23209
23866
|
queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
|
|
23210
23867
|
enabled: enabled && !!clientSecret && !!publishableKey,
|
|
@@ -23283,6 +23940,7 @@ function CheckoutModal({
|
|
|
23283
23940
|
modalTitle,
|
|
23284
23941
|
enableTransferCrypto,
|
|
23285
23942
|
enableConnectWallet,
|
|
23943
|
+
enableIncidentBanner = false,
|
|
23286
23944
|
defaultSourceChainType,
|
|
23287
23945
|
defaultSourceChainId,
|
|
23288
23946
|
defaultSourceTokenAddress,
|
|
@@ -23294,11 +23952,11 @@ function CheckoutModal({
|
|
|
23294
23952
|
}) {
|
|
23295
23953
|
const { colors: colors2, fonts, components } = useTheme();
|
|
23296
23954
|
const [view, setView] = useState41("main");
|
|
23297
|
-
const resetViewTimeoutRef =
|
|
23955
|
+
const resetViewTimeoutRef = useRef14(null);
|
|
23298
23956
|
const [browserWalletInfo, setBrowserWalletInfo] = useState41(null);
|
|
23299
23957
|
const [browserWalletChainType, setBrowserWalletChainType] = useState41(() => getStoredWalletState()?.chainType);
|
|
23300
|
-
const lastCheckoutMethodRef =
|
|
23301
|
-
const emitCheckoutSuccess =
|
|
23958
|
+
const lastCheckoutMethodRef = useRef14(void 0);
|
|
23959
|
+
const emitCheckoutSuccess = useCallback12(
|
|
23302
23960
|
(data, method) => {
|
|
23303
23961
|
const isSucceeded = data.status === "succeeded";
|
|
23304
23962
|
const richIntent = isSucceeded && data.paymentIntent ? mapToCheckoutPaymentIntent(data.paymentIntent) : void 0;
|
|
@@ -23354,6 +24012,16 @@ function CheckoutModal({
|
|
|
23354
24012
|
});
|
|
23355
24013
|
const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
|
|
23356
24014
|
const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
|
|
24015
|
+
const { incident: publicIncident } = usePublicIncident({
|
|
24016
|
+
publishableKey,
|
|
24017
|
+
enabled: open && enableIncidentBanner
|
|
24018
|
+
});
|
|
24019
|
+
const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
|
|
24020
|
+
enabled: true,
|
|
24021
|
+
messages: publicIncident.messages,
|
|
24022
|
+
severity: publicIncident.severity,
|
|
24023
|
+
statusPageUrl: publicIncident.status_page_url
|
|
24024
|
+
} : void 0;
|
|
23357
24025
|
useEffect35(() => {
|
|
23358
24026
|
if (view === "transfer" && !showTransferCrypto) {
|
|
23359
24027
|
setView("main");
|
|
@@ -23361,7 +24029,7 @@ function CheckoutModal({
|
|
|
23361
24029
|
setView("main");
|
|
23362
24030
|
}
|
|
23363
24031
|
}, [showConnectWallet, showTransferCrypto, view]);
|
|
23364
|
-
const prevStatusRef =
|
|
24032
|
+
const prevStatusRef = useRef14(null);
|
|
23365
24033
|
useEffect35(() => {
|
|
23366
24034
|
if (!paymentIntent) return;
|
|
23367
24035
|
const prev = prevStatusRef.current;
|
|
@@ -23380,11 +24048,11 @@ function CheckoutModal({
|
|
|
23380
24048
|
);
|
|
23381
24049
|
}
|
|
23382
24050
|
}, [emitCheckoutSuccess, paymentIntent, view]);
|
|
23383
|
-
const wallets =
|
|
24051
|
+
const wallets = useMemo15(() => {
|
|
23384
24052
|
if (!paymentIntent) return [];
|
|
23385
24053
|
return mapDepositAddressesToWallets(paymentIntent.deposit_addresses, paymentIntent);
|
|
23386
24054
|
}, [paymentIntent]);
|
|
23387
|
-
const formatCryptoAmount =
|
|
24055
|
+
const formatCryptoAmount = useMemo15(() => {
|
|
23388
24056
|
if (!paymentIntent) return (_) => "";
|
|
23389
24057
|
const decimals = paymentIntent.destination_token_decimals ?? 6;
|
|
23390
24058
|
const symbol = paymentIntent.currency.toUpperCase();
|
|
@@ -23394,7 +24062,7 @@ function CheckoutModal({
|
|
|
23394
24062
|
return `${formatted} ${symbol}`;
|
|
23395
24063
|
};
|
|
23396
24064
|
}, [paymentIntent]);
|
|
23397
|
-
const remainingAmountUsd =
|
|
24065
|
+
const remainingAmountUsd = useMemo15(() => {
|
|
23398
24066
|
if (!paymentIntent) return void 0;
|
|
23399
24067
|
const total = parseFloat(paymentIntent.destination_amount_usd || paymentIntent.amount_usd);
|
|
23400
24068
|
const received = parseFloat(
|
|
@@ -23406,7 +24074,7 @@ function CheckoutModal({
|
|
|
23406
24074
|
return remaining > 0 ? remaining.toFixed(2) : "0.00";
|
|
23407
24075
|
}, [paymentIntent]);
|
|
23408
24076
|
const [selectedSource, setSelectedSource] = useState41(null);
|
|
23409
|
-
const remainingDestinationAmount =
|
|
24077
|
+
const remainingDestinationAmount = useMemo15(() => {
|
|
23410
24078
|
if (!paymentIntent) return "0";
|
|
23411
24079
|
const remaining = BigInt(paymentIntent.destination_amount) - BigInt(paymentIntent.destination_amount_received);
|
|
23412
24080
|
return remaining > 0n ? remaining.toString() : "0";
|
|
@@ -23428,7 +24096,7 @@ function CheckoutModal({
|
|
|
23428
24096
|
stablecoinParity: paymentIntent?.stablecoin_parity ?? false,
|
|
23429
24097
|
enabled: open && view === "transfer" && !!paymentIntent && !!selectedSource && remainingDestinationAmount !== "0"
|
|
23430
24098
|
});
|
|
23431
|
-
const effectiveCheckoutQuote =
|
|
24099
|
+
const effectiveCheckoutQuote = useMemo15(() => {
|
|
23432
24100
|
if (!sourceQuote || !selectedSource) return null;
|
|
23433
24101
|
const baseQuote = {
|
|
23434
24102
|
sourceAmount: sourceQuote.source_amount,
|
|
@@ -23449,7 +24117,7 @@ function CheckoutModal({
|
|
|
23449
24117
|
sourceAmountUsd: minUsd.toFixed(2)
|
|
23450
24118
|
};
|
|
23451
24119
|
}, [sourceQuote, selectedSource]);
|
|
23452
|
-
const handleBrowserWalletClick =
|
|
24120
|
+
const handleBrowserWalletClick = useCallback12(
|
|
23453
24121
|
(walletInfo) => {
|
|
23454
24122
|
const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
|
|
23455
24123
|
setStoredWalletState(walletInfo.type);
|
|
@@ -23472,19 +24140,19 @@ function CheckoutModal({
|
|
|
23472
24140
|
},
|
|
23473
24141
|
[wallets, onCheckoutError]
|
|
23474
24142
|
);
|
|
23475
|
-
const handleWalletConnectClick =
|
|
24143
|
+
const handleWalletConnectClick = useCallback12(() => {
|
|
23476
24144
|
setBrowserWalletInfo(null);
|
|
23477
24145
|
lastCheckoutMethodRef.current = "wallet_connect";
|
|
23478
24146
|
setView("wallet_connect");
|
|
23479
24147
|
}, []);
|
|
23480
|
-
const handleWalletDisconnect =
|
|
24148
|
+
const handleWalletDisconnect = useCallback12(() => {
|
|
23481
24149
|
setUserDisconnectedWallet(true);
|
|
23482
24150
|
clearStoredWalletState();
|
|
23483
24151
|
setBrowserWalletChainType(void 0);
|
|
23484
24152
|
setBrowserWalletInfo(null);
|
|
23485
24153
|
setView("main");
|
|
23486
24154
|
}, []);
|
|
23487
|
-
const handleClose =
|
|
24155
|
+
const handleClose = useCallback12(() => {
|
|
23488
24156
|
onOpenChange(false);
|
|
23489
24157
|
if (resetViewTimeoutRef.current) {
|
|
23490
24158
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -23514,7 +24182,7 @@ function CheckoutModal({
|
|
|
23514
24182
|
},
|
|
23515
24183
|
[]
|
|
23516
24184
|
);
|
|
23517
|
-
const handleBack =
|
|
24185
|
+
const handleBack = useCallback12(() => {
|
|
23518
24186
|
setView("main");
|
|
23519
24187
|
}, []);
|
|
23520
24188
|
const poweredByFooter = /* @__PURE__ */ jsx64("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx64(
|
|
@@ -23655,7 +24323,15 @@ function CheckoutModal({
|
|
|
23655
24323
|
{
|
|
23656
24324
|
className: view === "wallet_connect" ? "uf-flex uf-min-h-0 uf-flex-col" : void 0,
|
|
23657
24325
|
children: view === "main" ? /* @__PURE__ */ jsxs58(Fragment15, { children: [
|
|
23658
|
-
/* @__PURE__ */ jsx64(
|
|
24326
|
+
/* @__PURE__ */ jsx64(
|
|
24327
|
+
DepositHeader,
|
|
24328
|
+
{
|
|
24329
|
+
title: modalTitle || "Checkout",
|
|
24330
|
+
showClose: true,
|
|
24331
|
+
onClose: handleClose,
|
|
24332
|
+
incident: activeIncident
|
|
24333
|
+
}
|
|
24334
|
+
),
|
|
23659
24335
|
/* @__PURE__ */ jsxs58("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
23660
24336
|
piLoading ? /* @__PURE__ */ jsxs58("div", { className: "uf-space-y-3", children: [
|
|
23661
24337
|
/* @__PURE__ */ jsx64(
|
|
@@ -23692,7 +24368,7 @@ function CheckoutModal({
|
|
|
23692
24368
|
/* @__PURE__ */ jsx64(SkeletonButton2, {}),
|
|
23693
24369
|
/* @__PURE__ */ jsx64(SkeletonButton2, {})
|
|
23694
24370
|
] }) : piError ? /* @__PURE__ */ jsxs58("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
23695
|
-
/* @__PURE__ */ jsx64("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__ */ jsx64(
|
|
24371
|
+
/* @__PURE__ */ jsx64("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__ */ jsx64(AlertTriangle5, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
23696
24372
|
/* @__PURE__ */ jsx64(
|
|
23697
24373
|
"h3",
|
|
23698
24374
|
{
|
|
@@ -23753,7 +24429,8 @@ function CheckoutModal({
|
|
|
23753
24429
|
title: modalTitle || "Checkout",
|
|
23754
24430
|
showBack: true,
|
|
23755
24431
|
onBack: handleBack,
|
|
23756
|
-
onClose: handleClose
|
|
24432
|
+
onClose: handleClose,
|
|
24433
|
+
incident: activeIncident
|
|
23757
24434
|
}
|
|
23758
24435
|
),
|
|
23759
24436
|
/* @__PURE__ */ jsxs58("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23852,7 +24529,7 @@ function CheckoutModal({
|
|
|
23852
24529
|
userId: paymentIntent.user_id || "",
|
|
23853
24530
|
publishableKey,
|
|
23854
24531
|
clientSecret,
|
|
23855
|
-
|
|
24532
|
+
prefilledAmountUsd: remainingAmountUsd,
|
|
23856
24533
|
checkoutAmountUsd: paymentIntent.amount_usd,
|
|
23857
24534
|
checkoutReceivedUsd: paymentIntent.amount_received_usd,
|
|
23858
24535
|
checkoutDestination: {
|
|
@@ -23914,16 +24591,16 @@ function CheckoutModal({
|
|
|
23914
24591
|
}
|
|
23915
24592
|
|
|
23916
24593
|
// src/components/withdrawals/WithdrawModal.tsx
|
|
23917
|
-
import { useState as useState45, useEffect as useEffect39, useLayoutEffect as useLayoutEffect4, useCallback as
|
|
23918
|
-
import { AlertTriangle as
|
|
24594
|
+
import { useState as useState45, useEffect as useEffect39, useLayoutEffect as useLayoutEffect4, useCallback as useCallback14, useRef as useRef16 } from "react";
|
|
24595
|
+
import { AlertTriangle as AlertTriangle7, ChevronRight as ChevronRight21, Clock as Clock6 } from "lucide-react";
|
|
23919
24596
|
|
|
23920
24597
|
// src/hooks/use-supported-destination-tokens.ts
|
|
23921
|
-
import { useQuery as
|
|
24598
|
+
import { useQuery as useQuery20 } from "@tanstack/react-query";
|
|
23922
24599
|
import {
|
|
23923
24600
|
getSupportedDestinationTokens
|
|
23924
24601
|
} from "@unifold/core";
|
|
23925
24602
|
function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
23926
|
-
return
|
|
24603
|
+
return useQuery20({
|
|
23927
24604
|
queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
|
|
23928
24605
|
queryFn: () => getSupportedDestinationTokens(publishableKey),
|
|
23929
24606
|
staleTime: 1e3 * 60 * 5,
|
|
@@ -23935,6 +24612,7 @@ function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
|
23935
24612
|
}
|
|
23936
24613
|
|
|
23937
24614
|
// src/hooks/use-default-destination-token.ts
|
|
24615
|
+
var STORAGE_KEY3 = "unifold_last_withdraw_to_token";
|
|
23938
24616
|
function useDefaultDestinationToken({
|
|
23939
24617
|
destinationTokens,
|
|
23940
24618
|
defaultDestinationChainType,
|
|
@@ -23947,12 +24625,13 @@ function useDefaultDestinationToken({
|
|
|
23947
24625
|
defaultChainType: defaultDestinationChainType,
|
|
23948
24626
|
defaultChainId: defaultDestinationChainId,
|
|
23949
24627
|
defaultTokenAddress: defaultDestinationTokenAddress,
|
|
23950
|
-
defaultSymbol: defaultDestinationSymbol
|
|
24628
|
+
defaultSymbol: defaultDestinationSymbol,
|
|
24629
|
+
storageKey: STORAGE_KEY3
|
|
23951
24630
|
});
|
|
23952
24631
|
}
|
|
23953
24632
|
|
|
23954
24633
|
// src/hooks/use-source-token-validation.ts
|
|
23955
|
-
import { useQuery as
|
|
24634
|
+
import { useQuery as useQuery21 } from "@tanstack/react-query";
|
|
23956
24635
|
import { getSupportedDepositTokens as getSupportedDepositTokens3 } from "@unifold/core";
|
|
23957
24636
|
function useSourceTokenValidation(params) {
|
|
23958
24637
|
const {
|
|
@@ -23964,7 +24643,7 @@ function useSourceTokenValidation(params) {
|
|
|
23964
24643
|
enabled = true
|
|
23965
24644
|
} = params;
|
|
23966
24645
|
const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
|
|
23967
|
-
return
|
|
24646
|
+
return useQuery21({
|
|
23968
24647
|
queryKey: [
|
|
23969
24648
|
"unifold",
|
|
23970
24649
|
"sourceTokenValidation",
|
|
@@ -24012,12 +24691,12 @@ function useSourceTokenValidation(params) {
|
|
|
24012
24691
|
}
|
|
24013
24692
|
|
|
24014
24693
|
// src/hooks/use-address-balance.ts
|
|
24015
|
-
import { useQuery as
|
|
24694
|
+
import { useQuery as useQuery22 } from "@tanstack/react-query";
|
|
24016
24695
|
import { getAddressBalance as getAddressBalance2 } from "@unifold/core";
|
|
24017
24696
|
function useAddressBalance(params) {
|
|
24018
24697
|
const { address, chainType, chainId, tokenAddress, publishableKey, enabled = true } = params;
|
|
24019
24698
|
const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
|
|
24020
|
-
return
|
|
24699
|
+
return useQuery22({
|
|
24021
24700
|
queryKey: [
|
|
24022
24701
|
"unifold",
|
|
24023
24702
|
"addressBalance",
|
|
@@ -24073,11 +24752,11 @@ function useAddressBalance(params) {
|
|
|
24073
24752
|
}
|
|
24074
24753
|
|
|
24075
24754
|
// src/hooks/use-executions.ts
|
|
24076
|
-
import { useQuery as
|
|
24755
|
+
import { useQuery as useQuery23 } from "@tanstack/react-query";
|
|
24077
24756
|
import { queryExecutions as queryExecutions4, ActionType as ActionType4 } from "@unifold/core";
|
|
24078
24757
|
function useExecutions(userId, publishableKey, options) {
|
|
24079
24758
|
const actionType = options?.actionType ?? ActionType4.Deposit;
|
|
24080
|
-
return
|
|
24759
|
+
return useQuery23({
|
|
24081
24760
|
queryKey: ["unifold", "executions", actionType, userId, publishableKey],
|
|
24082
24761
|
queryFn: () => queryExecutions4(userId, publishableKey, actionType),
|
|
24083
24762
|
enabled: (options?.enabled ?? true) && !!userId,
|
|
@@ -24089,7 +24768,7 @@ function useExecutions(userId, publishableKey, options) {
|
|
|
24089
24768
|
}
|
|
24090
24769
|
|
|
24091
24770
|
// src/hooks/use-withdraw-polling.ts
|
|
24092
|
-
import { useState as useState42, useEffect as useEffect36, useRef as
|
|
24771
|
+
import { useState as useState42, useEffect as useEffect36, useRef as useRef15 } from "react";
|
|
24093
24772
|
import {
|
|
24094
24773
|
queryExecutions as queryExecutions5,
|
|
24095
24774
|
pollDirectExecutions as pollDirectExecutions2,
|
|
@@ -24136,11 +24815,11 @@ function useWithdrawPolling({
|
|
|
24136
24815
|
});
|
|
24137
24816
|
const [executions, setExecutions] = useState42([]);
|
|
24138
24817
|
const [isPolling, setIsPolling] = useState42(false);
|
|
24139
|
-
const enabledAtRef =
|
|
24140
|
-
const trackedRef =
|
|
24141
|
-
const prevEnabledRef =
|
|
24142
|
-
const onSuccessRef =
|
|
24143
|
-
const onErrorRef =
|
|
24818
|
+
const enabledAtRef = useRef15(/* @__PURE__ */ new Date());
|
|
24819
|
+
const trackedRef = useRef15(/* @__PURE__ */ new Map());
|
|
24820
|
+
const prevEnabledRef = useRef15(false);
|
|
24821
|
+
const onSuccessRef = useRef15(onWithdrawSuccess);
|
|
24822
|
+
const onErrorRef = useRef15(onWithdrawError);
|
|
24144
24823
|
useEffect36(() => {
|
|
24145
24824
|
onSuccessRef.current = onWithdrawSuccess;
|
|
24146
24825
|
}, [onWithdrawSuccess]);
|
|
@@ -24408,9 +25087,9 @@ function WithdrawDoubleInput({
|
|
|
24408
25087
|
}
|
|
24409
25088
|
|
|
24410
25089
|
// src/components/withdrawals/WithdrawForm.tsx
|
|
24411
|
-
import { useState as useState43, useCallback as
|
|
25090
|
+
import { useState as useState43, useCallback as useCallback13, useMemo as useMemo17, useEffect as useEffect37 } from "react";
|
|
24412
25091
|
import {
|
|
24413
|
-
AlertTriangle as
|
|
25092
|
+
AlertTriangle as AlertTriangle6,
|
|
24414
25093
|
ArrowUpDown,
|
|
24415
25094
|
ChevronDown as ChevronDown9,
|
|
24416
25095
|
ChevronUp as ChevronUp7,
|
|
@@ -24426,7 +25105,7 @@ import {
|
|
|
24426
25105
|
} from "@unifold/core";
|
|
24427
25106
|
|
|
24428
25107
|
// src/hooks/use-verify-recipient-address.ts
|
|
24429
|
-
import { useQuery as
|
|
25108
|
+
import { useQuery as useQuery24 } from "@tanstack/react-query";
|
|
24430
25109
|
import { verifyRecipientAddress as verifyRecipientAddress2 } from "@unifold/core";
|
|
24431
25110
|
function useVerifyRecipientAddress(params) {
|
|
24432
25111
|
const {
|
|
@@ -24439,7 +25118,7 @@ function useVerifyRecipientAddress(params) {
|
|
|
24439
25118
|
} = params;
|
|
24440
25119
|
const trimmedAddress = recipientAddress?.trim() || "";
|
|
24441
25120
|
const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
|
|
24442
|
-
return
|
|
25121
|
+
return useQuery24({
|
|
24443
25122
|
queryKey: [
|
|
24444
25123
|
"unifold",
|
|
24445
25124
|
"verifyRecipientAddress",
|
|
@@ -24686,11 +25365,11 @@ async function detectBrowserWallet(chainType, senderAddress) {
|
|
|
24686
25365
|
}
|
|
24687
25366
|
|
|
24688
25367
|
// src/hooks/use-hypercore-withdraw-activation.ts
|
|
24689
|
-
import { useMemo as
|
|
25368
|
+
import { useMemo as useMemo16 } from "react";
|
|
24690
25369
|
import { ActionType as ActionType6 } from "@unifold/core";
|
|
24691
25370
|
|
|
24692
25371
|
// src/hooks/use-get-deposit-address.ts
|
|
24693
|
-
import { useQuery as
|
|
25372
|
+
import { useQuery as useQuery25 } from "@tanstack/react-query";
|
|
24694
25373
|
import { getDepositAddress } from "@unifold/core";
|
|
24695
25374
|
function useGetDepositAddress(params) {
|
|
24696
25375
|
const {
|
|
@@ -24704,7 +25383,7 @@ function useGetDepositAddress(params) {
|
|
|
24704
25383
|
enabled = true
|
|
24705
25384
|
} = params;
|
|
24706
25385
|
const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
24707
|
-
return
|
|
25386
|
+
return useQuery25({
|
|
24708
25387
|
queryKey: [
|
|
24709
25388
|
"unifold",
|
|
24710
25389
|
"getDepositAddress",
|
|
@@ -24773,7 +25452,7 @@ function useHypercoreWithdrawActivation(params) {
|
|
|
24773
25452
|
actionType: ActionType6.Withdraw,
|
|
24774
25453
|
enabled: enabled && isHypercore(sourceChainId)
|
|
24775
25454
|
});
|
|
24776
|
-
const depositWalletAddress =
|
|
25455
|
+
const depositWalletAddress = useMemo16(() => {
|
|
24777
25456
|
const wallets = depositWalletLookup.data?.data ?? [];
|
|
24778
25457
|
return wallets.find((w) => w.chain_type === sourceChainType)?.address;
|
|
24779
25458
|
}, [depositWalletLookup.data, sourceChainType]);
|
|
@@ -24895,11 +25574,14 @@ function WithdrawForm({
|
|
|
24895
25574
|
enabled: debouncedAddress.length > 5 && !!selectedChain
|
|
24896
25575
|
});
|
|
24897
25576
|
const isDebouncing = trimmedAddress !== debouncedAddress;
|
|
24898
|
-
const addressError =
|
|
25577
|
+
const addressError = useMemo17(() => {
|
|
24899
25578
|
if (!trimmedAddress || trimmedAddress.length <= 5) return null;
|
|
24900
25579
|
if (isDebouncing || isVerifyingAddress) return null;
|
|
24901
25580
|
if (verifyError) return t10.invalidAddress;
|
|
24902
25581
|
if (addressVerification && !addressVerification.valid) {
|
|
25582
|
+
if (addressVerification.message && addressVerification.message.trim().length > 0) {
|
|
25583
|
+
return addressVerification.message;
|
|
25584
|
+
}
|
|
24903
25585
|
if (addressVerification.failure_code === "account_not_found")
|
|
24904
25586
|
return `Account not found on ${selectedChain?.chain_name}`;
|
|
24905
25587
|
if (addressVerification.failure_code === "not_opted_in")
|
|
@@ -24929,33 +25611,33 @@ function WithdrawForm({
|
|
|
24929
25611
|
destinationTokenAddress: selectedChain?.token_address,
|
|
24930
25612
|
enabled: isAddressValid
|
|
24931
25613
|
});
|
|
24932
|
-
const exchangeRate =
|
|
25614
|
+
const exchangeRate = useMemo17(() => {
|
|
24933
25615
|
if (!balanceData?.exchangeRate) return 0;
|
|
24934
25616
|
return parseFloat(balanceData.exchangeRate);
|
|
24935
25617
|
}, [balanceData]);
|
|
24936
|
-
const balanceCrypto =
|
|
25618
|
+
const balanceCrypto = useMemo17(() => {
|
|
24937
25619
|
if (!balanceData?.balanceHuman) return 0;
|
|
24938
25620
|
return parseFloat(balanceData.balanceHuman);
|
|
24939
25621
|
}, [balanceData]);
|
|
24940
|
-
const balanceUsdNum =
|
|
25622
|
+
const balanceUsdNum = useMemo17(() => {
|
|
24941
25623
|
if (!balanceData?.balanceUsd) return 0;
|
|
24942
25624
|
return parseFloat(balanceData.balanceUsd);
|
|
24943
25625
|
}, [balanceData]);
|
|
24944
25626
|
const tokenSymbol = sourceTokenSymbol || balanceData?.symbol || "TOKEN";
|
|
24945
25627
|
const sourceDecimals = balanceData?.decimals ?? 6;
|
|
24946
|
-
const cryptoAmountFromInput =
|
|
25628
|
+
const cryptoAmountFromInput = useMemo17(() => {
|
|
24947
25629
|
const val = parseFloat(amount);
|
|
24948
25630
|
if (!val || val <= 0) return 0;
|
|
24949
25631
|
if (inputUnit === "crypto") return val;
|
|
24950
25632
|
return exchangeRate > 0 ? val / exchangeRate : 0;
|
|
24951
25633
|
}, [amount, inputUnit, exchangeRate]);
|
|
24952
|
-
const fiatAmountFromInput =
|
|
25634
|
+
const fiatAmountFromInput = useMemo17(() => {
|
|
24953
25635
|
const val = parseFloat(amount);
|
|
24954
25636
|
if (!val || val <= 0) return 0;
|
|
24955
25637
|
if (inputUnit === "fiat") return val;
|
|
24956
25638
|
return val * exchangeRate;
|
|
24957
25639
|
}, [amount, inputUnit, exchangeRate]);
|
|
24958
|
-
const convertedDisplay =
|
|
25640
|
+
const convertedDisplay = useMemo17(() => {
|
|
24959
25641
|
if (!amount || parseFloat(amount) <= 0) return null;
|
|
24960
25642
|
if (inputUnit === "crypto") {
|
|
24961
25643
|
return `$${fiatAmountFromInput.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
@@ -24974,7 +25656,7 @@ function WithdrawForm({
|
|
|
24974
25656
|
isMaxed,
|
|
24975
25657
|
isStablecoin
|
|
24976
25658
|
]);
|
|
24977
|
-
const balanceDisplay =
|
|
25659
|
+
const balanceDisplay = useMemo17(() => {
|
|
24978
25660
|
if (isLoadingBalance || !balanceData) return null;
|
|
24979
25661
|
if (inputUnit === "crypto") {
|
|
24980
25662
|
const displayDecimals = isStablecoin ? 2 : 6;
|
|
@@ -24997,7 +25679,7 @@ function WithdrawForm({
|
|
|
24997
25679
|
tokenSymbol,
|
|
24998
25680
|
isStablecoin
|
|
24999
25681
|
]);
|
|
25000
|
-
const handleSwitchUnit =
|
|
25682
|
+
const handleSwitchUnit = useCallback13(() => {
|
|
25001
25683
|
if (isMaxed && balanceData) {
|
|
25002
25684
|
if (inputUnit === "crypto") {
|
|
25003
25685
|
setAmount((Math.round(balanceUsdNum * 100) / 100).toFixed(2));
|
|
@@ -25024,7 +25706,7 @@ function WithdrawForm({
|
|
|
25024
25706
|
setInputUnit("crypto");
|
|
25025
25707
|
}
|
|
25026
25708
|
}, [amount, inputUnit, exchangeRate, sourceDecimals, isMaxed, balanceData, balanceUsdNum]);
|
|
25027
|
-
const handleMaxClick =
|
|
25709
|
+
const handleMaxClick = useCallback13(() => {
|
|
25028
25710
|
if (inputUnit === "crypto") {
|
|
25029
25711
|
if (balanceCrypto <= 0) return;
|
|
25030
25712
|
setAmount(balanceData?.balanceHuman ?? "0");
|
|
@@ -25038,7 +25720,7 @@ function WithdrawForm({
|
|
|
25038
25720
|
const isBelowMinimum = minimumWithdrawAmountUsd !== null && fiatAmountFromInput > 0 && Math.round(fiatAmountFromInput * 100) / 100 < minimumWithdrawAmountUsd;
|
|
25039
25721
|
const isOverBalance = inputUnit === "crypto" ? cryptoAmountFromInput > 0 && balanceCrypto > 0 && cryptoAmountFromInput > balanceCrypto : fiatAmountFromInput > 0 && balanceUsdNum > 0 && Math.round(fiatAmountFromInput * 100) / 100 > Math.round(balanceUsdNum * 100) / 100;
|
|
25040
25722
|
const isFormValid = trimmedAddress.length > 0 && amount.trim().length > 0 && cryptoAmountFromInput > 0 && isAddressValid && !isBelowMinimum && !isOverBalance && !isBalanceBelowMinimum && !!balanceData;
|
|
25041
|
-
const handleWithdraw =
|
|
25723
|
+
const handleWithdraw = useCallback13(async () => {
|
|
25042
25724
|
if (!selectedToken || !selectedChain) return;
|
|
25043
25725
|
if (!isFormValid) return;
|
|
25044
25726
|
setIsSubmitting(true);
|
|
@@ -25235,7 +25917,7 @@ function WithdrawForm({
|
|
|
25235
25917
|
)
|
|
25236
25918
|
] }),
|
|
25237
25919
|
addressError && /* @__PURE__ */ jsxs60("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-1.5", children: [
|
|
25238
|
-
/* @__PURE__ */ jsx66(
|
|
25920
|
+
/* @__PURE__ */ jsx66(AlertTriangle6, { className: "uf-w-3 uf-h-3", style: { color: colors2.error } }),
|
|
25239
25921
|
/* @__PURE__ */ jsx66("span", { className: "uf-text-xs", style: { color: colors2.error, fontFamily: fonts.regular }, children: addressError })
|
|
25240
25922
|
] })
|
|
25241
25923
|
] }),
|
|
@@ -25824,7 +26506,7 @@ function WithdrawModal({
|
|
|
25824
26506
|
theme = "dark",
|
|
25825
26507
|
hideOverlay = false
|
|
25826
26508
|
}) {
|
|
25827
|
-
const onWithdrawSuccessFor =
|
|
26509
|
+
const onWithdrawSuccessFor = useCallback14(
|
|
25828
26510
|
(data) => {
|
|
25829
26511
|
onWithdrawSuccess?.(data);
|
|
25830
26512
|
if (data.execution) {
|
|
@@ -25835,7 +26517,7 @@ function WithdrawModal({
|
|
|
25835
26517
|
);
|
|
25836
26518
|
const { colors: colors2, fonts, components } = useTheme();
|
|
25837
26519
|
const [containerEl, setContainerEl] = useState45(null);
|
|
25838
|
-
const containerCallbackRef =
|
|
26520
|
+
const containerCallbackRef = useCallback14((el) => {
|
|
25839
26521
|
setContainerEl(el);
|
|
25840
26522
|
}, []);
|
|
25841
26523
|
const [resolvedTheme, setResolvedTheme] = useState45(
|
|
@@ -25908,7 +26590,7 @@ function WithdrawModal({
|
|
|
25908
26590
|
refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
|
|
25909
26591
|
});
|
|
25910
26592
|
const allWithdrawals = allWithdrawalsData?.data ?? [];
|
|
25911
|
-
const handleDepositWalletCreation =
|
|
26593
|
+
const handleDepositWalletCreation = useCallback14(
|
|
25912
26594
|
async (params) => {
|
|
25913
26595
|
const { data: wallets } = await createDepositAddress2(
|
|
25914
26596
|
{
|
|
@@ -25931,12 +26613,12 @@ function WithdrawModal({
|
|
|
25931
26613
|
},
|
|
25932
26614
|
[externalUserId, publishableKey, sourceChainType]
|
|
25933
26615
|
);
|
|
25934
|
-
const handleWithdrawSubmitted =
|
|
26616
|
+
const handleWithdrawSubmitted = useCallback14((txInfo) => {
|
|
25935
26617
|
setSubmittedTxInfo(txInfo);
|
|
25936
26618
|
setView("confirming");
|
|
25937
26619
|
}, []);
|
|
25938
|
-
const resetViewTimeoutRef =
|
|
25939
|
-
const handleClose =
|
|
26620
|
+
const resetViewTimeoutRef = useRef16(null);
|
|
26621
|
+
const handleClose = useCallback14(() => {
|
|
25940
26622
|
onOpenChange(false);
|
|
25941
26623
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
25942
26624
|
resetViewTimeoutRef.current = setTimeout(() => {
|
|
@@ -25964,13 +26646,13 @@ function WithdrawModal({
|
|
|
25964
26646
|
},
|
|
25965
26647
|
[]
|
|
25966
26648
|
);
|
|
25967
|
-
const handleTokenSymbolChange =
|
|
26649
|
+
const handleTokenSymbolChange = useCallback14(
|
|
25968
26650
|
(symbol) => {
|
|
25969
26651
|
setSelectedTokenSymbol(symbol);
|
|
25970
26652
|
},
|
|
25971
26653
|
[setSelectedTokenSymbol]
|
|
25972
26654
|
);
|
|
25973
|
-
const handleChainKeyChange =
|
|
26655
|
+
const handleChainKeyChange = useCallback14(
|
|
25974
26656
|
(chainKey) => {
|
|
25975
26657
|
setSelectedChainKey(chainKey);
|
|
25976
26658
|
},
|
|
@@ -26077,7 +26759,7 @@ function WithdrawModal({
|
|
|
26077
26759
|
},
|
|
26078
26760
|
i
|
|
26079
26761
|
)) }) : isSourceSupported === false ? /* @__PURE__ */ jsxs63("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
26080
|
-
/* @__PURE__ */ jsx69("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__ */ jsx69(
|
|
26762
|
+
/* @__PURE__ */ jsx69("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__ */ jsx69(AlertTriangle7, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
26081
26763
|
/* @__PURE__ */ jsx69(
|
|
26082
26764
|
"h3",
|
|
26083
26765
|
{
|
|
@@ -26157,7 +26839,7 @@ function WithdrawModal({
|
|
|
26157
26839
|
}
|
|
26158
26840
|
|
|
26159
26841
|
// src/components/withdrawals/WithdrawTokenSelector.tsx
|
|
26160
|
-
import { useState as useState46, useMemo as
|
|
26842
|
+
import { useState as useState46, useMemo as useMemo18 } from "react";
|
|
26161
26843
|
import { Search } from "lucide-react";
|
|
26162
26844
|
import Fuse2 from "fuse.js";
|
|
26163
26845
|
import { jsx as jsx70, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
@@ -26166,7 +26848,7 @@ function WithdrawTokenSelector({ tokens, onSelect, onBack }) {
|
|
|
26166
26848
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
26167
26849
|
const [searchQuery, setSearchQuery] = useState46("");
|
|
26168
26850
|
const [hoveredKey, setHoveredKey] = useState46(null);
|
|
26169
|
-
const allOptions =
|
|
26851
|
+
const allOptions = useMemo18(() => {
|
|
26170
26852
|
const options = [];
|
|
26171
26853
|
tokens.forEach((token) => {
|
|
26172
26854
|
token.chains.forEach((chain) => {
|
|
@@ -26175,7 +26857,7 @@ function WithdrawTokenSelector({ tokens, onSelect, onBack }) {
|
|
|
26175
26857
|
});
|
|
26176
26858
|
return options;
|
|
26177
26859
|
}, [tokens]);
|
|
26178
|
-
const fuse =
|
|
26860
|
+
const fuse = useMemo18(
|
|
26179
26861
|
() => new Fuse2(allOptions, {
|
|
26180
26862
|
keys: [
|
|
26181
26863
|
{ name: "token.symbol", weight: 2 },
|
|
@@ -26188,7 +26870,7 @@ function WithdrawTokenSelector({ tokens, onSelect, onBack }) {
|
|
|
26188
26870
|
}),
|
|
26189
26871
|
[allOptions]
|
|
26190
26872
|
);
|
|
26191
|
-
const filteredOptions =
|
|
26873
|
+
const filteredOptions = useMemo18(() => {
|
|
26192
26874
|
if (!searchQuery.trim()) return allOptions;
|
|
26193
26875
|
const query = searchQuery.trim();
|
|
26194
26876
|
const results = fuse.search(query);
|
|
@@ -26446,6 +27128,7 @@ export {
|
|
|
26446
27128
|
useDepositPolling,
|
|
26447
27129
|
useDepositQuote,
|
|
26448
27130
|
usePaymentIntent,
|
|
27131
|
+
usePublicIncident,
|
|
26449
27132
|
useSourceTokenValidation,
|
|
26450
27133
|
useSupportedDepositTokens,
|
|
26451
27134
|
useSupportedDestinationTokens,
|