@unifold/ui-react 0.1.21 → 0.1.23
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 +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +550 -254
- package/dist/index.mjs +486 -189
- package/dist/styles-base.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/deposits/DepositModal.tsx
|
|
2
|
-
import { useState as
|
|
2
|
+
import { useState as useState17, useEffect as useEffect14 } from "react";
|
|
3
3
|
import { ChevronRight as ChevronRight8, MapPinOff, AlertTriangle } from "lucide-react";
|
|
4
4
|
|
|
5
5
|
// src/components/shared/dialog.tsx
|
|
@@ -13,6 +13,35 @@ import { twMerge } from "tailwind-merge";
|
|
|
13
13
|
function cn(...inputs) {
|
|
14
14
|
return twMerge(clsx(inputs));
|
|
15
15
|
}
|
|
16
|
+
function truncateAddress(address, startChars = 10, endChars = 8) {
|
|
17
|
+
if (!address) return "";
|
|
18
|
+
const totalChars = startChars + endChars + 3;
|
|
19
|
+
if (address.length <= totalChars) return address;
|
|
20
|
+
return `${address.slice(0, startChars)}...${address.slice(-endChars)}`;
|
|
21
|
+
}
|
|
22
|
+
function formatEstimatedTime(seconds) {
|
|
23
|
+
if (seconds == null) {
|
|
24
|
+
return "< 1 min";
|
|
25
|
+
}
|
|
26
|
+
if (seconds < 60) {
|
|
27
|
+
return `< ${seconds} sec${seconds > 1 ? "s" : ""}`;
|
|
28
|
+
} else if (seconds < 3600) {
|
|
29
|
+
const mins = Math.ceil(seconds / 60);
|
|
30
|
+
return `< ${mins} min${mins > 1 ? "s" : ""}`;
|
|
31
|
+
} else {
|
|
32
|
+
let hrs = Math.floor(seconds / 3600);
|
|
33
|
+
let mins = Math.ceil(seconds % 3600 / 60);
|
|
34
|
+
if (mins === 60) {
|
|
35
|
+
hrs += 1;
|
|
36
|
+
mins = 0;
|
|
37
|
+
}
|
|
38
|
+
const hrLabel = hrs > 1 ? "hrs" : "hr";
|
|
39
|
+
if (mins === 0) {
|
|
40
|
+
return `< ${hrs} ${hrLabel}`;
|
|
41
|
+
}
|
|
42
|
+
return `< ${hrs} ${hrLabel} ${mins} min${mins > 1 ? "s" : ""}`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
16
45
|
|
|
17
46
|
// src/context/ThemeContext.tsx
|
|
18
47
|
import * as React from "react";
|
|
@@ -466,7 +495,7 @@ var DialogDescription = React2.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
466
495
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
467
496
|
|
|
468
497
|
// src/components/deposits/BuyWithCard.tsx
|
|
469
|
-
import { useState as
|
|
498
|
+
import { useState as useState9, useEffect as useEffect5, useRef as useRef2 } from "react";
|
|
470
499
|
import { ChevronDown as ChevronDown2, ChevronRight } from "lucide-react";
|
|
471
500
|
import {
|
|
472
501
|
getOnrampQuotes,
|
|
@@ -481,10 +510,12 @@ import {
|
|
|
481
510
|
} from "@unifold/core";
|
|
482
511
|
|
|
483
512
|
// src/components/deposits/CurrencyModal.tsx
|
|
484
|
-
import { useState as
|
|
513
|
+
import { useState as useState4 } from "react";
|
|
485
514
|
|
|
486
515
|
// src/components/deposits/DepositHeader.tsx
|
|
487
516
|
import { ArrowLeft, X as X2 } from "lucide-react";
|
|
517
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
518
|
+
import { getAddressBalance } from "@unifold/core";
|
|
488
519
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
489
520
|
function DepositHeader({
|
|
490
521
|
title,
|
|
@@ -492,10 +523,83 @@ function DepositHeader({
|
|
|
492
523
|
showClose = true,
|
|
493
524
|
onBack,
|
|
494
525
|
onClose,
|
|
495
|
-
badge
|
|
526
|
+
badge,
|
|
527
|
+
showBalance = false,
|
|
528
|
+
balanceAddress,
|
|
529
|
+
balanceChainType,
|
|
530
|
+
balanceChainId,
|
|
531
|
+
balanceTokenAddress,
|
|
532
|
+
publishableKey
|
|
496
533
|
}) {
|
|
497
534
|
const { colors: colors2, fonts, components } = useTheme();
|
|
498
|
-
|
|
535
|
+
const [balance, setBalance] = useState2(null);
|
|
536
|
+
const [isLoadingBalance, setIsLoadingBalance] = useState2(false);
|
|
537
|
+
useEffect2(() => {
|
|
538
|
+
if (!showBalance || !balanceAddress || !balanceChainType || !balanceChainId || !balanceTokenAddress || !publishableKey) {
|
|
539
|
+
setBalance(null);
|
|
540
|
+
setIsLoadingBalance(false);
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
let cancelled = false;
|
|
544
|
+
setIsLoadingBalance(true);
|
|
545
|
+
getAddressBalance(
|
|
546
|
+
balanceAddress,
|
|
547
|
+
balanceChainType,
|
|
548
|
+
balanceChainId,
|
|
549
|
+
balanceTokenAddress,
|
|
550
|
+
publishableKey
|
|
551
|
+
).then((response) => {
|
|
552
|
+
if (cancelled) return;
|
|
553
|
+
if (response.balance && response.balance.amount !== "0") {
|
|
554
|
+
const value = Number(response.balance.amount) / 10 ** response.balance.token.decimals;
|
|
555
|
+
let formatted;
|
|
556
|
+
let maxDecimals = 4;
|
|
557
|
+
const symbol = response.balance.token.symbol?.toUpperCase() || "";
|
|
558
|
+
if (symbol === "BTC" || symbol === "WBTC") {
|
|
559
|
+
maxDecimals = 8;
|
|
560
|
+
} else if (symbol === "ETH" || symbol === "WETH") {
|
|
561
|
+
maxDecimals = 6;
|
|
562
|
+
}
|
|
563
|
+
if (value >= 1) {
|
|
564
|
+
formatted = value.toLocaleString(void 0, {
|
|
565
|
+
minimumFractionDigits: 2,
|
|
566
|
+
maximumFractionDigits: maxDecimals
|
|
567
|
+
});
|
|
568
|
+
} else if (value > 0) {
|
|
569
|
+
formatted = value.toLocaleString(void 0, {
|
|
570
|
+
minimumFractionDigits: 2,
|
|
571
|
+
maximumFractionDigits: maxDecimals,
|
|
572
|
+
minimumSignificantDigits: 2,
|
|
573
|
+
maximumSignificantDigits: 6
|
|
574
|
+
});
|
|
575
|
+
} else {
|
|
576
|
+
formatted = value.toExponential(2);
|
|
577
|
+
}
|
|
578
|
+
const balanceText = response.balance.amount_usd ? `Balance: $${response.balance.amount_usd} (${formatted} ${response.balance.token.symbol})` : `Balance: ${formatted} ${response.balance.token.symbol}`;
|
|
579
|
+
setBalance(balanceText);
|
|
580
|
+
} else {
|
|
581
|
+
setBalance(null);
|
|
582
|
+
}
|
|
583
|
+
}).catch((error) => {
|
|
584
|
+
if (cancelled) return;
|
|
585
|
+
console.error("Error fetching balance:", error);
|
|
586
|
+
setBalance(null);
|
|
587
|
+
}).finally(() => {
|
|
588
|
+
if (cancelled) return;
|
|
589
|
+
setIsLoadingBalance(false);
|
|
590
|
+
});
|
|
591
|
+
return () => {
|
|
592
|
+
cancelled = true;
|
|
593
|
+
};
|
|
594
|
+
}, [
|
|
595
|
+
showBalance,
|
|
596
|
+
balanceAddress,
|
|
597
|
+
balanceChainType,
|
|
598
|
+
balanceChainId,
|
|
599
|
+
balanceTokenAddress,
|
|
600
|
+
publishableKey
|
|
601
|
+
]);
|
|
602
|
+
return /* @__PURE__ */ jsx3("div", { children: /* @__PURE__ */ jsxs2("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-6", children: [
|
|
499
603
|
showBack ? /* @__PURE__ */ jsx3(
|
|
500
604
|
"button",
|
|
501
605
|
{
|
|
@@ -505,8 +609,32 @@ function DepositHeader({
|
|
|
505
609
|
children: /* @__PURE__ */ jsx3(ArrowLeft, { className: "uf-w-5 uf-h-5" })
|
|
506
610
|
}
|
|
507
611
|
) : /* @__PURE__ */ jsx3("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
|
|
508
|
-
|
|
509
|
-
/* @__PURE__ */
|
|
612
|
+
/* @__PURE__ */ jsxs2("div", { className: "uf-flex uf-flex-col uf-items-center", children: [
|
|
613
|
+
badge ? /* @__PURE__ */ jsxs2("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
|
|
614
|
+
/* @__PURE__ */ jsx3(
|
|
615
|
+
DialogTitle,
|
|
616
|
+
{
|
|
617
|
+
className: "uf-text-center uf-text-base",
|
|
618
|
+
style: {
|
|
619
|
+
color: components.header.titleColor,
|
|
620
|
+
fontFamily: fonts.medium
|
|
621
|
+
},
|
|
622
|
+
children: title
|
|
623
|
+
}
|
|
624
|
+
),
|
|
625
|
+
/* @__PURE__ */ jsx3(
|
|
626
|
+
"div",
|
|
627
|
+
{
|
|
628
|
+
className: "uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px]",
|
|
629
|
+
style: {
|
|
630
|
+
backgroundColor: colors2.card,
|
|
631
|
+
color: colors2.foregroundMuted,
|
|
632
|
+
fontFamily: fonts.regular
|
|
633
|
+
},
|
|
634
|
+
children: badge.count
|
|
635
|
+
}
|
|
636
|
+
)
|
|
637
|
+
] }) : /* @__PURE__ */ jsx3(
|
|
510
638
|
DialogTitle,
|
|
511
639
|
{
|
|
512
640
|
className: "uf-text-center uf-text-base",
|
|
@@ -517,29 +645,19 @@ function DepositHeader({
|
|
|
517
645
|
children: title
|
|
518
646
|
}
|
|
519
647
|
),
|
|
520
|
-
/* @__PURE__ */ jsx3(
|
|
648
|
+
showBalance && (isLoadingBalance ? /* @__PURE__ */ jsx3("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-2" }) : balance ? /* @__PURE__ */ jsx3(
|
|
521
649
|
"div",
|
|
522
650
|
{
|
|
523
|
-
className: "uf-
|
|
651
|
+
className: "uf-text-xs uf-mt-2",
|
|
524
652
|
style: {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
653
|
+
color: colors2.foreground,
|
|
654
|
+
fontFamily: fonts.regular,
|
|
655
|
+
opacity: 0.7
|
|
528
656
|
},
|
|
529
|
-
children:
|
|
657
|
+
children: balance
|
|
530
658
|
}
|
|
531
|
-
)
|
|
532
|
-
] })
|
|
533
|
-
DialogTitle,
|
|
534
|
-
{
|
|
535
|
-
className: "uf-text-center uf-text-base",
|
|
536
|
-
style: {
|
|
537
|
-
color: components.header.titleColor,
|
|
538
|
-
fontFamily: fonts.medium
|
|
539
|
-
},
|
|
540
|
-
children: title
|
|
541
|
-
}
|
|
542
|
-
),
|
|
659
|
+
) : null)
|
|
660
|
+
] }),
|
|
543
661
|
showClose ? /* @__PURE__ */ jsx3(
|
|
544
662
|
"button",
|
|
545
663
|
{
|
|
@@ -549,7 +667,7 @@ function DepositHeader({
|
|
|
549
667
|
children: /* @__PURE__ */ jsx3(X2, { className: "uf-w-5 uf-h-5" })
|
|
550
668
|
}
|
|
551
669
|
) : /* @__PURE__ */ jsx3("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
|
|
552
|
-
] });
|
|
670
|
+
] }) });
|
|
553
671
|
}
|
|
554
672
|
|
|
555
673
|
// src/components/currency/CurrencyListItem.tsx
|
|
@@ -662,7 +780,7 @@ function CurrencyModal({
|
|
|
662
780
|
themeClass = ""
|
|
663
781
|
}) {
|
|
664
782
|
const { colors: colors2, fonts, components } = useTheme();
|
|
665
|
-
const [searchQuery, setSearchQuery] =
|
|
783
|
+
const [searchQuery, setSearchQuery] = useState4("");
|
|
666
784
|
const preferredCurrencies = preferredCurrencyCodes.map(
|
|
667
785
|
(code) => currencies.find(
|
|
668
786
|
(currency) => currency.currency_code.toLowerCase() === code.toLowerCase()
|
|
@@ -823,8 +941,8 @@ var en_default = {
|
|
|
823
941
|
seeTerms: "See terms",
|
|
824
942
|
termsApply: "Terms apply"
|
|
825
943
|
},
|
|
826
|
-
|
|
827
|
-
|
|
944
|
+
selectedToken: "Selected token",
|
|
945
|
+
selectedChain: "Selected chain",
|
|
828
946
|
depositAddress: {
|
|
829
947
|
label: "Your deposit address",
|
|
830
948
|
tooltip: "Send any supported token to this address, and it will be automatically converted to {{token}} in your account."
|
|
@@ -838,7 +956,19 @@ var en_default = {
|
|
|
838
956
|
minimumDeposit: "Minimum: {{amount}}",
|
|
839
957
|
minimumDepositTooltip: "The minimum amount you can deposit on the selected network.",
|
|
840
958
|
selectTokenDeposit: "Your deposit token",
|
|
841
|
-
selectTokenDepositTooltip: "Select the token you want to deposit with in order to begin the deposit process."
|
|
959
|
+
selectTokenDepositTooltip: "Select the token you want to deposit with in order to begin the deposit process.",
|
|
960
|
+
addressValidation: {
|
|
961
|
+
validating: "Verifying recipient address...",
|
|
962
|
+
unableToReceiveFunds: "Unable to Receive Funds",
|
|
963
|
+
errors: {
|
|
964
|
+
token_not_supported: "The destination token is not supported",
|
|
965
|
+
not_opted_in: "Please make sure you opt-in {{token_symbol}}({{chain_name}}) before receiving funds",
|
|
966
|
+
insufficient_balance: "Recipient account does not meet the minimum balance requirement",
|
|
967
|
+
account_not_found: "Recipient account does not exist on {{chain_name}}",
|
|
968
|
+
validation_error: "Unable to verify recipient address on {{chain_name}}"
|
|
969
|
+
},
|
|
970
|
+
defaultError: "The recipient address cannot receive funds for the selected token"
|
|
971
|
+
}
|
|
842
972
|
},
|
|
843
973
|
depositModal: {
|
|
844
974
|
transferCrypto: {
|
|
@@ -847,7 +977,7 @@ var en_default = {
|
|
|
847
977
|
},
|
|
848
978
|
depositWithCard: {
|
|
849
979
|
title: "Deposit with Card",
|
|
850
|
-
subtitle: "$50,000 limit
|
|
980
|
+
subtitle: "$50,000 limit"
|
|
851
981
|
},
|
|
852
982
|
quotes: "Quotes"
|
|
853
983
|
},
|
|
@@ -865,9 +995,16 @@ var en_default = {
|
|
|
865
995
|
|
|
866
996
|
// src/lib/i18n.ts
|
|
867
997
|
var i18n = en_default;
|
|
998
|
+
function interpolate(template, params) {
|
|
999
|
+
if (!params) return template;
|
|
1000
|
+
return template.replace(/\{\{(\w+)\}\}/g, (_, key) => {
|
|
1001
|
+
const value = params[key];
|
|
1002
|
+
return value !== void 0 ? String(value) : `{{${key}}}`;
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
868
1005
|
|
|
869
1006
|
// src/hooks/use-deposit-polling.ts
|
|
870
|
-
import { useState as
|
|
1007
|
+
import { useState as useState5, useEffect as useEffect3, useRef } from "react";
|
|
871
1008
|
import {
|
|
872
1009
|
queryExecutions,
|
|
873
1010
|
ExecutionStatus
|
|
@@ -879,14 +1016,14 @@ function useDepositPolling({
|
|
|
879
1016
|
onDepositSuccess,
|
|
880
1017
|
onDepositError
|
|
881
1018
|
}) {
|
|
882
|
-
const [executions, setExecutions] =
|
|
883
|
-
const [isPolling, setIsPolling] =
|
|
1019
|
+
const [executions, setExecutions] = useState5([]);
|
|
1020
|
+
const [isPolling, setIsPolling] = useState5(false);
|
|
884
1021
|
const pollingIntervalRef = useRef(
|
|
885
1022
|
null
|
|
886
1023
|
);
|
|
887
|
-
const [modalOpenedAt] =
|
|
888
|
-
const [trackedExecutions, setTrackedExecutions] =
|
|
889
|
-
|
|
1024
|
+
const [modalOpenedAt] = useState5(/* @__PURE__ */ new Date());
|
|
1025
|
+
const [trackedExecutions, setTrackedExecutions] = useState5(/* @__PURE__ */ new Map());
|
|
1026
|
+
useEffect3(() => {
|
|
890
1027
|
if (!userId || !modalOpenedAt || !enabled) return;
|
|
891
1028
|
const pollInterval = setInterval(async () => {
|
|
892
1029
|
try {
|
|
@@ -989,10 +1126,10 @@ function useDepositPolling({
|
|
|
989
1126
|
}
|
|
990
1127
|
|
|
991
1128
|
// src/components/deposits/DepositPollingToasts.tsx
|
|
992
|
-
import { useState as
|
|
1129
|
+
import { useState as useState8 } from "react";
|
|
993
1130
|
|
|
994
1131
|
// src/components/deposits/DepositSuccessToast.tsx
|
|
995
|
-
import { useState as
|
|
1132
|
+
import { useState as useState7 } from "react";
|
|
996
1133
|
import { X as X3 } from "lucide-react";
|
|
997
1134
|
import {
|
|
998
1135
|
ExecutionStatus as ExecutionStatus3,
|
|
@@ -1000,7 +1137,7 @@ import {
|
|
|
1000
1137
|
} from "@unifold/core";
|
|
1001
1138
|
|
|
1002
1139
|
// src/components/deposits/DepositDetailContent.tsx
|
|
1003
|
-
import { useEffect as
|
|
1140
|
+
import { useEffect as useEffect4, useState as useState6 } from "react";
|
|
1004
1141
|
import { ExternalLink, ChevronDown, ChevronUp } from "lucide-react";
|
|
1005
1142
|
import {
|
|
1006
1143
|
ExecutionStatus as ExecutionStatus2,
|
|
@@ -1019,12 +1156,12 @@ function formatCurrency(currency) {
|
|
|
1019
1156
|
}
|
|
1020
1157
|
function DepositDetailContent({ execution }) {
|
|
1021
1158
|
const { colors: colors2, fonts, components } = useTheme();
|
|
1022
|
-
const [chains, setChains] =
|
|
1023
|
-
const [showNetworkDetails, setShowNetworkDetails] =
|
|
1024
|
-
|
|
1159
|
+
const [chains, setChains] = useState6([]);
|
|
1160
|
+
const [showNetworkDetails, setShowNetworkDetails] = useState6(false);
|
|
1161
|
+
useEffect4(() => {
|
|
1025
1162
|
getTokenChains().then((response) => setChains(response.data)).catch((err) => console.error("Failed to fetch chains:", err));
|
|
1026
1163
|
}, []);
|
|
1027
|
-
|
|
1164
|
+
useEffect4(() => {
|
|
1028
1165
|
setShowNetworkDetails(false);
|
|
1029
1166
|
}, [execution?.id]);
|
|
1030
1167
|
const isPending = execution.status === ExecutionStatus2.PENDING || execution.status === ExecutionStatus2.WAITING || execution.status === ExecutionStatus2.DELAYED;
|
|
@@ -1319,6 +1456,37 @@ function DepositDetailContent({ execution }) {
|
|
|
1319
1456
|
]
|
|
1320
1457
|
}
|
|
1321
1458
|
),
|
|
1459
|
+
isPending && /* @__PURE__ */ jsxs6(
|
|
1460
|
+
"div",
|
|
1461
|
+
{
|
|
1462
|
+
className: "uf-flex uf-justify-between uf-items-center uf-px-4 uf-py-3 uf-border-b",
|
|
1463
|
+
style: { borderColor: colors2.border },
|
|
1464
|
+
children: [
|
|
1465
|
+
/* @__PURE__ */ jsx7(
|
|
1466
|
+
"span",
|
|
1467
|
+
{
|
|
1468
|
+
className: "uf-text-sm",
|
|
1469
|
+
style: {
|
|
1470
|
+
color: components.card.labelColor,
|
|
1471
|
+
fontFamily: fonts.regular
|
|
1472
|
+
},
|
|
1473
|
+
children: "Estimated delivery time"
|
|
1474
|
+
}
|
|
1475
|
+
),
|
|
1476
|
+
/* @__PURE__ */ jsx7(
|
|
1477
|
+
"span",
|
|
1478
|
+
{
|
|
1479
|
+
style: {
|
|
1480
|
+
color: components.card.titleColor,
|
|
1481
|
+
fontFamily: fonts.regular,
|
|
1482
|
+
fontSize: "14px"
|
|
1483
|
+
},
|
|
1484
|
+
children: formatEstimatedTime(execution?.estimated_processing_time)
|
|
1485
|
+
}
|
|
1486
|
+
)
|
|
1487
|
+
]
|
|
1488
|
+
}
|
|
1489
|
+
),
|
|
1322
1490
|
/* @__PURE__ */ jsxs6(
|
|
1323
1491
|
"div",
|
|
1324
1492
|
{
|
|
@@ -1505,7 +1673,7 @@ function DepositSuccessToast({
|
|
|
1505
1673
|
onClose,
|
|
1506
1674
|
execution
|
|
1507
1675
|
}) {
|
|
1508
|
-
const [detailModalOpen, setDetailModalOpen] =
|
|
1676
|
+
const [detailModalOpen, setDetailModalOpen] = useState7(false);
|
|
1509
1677
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
1510
1678
|
const isPending = status === ExecutionStatus3.PENDING || status === ExecutionStatus3.WAITING || status === ExecutionStatus3.DELAYED;
|
|
1511
1679
|
const formatDateTime = (timestamp) => {
|
|
@@ -1639,14 +1807,28 @@ function DepositSuccessToast({
|
|
|
1639
1807
|
}
|
|
1640
1808
|
)
|
|
1641
1809
|
] }),
|
|
1642
|
-
/* @__PURE__ */
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1810
|
+
/* @__PURE__ */ jsxs7("div", { className: "uf-flex-shrink-0 uf-text-right", children: [
|
|
1811
|
+
/* @__PURE__ */ jsx8(
|
|
1812
|
+
"div",
|
|
1813
|
+
{
|
|
1814
|
+
className: "uf-font-medium uf-text-sm",
|
|
1815
|
+
style: { color: colors2.background },
|
|
1816
|
+
children: formatUsdAmount(sourceAmountUsd)
|
|
1817
|
+
}
|
|
1818
|
+
),
|
|
1819
|
+
isPending && execution?.estimated_processing_time && /* @__PURE__ */ jsxs7(
|
|
1820
|
+
"p",
|
|
1821
|
+
{
|
|
1822
|
+
className: "uf-text-xs",
|
|
1823
|
+
style: { color: colors2.foregroundMuted },
|
|
1824
|
+
children: [
|
|
1825
|
+
"Est.",
|
|
1826
|
+
" ",
|
|
1827
|
+
formatEstimatedTime(execution.estimated_processing_time)
|
|
1828
|
+
]
|
|
1829
|
+
}
|
|
1830
|
+
)
|
|
1831
|
+
] }),
|
|
1650
1832
|
/* @__PURE__ */ jsx8(
|
|
1651
1833
|
"button",
|
|
1652
1834
|
{
|
|
@@ -1695,7 +1877,7 @@ function DepositPollingToasts({
|
|
|
1695
1877
|
executions,
|
|
1696
1878
|
horizontalPadding = "24px"
|
|
1697
1879
|
}) {
|
|
1698
|
-
const [closedExecutionIds, setClosedExecutionIds] =
|
|
1880
|
+
const [closedExecutionIds, setClosedExecutionIds] = useState8(
|
|
1699
1881
|
/* @__PURE__ */ new Set()
|
|
1700
1882
|
);
|
|
1701
1883
|
const handleClose = (executionId) => {
|
|
@@ -1776,28 +1958,28 @@ function BuyWithCard({
|
|
|
1776
1958
|
assetCdnUrl
|
|
1777
1959
|
}) {
|
|
1778
1960
|
const { colors: colors2, fonts, components } = useTheme();
|
|
1779
|
-
const [amount, setAmount] =
|
|
1780
|
-
const [currency, setCurrency] =
|
|
1781
|
-
const [hasManualCurrencySelection, setHasManualCurrencySelection] =
|
|
1782
|
-
const [hasManualAmountEntry, setHasManualAmountEntry] =
|
|
1783
|
-
const [showCurrencyModal, setShowCurrencyModal] =
|
|
1784
|
-
const [quotes, setQuotes] =
|
|
1785
|
-
const [quotesLoading, setQuotesLoading] =
|
|
1786
|
-
const [quotesError, setQuotesError] =
|
|
1787
|
-
const [amountValidationError, setAmountValidationError] =
|
|
1788
|
-
const [internalView, setInternalView] =
|
|
1789
|
-
const [defaultToken, setDefaultToken] =
|
|
1961
|
+
const [amount, setAmount] = useState9("");
|
|
1962
|
+
const [currency, setCurrency] = useState9("usd");
|
|
1963
|
+
const [hasManualCurrencySelection, setHasManualCurrencySelection] = useState9(false);
|
|
1964
|
+
const [hasManualAmountEntry, setHasManualAmountEntry] = useState9(false);
|
|
1965
|
+
const [showCurrencyModal, setShowCurrencyModal] = useState9(false);
|
|
1966
|
+
const [quotes, setQuotes] = useState9([]);
|
|
1967
|
+
const [quotesLoading, setQuotesLoading] = useState9(false);
|
|
1968
|
+
const [quotesError, setQuotesError] = useState9(null);
|
|
1969
|
+
const [amountValidationError, setAmountValidationError] = useState9(null);
|
|
1970
|
+
const [internalView, setInternalView] = useState9("amount");
|
|
1971
|
+
const [defaultToken, setDefaultToken] = useState9(
|
|
1790
1972
|
null
|
|
1791
1973
|
);
|
|
1792
|
-
const [defaultTokenLoading, setDefaultTokenLoading] =
|
|
1974
|
+
const [defaultTokenLoading, setDefaultTokenLoading] = useState9(false);
|
|
1793
1975
|
const { userIpInfo, isLoading: isLoadingIp } = useUserIp();
|
|
1794
|
-
const [onrampSession, setOnrampSession] =
|
|
1976
|
+
const [onrampSession, setOnrampSession] = useState9(
|
|
1795
1977
|
null
|
|
1796
1978
|
);
|
|
1797
1979
|
const currentView = externalView ?? internalView;
|
|
1798
1980
|
const showQuotesView = currentView === "quotes";
|
|
1799
1981
|
const showOnrampView = currentView === "onramp";
|
|
1800
|
-
|
|
1982
|
+
useEffect5(() => {
|
|
1801
1983
|
if (externalView) {
|
|
1802
1984
|
setInternalView(externalView);
|
|
1803
1985
|
}
|
|
@@ -1810,31 +1992,31 @@ function BuyWithCard({
|
|
|
1810
1992
|
onViewChange?.(newView);
|
|
1811
1993
|
}
|
|
1812
1994
|
};
|
|
1813
|
-
const [selectedProvider, setSelectedProvider] =
|
|
1995
|
+
const [selectedProvider, setSelectedProvider] = useState9(
|
|
1814
1996
|
null
|
|
1815
1997
|
);
|
|
1816
|
-
const [isAutoSelected, setIsAutoSelected] =
|
|
1817
|
-
const [autoSelectedProvider, setAutoSelectedProvider] =
|
|
1818
|
-
const [hoveredProviderIndex, setHoveredProviderIndex] =
|
|
1819
|
-
const [hasManualSelection, setHasManualSelection] =
|
|
1998
|
+
const [isAutoSelected, setIsAutoSelected] = useState9(true);
|
|
1999
|
+
const [autoSelectedProvider, setAutoSelectedProvider] = useState9(null);
|
|
2000
|
+
const [hoveredProviderIndex, setHoveredProviderIndex] = useState9(null);
|
|
2001
|
+
const [hasManualSelection, setHasManualSelection] = useState9(false);
|
|
1820
2002
|
const selectedProviderRef = useRef2(null);
|
|
1821
2003
|
const hasManualSelectionRef = useRef2(false);
|
|
1822
|
-
|
|
2004
|
+
useEffect5(() => {
|
|
1823
2005
|
selectedProviderRef.current = selectedProvider;
|
|
1824
2006
|
}, [selectedProvider]);
|
|
1825
|
-
|
|
2007
|
+
useEffect5(() => {
|
|
1826
2008
|
hasManualSelectionRef.current = hasManualSelection;
|
|
1827
2009
|
}, [hasManualSelection]);
|
|
1828
|
-
const [internalWallets, setInternalWallets] =
|
|
1829
|
-
const [walletsLoading, setWalletsLoading] =
|
|
2010
|
+
const [internalWallets, setInternalWallets] = useState9([]);
|
|
2011
|
+
const [walletsLoading, setWalletsLoading] = useState9(
|
|
1830
2012
|
!externalWallets?.length
|
|
1831
2013
|
);
|
|
1832
2014
|
const wallets = externalWallets?.length ? externalWallets : internalWallets;
|
|
1833
|
-
const [countdown, setCountdown] =
|
|
1834
|
-
const [fiatCurrencies, setFiatCurrencies] =
|
|
1835
|
-
const [preferredCurrencyCodes, setPreferredCurrencyCodes] =
|
|
1836
|
-
const [currenciesLoading, setCurrenciesLoading] =
|
|
1837
|
-
const [destinationToken, setDestinationToken] =
|
|
2015
|
+
const [countdown, setCountdown] = useState9(60);
|
|
2016
|
+
const [fiatCurrencies, setFiatCurrencies] = useState9([]);
|
|
2017
|
+
const [preferredCurrencyCodes, setPreferredCurrencyCodes] = useState9([]);
|
|
2018
|
+
const [currenciesLoading, setCurrenciesLoading] = useState9(true);
|
|
2019
|
+
const [destinationToken, setDestinationToken] = useState9(null);
|
|
1838
2020
|
const { executions, isPolling } = useDepositPolling({
|
|
1839
2021
|
userId,
|
|
1840
2022
|
publishableKey,
|
|
@@ -1846,7 +2028,7 @@ function BuyWithCard({
|
|
|
1846
2028
|
const destinationTokenIcon = destinationToken?.icon_url;
|
|
1847
2029
|
const destinationChainIcon = destinationToken?.chain_icon_url;
|
|
1848
2030
|
const destinationChainName = destinationToken?.chain_name;
|
|
1849
|
-
|
|
2031
|
+
useEffect5(() => {
|
|
1850
2032
|
async function fetchFiatCurrencies() {
|
|
1851
2033
|
try {
|
|
1852
2034
|
const response = await getFiatCurrencies(publishableKey);
|
|
@@ -1860,7 +2042,7 @@ function BuyWithCard({
|
|
|
1860
2042
|
}
|
|
1861
2043
|
fetchFiatCurrencies();
|
|
1862
2044
|
}, [publishableKey]);
|
|
1863
|
-
|
|
2045
|
+
useEffect5(() => {
|
|
1864
2046
|
if (hasManualCurrencySelection) return;
|
|
1865
2047
|
if (fiatCurrencies.length === 0 || !userIpInfo?.alpha2) return;
|
|
1866
2048
|
const userCountryCode = userIpInfo.alpha2.toUpperCase();
|
|
@@ -1888,7 +2070,7 @@ function BuyWithCard({
|
|
|
1888
2070
|
hasManualAmountEntry
|
|
1889
2071
|
]);
|
|
1890
2072
|
const prevCurrencyRef = useRef2(null);
|
|
1891
|
-
|
|
2073
|
+
useEffect5(() => {
|
|
1892
2074
|
if (fiatCurrencies.length === 0) return;
|
|
1893
2075
|
if (prevCurrencyRef.current !== null && prevCurrencyRef.current !== currency) {
|
|
1894
2076
|
const currentCurrency = fiatCurrencies.find(
|
|
@@ -1900,7 +2082,7 @@ function BuyWithCard({
|
|
|
1900
2082
|
}
|
|
1901
2083
|
prevCurrencyRef.current = currency;
|
|
1902
2084
|
}, [currency]);
|
|
1903
|
-
|
|
2085
|
+
useEffect5(() => {
|
|
1904
2086
|
if (externalWallets?.length) {
|
|
1905
2087
|
setWalletsLoading(false);
|
|
1906
2088
|
return;
|
|
@@ -1953,7 +2135,7 @@ function BuyWithCard({
|
|
|
1953
2135
|
publishableKey,
|
|
1954
2136
|
externalWallets
|
|
1955
2137
|
]);
|
|
1956
|
-
|
|
2138
|
+
useEffect5(() => {
|
|
1957
2139
|
async function fetchDestinationToken() {
|
|
1958
2140
|
try {
|
|
1959
2141
|
const response = await getTokenMetadata(
|
|
@@ -1971,7 +2153,7 @@ function BuyWithCard({
|
|
|
1971
2153
|
}
|
|
1972
2154
|
fetchDestinationToken();
|
|
1973
2155
|
}, [publishableKey]);
|
|
1974
|
-
|
|
2156
|
+
useEffect5(() => {
|
|
1975
2157
|
async function fetchDefaultToken() {
|
|
1976
2158
|
if (!destinationTokenAddress || !destinationChainId || !destinationChainType) {
|
|
1977
2159
|
return;
|
|
@@ -2007,7 +2189,7 @@ function BuyWithCard({
|
|
|
2007
2189
|
isLoadingIp,
|
|
2008
2190
|
publishableKey
|
|
2009
2191
|
]);
|
|
2010
|
-
|
|
2192
|
+
useEffect5(() => {
|
|
2011
2193
|
const amountNum = parseFloat(amount);
|
|
2012
2194
|
if (isNaN(amountNum) || amountNum <= 0) {
|
|
2013
2195
|
setQuotes([]);
|
|
@@ -2116,7 +2298,7 @@ function BuyWithCard({
|
|
|
2116
2298
|
setQuotesLoading(false);
|
|
2117
2299
|
}
|
|
2118
2300
|
};
|
|
2119
|
-
|
|
2301
|
+
useEffect5(() => {
|
|
2120
2302
|
if (quotes.length === 0) return;
|
|
2121
2303
|
const timer = setInterval(() => {
|
|
2122
2304
|
setCountdown((prev) => {
|
|
@@ -2451,6 +2633,21 @@ function BuyWithCard({
|
|
|
2451
2633
|
},
|
|
2452
2634
|
children: quotesError
|
|
2453
2635
|
}
|
|
2636
|
+
),
|
|
2637
|
+
defaultToken?.estimated_processing_time && !quotesLoading && selectedProvider && /* @__PURE__ */ jsxs8(
|
|
2638
|
+
"div",
|
|
2639
|
+
{
|
|
2640
|
+
className: "uf-text-xs uf-mt-2 uf-px-1",
|
|
2641
|
+
style: {
|
|
2642
|
+
color: components.card.subtitleColor,
|
|
2643
|
+
fontFamily: fonts.regular
|
|
2644
|
+
},
|
|
2645
|
+
children: [
|
|
2646
|
+
"Estimated delivery time:",
|
|
2647
|
+
" ",
|
|
2648
|
+
formatEstimatedTime(defaultToken.estimated_processing_time)
|
|
2649
|
+
]
|
|
2650
|
+
}
|
|
2454
2651
|
)
|
|
2455
2652
|
] }),
|
|
2456
2653
|
/* @__PURE__ */ jsx10(
|
|
@@ -2668,7 +2865,7 @@ function BuyWithCard({
|
|
|
2668
2865
|
}
|
|
2669
2866
|
|
|
2670
2867
|
// src/components/deposits/DepositsModal.tsx
|
|
2671
|
-
import { useEffect as
|
|
2868
|
+
import { useEffect as useEffect6, useState as useState10 } from "react";
|
|
2672
2869
|
|
|
2673
2870
|
// src/components/deposits/DepositExecutionItem.tsx
|
|
2674
2871
|
import { ChevronRight as ChevronRight2 } from "lucide-react";
|
|
@@ -2913,9 +3110,9 @@ function DepositsModal({
|
|
|
2913
3110
|
themeClass = ""
|
|
2914
3111
|
}) {
|
|
2915
3112
|
const { colors: colors2 } = useTheme();
|
|
2916
|
-
const [allExecutions, setAllExecutions] =
|
|
2917
|
-
const [selectedExecution, setSelectedExecution] =
|
|
2918
|
-
|
|
3113
|
+
const [allExecutions, setAllExecutions] = useState10(sessionExecutions);
|
|
3114
|
+
const [selectedExecution, setSelectedExecution] = useState10(null);
|
|
3115
|
+
useEffect6(() => {
|
|
2919
3116
|
if (!open || !userId) return;
|
|
2920
3117
|
const fetchExecutions = async () => {
|
|
2921
3118
|
try {
|
|
@@ -2937,7 +3134,7 @@ function DepositsModal({
|
|
|
2937
3134
|
clearInterval(pollInterval);
|
|
2938
3135
|
};
|
|
2939
3136
|
}, [open, userId, publishableKey, sessionExecutions]);
|
|
2940
|
-
|
|
3137
|
+
useEffect6(() => {
|
|
2941
3138
|
if (!open) {
|
|
2942
3139
|
setSelectedExecution(null);
|
|
2943
3140
|
}
|
|
@@ -3325,8 +3522,68 @@ function useAllowedCountry(publishableKey) {
|
|
|
3325
3522
|
};
|
|
3326
3523
|
}
|
|
3327
3524
|
|
|
3525
|
+
// src/hooks/use-address-validation.ts
|
|
3526
|
+
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
3527
|
+
import {
|
|
3528
|
+
verifyRecipientAddress
|
|
3529
|
+
} from "@unifold/core";
|
|
3530
|
+
function useAddressValidation({
|
|
3531
|
+
recipientAddress,
|
|
3532
|
+
destinationChainType,
|
|
3533
|
+
destinationChainId,
|
|
3534
|
+
destinationTokenAddress,
|
|
3535
|
+
publishableKey,
|
|
3536
|
+
enabled = true,
|
|
3537
|
+
refetchOnMount = false
|
|
3538
|
+
}) {
|
|
3539
|
+
const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
3540
|
+
const { data, isLoading, error } = useQuery3({
|
|
3541
|
+
queryKey: [
|
|
3542
|
+
"unifold",
|
|
3543
|
+
"addressValidation",
|
|
3544
|
+
recipientAddress,
|
|
3545
|
+
destinationChainType,
|
|
3546
|
+
destinationChainId,
|
|
3547
|
+
destinationTokenAddress
|
|
3548
|
+
],
|
|
3549
|
+
queryFn: () => verifyRecipientAddress(
|
|
3550
|
+
{
|
|
3551
|
+
chain_type: destinationChainType,
|
|
3552
|
+
chain_id: destinationChainId,
|
|
3553
|
+
token_address: destinationTokenAddress,
|
|
3554
|
+
recipient_address: recipientAddress
|
|
3555
|
+
},
|
|
3556
|
+
publishableKey
|
|
3557
|
+
),
|
|
3558
|
+
enabled: shouldValidate,
|
|
3559
|
+
refetchOnMount,
|
|
3560
|
+
refetchOnReconnect: false,
|
|
3561
|
+
refetchOnWindowFocus: false,
|
|
3562
|
+
staleTime: 1e3 * 60 * 5,
|
|
3563
|
+
// 5 minutes - address state can change
|
|
3564
|
+
gcTime: 1e3 * 60 * 30
|
|
3565
|
+
// 30 minutes
|
|
3566
|
+
});
|
|
3567
|
+
if (!shouldValidate) {
|
|
3568
|
+
return {
|
|
3569
|
+
isValid: null,
|
|
3570
|
+
failureCode: null,
|
|
3571
|
+
metadata: null,
|
|
3572
|
+
isLoading: false,
|
|
3573
|
+
error: null
|
|
3574
|
+
};
|
|
3575
|
+
}
|
|
3576
|
+
return {
|
|
3577
|
+
isValid: data?.valid ?? null,
|
|
3578
|
+
failureCode: data?.failure_code ?? null,
|
|
3579
|
+
metadata: data?.metadata ?? null,
|
|
3580
|
+
isLoading,
|
|
3581
|
+
error: error ?? null
|
|
3582
|
+
};
|
|
3583
|
+
}
|
|
3584
|
+
|
|
3328
3585
|
// src/components/deposits/TransferCryptoSingleInput.tsx
|
|
3329
|
-
import { useState as
|
|
3586
|
+
import { useState as useState15, useEffect as useEffect12 } from "react";
|
|
3330
3587
|
import {
|
|
3331
3588
|
ChevronDown as ChevronDown3,
|
|
3332
3589
|
ChevronUp as ChevronUp2,
|
|
@@ -3342,7 +3599,7 @@ import {
|
|
|
3342
3599
|
} from "lucide-react";
|
|
3343
3600
|
|
|
3344
3601
|
// src/components/deposits/StyledQRCode.tsx
|
|
3345
|
-
import { useEffect as
|
|
3602
|
+
import { useEffect as useEffect10, useRef as useRef3 } from "react";
|
|
3346
3603
|
import QRCodeStyling from "qr-code-styling";
|
|
3347
3604
|
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
3348
3605
|
function StyledQRCode({
|
|
@@ -3354,7 +3611,7 @@ function StyledQRCode({
|
|
|
3354
3611
|
}) {
|
|
3355
3612
|
const ref = useRef3(null);
|
|
3356
3613
|
const qrCodeRef = useRef3(null);
|
|
3357
|
-
|
|
3614
|
+
useEffect10(() => {
|
|
3358
3615
|
if (!ref.current) return;
|
|
3359
3616
|
if (!qrCodeRef.current) {
|
|
3360
3617
|
qrCodeRef.current = new QRCodeStyling({
|
|
@@ -3394,7 +3651,7 @@ function StyledQRCode({
|
|
|
3394
3651
|
qrCodeRef.current.append(ref.current);
|
|
3395
3652
|
}
|
|
3396
3653
|
}, []);
|
|
3397
|
-
|
|
3654
|
+
useEffect10(() => {
|
|
3398
3655
|
if (qrCodeRef.current) {
|
|
3399
3656
|
qrCodeRef.current.update({
|
|
3400
3657
|
data: value,
|
|
@@ -3435,7 +3692,7 @@ function StyledQRCode({
|
|
|
3435
3692
|
}
|
|
3436
3693
|
|
|
3437
3694
|
// src/components/deposits/TokenSelectorSheet.tsx
|
|
3438
|
-
import { useState as
|
|
3695
|
+
import { useState as useState14, useMemo as useMemo3, useEffect as useEffect11 } from "react";
|
|
3439
3696
|
import { ArrowLeft as ArrowLeft2, X as X4 } from "lucide-react";
|
|
3440
3697
|
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3441
3698
|
var STORAGE_KEY = "unifold_recent_tokens";
|
|
@@ -3493,10 +3750,10 @@ function TokenSelectorSheet({
|
|
|
3493
3750
|
}) {
|
|
3494
3751
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
3495
3752
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
3496
|
-
const [searchQuery, setSearchQuery] =
|
|
3497
|
-
const [recentTokens, setRecentTokens] =
|
|
3498
|
-
const [hoveredTokenKey, setHoveredTokenKey] =
|
|
3499
|
-
|
|
3753
|
+
const [searchQuery, setSearchQuery] = useState14("");
|
|
3754
|
+
const [recentTokens, setRecentTokens] = useState14([]);
|
|
3755
|
+
const [hoveredTokenKey, setHoveredTokenKey] = useState14(null);
|
|
3756
|
+
useEffect11(() => {
|
|
3500
3757
|
setRecentTokens(getRecentTokens());
|
|
3501
3758
|
}, []);
|
|
3502
3759
|
const allOptions = useMemo3(() => {
|
|
@@ -3938,13 +4195,13 @@ function TransferCryptoSingleInput({
|
|
|
3938
4195
|
}) {
|
|
3939
4196
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
3940
4197
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
3941
|
-
const [token, setToken] =
|
|
3942
|
-
const [chain, setChain] =
|
|
3943
|
-
const [copied, setCopied] =
|
|
3944
|
-
const [internalWallets, setInternalWallets] =
|
|
3945
|
-
const [loading, setLoading] =
|
|
4198
|
+
const [token, setToken] = useState15("USDC");
|
|
4199
|
+
const [chain, setChain] = useState15("solana:mainnet");
|
|
4200
|
+
const [copied, setCopied] = useState15(false);
|
|
4201
|
+
const [internalWallets, setInternalWallets] = useState15([]);
|
|
4202
|
+
const [loading, setLoading] = useState15(!externalWallets?.length);
|
|
3946
4203
|
const wallets = externalWallets?.length ? externalWallets : internalWallets;
|
|
3947
|
-
const [error, setError] =
|
|
4204
|
+
const [error, setError] = useState15(null);
|
|
3948
4205
|
const { executions: depositExecutions, isPolling } = useDepositPolling({
|
|
3949
4206
|
userId,
|
|
3950
4207
|
publishableKey,
|
|
@@ -3952,11 +4209,11 @@ function TransferCryptoSingleInput({
|
|
|
3952
4209
|
onDepositSuccess,
|
|
3953
4210
|
onDepositError
|
|
3954
4211
|
});
|
|
3955
|
-
const [supportedTokens, setSupportedTokens] =
|
|
3956
|
-
const [tokensLoading, setTokensLoading] =
|
|
3957
|
-
const [detailsExpanded, setDetailsExpanded] =
|
|
3958
|
-
const [depositsModalOpen, setDepositsModalOpen] =
|
|
3959
|
-
const [tokenSelectorOpen, setTokenSelectorOpen] =
|
|
4212
|
+
const [supportedTokens, setSupportedTokens] = useState15([]);
|
|
4213
|
+
const [tokensLoading, setTokensLoading] = useState15(true);
|
|
4214
|
+
const [detailsExpanded, setDetailsExpanded] = useState15(false);
|
|
4215
|
+
const [depositsModalOpen, setDepositsModalOpen] = useState15(false);
|
|
4216
|
+
const [tokenSelectorOpen, setTokenSelectorOpen] = useState15(false);
|
|
3960
4217
|
const allChainsMap = /* @__PURE__ */ new Map();
|
|
3961
4218
|
supportedTokens.forEach((t5) => {
|
|
3962
4219
|
t5.chains.forEach((c) => {
|
|
@@ -3974,7 +4231,7 @@ function TransferCryptoSingleInput({
|
|
|
3974
4231
|
const currentChainType = currentChainData?.chain_type || "ethereum";
|
|
3975
4232
|
const currentWallet = getWalletByChainType2(wallets, currentChainType);
|
|
3976
4233
|
const depositAddress = currentWallet?.address || "";
|
|
3977
|
-
|
|
4234
|
+
useEffect12(() => {
|
|
3978
4235
|
async function fetchSupportedTokens() {
|
|
3979
4236
|
try {
|
|
3980
4237
|
setTokensLoading(true);
|
|
@@ -4046,12 +4303,12 @@ function TransferCryptoSingleInput({
|
|
|
4046
4303
|
destinationChainId,
|
|
4047
4304
|
destinationChainType
|
|
4048
4305
|
]);
|
|
4049
|
-
|
|
4306
|
+
useEffect12(() => {
|
|
4050
4307
|
if (onExecutionsChange) {
|
|
4051
4308
|
onExecutionsChange(depositExecutions);
|
|
4052
4309
|
}
|
|
4053
4310
|
}, [depositExecutions, onExecutionsChange]);
|
|
4054
|
-
|
|
4311
|
+
useEffect12(() => {
|
|
4055
4312
|
if (externalWallets?.length) {
|
|
4056
4313
|
setLoading(false);
|
|
4057
4314
|
return;
|
|
@@ -4108,7 +4365,7 @@ function TransferCryptoSingleInput({
|
|
|
4108
4365
|
publishableKey,
|
|
4109
4366
|
externalWallets
|
|
4110
4367
|
]);
|
|
4111
|
-
|
|
4368
|
+
useEffect12(() => {
|
|
4112
4369
|
if (!supportedTokens.length) return;
|
|
4113
4370
|
const currentToken = supportedTokens.find((t5) => t5.symbol === token);
|
|
4114
4371
|
if (!currentToken || currentToken.chains.length === 0) return;
|
|
@@ -4300,24 +4557,24 @@ function TransferCryptoSingleInput({
|
|
|
4300
4557
|
)
|
|
4301
4558
|
] })
|
|
4302
4559
|
] }),
|
|
4303
|
-
loading ? /* @__PURE__ */ jsx20("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-muted-foreground uf-animate-pulse", children: t2.loading }) : error ? /* @__PURE__ */ jsx20("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-red-400", children: error }) : /* @__PURE__ */ jsxs15(
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
children: depositAddress
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4560
|
+
loading ? /* @__PURE__ */ jsx20("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-muted-foreground uf-animate-pulse", children: t2.loading }) : error ? /* @__PURE__ */ jsx20("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-red-400", children: error }) : /* @__PURE__ */ jsxs15(
|
|
4561
|
+
"button",
|
|
4562
|
+
{
|
|
4563
|
+
onClick: handleCopyAddress,
|
|
4564
|
+
disabled: !depositAddress,
|
|
4565
|
+
className: "uf-w-full uf-bg-secondary hover:uf-bg-accent uf-rounded-lg uf-px-3 uf-py-2.5 uf-flex uf-items-center uf-justify-between uf-gap-2 uf-transition-colors uf-cursor-pointer disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
|
|
4566
|
+
children: [
|
|
4567
|
+
/* @__PURE__ */ jsx20("span", { className: "uf-text-xs uf-font-mono uf-truncate uf-min-w-0", children: depositAddress ? truncateAddress(depositAddress, 18, 12) : t2.noAddressAvailable }),
|
|
4568
|
+
depositAddress && /* @__PURE__ */ jsx20(
|
|
4569
|
+
"span",
|
|
4570
|
+
{
|
|
4571
|
+
className: `uf-flex-shrink-0 uf-transition-colors ${copied ? "uf-text-green-500" : "uf-text-muted-foreground"}`,
|
|
4572
|
+
children: copied ? /* @__PURE__ */ jsx20(Check3, { className: "uf-w-3.5 uf-h-3.5" }) : /* @__PURE__ */ jsx20(Copy, { className: "uf-w-3.5 uf-h-3.5" })
|
|
4573
|
+
}
|
|
4574
|
+
)
|
|
4575
|
+
]
|
|
4576
|
+
}
|
|
4577
|
+
)
|
|
4321
4578
|
] }),
|
|
4322
4579
|
/* @__PURE__ */ jsxs15("div", { className: "uf-bg-secondary uf-rounded-xl uf-px-2.5", children: [
|
|
4323
4580
|
/* @__PURE__ */ jsxs15(
|
|
@@ -4486,7 +4743,7 @@ function TransferCryptoSingleInput({
|
|
|
4486
4743
|
}
|
|
4487
4744
|
|
|
4488
4745
|
// src/components/deposits/TransferCryptoDoubleInput.tsx
|
|
4489
|
-
import { useState as
|
|
4746
|
+
import { useState as useState16, useEffect as useEffect13 } from "react";
|
|
4490
4747
|
import {
|
|
4491
4748
|
ChevronDown as ChevronDown5,
|
|
4492
4749
|
ChevronUp as ChevronUp4,
|
|
@@ -4651,13 +4908,13 @@ function TransferCryptoDoubleInput({
|
|
|
4651
4908
|
}) {
|
|
4652
4909
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
4653
4910
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
4654
|
-
const [token, setToken] =
|
|
4655
|
-
const [chain, setChain] =
|
|
4656
|
-
const [copied, setCopied] =
|
|
4657
|
-
const [internalWallets, setInternalWallets] =
|
|
4658
|
-
const [loading, setLoading] =
|
|
4911
|
+
const [token, setToken] = useState16("USDC");
|
|
4912
|
+
const [chain, setChain] = useState16("solana:mainnet");
|
|
4913
|
+
const [copied, setCopied] = useState16(false);
|
|
4914
|
+
const [internalWallets, setInternalWallets] = useState16([]);
|
|
4915
|
+
const [loading, setLoading] = useState16(!externalWallets?.length);
|
|
4659
4916
|
const wallets = externalWallets?.length ? externalWallets : internalWallets;
|
|
4660
|
-
const [error, setError] =
|
|
4917
|
+
const [error, setError] = useState16(null);
|
|
4661
4918
|
const { executions: depositExecutions, isPolling } = useDepositPolling({
|
|
4662
4919
|
userId,
|
|
4663
4920
|
publishableKey,
|
|
@@ -4665,10 +4922,10 @@ function TransferCryptoDoubleInput({
|
|
|
4665
4922
|
onDepositSuccess,
|
|
4666
4923
|
onDepositError
|
|
4667
4924
|
});
|
|
4668
|
-
const [supportedTokens, setSupportedTokens] =
|
|
4669
|
-
const [tokensLoading, setTokensLoading] =
|
|
4670
|
-
const [detailsExpanded, setDetailsExpanded] =
|
|
4671
|
-
const [depositsModalOpen, setDepositsModalOpen] =
|
|
4925
|
+
const [supportedTokens, setSupportedTokens] = useState16([]);
|
|
4926
|
+
const [tokensLoading, setTokensLoading] = useState16(true);
|
|
4927
|
+
const [detailsExpanded, setDetailsExpanded] = useState16(false);
|
|
4928
|
+
const [depositsModalOpen, setDepositsModalOpen] = useState16(false);
|
|
4672
4929
|
const allChainsMap = /* @__PURE__ */ new Map();
|
|
4673
4930
|
supportedTokens.forEach((t5) => {
|
|
4674
4931
|
t5.chains.forEach((c) => {
|
|
@@ -4686,7 +4943,7 @@ function TransferCryptoDoubleInput({
|
|
|
4686
4943
|
const currentChainType = currentChainData?.chain_type || "ethereum";
|
|
4687
4944
|
const currentWallet = getWalletByChainType3(wallets, currentChainType);
|
|
4688
4945
|
const depositAddress = currentWallet?.address || "";
|
|
4689
|
-
|
|
4946
|
+
useEffect13(() => {
|
|
4690
4947
|
async function fetchSupportedTokens() {
|
|
4691
4948
|
try {
|
|
4692
4949
|
setTokensLoading(true);
|
|
@@ -4729,12 +4986,12 @@ function TransferCryptoDoubleInput({
|
|
|
4729
4986
|
destinationChainId,
|
|
4730
4987
|
destinationChainType
|
|
4731
4988
|
]);
|
|
4732
|
-
|
|
4989
|
+
useEffect13(() => {
|
|
4733
4990
|
if (onExecutionsChange) {
|
|
4734
4991
|
onExecutionsChange(depositExecutions);
|
|
4735
4992
|
}
|
|
4736
4993
|
}, [depositExecutions, onExecutionsChange]);
|
|
4737
|
-
|
|
4994
|
+
useEffect13(() => {
|
|
4738
4995
|
if (externalWallets?.length) {
|
|
4739
4996
|
setLoading(false);
|
|
4740
4997
|
return;
|
|
@@ -4791,7 +5048,7 @@ function TransferCryptoDoubleInput({
|
|
|
4791
5048
|
publishableKey,
|
|
4792
5049
|
externalWallets
|
|
4793
5050
|
]);
|
|
4794
|
-
|
|
5051
|
+
useEffect13(() => {
|
|
4795
5052
|
if (!supportedTokens.length) return;
|
|
4796
5053
|
const currentToken = supportedTokens.find((t5) => t5.symbol === token);
|
|
4797
5054
|
if (!currentToken || currentToken.chains.length === 0) return;
|
|
@@ -4881,7 +5138,7 @@ function TransferCryptoDoubleInput({
|
|
|
4881
5138
|
children: [
|
|
4882
5139
|
/* @__PURE__ */ jsxs17("div", { className: "uf-grid uf-grid-cols-2 uf-gap-2.5", children: [
|
|
4883
5140
|
/* @__PURE__ */ jsxs17("div", { children: [
|
|
4884
|
-
/* @__PURE__ */ jsx22("div", { className: "uf-text-xs uf-text-muted-foreground uf-mb-2 uf-flex uf-items-center uf-gap-1", children: t3.
|
|
5141
|
+
/* @__PURE__ */ jsx22("div", { className: "uf-text-xs uf-text-muted-foreground uf-mb-2 uf-flex uf-items-center uf-gap-1", children: t3.selectedToken }),
|
|
4885
5142
|
/* @__PURE__ */ jsxs17(
|
|
4886
5143
|
Select,
|
|
4887
5144
|
{
|
|
@@ -4905,7 +5162,7 @@ function TransferCryptoDoubleInput({
|
|
|
4905
5162
|
] }),
|
|
4906
5163
|
/* @__PURE__ */ jsxs17("div", { children: [
|
|
4907
5164
|
/* @__PURE__ */ jsxs17("div", { className: "uf-text-xs uf-text-muted-foreground uf-mb-2 uf-flex uf-items-center uf-gap-1", children: [
|
|
4908
|
-
t3.
|
|
5165
|
+
t3.selectedChain,
|
|
4909
5166
|
/* @__PURE__ */ jsxs17("span", { className: "uf-text-amber-400 uf-font-medium", children: [
|
|
4910
5167
|
"$",
|
|
4911
5168
|
minDepositUsd,
|
|
@@ -5019,24 +5276,24 @@ function TransferCryptoDoubleInput({
|
|
|
5019
5276
|
)
|
|
5020
5277
|
] })
|
|
5021
5278
|
] }),
|
|
5022
|
-
loading ? /* @__PURE__ */ jsx22("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-muted-foreground uf-animate-pulse", children: t3.loading }) : error ? /* @__PURE__ */ jsx22("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-red-400", children: error }) : /* @__PURE__ */ jsxs17(
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
children: depositAddress
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5279
|
+
loading ? /* @__PURE__ */ jsx22("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-muted-foreground uf-animate-pulse", children: t3.loading }) : error ? /* @__PURE__ */ jsx22("div", { className: "uf-bg-secondary uf-rounded-lg uf-px-3 uf-py-2.5 uf-text-xs uf-text-red-400", children: error }) : /* @__PURE__ */ jsxs17(
|
|
5280
|
+
"button",
|
|
5281
|
+
{
|
|
5282
|
+
onClick: handleCopyAddress,
|
|
5283
|
+
disabled: !depositAddress,
|
|
5284
|
+
className: "uf-w-full uf-bg-secondary hover:uf-bg-accent uf-rounded-lg uf-px-3 uf-py-2.5 uf-flex uf-items-center uf-justify-between uf-gap-2 uf-transition-colors uf-cursor-pointer disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
|
|
5285
|
+
children: [
|
|
5286
|
+
/* @__PURE__ */ jsx22("span", { className: "uf-text-xs uf-font-mono uf-truncate uf-min-w-0", children: depositAddress ? truncateAddress(depositAddress, 18, 12) : t3.noAddressAvailable }),
|
|
5287
|
+
depositAddress && /* @__PURE__ */ jsx22(
|
|
5288
|
+
"span",
|
|
5289
|
+
{
|
|
5290
|
+
className: `uf-flex-shrink-0 uf-transition-colors ${copied ? "uf-text-green-500" : "uf-text-muted-foreground"}`,
|
|
5291
|
+
children: copied ? /* @__PURE__ */ jsx22(Check5, { className: "uf-w-3.5 uf-h-3.5" }) : /* @__PURE__ */ jsx22(Copy2, { className: "uf-w-3.5 uf-h-3.5" })
|
|
5292
|
+
}
|
|
5293
|
+
)
|
|
5294
|
+
]
|
|
5295
|
+
}
|
|
5296
|
+
)
|
|
5040
5297
|
] }),
|
|
5041
5298
|
/* @__PURE__ */ jsxs17("div", { className: "uf-bg-secondary uf-rounded-xl uf-px-2.5", children: [
|
|
5042
5299
|
/* @__PURE__ */ jsxs17(
|
|
@@ -5242,26 +5499,27 @@ function DepositModal({
|
|
|
5242
5499
|
destinationChainId,
|
|
5243
5500
|
destinationTokenAddress,
|
|
5244
5501
|
hideDepositTracker = false,
|
|
5502
|
+
showBalanceHeader = false,
|
|
5245
5503
|
transferInputVariant = "double_input",
|
|
5246
5504
|
onDepositSuccess,
|
|
5247
5505
|
onDepositError,
|
|
5248
5506
|
theme = "dark"
|
|
5249
5507
|
}) {
|
|
5250
|
-
const { colors: colors2 } = useTheme();
|
|
5251
|
-
const [view, setView] =
|
|
5252
|
-
const [cardView, setCardView] =
|
|
5508
|
+
const { colors: colors2, fonts } = useTheme();
|
|
5509
|
+
const [view, setView] = useState17("main");
|
|
5510
|
+
const [cardView, setCardView] = useState17(
|
|
5253
5511
|
"amount"
|
|
5254
5512
|
);
|
|
5255
|
-
const [quotesCount, setQuotesCount] =
|
|
5256
|
-
const [depositsModalOpen, setDepositsModalOpen] =
|
|
5257
|
-
const [depositExecutions, setDepositExecutions] =
|
|
5258
|
-
const [projectConfig, setProjectConfig] =
|
|
5259
|
-
const [wallets, setWallets] =
|
|
5260
|
-
const [walletsLoading, setWalletsLoading] =
|
|
5261
|
-
|
|
5513
|
+
const [quotesCount, setQuotesCount] = useState17(0);
|
|
5514
|
+
const [depositsModalOpen, setDepositsModalOpen] = useState17(false);
|
|
5515
|
+
const [depositExecutions, setDepositExecutions] = useState17([]);
|
|
5516
|
+
const [projectConfig, setProjectConfig] = useState17(null);
|
|
5517
|
+
const [wallets, setWallets] = useState17([]);
|
|
5518
|
+
const [walletsLoading, setWalletsLoading] = useState17(false);
|
|
5519
|
+
useEffect14(() => {
|
|
5262
5520
|
setProjectConfig(null);
|
|
5263
5521
|
}, [publishableKey]);
|
|
5264
|
-
|
|
5522
|
+
useEffect14(() => {
|
|
5265
5523
|
setWallets([]);
|
|
5266
5524
|
}, [
|
|
5267
5525
|
userId,
|
|
@@ -5271,10 +5529,10 @@ function DepositModal({
|
|
|
5271
5529
|
destinationTokenAddress,
|
|
5272
5530
|
publishableKey
|
|
5273
5531
|
]);
|
|
5274
|
-
const [resolvedTheme, setResolvedTheme] =
|
|
5532
|
+
const [resolvedTheme, setResolvedTheme] = useState17(
|
|
5275
5533
|
theme === "auto" ? "dark" : theme
|
|
5276
5534
|
);
|
|
5277
|
-
|
|
5535
|
+
useEffect14(() => {
|
|
5278
5536
|
if (theme === "auto") {
|
|
5279
5537
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
5280
5538
|
setResolvedTheme(mediaQuery.matches ? "dark" : "light");
|
|
@@ -5287,7 +5545,7 @@ function DepositModal({
|
|
|
5287
5545
|
setResolvedTheme(theme);
|
|
5288
5546
|
}
|
|
5289
5547
|
}, [theme]);
|
|
5290
|
-
|
|
5548
|
+
useEffect14(() => {
|
|
5291
5549
|
if (open && !projectConfig) {
|
|
5292
5550
|
getProjectConfig2(publishableKey).then(setProjectConfig).catch(console.error);
|
|
5293
5551
|
}
|
|
@@ -5297,7 +5555,29 @@ function DepositModal({
|
|
|
5297
5555
|
isLoading: isCountryLoading,
|
|
5298
5556
|
error: countryError
|
|
5299
5557
|
} = useAllowedCountry(publishableKey);
|
|
5300
|
-
|
|
5558
|
+
const {
|
|
5559
|
+
isValid: isAddressValid,
|
|
5560
|
+
failureCode: addressFailureCode,
|
|
5561
|
+
metadata: addressFailureMetadata,
|
|
5562
|
+
isLoading: isAddressValidationLoading
|
|
5563
|
+
} = useAddressValidation({
|
|
5564
|
+
recipientAddress,
|
|
5565
|
+
destinationChainType,
|
|
5566
|
+
destinationChainId,
|
|
5567
|
+
destinationTokenAddress,
|
|
5568
|
+
publishableKey,
|
|
5569
|
+
enabled: open,
|
|
5570
|
+
// Only validate when modal is open
|
|
5571
|
+
refetchOnMount: "always"
|
|
5572
|
+
});
|
|
5573
|
+
const addressValidationMessages = i18n.transferCrypto.addressValidation;
|
|
5574
|
+
const getAddressValidationErrorMessage = (code, metadata) => {
|
|
5575
|
+
if (!code) return addressValidationMessages.defaultError;
|
|
5576
|
+
const errors = addressValidationMessages.errors;
|
|
5577
|
+
const template = errors[code] ?? addressValidationMessages.defaultError;
|
|
5578
|
+
return interpolate(template, metadata);
|
|
5579
|
+
};
|
|
5580
|
+
useEffect14(() => {
|
|
5301
5581
|
if (!open || wallets.length > 0) return;
|
|
5302
5582
|
let retryTimeout = null;
|
|
5303
5583
|
let isCancelled = false;
|
|
@@ -5381,10 +5661,16 @@ function DepositModal({
|
|
|
5381
5661
|
DepositHeader,
|
|
5382
5662
|
{
|
|
5383
5663
|
title: modalTitle || "Deposit",
|
|
5384
|
-
onClose: handleClose
|
|
5664
|
+
onClose: handleClose,
|
|
5665
|
+
showBalance: showBalanceHeader,
|
|
5666
|
+
balanceAddress: recipientAddress,
|
|
5667
|
+
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
|
|
5668
|
+
balanceChainId: destinationChainId,
|
|
5669
|
+
balanceTokenAddress: destinationTokenAddress,
|
|
5670
|
+
publishableKey
|
|
5385
5671
|
}
|
|
5386
5672
|
),
|
|
5387
|
-
/* @__PURE__ */ jsx23("div", { className: "uf-pb-4 uf-space-y-3", children: isCountryLoading || !projectConfig ? /* @__PURE__ */ jsxs18(Fragment5, { children: [
|
|
5673
|
+
/* @__PURE__ */ jsx23("div", { className: "uf-pb-4 uf-space-y-3", children: isCountryLoading || isAddressValidationLoading || !projectConfig ? /* @__PURE__ */ jsxs18(Fragment5, { children: [
|
|
5388
5674
|
/* @__PURE__ */ jsx23(SkeletonButton, { variant: "with-icons" }),
|
|
5389
5675
|
/* @__PURE__ */ jsx23(SkeletonButton, { variant: "with-icons" }),
|
|
5390
5676
|
!hideDepositTracker && /* @__PURE__ */ jsx23(SkeletonButton, {})
|
|
@@ -5402,6 +5688,16 @@ function DepositModal({
|
|
|
5402
5688
|
/* @__PURE__ */ jsx23("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "No Tokens Available" }),
|
|
5403
5689
|
/* @__PURE__ */ jsx23("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: "There are no supported tokens available from your current location." })
|
|
5404
5690
|
] })
|
|
5691
|
+
) : isAddressValid === false ? (
|
|
5692
|
+
/* Invalid recipient address state (e.g., Algorand not opted in) */
|
|
5693
|
+
/* @__PURE__ */ jsxs18("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
5694
|
+
/* @__PURE__ */ jsx23("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__ */ jsx23(AlertTriangle, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
5695
|
+
/* @__PURE__ */ jsx23("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
|
|
5696
|
+
/* @__PURE__ */ jsx23("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: getAddressValidationErrorMessage(
|
|
5697
|
+
addressFailureCode,
|
|
5698
|
+
addressFailureMetadata
|
|
5699
|
+
) })
|
|
5700
|
+
] })
|
|
5405
5701
|
) : (
|
|
5406
5702
|
/* Normal deposit options */
|
|
5407
5703
|
/* @__PURE__ */ jsxs18(Fragment5, { children: [
|
|
@@ -5631,6 +5927,7 @@ export {
|
|
|
5631
5927
|
getColors,
|
|
5632
5928
|
mergeColors,
|
|
5633
5929
|
resolveComponentTokens,
|
|
5930
|
+
truncateAddress,
|
|
5634
5931
|
useAllowedCountry,
|
|
5635
5932
|
useTheme
|
|
5636
5933
|
};
|