@unifold/ui-react 0.1.21 → 0.1.22
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 +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.js +500 -214
- package/dist/index.mjs +437 -149
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -85,7 +85,7 @@ __export(index_exports, {
|
|
|
85
85
|
module.exports = __toCommonJS(index_exports);
|
|
86
86
|
|
|
87
87
|
// src/components/deposits/DepositModal.tsx
|
|
88
|
-
var
|
|
88
|
+
var import_react13 = require("react");
|
|
89
89
|
var import_lucide_react15 = require("lucide-react");
|
|
90
90
|
|
|
91
91
|
// src/components/shared/dialog.tsx
|
|
@@ -99,6 +99,29 @@ var import_tailwind_merge = require("tailwind-merge");
|
|
|
99
99
|
function cn(...inputs) {
|
|
100
100
|
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
101
101
|
}
|
|
102
|
+
function formatEstimatedTime(seconds) {
|
|
103
|
+
if (seconds == null) {
|
|
104
|
+
return "< 1 min";
|
|
105
|
+
}
|
|
106
|
+
if (seconds < 60) {
|
|
107
|
+
return `< ${seconds} sec${seconds > 1 ? "s" : ""}`;
|
|
108
|
+
} else if (seconds < 3600) {
|
|
109
|
+
const mins = Math.ceil(seconds / 60);
|
|
110
|
+
return `< ${mins} min${mins > 1 ? "s" : ""}`;
|
|
111
|
+
} else {
|
|
112
|
+
let hrs = Math.floor(seconds / 3600);
|
|
113
|
+
let mins = Math.ceil(seconds % 3600 / 60);
|
|
114
|
+
if (mins === 60) {
|
|
115
|
+
hrs += 1;
|
|
116
|
+
mins = 0;
|
|
117
|
+
}
|
|
118
|
+
const hrLabel = hrs > 1 ? "hrs" : "hr";
|
|
119
|
+
if (mins === 0) {
|
|
120
|
+
return `< ${hrs} ${hrLabel}`;
|
|
121
|
+
}
|
|
122
|
+
return `< ${hrs} ${hrLabel} ${mins} min${mins > 1 ? "s" : ""}`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
102
125
|
|
|
103
126
|
// src/context/ThemeContext.tsx
|
|
104
127
|
var React = __toESM(require("react"));
|
|
@@ -552,15 +575,17 @@ var DialogDescription = React2.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
552
575
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
553
576
|
|
|
554
577
|
// src/components/deposits/BuyWithCard.tsx
|
|
555
|
-
var
|
|
578
|
+
var import_react7 = require("react");
|
|
556
579
|
var import_lucide_react6 = require("lucide-react");
|
|
557
|
-
var
|
|
580
|
+
var import_core7 = require("@unifold/core");
|
|
558
581
|
|
|
559
582
|
// src/components/deposits/CurrencyModal.tsx
|
|
560
|
-
var
|
|
583
|
+
var import_react2 = require("react");
|
|
561
584
|
|
|
562
585
|
// src/components/deposits/DepositHeader.tsx
|
|
563
586
|
var import_lucide_react2 = require("lucide-react");
|
|
587
|
+
var import_react = require("react");
|
|
588
|
+
var import_core = require("@unifold/core");
|
|
564
589
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
565
590
|
function DepositHeader({
|
|
566
591
|
title,
|
|
@@ -568,10 +593,83 @@ function DepositHeader({
|
|
|
568
593
|
showClose = true,
|
|
569
594
|
onBack,
|
|
570
595
|
onClose,
|
|
571
|
-
badge
|
|
596
|
+
badge,
|
|
597
|
+
showBalance = false,
|
|
598
|
+
balanceAddress,
|
|
599
|
+
balanceChainType,
|
|
600
|
+
balanceChainId,
|
|
601
|
+
balanceTokenAddress,
|
|
602
|
+
publishableKey
|
|
572
603
|
}) {
|
|
573
604
|
const { colors: colors2, fonts, components } = useTheme();
|
|
574
|
-
|
|
605
|
+
const [balance, setBalance] = (0, import_react.useState)(null);
|
|
606
|
+
const [isLoadingBalance, setIsLoadingBalance] = (0, import_react.useState)(false);
|
|
607
|
+
(0, import_react.useEffect)(() => {
|
|
608
|
+
if (!showBalance || !balanceAddress || !balanceChainType || !balanceChainId || !balanceTokenAddress || !publishableKey) {
|
|
609
|
+
setBalance(null);
|
|
610
|
+
setIsLoadingBalance(false);
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
let cancelled = false;
|
|
614
|
+
setIsLoadingBalance(true);
|
|
615
|
+
(0, import_core.getAddressBalance)(
|
|
616
|
+
balanceAddress,
|
|
617
|
+
balanceChainType,
|
|
618
|
+
balanceChainId,
|
|
619
|
+
balanceTokenAddress,
|
|
620
|
+
publishableKey
|
|
621
|
+
).then((response) => {
|
|
622
|
+
if (cancelled) return;
|
|
623
|
+
if (response.balance && response.balance.amount !== "0") {
|
|
624
|
+
const value = Number(response.balance.amount) / 10 ** response.balance.token.decimals;
|
|
625
|
+
let formatted;
|
|
626
|
+
let maxDecimals = 4;
|
|
627
|
+
const symbol = response.balance.token.symbol?.toUpperCase() || "";
|
|
628
|
+
if (symbol === "BTC" || symbol === "WBTC") {
|
|
629
|
+
maxDecimals = 8;
|
|
630
|
+
} else if (symbol === "ETH" || symbol === "WETH") {
|
|
631
|
+
maxDecimals = 6;
|
|
632
|
+
}
|
|
633
|
+
if (value >= 1) {
|
|
634
|
+
formatted = value.toLocaleString(void 0, {
|
|
635
|
+
minimumFractionDigits: 2,
|
|
636
|
+
maximumFractionDigits: maxDecimals
|
|
637
|
+
});
|
|
638
|
+
} else if (value > 0) {
|
|
639
|
+
formatted = value.toLocaleString(void 0, {
|
|
640
|
+
minimumFractionDigits: 2,
|
|
641
|
+
maximumFractionDigits: maxDecimals,
|
|
642
|
+
minimumSignificantDigits: 2,
|
|
643
|
+
maximumSignificantDigits: 6
|
|
644
|
+
});
|
|
645
|
+
} else {
|
|
646
|
+
formatted = value.toExponential(2);
|
|
647
|
+
}
|
|
648
|
+
const balanceText = response.balance.amount_usd ? `Balance: $${response.balance.amount_usd} (${formatted} ${response.balance.token.symbol})` : `Balance: ${formatted} ${response.balance.token.symbol}`;
|
|
649
|
+
setBalance(balanceText);
|
|
650
|
+
} else {
|
|
651
|
+
setBalance(null);
|
|
652
|
+
}
|
|
653
|
+
}).catch((error) => {
|
|
654
|
+
if (cancelled) return;
|
|
655
|
+
console.error("Error fetching balance:", error);
|
|
656
|
+
setBalance(null);
|
|
657
|
+
}).finally(() => {
|
|
658
|
+
if (cancelled) return;
|
|
659
|
+
setIsLoadingBalance(false);
|
|
660
|
+
});
|
|
661
|
+
return () => {
|
|
662
|
+
cancelled = true;
|
|
663
|
+
};
|
|
664
|
+
}, [
|
|
665
|
+
showBalance,
|
|
666
|
+
balanceAddress,
|
|
667
|
+
balanceChainType,
|
|
668
|
+
balanceChainId,
|
|
669
|
+
balanceTokenAddress,
|
|
670
|
+
publishableKey
|
|
671
|
+
]);
|
|
672
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-6", children: [
|
|
575
673
|
showBack ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
576
674
|
"button",
|
|
577
675
|
{
|
|
@@ -581,8 +679,32 @@ function DepositHeader({
|
|
|
581
679
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.ArrowLeft, { className: "uf-w-5 uf-h-5" })
|
|
582
680
|
}
|
|
583
681
|
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
|
|
584
|
-
|
|
585
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.
|
|
682
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center", children: [
|
|
683
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
|
|
684
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
685
|
+
DialogTitle,
|
|
686
|
+
{
|
|
687
|
+
className: "uf-text-center uf-text-base",
|
|
688
|
+
style: {
|
|
689
|
+
color: components.header.titleColor,
|
|
690
|
+
fontFamily: fonts.medium
|
|
691
|
+
},
|
|
692
|
+
children: title
|
|
693
|
+
}
|
|
694
|
+
),
|
|
695
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
696
|
+
"div",
|
|
697
|
+
{
|
|
698
|
+
className: "uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px]",
|
|
699
|
+
style: {
|
|
700
|
+
backgroundColor: colors2.card,
|
|
701
|
+
color: colors2.foregroundMuted,
|
|
702
|
+
fontFamily: fonts.regular
|
|
703
|
+
},
|
|
704
|
+
children: badge.count
|
|
705
|
+
}
|
|
706
|
+
)
|
|
707
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
586
708
|
DialogTitle,
|
|
587
709
|
{
|
|
588
710
|
className: "uf-text-center uf-text-base",
|
|
@@ -593,29 +715,19 @@ function DepositHeader({
|
|
|
593
715
|
children: title
|
|
594
716
|
}
|
|
595
717
|
),
|
|
596
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
718
|
+
showBalance && (isLoadingBalance ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-2" }) : balance ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
597
719
|
"div",
|
|
598
720
|
{
|
|
599
|
-
className: "uf-
|
|
721
|
+
className: "uf-text-xs uf-mt-2",
|
|
600
722
|
style: {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
723
|
+
color: colors2.foreground,
|
|
724
|
+
fontFamily: fonts.regular,
|
|
725
|
+
opacity: 0.7
|
|
604
726
|
},
|
|
605
|
-
children:
|
|
727
|
+
children: balance
|
|
606
728
|
}
|
|
607
|
-
)
|
|
608
|
-
] })
|
|
609
|
-
DialogTitle,
|
|
610
|
-
{
|
|
611
|
-
className: "uf-text-center uf-text-base",
|
|
612
|
-
style: {
|
|
613
|
-
color: components.header.titleColor,
|
|
614
|
-
fontFamily: fonts.medium
|
|
615
|
-
},
|
|
616
|
-
children: title
|
|
617
|
-
}
|
|
618
|
-
),
|
|
729
|
+
) : null)
|
|
730
|
+
] }),
|
|
619
731
|
showClose ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
620
732
|
"button",
|
|
621
733
|
{
|
|
@@ -625,13 +737,13 @@ function DepositHeader({
|
|
|
625
737
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.X, { className: "uf-w-5 uf-h-5" })
|
|
626
738
|
}
|
|
627
739
|
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
|
|
628
|
-
] });
|
|
740
|
+
] }) });
|
|
629
741
|
}
|
|
630
742
|
|
|
631
743
|
// src/components/currency/CurrencyListItem.tsx
|
|
632
744
|
var React3 = __toESM(require("react"));
|
|
633
745
|
var import_lucide_react3 = require("lucide-react");
|
|
634
|
-
var
|
|
746
|
+
var import_core2 = require("@unifold/core");
|
|
635
747
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
636
748
|
function CurrencyListItem({
|
|
637
749
|
currency,
|
|
@@ -640,7 +752,7 @@ function CurrencyListItem({
|
|
|
640
752
|
}) {
|
|
641
753
|
const { colors: colors2, fonts, components } = useTheme();
|
|
642
754
|
const [isHovered, setIsHovered] = React3.useState(false);
|
|
643
|
-
const iconUrl = (0,
|
|
755
|
+
const iconUrl = (0, import_core2.getPreferredIconUrl)(currency.icon_urls, "png") || currency.icon_url;
|
|
644
756
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
645
757
|
"button",
|
|
646
758
|
{
|
|
@@ -738,7 +850,7 @@ function CurrencyModal({
|
|
|
738
850
|
themeClass = ""
|
|
739
851
|
}) {
|
|
740
852
|
const { colors: colors2, fonts, components } = useTheme();
|
|
741
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
853
|
+
const [searchQuery, setSearchQuery] = (0, import_react2.useState)("");
|
|
742
854
|
const preferredCurrencies = preferredCurrencyCodes.map(
|
|
743
855
|
(code) => currencies.find(
|
|
744
856
|
(currency) => currency.currency_code.toLowerCase() === code.toLowerCase()
|
|
@@ -834,7 +946,7 @@ function CurrencyModal({
|
|
|
834
946
|
|
|
835
947
|
// src/hooks/use-user-ip.ts
|
|
836
948
|
var import_react_query = require("@tanstack/react-query");
|
|
837
|
-
var
|
|
949
|
+
var import_core3 = require("@unifold/core");
|
|
838
950
|
function useUserIp() {
|
|
839
951
|
const {
|
|
840
952
|
data: userIpInfo,
|
|
@@ -843,7 +955,7 @@ function useUserIp() {
|
|
|
843
955
|
} = (0, import_react_query.useQuery)({
|
|
844
956
|
queryKey: ["unifold", "userIpInfo"],
|
|
845
957
|
queryFn: async () => {
|
|
846
|
-
const data = await (0,
|
|
958
|
+
const data = await (0, import_core3.getIpAddress)();
|
|
847
959
|
return {
|
|
848
960
|
alpha2: data.alpha2.toLowerCase(),
|
|
849
961
|
alpha3: data.alpha3?.toLowerCase(),
|
|
@@ -914,7 +1026,19 @@ var en_default = {
|
|
|
914
1026
|
minimumDeposit: "Minimum: {{amount}}",
|
|
915
1027
|
minimumDepositTooltip: "The minimum amount you can deposit on the selected network.",
|
|
916
1028
|
selectTokenDeposit: "Your deposit token",
|
|
917
|
-
selectTokenDepositTooltip: "Select the token you want to deposit with in order to begin the deposit process."
|
|
1029
|
+
selectTokenDepositTooltip: "Select the token you want to deposit with in order to begin the deposit process.",
|
|
1030
|
+
addressValidation: {
|
|
1031
|
+
validating: "Verifying recipient address...",
|
|
1032
|
+
unableToReceiveFunds: "Unable to Receive Funds",
|
|
1033
|
+
errors: {
|
|
1034
|
+
token_not_supported: "The destination token is not supported",
|
|
1035
|
+
not_opted_in: "Please make sure you opt-in {{token_symbol}}({{chain_name}}) before receiving funds",
|
|
1036
|
+
insufficient_balance: "Recipient account does not meet the minimum balance requirement",
|
|
1037
|
+
account_not_found: "Recipient account does not exist on {{chain_name}}",
|
|
1038
|
+
validation_error: "Unable to verify recipient address on {{chain_name}}"
|
|
1039
|
+
},
|
|
1040
|
+
defaultError: "The recipient address cannot receive funds for the selected token"
|
|
1041
|
+
}
|
|
918
1042
|
},
|
|
919
1043
|
depositModal: {
|
|
920
1044
|
transferCrypto: {
|
|
@@ -923,7 +1047,7 @@ var en_default = {
|
|
|
923
1047
|
},
|
|
924
1048
|
depositWithCard: {
|
|
925
1049
|
title: "Deposit with Card",
|
|
926
|
-
subtitle: "$50,000 limit
|
|
1050
|
+
subtitle: "$50,000 limit"
|
|
927
1051
|
},
|
|
928
1052
|
quotes: "Quotes"
|
|
929
1053
|
},
|
|
@@ -941,10 +1065,17 @@ var en_default = {
|
|
|
941
1065
|
|
|
942
1066
|
// src/lib/i18n.ts
|
|
943
1067
|
var i18n = en_default;
|
|
1068
|
+
function interpolate(template, params) {
|
|
1069
|
+
if (!params) return template;
|
|
1070
|
+
return template.replace(/\{\{(\w+)\}\}/g, (_, key) => {
|
|
1071
|
+
const value = params[key];
|
|
1072
|
+
return value !== void 0 ? String(value) : `{{${key}}}`;
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
944
1075
|
|
|
945
1076
|
// src/hooks/use-deposit-polling.ts
|
|
946
|
-
var
|
|
947
|
-
var
|
|
1077
|
+
var import_react3 = require("react");
|
|
1078
|
+
var import_core4 = require("@unifold/core");
|
|
948
1079
|
function useDepositPolling({
|
|
949
1080
|
userId,
|
|
950
1081
|
publishableKey,
|
|
@@ -952,18 +1083,18 @@ function useDepositPolling({
|
|
|
952
1083
|
onDepositSuccess,
|
|
953
1084
|
onDepositError
|
|
954
1085
|
}) {
|
|
955
|
-
const [executions, setExecutions] = (0,
|
|
956
|
-
const [isPolling, setIsPolling] = (0,
|
|
957
|
-
const pollingIntervalRef = (0,
|
|
1086
|
+
const [executions, setExecutions] = (0, import_react3.useState)([]);
|
|
1087
|
+
const [isPolling, setIsPolling] = (0, import_react3.useState)(false);
|
|
1088
|
+
const pollingIntervalRef = (0, import_react3.useRef)(
|
|
958
1089
|
null
|
|
959
1090
|
);
|
|
960
|
-
const [modalOpenedAt] = (0,
|
|
961
|
-
const [trackedExecutions, setTrackedExecutions] = (0,
|
|
962
|
-
(0,
|
|
1091
|
+
const [modalOpenedAt] = (0, import_react3.useState)(/* @__PURE__ */ new Date());
|
|
1092
|
+
const [trackedExecutions, setTrackedExecutions] = (0, import_react3.useState)(/* @__PURE__ */ new Map());
|
|
1093
|
+
(0, import_react3.useEffect)(() => {
|
|
963
1094
|
if (!userId || !modalOpenedAt || !enabled) return;
|
|
964
1095
|
const pollInterval = setInterval(async () => {
|
|
965
1096
|
try {
|
|
966
|
-
const response = await (0,
|
|
1097
|
+
const response = await (0, import_core4.queryExecutions)(userId, publishableKey);
|
|
967
1098
|
let executionToShow = null;
|
|
968
1099
|
for (const execution of response.data) {
|
|
969
1100
|
const executionTime = execution.created_at ? new Date(execution.created_at) : null;
|
|
@@ -976,13 +1107,13 @@ function useDepositPolling({
|
|
|
976
1107
|
break;
|
|
977
1108
|
}
|
|
978
1109
|
const inProgressStatuses = [
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1110
|
+
import_core4.ExecutionStatus.PENDING,
|
|
1111
|
+
import_core4.ExecutionStatus.WAITING,
|
|
1112
|
+
import_core4.ExecutionStatus.DELAYED
|
|
982
1113
|
];
|
|
983
1114
|
const terminalStatuses = [
|
|
984
|
-
|
|
985
|
-
|
|
1115
|
+
import_core4.ExecutionStatus.SUCCEEDED,
|
|
1116
|
+
import_core4.ExecutionStatus.FAILED
|
|
986
1117
|
];
|
|
987
1118
|
if (inProgressStatuses.includes(trackedStatus) && terminalStatuses.includes(execution.status)) {
|
|
988
1119
|
executionToShow = execution;
|
|
@@ -1008,17 +1139,17 @@ function useDepositPolling({
|
|
|
1008
1139
|
return updated;
|
|
1009
1140
|
});
|
|
1010
1141
|
const inProgressStatuses = [
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1142
|
+
import_core4.ExecutionStatus.PENDING,
|
|
1143
|
+
import_core4.ExecutionStatus.WAITING,
|
|
1144
|
+
import_core4.ExecutionStatus.DELAYED
|
|
1014
1145
|
];
|
|
1015
|
-
if (execution.status ===
|
|
1146
|
+
if (execution.status === import_core4.ExecutionStatus.SUCCEEDED && onDepositSuccess && (!previousStatus || inProgressStatuses.includes(previousStatus))) {
|
|
1016
1147
|
onDepositSuccess({
|
|
1017
1148
|
message: "Deposit completed successfully",
|
|
1018
1149
|
executionId: execution.id,
|
|
1019
1150
|
transaction: execution
|
|
1020
1151
|
});
|
|
1021
|
-
} else if (execution.status ===
|
|
1152
|
+
} else if (execution.status === import_core4.ExecutionStatus.FAILED && onDepositError && previousStatus !== import_core4.ExecutionStatus.FAILED) {
|
|
1022
1153
|
onDepositError({
|
|
1023
1154
|
message: "Deposit failed",
|
|
1024
1155
|
code: "DEPOSIT_FAILED",
|
|
@@ -1062,17 +1193,17 @@ function useDepositPolling({
|
|
|
1062
1193
|
}
|
|
1063
1194
|
|
|
1064
1195
|
// src/components/deposits/DepositPollingToasts.tsx
|
|
1065
|
-
var
|
|
1196
|
+
var import_react6 = require("react");
|
|
1066
1197
|
|
|
1067
1198
|
// src/components/deposits/DepositSuccessToast.tsx
|
|
1068
|
-
var
|
|
1199
|
+
var import_react5 = require("react");
|
|
1069
1200
|
var import_lucide_react5 = require("lucide-react");
|
|
1070
|
-
var
|
|
1201
|
+
var import_core6 = require("@unifold/core");
|
|
1071
1202
|
|
|
1072
1203
|
// src/components/deposits/DepositDetailContent.tsx
|
|
1073
|
-
var
|
|
1204
|
+
var import_react4 = require("react");
|
|
1074
1205
|
var import_lucide_react4 = require("lucide-react");
|
|
1075
|
-
var
|
|
1206
|
+
var import_core5 = require("@unifold/core");
|
|
1076
1207
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1077
1208
|
function formatCurrency(currency) {
|
|
1078
1209
|
if (!currency) return "";
|
|
@@ -1084,15 +1215,15 @@ function formatCurrency(currency) {
|
|
|
1084
1215
|
}
|
|
1085
1216
|
function DepositDetailContent({ execution }) {
|
|
1086
1217
|
const { colors: colors2, fonts, components } = useTheme();
|
|
1087
|
-
const [chains, setChains] = (0,
|
|
1088
|
-
const [showNetworkDetails, setShowNetworkDetails] = (0,
|
|
1089
|
-
(0,
|
|
1090
|
-
(0,
|
|
1218
|
+
const [chains, setChains] = (0, import_react4.useState)([]);
|
|
1219
|
+
const [showNetworkDetails, setShowNetworkDetails] = (0, import_react4.useState)(false);
|
|
1220
|
+
(0, import_react4.useEffect)(() => {
|
|
1221
|
+
(0, import_core5.getTokenChains)().then((response) => setChains(response.data)).catch((err) => console.error("Failed to fetch chains:", err));
|
|
1091
1222
|
}, []);
|
|
1092
|
-
(0,
|
|
1223
|
+
(0, import_react4.useEffect)(() => {
|
|
1093
1224
|
setShowNetworkDetails(false);
|
|
1094
1225
|
}, [execution?.id]);
|
|
1095
|
-
const isPending = execution.status ===
|
|
1226
|
+
const isPending = execution.status === import_core5.ExecutionStatus.PENDING || execution.status === import_core5.ExecutionStatus.WAITING || execution.status === import_core5.ExecutionStatus.DELAYED;
|
|
1096
1227
|
const formatDateTime = (timestamp) => {
|
|
1097
1228
|
try {
|
|
1098
1229
|
const date = new Date(timestamp);
|
|
@@ -1162,7 +1293,7 @@ function DepositDetailContent({ execution }) {
|
|
|
1162
1293
|
return "$0.00";
|
|
1163
1294
|
};
|
|
1164
1295
|
const getNetworkName = (chainType, chainId) => {
|
|
1165
|
-
return (0,
|
|
1296
|
+
return (0, import_core5.getChainName)(chains, chainType, chainId);
|
|
1166
1297
|
};
|
|
1167
1298
|
const formatTransactionHash = (hash) => {
|
|
1168
1299
|
if (!hash || hash.length < 12) return hash;
|
|
@@ -1174,7 +1305,7 @@ function DepositDetailContent({ execution }) {
|
|
|
1174
1305
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1175
1306
|
"img",
|
|
1176
1307
|
{
|
|
1177
|
-
src: execution.destination_token_metadata?.icon_url || (0,
|
|
1308
|
+
src: execution.destination_token_metadata?.icon_url || (0, import_core5.getIconUrl)("/icons/tokens/svg/usdc.svg"),
|
|
1178
1309
|
alt: "Token",
|
|
1179
1310
|
width: 64,
|
|
1180
1311
|
height: 64,
|
|
@@ -1384,6 +1515,37 @@ function DepositDetailContent({ execution }) {
|
|
|
1384
1515
|
]
|
|
1385
1516
|
}
|
|
1386
1517
|
),
|
|
1518
|
+
isPending && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1519
|
+
"div",
|
|
1520
|
+
{
|
|
1521
|
+
className: "uf-flex uf-justify-between uf-items-center uf-px-4 uf-py-3 uf-border-b",
|
|
1522
|
+
style: { borderColor: colors2.border },
|
|
1523
|
+
children: [
|
|
1524
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1525
|
+
"span",
|
|
1526
|
+
{
|
|
1527
|
+
className: "uf-text-sm",
|
|
1528
|
+
style: {
|
|
1529
|
+
color: components.card.labelColor,
|
|
1530
|
+
fontFamily: fonts.regular
|
|
1531
|
+
},
|
|
1532
|
+
children: "Estimated delivery time"
|
|
1533
|
+
}
|
|
1534
|
+
),
|
|
1535
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1536
|
+
"span",
|
|
1537
|
+
{
|
|
1538
|
+
style: {
|
|
1539
|
+
color: components.card.titleColor,
|
|
1540
|
+
fontFamily: fonts.regular,
|
|
1541
|
+
fontSize: "14px"
|
|
1542
|
+
},
|
|
1543
|
+
children: formatEstimatedTime(execution?.estimated_processing_time)
|
|
1544
|
+
}
|
|
1545
|
+
)
|
|
1546
|
+
]
|
|
1547
|
+
}
|
|
1548
|
+
),
|
|
1387
1549
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1388
1550
|
"div",
|
|
1389
1551
|
{
|
|
@@ -1570,9 +1732,9 @@ function DepositSuccessToast({
|
|
|
1570
1732
|
onClose,
|
|
1571
1733
|
execution
|
|
1572
1734
|
}) {
|
|
1573
|
-
const [detailModalOpen, setDetailModalOpen] = (0,
|
|
1735
|
+
const [detailModalOpen, setDetailModalOpen] = (0, import_react5.useState)(false);
|
|
1574
1736
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
1575
|
-
const isPending = status ===
|
|
1737
|
+
const isPending = status === import_core6.ExecutionStatus.PENDING || status === import_core6.ExecutionStatus.WAITING || status === import_core6.ExecutionStatus.DELAYED;
|
|
1576
1738
|
const formatDateTime = (timestamp) => {
|
|
1577
1739
|
try {
|
|
1578
1740
|
const date = new Date(timestamp);
|
|
@@ -1650,7 +1812,7 @@ function DepositSuccessToast({
|
|
|
1650
1812
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1651
1813
|
"img",
|
|
1652
1814
|
{
|
|
1653
|
-
src: tokenIconUrl || (0,
|
|
1815
|
+
src: tokenIconUrl || (0, import_core6.getIconUrl)("/icons/tokens/svg/usdc.svg"),
|
|
1654
1816
|
alt: "Token",
|
|
1655
1817
|
width: 36,
|
|
1656
1818
|
height: 36,
|
|
@@ -1704,14 +1866,27 @@ function DepositSuccessToast({
|
|
|
1704
1866
|
}
|
|
1705
1867
|
)
|
|
1706
1868
|
] }),
|
|
1707
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1869
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "uf-flex-shrink-0 uf-text-right", children: [
|
|
1870
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1871
|
+
"div",
|
|
1872
|
+
{
|
|
1873
|
+
className: "uf-font-medium uf-text-sm",
|
|
1874
|
+
style: { color: colors2.background },
|
|
1875
|
+
children: formatUsdAmount(sourceAmountUsd)
|
|
1876
|
+
}
|
|
1877
|
+
),
|
|
1878
|
+
isPending && execution?.estimated_processing_time && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1879
|
+
"p",
|
|
1880
|
+
{
|
|
1881
|
+
className: "uf-text-xs",
|
|
1882
|
+
style: { color: colors2.foregroundMuted },
|
|
1883
|
+
children: [
|
|
1884
|
+
"Est. ",
|
|
1885
|
+
formatEstimatedTime(execution.estimated_processing_time)
|
|
1886
|
+
]
|
|
1887
|
+
}
|
|
1888
|
+
)
|
|
1889
|
+
] }),
|
|
1715
1890
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1716
1891
|
"button",
|
|
1717
1892
|
{
|
|
@@ -1760,7 +1935,7 @@ function DepositPollingToasts({
|
|
|
1760
1935
|
executions,
|
|
1761
1936
|
horizontalPadding = "24px"
|
|
1762
1937
|
}) {
|
|
1763
|
-
const [closedExecutionIds, setClosedExecutionIds] = (0,
|
|
1938
|
+
const [closedExecutionIds, setClosedExecutionIds] = (0, import_react6.useState)(
|
|
1764
1939
|
/* @__PURE__ */ new Set()
|
|
1765
1940
|
);
|
|
1766
1941
|
const handleClose = (executionId) => {
|
|
@@ -1841,28 +2016,28 @@ function BuyWithCard({
|
|
|
1841
2016
|
assetCdnUrl
|
|
1842
2017
|
}) {
|
|
1843
2018
|
const { colors: colors2, fonts, components } = useTheme();
|
|
1844
|
-
const [amount, setAmount] = (0,
|
|
1845
|
-
const [currency, setCurrency] = (0,
|
|
1846
|
-
const [hasManualCurrencySelection, setHasManualCurrencySelection] = (0,
|
|
1847
|
-
const [hasManualAmountEntry, setHasManualAmountEntry] = (0,
|
|
1848
|
-
const [showCurrencyModal, setShowCurrencyModal] = (0,
|
|
1849
|
-
const [quotes, setQuotes] = (0,
|
|
1850
|
-
const [quotesLoading, setQuotesLoading] = (0,
|
|
1851
|
-
const [quotesError, setQuotesError] = (0,
|
|
1852
|
-
const [amountValidationError, setAmountValidationError] = (0,
|
|
1853
|
-
const [internalView, setInternalView] = (0,
|
|
1854
|
-
const [defaultToken, setDefaultToken] = (0,
|
|
2019
|
+
const [amount, setAmount] = (0, import_react7.useState)("");
|
|
2020
|
+
const [currency, setCurrency] = (0, import_react7.useState)("usd");
|
|
2021
|
+
const [hasManualCurrencySelection, setHasManualCurrencySelection] = (0, import_react7.useState)(false);
|
|
2022
|
+
const [hasManualAmountEntry, setHasManualAmountEntry] = (0, import_react7.useState)(false);
|
|
2023
|
+
const [showCurrencyModal, setShowCurrencyModal] = (0, import_react7.useState)(false);
|
|
2024
|
+
const [quotes, setQuotes] = (0, import_react7.useState)([]);
|
|
2025
|
+
const [quotesLoading, setQuotesLoading] = (0, import_react7.useState)(false);
|
|
2026
|
+
const [quotesError, setQuotesError] = (0, import_react7.useState)(null);
|
|
2027
|
+
const [amountValidationError, setAmountValidationError] = (0, import_react7.useState)(null);
|
|
2028
|
+
const [internalView, setInternalView] = (0, import_react7.useState)("amount");
|
|
2029
|
+
const [defaultToken, setDefaultToken] = (0, import_react7.useState)(
|
|
1855
2030
|
null
|
|
1856
2031
|
);
|
|
1857
|
-
const [defaultTokenLoading, setDefaultTokenLoading] = (0,
|
|
2032
|
+
const [defaultTokenLoading, setDefaultTokenLoading] = (0, import_react7.useState)(false);
|
|
1858
2033
|
const { userIpInfo, isLoading: isLoadingIp } = useUserIp();
|
|
1859
|
-
const [onrampSession, setOnrampSession] = (0,
|
|
2034
|
+
const [onrampSession, setOnrampSession] = (0, import_react7.useState)(
|
|
1860
2035
|
null
|
|
1861
2036
|
);
|
|
1862
2037
|
const currentView = externalView ?? internalView;
|
|
1863
2038
|
const showQuotesView = currentView === "quotes";
|
|
1864
2039
|
const showOnrampView = currentView === "onramp";
|
|
1865
|
-
(0,
|
|
2040
|
+
(0, import_react7.useEffect)(() => {
|
|
1866
2041
|
if (externalView) {
|
|
1867
2042
|
setInternalView(externalView);
|
|
1868
2043
|
}
|
|
@@ -1875,31 +2050,31 @@ function BuyWithCard({
|
|
|
1875
2050
|
onViewChange?.(newView);
|
|
1876
2051
|
}
|
|
1877
2052
|
};
|
|
1878
|
-
const [selectedProvider, setSelectedProvider] = (0,
|
|
2053
|
+
const [selectedProvider, setSelectedProvider] = (0, import_react7.useState)(
|
|
1879
2054
|
null
|
|
1880
2055
|
);
|
|
1881
|
-
const [isAutoSelected, setIsAutoSelected] = (0,
|
|
1882
|
-
const [autoSelectedProvider, setAutoSelectedProvider] = (0,
|
|
1883
|
-
const [hoveredProviderIndex, setHoveredProviderIndex] = (0,
|
|
1884
|
-
const [hasManualSelection, setHasManualSelection] = (0,
|
|
1885
|
-
const selectedProviderRef = (0,
|
|
1886
|
-
const hasManualSelectionRef = (0,
|
|
1887
|
-
(0,
|
|
2056
|
+
const [isAutoSelected, setIsAutoSelected] = (0, import_react7.useState)(true);
|
|
2057
|
+
const [autoSelectedProvider, setAutoSelectedProvider] = (0, import_react7.useState)(null);
|
|
2058
|
+
const [hoveredProviderIndex, setHoveredProviderIndex] = (0, import_react7.useState)(null);
|
|
2059
|
+
const [hasManualSelection, setHasManualSelection] = (0, import_react7.useState)(false);
|
|
2060
|
+
const selectedProviderRef = (0, import_react7.useRef)(null);
|
|
2061
|
+
const hasManualSelectionRef = (0, import_react7.useRef)(false);
|
|
2062
|
+
(0, import_react7.useEffect)(() => {
|
|
1888
2063
|
selectedProviderRef.current = selectedProvider;
|
|
1889
2064
|
}, [selectedProvider]);
|
|
1890
|
-
(0,
|
|
2065
|
+
(0, import_react7.useEffect)(() => {
|
|
1891
2066
|
hasManualSelectionRef.current = hasManualSelection;
|
|
1892
2067
|
}, [hasManualSelection]);
|
|
1893
|
-
const [internalWallets, setInternalWallets] = (0,
|
|
1894
|
-
const [walletsLoading, setWalletsLoading] = (0,
|
|
2068
|
+
const [internalWallets, setInternalWallets] = (0, import_react7.useState)([]);
|
|
2069
|
+
const [walletsLoading, setWalletsLoading] = (0, import_react7.useState)(
|
|
1895
2070
|
!externalWallets?.length
|
|
1896
2071
|
);
|
|
1897
2072
|
const wallets = externalWallets?.length ? externalWallets : internalWallets;
|
|
1898
|
-
const [countdown, setCountdown] = (0,
|
|
1899
|
-
const [fiatCurrencies, setFiatCurrencies] = (0,
|
|
1900
|
-
const [preferredCurrencyCodes, setPreferredCurrencyCodes] = (0,
|
|
1901
|
-
const [currenciesLoading, setCurrenciesLoading] = (0,
|
|
1902
|
-
const [destinationToken, setDestinationToken] = (0,
|
|
2073
|
+
const [countdown, setCountdown] = (0, import_react7.useState)(60);
|
|
2074
|
+
const [fiatCurrencies, setFiatCurrencies] = (0, import_react7.useState)([]);
|
|
2075
|
+
const [preferredCurrencyCodes, setPreferredCurrencyCodes] = (0, import_react7.useState)([]);
|
|
2076
|
+
const [currenciesLoading, setCurrenciesLoading] = (0, import_react7.useState)(true);
|
|
2077
|
+
const [destinationToken, setDestinationToken] = (0, import_react7.useState)(null);
|
|
1903
2078
|
const { executions, isPolling } = useDepositPolling({
|
|
1904
2079
|
userId,
|
|
1905
2080
|
publishableKey,
|
|
@@ -1911,10 +2086,10 @@ function BuyWithCard({
|
|
|
1911
2086
|
const destinationTokenIcon = destinationToken?.icon_url;
|
|
1912
2087
|
const destinationChainIcon = destinationToken?.chain_icon_url;
|
|
1913
2088
|
const destinationChainName = destinationToken?.chain_name;
|
|
1914
|
-
(0,
|
|
2089
|
+
(0, import_react7.useEffect)(() => {
|
|
1915
2090
|
async function fetchFiatCurrencies() {
|
|
1916
2091
|
try {
|
|
1917
|
-
const response = await (0,
|
|
2092
|
+
const response = await (0, import_core7.getFiatCurrencies)(publishableKey);
|
|
1918
2093
|
setFiatCurrencies(response.data);
|
|
1919
2094
|
setPreferredCurrencyCodes(response.preferred || []);
|
|
1920
2095
|
} catch (err) {
|
|
@@ -1925,7 +2100,7 @@ function BuyWithCard({
|
|
|
1925
2100
|
}
|
|
1926
2101
|
fetchFiatCurrencies();
|
|
1927
2102
|
}, [publishableKey]);
|
|
1928
|
-
(0,
|
|
2103
|
+
(0, import_react7.useEffect)(() => {
|
|
1929
2104
|
if (hasManualCurrencySelection) return;
|
|
1930
2105
|
if (fiatCurrencies.length === 0 || !userIpInfo?.alpha2) return;
|
|
1931
2106
|
const userCountryCode = userIpInfo.alpha2.toUpperCase();
|
|
@@ -1952,8 +2127,8 @@ function BuyWithCard({
|
|
|
1952
2127
|
amount,
|
|
1953
2128
|
hasManualAmountEntry
|
|
1954
2129
|
]);
|
|
1955
|
-
const prevCurrencyRef = (0,
|
|
1956
|
-
(0,
|
|
2130
|
+
const prevCurrencyRef = (0, import_react7.useRef)(null);
|
|
2131
|
+
(0, import_react7.useEffect)(() => {
|
|
1957
2132
|
if (fiatCurrencies.length === 0) return;
|
|
1958
2133
|
if (prevCurrencyRef.current !== null && prevCurrencyRef.current !== currency) {
|
|
1959
2134
|
const currentCurrency = fiatCurrencies.find(
|
|
@@ -1965,7 +2140,7 @@ function BuyWithCard({
|
|
|
1965
2140
|
}
|
|
1966
2141
|
prevCurrencyRef.current = currency;
|
|
1967
2142
|
}, [currency]);
|
|
1968
|
-
(0,
|
|
2143
|
+
(0, import_react7.useEffect)(() => {
|
|
1969
2144
|
if (externalWallets?.length) {
|
|
1970
2145
|
setWalletsLoading(false);
|
|
1971
2146
|
return;
|
|
@@ -1980,7 +2155,7 @@ function BuyWithCard({
|
|
|
1980
2155
|
if (isCancelled) return;
|
|
1981
2156
|
setWalletsLoading(true);
|
|
1982
2157
|
try {
|
|
1983
|
-
const response = await (0,
|
|
2158
|
+
const response = await (0, import_core7.createDepositAddress)(
|
|
1984
2159
|
{
|
|
1985
2160
|
external_user_id: userId,
|
|
1986
2161
|
recipient_address: recipientAddress,
|
|
@@ -2018,10 +2193,10 @@ function BuyWithCard({
|
|
|
2018
2193
|
publishableKey,
|
|
2019
2194
|
externalWallets
|
|
2020
2195
|
]);
|
|
2021
|
-
(0,
|
|
2196
|
+
(0, import_react7.useEffect)(() => {
|
|
2022
2197
|
async function fetchDestinationToken() {
|
|
2023
2198
|
try {
|
|
2024
|
-
const response = await (0,
|
|
2199
|
+
const response = await (0, import_core7.getTokenMetadata)(
|
|
2025
2200
|
{
|
|
2026
2201
|
chain_type: destinationChainType || "",
|
|
2027
2202
|
chain_id: destinationChainId || "",
|
|
@@ -2036,7 +2211,7 @@ function BuyWithCard({
|
|
|
2036
2211
|
}
|
|
2037
2212
|
fetchDestinationToken();
|
|
2038
2213
|
}, [publishableKey]);
|
|
2039
|
-
(0,
|
|
2214
|
+
(0, import_react7.useEffect)(() => {
|
|
2040
2215
|
async function fetchDefaultToken() {
|
|
2041
2216
|
if (!destinationTokenAddress || !destinationChainId || !destinationChainType) {
|
|
2042
2217
|
return;
|
|
@@ -2046,7 +2221,7 @@ function BuyWithCard({
|
|
|
2046
2221
|
}
|
|
2047
2222
|
setDefaultTokenLoading(true);
|
|
2048
2223
|
try {
|
|
2049
|
-
const response = await (0,
|
|
2224
|
+
const response = await (0, import_core7.getDefaultOnrampToken)(
|
|
2050
2225
|
{
|
|
2051
2226
|
country_code: userIpInfo?.alpha2?.toUpperCase() || "US",
|
|
2052
2227
|
subdivision_code: userIpInfo?.state || void 0,
|
|
@@ -2072,7 +2247,7 @@ function BuyWithCard({
|
|
|
2072
2247
|
isLoadingIp,
|
|
2073
2248
|
publishableKey
|
|
2074
2249
|
]);
|
|
2075
|
-
(0,
|
|
2250
|
+
(0, import_react7.useEffect)(() => {
|
|
2076
2251
|
const amountNum = parseFloat(amount);
|
|
2077
2252
|
if (isNaN(amountNum) || amountNum <= 0) {
|
|
2078
2253
|
setQuotes([]);
|
|
@@ -2134,7 +2309,7 @@ function BuyWithCard({
|
|
|
2134
2309
|
destination_network: defaultToken.destination_network,
|
|
2135
2310
|
subdivision_code: userIpInfo?.state || void 0
|
|
2136
2311
|
};
|
|
2137
|
-
const response = await (0,
|
|
2312
|
+
const response = await (0, import_core7.getOnrampQuotes)(request, publishableKey);
|
|
2138
2313
|
setQuotes(response.data);
|
|
2139
2314
|
const currentHasManualSelection = hasManualSelectionRef.current;
|
|
2140
2315
|
const currentSelectedProvider = selectedProviderRef.current;
|
|
@@ -2181,7 +2356,7 @@ function BuyWithCard({
|
|
|
2181
2356
|
setQuotesLoading(false);
|
|
2182
2357
|
}
|
|
2183
2358
|
};
|
|
2184
|
-
(0,
|
|
2359
|
+
(0, import_react7.useEffect)(() => {
|
|
2185
2360
|
if (quotes.length === 0) return;
|
|
2186
2361
|
const timer = setInterval(() => {
|
|
2187
2362
|
setCountdown((prev) => {
|
|
@@ -2218,7 +2393,7 @@ function BuyWithCard({
|
|
|
2218
2393
|
const handleContinue = () => {
|
|
2219
2394
|
if (!selectedProvider) return;
|
|
2220
2395
|
if (!defaultToken) return;
|
|
2221
|
-
const wallet = (0,
|
|
2396
|
+
const wallet = (0, import_core7.getWalletByChainType)(
|
|
2222
2397
|
wallets,
|
|
2223
2398
|
defaultToken.destination_token_metadata.chain_type
|
|
2224
2399
|
);
|
|
@@ -2236,7 +2411,7 @@ function BuyWithCard({
|
|
|
2236
2411
|
wallet_address: wallet.address,
|
|
2237
2412
|
subdivision_code: userIpInfo?.state || void 0
|
|
2238
2413
|
};
|
|
2239
|
-
const sessionStartUrl = (0,
|
|
2414
|
+
const sessionStartUrl = (0, import_core7.getOnrampSessionStartUrl)(
|
|
2240
2415
|
sessionRequest,
|
|
2241
2416
|
publishableKey
|
|
2242
2417
|
);
|
|
@@ -2286,7 +2461,7 @@ function BuyWithCard({
|
|
|
2286
2461
|
selectedCurrencyData && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2287
2462
|
"img",
|
|
2288
2463
|
{
|
|
2289
|
-
src: (0,
|
|
2464
|
+
src: (0, import_core7.getPreferredIconUrl)(
|
|
2290
2465
|
selectedCurrencyData.icon_urls,
|
|
2291
2466
|
"png"
|
|
2292
2467
|
) || selectedCurrencyData.icon_url,
|
|
@@ -2516,6 +2691,20 @@ function BuyWithCard({
|
|
|
2516
2691
|
},
|
|
2517
2692
|
children: quotesError
|
|
2518
2693
|
}
|
|
2694
|
+
),
|
|
2695
|
+
defaultToken?.estimated_processing_time && !quotesLoading && selectedProvider && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2696
|
+
"div",
|
|
2697
|
+
{
|
|
2698
|
+
className: "uf-text-xs uf-mt-2 uf-px-1",
|
|
2699
|
+
style: {
|
|
2700
|
+
color: components.card.subtitleColor,
|
|
2701
|
+
fontFamily: fonts.regular
|
|
2702
|
+
},
|
|
2703
|
+
children: [
|
|
2704
|
+
"Estimated delivery time: ",
|
|
2705
|
+
formatEstimatedTime(defaultToken.estimated_processing_time)
|
|
2706
|
+
]
|
|
2707
|
+
}
|
|
2519
2708
|
)
|
|
2520
2709
|
] }),
|
|
2521
2710
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
@@ -2633,7 +2822,7 @@ function BuyWithCard({
|
|
|
2633
2822
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "uf-h-8 uf-flex uf-items-center uf-justify-center uf-mb-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2634
2823
|
"img",
|
|
2635
2824
|
{
|
|
2636
|
-
src: (0,
|
|
2825
|
+
src: (0, import_core7.getIconUrlWithCdn)(
|
|
2637
2826
|
`/icons/currencies/png/${onrampSession.sourceCurrency.toLowerCase()}.png`,
|
|
2638
2827
|
assetCdnUrl
|
|
2639
2828
|
),
|
|
@@ -2650,7 +2839,7 @@ function BuyWithCard({
|
|
|
2650
2839
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2651
2840
|
"img",
|
|
2652
2841
|
{
|
|
2653
|
-
src: defaultToken?.destination_token_metadata?.icon_url || (0,
|
|
2842
|
+
src: defaultToken?.destination_token_metadata?.icon_url || (0, import_core7.getIconUrlWithCdn)(
|
|
2654
2843
|
"/icons/tokens/png/usdc.png",
|
|
2655
2844
|
assetCdnUrl
|
|
2656
2845
|
),
|
|
@@ -2661,7 +2850,7 @@ function BuyWithCard({
|
|
|
2661
2850
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2662
2851
|
"img",
|
|
2663
2852
|
{
|
|
2664
|
-
src: defaultToken?.destination_token_metadata?.chain.icon_url || (0,
|
|
2853
|
+
src: defaultToken?.destination_token_metadata?.chain.icon_url || (0, import_core7.getIconUrlWithCdn)(
|
|
2665
2854
|
"/icons/networks/png/polygon.png",
|
|
2666
2855
|
assetCdnUrl
|
|
2667
2856
|
),
|
|
@@ -2679,7 +2868,7 @@ function BuyWithCard({
|
|
|
2679
2868
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2680
2869
|
"img",
|
|
2681
2870
|
{
|
|
2682
|
-
src: destinationTokenIcon || (0,
|
|
2871
|
+
src: destinationTokenIcon || (0, import_core7.getIconUrlWithCdn)(
|
|
2683
2872
|
"/icons/tokens/png/usdc.png",
|
|
2684
2873
|
assetCdnUrl
|
|
2685
2874
|
),
|
|
@@ -2733,18 +2922,18 @@ function BuyWithCard({
|
|
|
2733
2922
|
}
|
|
2734
2923
|
|
|
2735
2924
|
// src/components/deposits/DepositsModal.tsx
|
|
2736
|
-
var
|
|
2925
|
+
var import_react8 = require("react");
|
|
2737
2926
|
|
|
2738
2927
|
// src/components/deposits/DepositExecutionItem.tsx
|
|
2739
2928
|
var import_lucide_react7 = require("lucide-react");
|
|
2740
|
-
var
|
|
2929
|
+
var import_core8 = require("@unifold/core");
|
|
2741
2930
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2742
2931
|
function DepositExecutionItem({
|
|
2743
2932
|
execution,
|
|
2744
2933
|
onClick
|
|
2745
2934
|
}) {
|
|
2746
2935
|
const { colors: colors2, fonts, components } = useTheme();
|
|
2747
|
-
const isPending = execution.status ===
|
|
2936
|
+
const isPending = execution.status === import_core8.ExecutionStatus.PENDING || execution.status === import_core8.ExecutionStatus.WAITING || execution.status === import_core8.ExecutionStatus.DELAYED;
|
|
2748
2937
|
const formatDateTime = (timestamp) => {
|
|
2749
2938
|
try {
|
|
2750
2939
|
const date = new Date(timestamp);
|
|
@@ -2787,7 +2976,7 @@ function DepositExecutionItem({
|
|
|
2787
2976
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2788
2977
|
"img",
|
|
2789
2978
|
{
|
|
2790
|
-
src: execution.destination_token_metadata?.icon_url || (0,
|
|
2979
|
+
src: execution.destination_token_metadata?.icon_url || (0, import_core8.getIconUrl)("/icons/tokens/svg/usdc.svg"),
|
|
2791
2980
|
alt: "Token",
|
|
2792
2981
|
width: 36,
|
|
2793
2982
|
height: 36,
|
|
@@ -2963,7 +3152,7 @@ function ThemeStyleInjector({
|
|
|
2963
3152
|
}
|
|
2964
3153
|
|
|
2965
3154
|
// src/components/deposits/DepositsModal.tsx
|
|
2966
|
-
var
|
|
3155
|
+
var import_core9 = require("@unifold/core");
|
|
2967
3156
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2968
3157
|
function DepositsModal({
|
|
2969
3158
|
open,
|
|
@@ -2975,13 +3164,13 @@ function DepositsModal({
|
|
|
2975
3164
|
themeClass = ""
|
|
2976
3165
|
}) {
|
|
2977
3166
|
const { colors: colors2 } = useTheme();
|
|
2978
|
-
const [allExecutions, setAllExecutions] = (0,
|
|
2979
|
-
const [selectedExecution, setSelectedExecution] = (0,
|
|
2980
|
-
(0,
|
|
3167
|
+
const [allExecutions, setAllExecutions] = (0, import_react8.useState)(sessionExecutions);
|
|
3168
|
+
const [selectedExecution, setSelectedExecution] = (0, import_react8.useState)(null);
|
|
3169
|
+
(0, import_react8.useEffect)(() => {
|
|
2981
3170
|
if (!open || !userId) return;
|
|
2982
3171
|
const fetchExecutions = async () => {
|
|
2983
3172
|
try {
|
|
2984
|
-
const response = await (0,
|
|
3173
|
+
const response = await (0, import_core9.queryExecutions)(userId, publishableKey);
|
|
2985
3174
|
const sorted = [...response.data].sort((a, b) => {
|
|
2986
3175
|
const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
|
|
2987
3176
|
const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
|
|
@@ -2999,7 +3188,7 @@ function DepositsModal({
|
|
|
2999
3188
|
clearInterval(pollInterval);
|
|
3000
3189
|
};
|
|
3001
3190
|
}, [open, userId, publishableKey, sessionExecutions]);
|
|
3002
|
-
(0,
|
|
3191
|
+
(0, import_react8.useEffect)(() => {
|
|
3003
3192
|
if (!open) {
|
|
3004
3193
|
setSelectedExecution(null);
|
|
3005
3194
|
}
|
|
@@ -3325,11 +3514,11 @@ function DepositTrackerButton({
|
|
|
3325
3514
|
}
|
|
3326
3515
|
|
|
3327
3516
|
// src/components/deposits/DepositModal.tsx
|
|
3328
|
-
var
|
|
3517
|
+
var import_core14 = require("@unifold/core");
|
|
3329
3518
|
|
|
3330
3519
|
// src/hooks/use-allowed-country.ts
|
|
3331
3520
|
var import_react_query2 = require("@tanstack/react-query");
|
|
3332
|
-
var
|
|
3521
|
+
var import_core10 = require("@unifold/core");
|
|
3333
3522
|
function useAllowedCountry(publishableKey) {
|
|
3334
3523
|
const {
|
|
3335
3524
|
data: ipData,
|
|
@@ -3337,7 +3526,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
3337
3526
|
error: ipError
|
|
3338
3527
|
} = (0, import_react_query2.useQuery)({
|
|
3339
3528
|
queryKey: ["unifold", "ipAddress"],
|
|
3340
|
-
queryFn: () => (0,
|
|
3529
|
+
queryFn: () => (0, import_core10.getIpAddress)(),
|
|
3341
3530
|
refetchOnMount: false,
|
|
3342
3531
|
refetchOnReconnect: true,
|
|
3343
3532
|
refetchOnWindowFocus: false,
|
|
@@ -3352,7 +3541,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
3352
3541
|
error: configError
|
|
3353
3542
|
} = (0, import_react_query2.useQuery)({
|
|
3354
3543
|
queryKey: ["unifold", "projectConfig", publishableKey],
|
|
3355
|
-
queryFn: () => (0,
|
|
3544
|
+
queryFn: () => (0, import_core10.getProjectConfig)(publishableKey),
|
|
3356
3545
|
refetchOnMount: false,
|
|
3357
3546
|
refetchOnReconnect: true,
|
|
3358
3547
|
refetchOnWindowFocus: false,
|
|
@@ -3381,12 +3570,70 @@ function useAllowedCountry(publishableKey) {
|
|
|
3381
3570
|
};
|
|
3382
3571
|
}
|
|
3383
3572
|
|
|
3573
|
+
// src/hooks/use-address-validation.ts
|
|
3574
|
+
var import_react_query3 = require("@tanstack/react-query");
|
|
3575
|
+
var import_core11 = require("@unifold/core");
|
|
3576
|
+
function useAddressValidation({
|
|
3577
|
+
recipientAddress,
|
|
3578
|
+
destinationChainType,
|
|
3579
|
+
destinationChainId,
|
|
3580
|
+
destinationTokenAddress,
|
|
3581
|
+
publishableKey,
|
|
3582
|
+
enabled = true,
|
|
3583
|
+
refetchOnMount = false
|
|
3584
|
+
}) {
|
|
3585
|
+
const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
3586
|
+
const { data, isLoading, error } = (0, import_react_query3.useQuery)({
|
|
3587
|
+
queryKey: [
|
|
3588
|
+
"unifold",
|
|
3589
|
+
"addressValidation",
|
|
3590
|
+
recipientAddress,
|
|
3591
|
+
destinationChainType,
|
|
3592
|
+
destinationChainId,
|
|
3593
|
+
destinationTokenAddress
|
|
3594
|
+
],
|
|
3595
|
+
queryFn: () => (0, import_core11.verifyRecipientAddress)(
|
|
3596
|
+
{
|
|
3597
|
+
chain_type: destinationChainType,
|
|
3598
|
+
chain_id: destinationChainId,
|
|
3599
|
+
token_address: destinationTokenAddress,
|
|
3600
|
+
recipient_address: recipientAddress
|
|
3601
|
+
},
|
|
3602
|
+
publishableKey
|
|
3603
|
+
),
|
|
3604
|
+
enabled: shouldValidate,
|
|
3605
|
+
refetchOnMount,
|
|
3606
|
+
refetchOnReconnect: false,
|
|
3607
|
+
refetchOnWindowFocus: false,
|
|
3608
|
+
staleTime: 1e3 * 60 * 5,
|
|
3609
|
+
// 5 minutes - address state can change
|
|
3610
|
+
gcTime: 1e3 * 60 * 30
|
|
3611
|
+
// 30 minutes
|
|
3612
|
+
});
|
|
3613
|
+
if (!shouldValidate) {
|
|
3614
|
+
return {
|
|
3615
|
+
isValid: null,
|
|
3616
|
+
failureCode: null,
|
|
3617
|
+
metadata: null,
|
|
3618
|
+
isLoading: false,
|
|
3619
|
+
error: null
|
|
3620
|
+
};
|
|
3621
|
+
}
|
|
3622
|
+
return {
|
|
3623
|
+
isValid: data?.valid ?? null,
|
|
3624
|
+
failureCode: data?.failure_code ?? null,
|
|
3625
|
+
metadata: data?.metadata ?? null,
|
|
3626
|
+
isLoading,
|
|
3627
|
+
error: error ?? null
|
|
3628
|
+
};
|
|
3629
|
+
}
|
|
3630
|
+
|
|
3384
3631
|
// src/components/deposits/TransferCryptoSingleInput.tsx
|
|
3385
|
-
var
|
|
3632
|
+
var import_react11 = require("react");
|
|
3386
3633
|
var import_lucide_react12 = require("lucide-react");
|
|
3387
3634
|
|
|
3388
3635
|
// src/components/deposits/StyledQRCode.tsx
|
|
3389
|
-
var
|
|
3636
|
+
var import_react9 = require("react");
|
|
3390
3637
|
var import_qr_code_styling = __toESM(require("qr-code-styling"));
|
|
3391
3638
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3392
3639
|
function StyledQRCode({
|
|
@@ -3396,9 +3643,9 @@ function StyledQRCode({
|
|
|
3396
3643
|
imageSize = 50,
|
|
3397
3644
|
darkMode = false
|
|
3398
3645
|
}) {
|
|
3399
|
-
const ref = (0,
|
|
3400
|
-
const qrCodeRef = (0,
|
|
3401
|
-
(0,
|
|
3646
|
+
const ref = (0, import_react9.useRef)(null);
|
|
3647
|
+
const qrCodeRef = (0, import_react9.useRef)(null);
|
|
3648
|
+
(0, import_react9.useEffect)(() => {
|
|
3402
3649
|
if (!ref.current) return;
|
|
3403
3650
|
if (!qrCodeRef.current) {
|
|
3404
3651
|
qrCodeRef.current = new import_qr_code_styling.default({
|
|
@@ -3438,7 +3685,7 @@ function StyledQRCode({
|
|
|
3438
3685
|
qrCodeRef.current.append(ref.current);
|
|
3439
3686
|
}
|
|
3440
3687
|
}, []);
|
|
3441
|
-
(0,
|
|
3688
|
+
(0, import_react9.useEffect)(() => {
|
|
3442
3689
|
if (qrCodeRef.current) {
|
|
3443
3690
|
qrCodeRef.current.update({
|
|
3444
3691
|
data: value,
|
|
@@ -3479,7 +3726,7 @@ function StyledQRCode({
|
|
|
3479
3726
|
}
|
|
3480
3727
|
|
|
3481
3728
|
// src/components/deposits/TokenSelectorSheet.tsx
|
|
3482
|
-
var
|
|
3729
|
+
var import_react10 = require("react");
|
|
3483
3730
|
var import_lucide_react11 = require("lucide-react");
|
|
3484
3731
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3485
3732
|
var STORAGE_KEY = "unifold_recent_tokens";
|
|
@@ -3537,13 +3784,13 @@ function TokenSelectorSheet({
|
|
|
3537
3784
|
}) {
|
|
3538
3785
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
3539
3786
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
3540
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
3541
|
-
const [recentTokens, setRecentTokens] = (0,
|
|
3542
|
-
const [hoveredTokenKey, setHoveredTokenKey] = (0,
|
|
3543
|
-
(0,
|
|
3787
|
+
const [searchQuery, setSearchQuery] = (0, import_react10.useState)("");
|
|
3788
|
+
const [recentTokens, setRecentTokens] = (0, import_react10.useState)([]);
|
|
3789
|
+
const [hoveredTokenKey, setHoveredTokenKey] = (0, import_react10.useState)(null);
|
|
3790
|
+
(0, import_react10.useEffect)(() => {
|
|
3544
3791
|
setRecentTokens(getRecentTokens());
|
|
3545
3792
|
}, []);
|
|
3546
|
-
const allOptions = (0,
|
|
3793
|
+
const allOptions = (0, import_react10.useMemo)(() => {
|
|
3547
3794
|
const options = [];
|
|
3548
3795
|
tokens.forEach((token) => {
|
|
3549
3796
|
token.chains.forEach((chain) => {
|
|
@@ -3552,7 +3799,7 @@ function TokenSelectorSheet({
|
|
|
3552
3799
|
});
|
|
3553
3800
|
return options;
|
|
3554
3801
|
}, [tokens]);
|
|
3555
|
-
const quickSelectOptions = (0,
|
|
3802
|
+
const quickSelectOptions = (0, import_react10.useMemo)(() => {
|
|
3556
3803
|
const result = [];
|
|
3557
3804
|
const seen = /* @__PURE__ */ new Set();
|
|
3558
3805
|
const addOption = (symbol, chainType, chainId, isRecent) => {
|
|
@@ -3584,7 +3831,7 @@ function TokenSelectorSheet({
|
|
|
3584
3831
|
});
|
|
3585
3832
|
setRecentTokens(updated);
|
|
3586
3833
|
};
|
|
3587
|
-
const filteredOptions = (0,
|
|
3834
|
+
const filteredOptions = (0, import_react10.useMemo)(() => {
|
|
3588
3835
|
if (!searchQuery.trim()) return allOptions;
|
|
3589
3836
|
const query = searchQuery.toLowerCase();
|
|
3590
3837
|
return allOptions.filter(
|
|
@@ -3954,7 +4201,7 @@ var TooltipContent = React8.forwardRef(({ className, sideOffset = 4, ...props },
|
|
|
3954
4201
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
3955
4202
|
|
|
3956
4203
|
// src/components/deposits/TransferCryptoSingleInput.tsx
|
|
3957
|
-
var
|
|
4204
|
+
var import_core12 = require("@unifold/core");
|
|
3958
4205
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3959
4206
|
var t2 = i18n.transferCrypto;
|
|
3960
4207
|
var getChainKey = (chainId, chainType) => {
|
|
@@ -3978,13 +4225,13 @@ function TransferCryptoSingleInput({
|
|
|
3978
4225
|
}) {
|
|
3979
4226
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
3980
4227
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
3981
|
-
const [token, setToken] = (0,
|
|
3982
|
-
const [chain, setChain] = (0,
|
|
3983
|
-
const [copied, setCopied] = (0,
|
|
3984
|
-
const [internalWallets, setInternalWallets] = (0,
|
|
3985
|
-
const [loading, setLoading] = (0,
|
|
4228
|
+
const [token, setToken] = (0, import_react11.useState)("USDC");
|
|
4229
|
+
const [chain, setChain] = (0, import_react11.useState)("solana:mainnet");
|
|
4230
|
+
const [copied, setCopied] = (0, import_react11.useState)(false);
|
|
4231
|
+
const [internalWallets, setInternalWallets] = (0, import_react11.useState)([]);
|
|
4232
|
+
const [loading, setLoading] = (0, import_react11.useState)(!externalWallets?.length);
|
|
3986
4233
|
const wallets = externalWallets?.length ? externalWallets : internalWallets;
|
|
3987
|
-
const [error, setError] = (0,
|
|
4234
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
3988
4235
|
const { executions: depositExecutions, isPolling } = useDepositPolling({
|
|
3989
4236
|
userId,
|
|
3990
4237
|
publishableKey,
|
|
@@ -3992,11 +4239,11 @@ function TransferCryptoSingleInput({
|
|
|
3992
4239
|
onDepositSuccess,
|
|
3993
4240
|
onDepositError
|
|
3994
4241
|
});
|
|
3995
|
-
const [supportedTokens, setSupportedTokens] = (0,
|
|
3996
|
-
const [tokensLoading, setTokensLoading] = (0,
|
|
3997
|
-
const [detailsExpanded, setDetailsExpanded] = (0,
|
|
3998
|
-
const [depositsModalOpen, setDepositsModalOpen] = (0,
|
|
3999
|
-
const [tokenSelectorOpen, setTokenSelectorOpen] = (0,
|
|
4242
|
+
const [supportedTokens, setSupportedTokens] = (0, import_react11.useState)([]);
|
|
4243
|
+
const [tokensLoading, setTokensLoading] = (0, import_react11.useState)(true);
|
|
4244
|
+
const [detailsExpanded, setDetailsExpanded] = (0, import_react11.useState)(false);
|
|
4245
|
+
const [depositsModalOpen, setDepositsModalOpen] = (0, import_react11.useState)(false);
|
|
4246
|
+
const [tokenSelectorOpen, setTokenSelectorOpen] = (0, import_react11.useState)(false);
|
|
4000
4247
|
const allChainsMap = /* @__PURE__ */ new Map();
|
|
4001
4248
|
supportedTokens.forEach((t5) => {
|
|
4002
4249
|
t5.chains.forEach((c) => {
|
|
@@ -4012,9 +4259,9 @@ function TransferCryptoSingleInput({
|
|
|
4012
4259
|
(c) => c.chain_type === currentChainCombo.chainType && c.chain_id === currentChainCombo.chainId
|
|
4013
4260
|
);
|
|
4014
4261
|
const currentChainType = currentChainData?.chain_type || "ethereum";
|
|
4015
|
-
const currentWallet = (0,
|
|
4262
|
+
const currentWallet = (0, import_core12.getWalletByChainType)(wallets, currentChainType);
|
|
4016
4263
|
const depositAddress = currentWallet?.address || "";
|
|
4017
|
-
(0,
|
|
4264
|
+
(0, import_react11.useEffect)(() => {
|
|
4018
4265
|
async function fetchSupportedTokens() {
|
|
4019
4266
|
try {
|
|
4020
4267
|
setTokensLoading(true);
|
|
@@ -4023,7 +4270,7 @@ function TransferCryptoSingleInput({
|
|
|
4023
4270
|
destination_chain_id: destinationChainId,
|
|
4024
4271
|
destination_chain_type: destinationChainType
|
|
4025
4272
|
} : void 0;
|
|
4026
|
-
const response = await (0,
|
|
4273
|
+
const response = await (0, import_core12.getSupportedDepositTokens)(
|
|
4027
4274
|
publishableKey,
|
|
4028
4275
|
options
|
|
4029
4276
|
);
|
|
@@ -4086,12 +4333,12 @@ function TransferCryptoSingleInput({
|
|
|
4086
4333
|
destinationChainId,
|
|
4087
4334
|
destinationChainType
|
|
4088
4335
|
]);
|
|
4089
|
-
(0,
|
|
4336
|
+
(0, import_react11.useEffect)(() => {
|
|
4090
4337
|
if (onExecutionsChange) {
|
|
4091
4338
|
onExecutionsChange(depositExecutions);
|
|
4092
4339
|
}
|
|
4093
4340
|
}, [depositExecutions, onExecutionsChange]);
|
|
4094
|
-
(0,
|
|
4341
|
+
(0, import_react11.useEffect)(() => {
|
|
4095
4342
|
if (externalWallets?.length) {
|
|
4096
4343
|
setLoading(false);
|
|
4097
4344
|
return;
|
|
@@ -4106,7 +4353,7 @@ function TransferCryptoSingleInput({
|
|
|
4106
4353
|
if (isCancelled) return;
|
|
4107
4354
|
setLoading(true);
|
|
4108
4355
|
try {
|
|
4109
|
-
const response = await (0,
|
|
4356
|
+
const response = await (0, import_core12.createDepositAddress)(
|
|
4110
4357
|
{
|
|
4111
4358
|
external_user_id: userId,
|
|
4112
4359
|
recipient_address: recipientAddress,
|
|
@@ -4148,7 +4395,7 @@ function TransferCryptoSingleInput({
|
|
|
4148
4395
|
publishableKey,
|
|
4149
4396
|
externalWallets
|
|
4150
4397
|
]);
|
|
4151
|
-
(0,
|
|
4398
|
+
(0, import_react11.useEffect)(() => {
|
|
4152
4399
|
if (!supportedTokens.length) return;
|
|
4153
4400
|
const currentToken = supportedTokens.find((t5) => t5.symbol === token);
|
|
4154
4401
|
if (!currentToken || currentToken.chains.length === 0) return;
|
|
@@ -4526,7 +4773,7 @@ function TransferCryptoSingleInput({
|
|
|
4526
4773
|
}
|
|
4527
4774
|
|
|
4528
4775
|
// src/components/deposits/TransferCryptoDoubleInput.tsx
|
|
4529
|
-
var
|
|
4776
|
+
var import_react12 = require("react");
|
|
4530
4777
|
var import_lucide_react14 = require("lucide-react");
|
|
4531
4778
|
|
|
4532
4779
|
// src/components/shared/select.tsx
|
|
@@ -4651,7 +4898,7 @@ var SelectSeparator = React9.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
4651
4898
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
4652
4899
|
|
|
4653
4900
|
// src/components/deposits/TransferCryptoDoubleInput.tsx
|
|
4654
|
-
var
|
|
4901
|
+
var import_core13 = require("@unifold/core");
|
|
4655
4902
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4656
4903
|
var t3 = i18n.transferCrypto;
|
|
4657
4904
|
var getChainKey2 = (chainId, chainType) => {
|
|
@@ -4675,13 +4922,13 @@ function TransferCryptoDoubleInput({
|
|
|
4675
4922
|
}) {
|
|
4676
4923
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
4677
4924
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
4678
|
-
const [token, setToken] = (0,
|
|
4679
|
-
const [chain, setChain] = (0,
|
|
4680
|
-
const [copied, setCopied] = (0,
|
|
4681
|
-
const [internalWallets, setInternalWallets] = (0,
|
|
4682
|
-
const [loading, setLoading] = (0,
|
|
4925
|
+
const [token, setToken] = (0, import_react12.useState)("USDC");
|
|
4926
|
+
const [chain, setChain] = (0, import_react12.useState)("solana:mainnet");
|
|
4927
|
+
const [copied, setCopied] = (0, import_react12.useState)(false);
|
|
4928
|
+
const [internalWallets, setInternalWallets] = (0, import_react12.useState)([]);
|
|
4929
|
+
const [loading, setLoading] = (0, import_react12.useState)(!externalWallets?.length);
|
|
4683
4930
|
const wallets = externalWallets?.length ? externalWallets : internalWallets;
|
|
4684
|
-
const [error, setError] = (0,
|
|
4931
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
4685
4932
|
const { executions: depositExecutions, isPolling } = useDepositPolling({
|
|
4686
4933
|
userId,
|
|
4687
4934
|
publishableKey,
|
|
@@ -4689,10 +4936,10 @@ function TransferCryptoDoubleInput({
|
|
|
4689
4936
|
onDepositSuccess,
|
|
4690
4937
|
onDepositError
|
|
4691
4938
|
});
|
|
4692
|
-
const [supportedTokens, setSupportedTokens] = (0,
|
|
4693
|
-
const [tokensLoading, setTokensLoading] = (0,
|
|
4694
|
-
const [detailsExpanded, setDetailsExpanded] = (0,
|
|
4695
|
-
const [depositsModalOpen, setDepositsModalOpen] = (0,
|
|
4939
|
+
const [supportedTokens, setSupportedTokens] = (0, import_react12.useState)([]);
|
|
4940
|
+
const [tokensLoading, setTokensLoading] = (0, import_react12.useState)(true);
|
|
4941
|
+
const [detailsExpanded, setDetailsExpanded] = (0, import_react12.useState)(false);
|
|
4942
|
+
const [depositsModalOpen, setDepositsModalOpen] = (0, import_react12.useState)(false);
|
|
4696
4943
|
const allChainsMap = /* @__PURE__ */ new Map();
|
|
4697
4944
|
supportedTokens.forEach((t5) => {
|
|
4698
4945
|
t5.chains.forEach((c) => {
|
|
@@ -4708,9 +4955,9 @@ function TransferCryptoDoubleInput({
|
|
|
4708
4955
|
(c) => c.chain_type === currentChainCombo.chainType && c.chain_id === currentChainCombo.chainId
|
|
4709
4956
|
);
|
|
4710
4957
|
const currentChainType = currentChainData?.chain_type || "ethereum";
|
|
4711
|
-
const currentWallet = (0,
|
|
4958
|
+
const currentWallet = (0, import_core13.getWalletByChainType)(wallets, currentChainType);
|
|
4712
4959
|
const depositAddress = currentWallet?.address || "";
|
|
4713
|
-
(0,
|
|
4960
|
+
(0, import_react12.useEffect)(() => {
|
|
4714
4961
|
async function fetchSupportedTokens() {
|
|
4715
4962
|
try {
|
|
4716
4963
|
setTokensLoading(true);
|
|
@@ -4719,7 +4966,7 @@ function TransferCryptoDoubleInput({
|
|
|
4719
4966
|
destination_chain_id: destinationChainId,
|
|
4720
4967
|
destination_chain_type: destinationChainType
|
|
4721
4968
|
} : void 0;
|
|
4722
|
-
const response = await (0,
|
|
4969
|
+
const response = await (0, import_core13.getSupportedDepositTokens)(
|
|
4723
4970
|
publishableKey,
|
|
4724
4971
|
options
|
|
4725
4972
|
);
|
|
@@ -4753,12 +5000,12 @@ function TransferCryptoDoubleInput({
|
|
|
4753
5000
|
destinationChainId,
|
|
4754
5001
|
destinationChainType
|
|
4755
5002
|
]);
|
|
4756
|
-
(0,
|
|
5003
|
+
(0, import_react12.useEffect)(() => {
|
|
4757
5004
|
if (onExecutionsChange) {
|
|
4758
5005
|
onExecutionsChange(depositExecutions);
|
|
4759
5006
|
}
|
|
4760
5007
|
}, [depositExecutions, onExecutionsChange]);
|
|
4761
|
-
(0,
|
|
5008
|
+
(0, import_react12.useEffect)(() => {
|
|
4762
5009
|
if (externalWallets?.length) {
|
|
4763
5010
|
setLoading(false);
|
|
4764
5011
|
return;
|
|
@@ -4773,7 +5020,7 @@ function TransferCryptoDoubleInput({
|
|
|
4773
5020
|
if (isCancelled) return;
|
|
4774
5021
|
setLoading(true);
|
|
4775
5022
|
try {
|
|
4776
|
-
const response = await (0,
|
|
5023
|
+
const response = await (0, import_core13.createDepositAddress)(
|
|
4777
5024
|
{
|
|
4778
5025
|
external_user_id: userId,
|
|
4779
5026
|
recipient_address: recipientAddress,
|
|
@@ -4815,7 +5062,7 @@ function TransferCryptoDoubleInput({
|
|
|
4815
5062
|
publishableKey,
|
|
4816
5063
|
externalWallets
|
|
4817
5064
|
]);
|
|
4818
|
-
(0,
|
|
5065
|
+
(0, import_react12.useEffect)(() => {
|
|
4819
5066
|
if (!supportedTokens.length) return;
|
|
4820
5067
|
const currentToken = supportedTokens.find((t5) => t5.symbol === token);
|
|
4821
5068
|
if (!currentToken || currentToken.chains.length === 0) return;
|
|
@@ -5266,26 +5513,27 @@ function DepositModal({
|
|
|
5266
5513
|
destinationChainId,
|
|
5267
5514
|
destinationTokenAddress,
|
|
5268
5515
|
hideDepositTracker = false,
|
|
5516
|
+
showBalanceHeader = false,
|
|
5269
5517
|
transferInputVariant = "double_input",
|
|
5270
5518
|
onDepositSuccess,
|
|
5271
5519
|
onDepositError,
|
|
5272
5520
|
theme = "dark"
|
|
5273
5521
|
}) {
|
|
5274
|
-
const { colors: colors2 } = useTheme();
|
|
5275
|
-
const [view, setView] = (0,
|
|
5276
|
-
const [cardView, setCardView] = (0,
|
|
5522
|
+
const { colors: colors2, fonts } = useTheme();
|
|
5523
|
+
const [view, setView] = (0, import_react13.useState)("main");
|
|
5524
|
+
const [cardView, setCardView] = (0, import_react13.useState)(
|
|
5277
5525
|
"amount"
|
|
5278
5526
|
);
|
|
5279
|
-
const [quotesCount, setQuotesCount] = (0,
|
|
5280
|
-
const [depositsModalOpen, setDepositsModalOpen] = (0,
|
|
5281
|
-
const [depositExecutions, setDepositExecutions] = (0,
|
|
5282
|
-
const [projectConfig, setProjectConfig] = (0,
|
|
5283
|
-
const [wallets, setWallets] = (0,
|
|
5284
|
-
const [walletsLoading, setWalletsLoading] = (0,
|
|
5285
|
-
(0,
|
|
5527
|
+
const [quotesCount, setQuotesCount] = (0, import_react13.useState)(0);
|
|
5528
|
+
const [depositsModalOpen, setDepositsModalOpen] = (0, import_react13.useState)(false);
|
|
5529
|
+
const [depositExecutions, setDepositExecutions] = (0, import_react13.useState)([]);
|
|
5530
|
+
const [projectConfig, setProjectConfig] = (0, import_react13.useState)(null);
|
|
5531
|
+
const [wallets, setWallets] = (0, import_react13.useState)([]);
|
|
5532
|
+
const [walletsLoading, setWalletsLoading] = (0, import_react13.useState)(false);
|
|
5533
|
+
(0, import_react13.useEffect)(() => {
|
|
5286
5534
|
setProjectConfig(null);
|
|
5287
5535
|
}, [publishableKey]);
|
|
5288
|
-
(0,
|
|
5536
|
+
(0, import_react13.useEffect)(() => {
|
|
5289
5537
|
setWallets([]);
|
|
5290
5538
|
}, [
|
|
5291
5539
|
userId,
|
|
@@ -5295,10 +5543,10 @@ function DepositModal({
|
|
|
5295
5543
|
destinationTokenAddress,
|
|
5296
5544
|
publishableKey
|
|
5297
5545
|
]);
|
|
5298
|
-
const [resolvedTheme, setResolvedTheme] = (0,
|
|
5546
|
+
const [resolvedTheme, setResolvedTheme] = (0, import_react13.useState)(
|
|
5299
5547
|
theme === "auto" ? "dark" : theme
|
|
5300
5548
|
);
|
|
5301
|
-
(0,
|
|
5549
|
+
(0, import_react13.useEffect)(() => {
|
|
5302
5550
|
if (theme === "auto") {
|
|
5303
5551
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
5304
5552
|
setResolvedTheme(mediaQuery.matches ? "dark" : "light");
|
|
@@ -5311,9 +5559,9 @@ function DepositModal({
|
|
|
5311
5559
|
setResolvedTheme(theme);
|
|
5312
5560
|
}
|
|
5313
5561
|
}, [theme]);
|
|
5314
|
-
(0,
|
|
5562
|
+
(0, import_react13.useEffect)(() => {
|
|
5315
5563
|
if (open && !projectConfig) {
|
|
5316
|
-
(0,
|
|
5564
|
+
(0, import_core14.getProjectConfig)(publishableKey).then(setProjectConfig).catch(console.error);
|
|
5317
5565
|
}
|
|
5318
5566
|
}, [open, publishableKey, projectConfig]);
|
|
5319
5567
|
const {
|
|
@@ -5321,7 +5569,29 @@ function DepositModal({
|
|
|
5321
5569
|
isLoading: isCountryLoading,
|
|
5322
5570
|
error: countryError
|
|
5323
5571
|
} = useAllowedCountry(publishableKey);
|
|
5324
|
-
|
|
5572
|
+
const {
|
|
5573
|
+
isValid: isAddressValid,
|
|
5574
|
+
failureCode: addressFailureCode,
|
|
5575
|
+
metadata: addressFailureMetadata,
|
|
5576
|
+
isLoading: isAddressValidationLoading
|
|
5577
|
+
} = useAddressValidation({
|
|
5578
|
+
recipientAddress,
|
|
5579
|
+
destinationChainType,
|
|
5580
|
+
destinationChainId,
|
|
5581
|
+
destinationTokenAddress,
|
|
5582
|
+
publishableKey,
|
|
5583
|
+
enabled: open,
|
|
5584
|
+
// Only validate when modal is open
|
|
5585
|
+
refetchOnMount: "always"
|
|
5586
|
+
});
|
|
5587
|
+
const addressValidationMessages = i18n.transferCrypto.addressValidation;
|
|
5588
|
+
const getAddressValidationErrorMessage = (code, metadata) => {
|
|
5589
|
+
if (!code) return addressValidationMessages.defaultError;
|
|
5590
|
+
const errors = addressValidationMessages.errors;
|
|
5591
|
+
const template = errors[code] ?? addressValidationMessages.defaultError;
|
|
5592
|
+
return interpolate(template, metadata);
|
|
5593
|
+
};
|
|
5594
|
+
(0, import_react13.useEffect)(() => {
|
|
5325
5595
|
if (!open || wallets.length > 0) return;
|
|
5326
5596
|
let retryTimeout = null;
|
|
5327
5597
|
let isCancelled = false;
|
|
@@ -5329,7 +5599,7 @@ function DepositModal({
|
|
|
5329
5599
|
if (isCancelled) return;
|
|
5330
5600
|
setWalletsLoading(true);
|
|
5331
5601
|
try {
|
|
5332
|
-
const response = await (0,
|
|
5602
|
+
const response = await (0, import_core14.createDepositAddress)(
|
|
5333
5603
|
{
|
|
5334
5604
|
external_user_id: userId,
|
|
5335
5605
|
recipient_address: recipientAddress,
|
|
@@ -5405,10 +5675,16 @@ function DepositModal({
|
|
|
5405
5675
|
DepositHeader,
|
|
5406
5676
|
{
|
|
5407
5677
|
title: modalTitle || "Deposit",
|
|
5408
|
-
onClose: handleClose
|
|
5678
|
+
onClose: handleClose,
|
|
5679
|
+
showBalance: showBalanceHeader,
|
|
5680
|
+
balanceAddress: recipientAddress,
|
|
5681
|
+
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
|
|
5682
|
+
balanceChainId: destinationChainId,
|
|
5683
|
+
balanceTokenAddress: destinationTokenAddress,
|
|
5684
|
+
publishableKey
|
|
5409
5685
|
}
|
|
5410
5686
|
),
|
|
5411
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: isCountryLoading || !projectConfig ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
5687
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: isCountryLoading || isAddressValidationLoading || !projectConfig ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
5412
5688
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SkeletonButton, { variant: "with-icons" }),
|
|
5413
5689
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SkeletonButton, { variant: "with-icons" }),
|
|
5414
5690
|
!hideDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SkeletonButton, {})
|
|
@@ -5426,6 +5702,16 @@ function DepositModal({
|
|
|
5426
5702
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "No Tokens Available" }),
|
|
5427
5703
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: "There are no supported tokens available from your current location." })
|
|
5428
5704
|
] })
|
|
5705
|
+
) : isAddressValid === false ? (
|
|
5706
|
+
/* Invalid recipient address state (e.g., Algorand not opted in) */
|
|
5707
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
5708
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react15.AlertTriangle, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
5709
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
|
|
5710
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: getAddressValidationErrorMessage(
|
|
5711
|
+
addressFailureCode,
|
|
5712
|
+
addressFailureMetadata
|
|
5713
|
+
) })
|
|
5714
|
+
] })
|
|
5429
5715
|
) : (
|
|
5430
5716
|
/* Normal deposit options */
|
|
5431
5717
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|