@unifold/ui-react 0.1.26 → 0.1.27
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 +84 -23
- package/dist/index.d.ts +84 -23
- package/dist/index.js +628 -808
- package/dist/index.mjs +637 -815
- package/dist/styles-base.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ __export(index_exports, {
|
|
|
39
39
|
DepositExecutionItem: () => DepositExecutionItem,
|
|
40
40
|
DepositHeader: () => DepositHeader,
|
|
41
41
|
DepositModal: () => DepositModal,
|
|
42
|
+
DepositPollingUi: () => DepositPollingUi,
|
|
42
43
|
DepositSuccessToast: () => DepositSuccessToast,
|
|
43
44
|
DepositTrackerButton: () => DepositTrackerButton,
|
|
44
45
|
DepositWithCardButton: () => DepositWithCardButton,
|
|
@@ -73,17 +74,15 @@ __export(index_exports, {
|
|
|
73
74
|
TransferCryptoDoubleInput: () => TransferCryptoDoubleInput,
|
|
74
75
|
TransferCryptoSingleInput: () => TransferCryptoSingleInput,
|
|
75
76
|
buttonVariants: () => buttonVariants,
|
|
76
|
-
clearQRCodeCache: () => clearQRCodeCache,
|
|
77
77
|
cn: () => cn,
|
|
78
78
|
colors: () => colors,
|
|
79
79
|
defaultColors: () => defaultColors,
|
|
80
80
|
getColors: () => getColors,
|
|
81
|
-
isQRCodeCached: () => isQRCodeCached,
|
|
82
81
|
mergeColors: () => mergeColors,
|
|
83
|
-
preloadQRCode: () => preloadQRCode,
|
|
84
82
|
resolveComponentTokens: () => resolveComponentTokens,
|
|
85
83
|
truncateAddress: () => truncateAddress,
|
|
86
84
|
useAllowedCountry: () => useAllowedCountry,
|
|
85
|
+
useDepositPolling: () => useDepositPolling,
|
|
87
86
|
useTheme: () => useTheme
|
|
88
87
|
});
|
|
89
88
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -104,6 +103,26 @@ function cn(...inputs) {
|
|
|
104
103
|
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
105
104
|
}
|
|
106
105
|
var WALLET_CHAIN_TYPE_STORAGE_KEY = "unifold_last_wallet_type";
|
|
106
|
+
var WALLET_USER_DISCONNECTED_KEY = "unifold_wallet_user_disconnected";
|
|
107
|
+
function getUserDisconnectedWallet() {
|
|
108
|
+
if (typeof window === "undefined") return false;
|
|
109
|
+
try {
|
|
110
|
+
return localStorage.getItem(WALLET_USER_DISCONNECTED_KEY) === "true";
|
|
111
|
+
} catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function setUserDisconnectedWallet(disconnected) {
|
|
116
|
+
if (typeof window === "undefined") return;
|
|
117
|
+
try {
|
|
118
|
+
if (disconnected) {
|
|
119
|
+
localStorage.setItem(WALLET_USER_DISCONNECTED_KEY, "true");
|
|
120
|
+
} else {
|
|
121
|
+
localStorage.removeItem(WALLET_USER_DISCONNECTED_KEY);
|
|
122
|
+
}
|
|
123
|
+
} catch {
|
|
124
|
+
}
|
|
125
|
+
}
|
|
107
126
|
function getStoredWalletChainType() {
|
|
108
127
|
if (typeof window === "undefined") return void 0;
|
|
109
128
|
try {
|
|
@@ -616,7 +635,7 @@ DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
|
616
635
|
// src/components/deposits/BuyWithCard.tsx
|
|
617
636
|
var import_react7 = require("react");
|
|
618
637
|
var import_lucide_react6 = require("lucide-react");
|
|
619
|
-
var
|
|
638
|
+
var import_core9 = require("@unifold/core");
|
|
620
639
|
|
|
621
640
|
// src/hooks/use-deposit-address.ts
|
|
622
641
|
var import_react_query = require("@tanstack/react-query");
|
|
@@ -671,10 +690,126 @@ var import_react2 = require("react");
|
|
|
671
690
|
// src/components/deposits/DepositHeader.tsx
|
|
672
691
|
var import_lucide_react2 = require("lucide-react");
|
|
673
692
|
var import_react = require("react");
|
|
693
|
+
var import_core3 = require("@unifold/core");
|
|
694
|
+
|
|
695
|
+
// src/components/deposits/browser-wallets/utils.ts
|
|
674
696
|
var import_core2 = require("@unifold/core");
|
|
697
|
+
function getIconUrl(iconUrl, assetCdnUrl) {
|
|
698
|
+
if (!iconUrl) return void 0;
|
|
699
|
+
if (iconUrl.startsWith("http://") || iconUrl.startsWith("https://")) {
|
|
700
|
+
return iconUrl;
|
|
701
|
+
}
|
|
702
|
+
if (assetCdnUrl) {
|
|
703
|
+
return `${assetCdnUrl}${iconUrl.startsWith("/") ? "" : "/"}${iconUrl}`;
|
|
704
|
+
}
|
|
705
|
+
return iconUrl;
|
|
706
|
+
}
|
|
707
|
+
function getTokenFromBalance(balance) {
|
|
708
|
+
if (balance.token) {
|
|
709
|
+
return balance.token;
|
|
710
|
+
}
|
|
711
|
+
const legacyBalance = balance;
|
|
712
|
+
if (legacyBalance.symbol && legacyBalance.decimals !== void 0) {
|
|
713
|
+
return {
|
|
714
|
+
symbol: legacyBalance.symbol,
|
|
715
|
+
name: legacyBalance.name,
|
|
716
|
+
icon_url: legacyBalance.icon_url,
|
|
717
|
+
icon_urls: [],
|
|
718
|
+
token_address: legacyBalance.token_address,
|
|
719
|
+
chain_id: legacyBalance.chain_id,
|
|
720
|
+
chain_name: legacyBalance.chain_name,
|
|
721
|
+
chain_type: legacyBalance.chain_type,
|
|
722
|
+
decimals: legacyBalance.decimals,
|
|
723
|
+
chain_icon_url: legacyBalance.chain_icon_url,
|
|
724
|
+
chain_icon_urls: [],
|
|
725
|
+
minimum_deposit_amount_usd: 0
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
return null;
|
|
729
|
+
}
|
|
730
|
+
function isBalanceEligible(balance) {
|
|
731
|
+
if (balance.is_eligible !== void 0) {
|
|
732
|
+
return balance.is_eligible;
|
|
733
|
+
}
|
|
734
|
+
const legacyBalance = balance;
|
|
735
|
+
if (legacyBalance.is_eligible !== void 0) {
|
|
736
|
+
return legacyBalance.is_eligible;
|
|
737
|
+
}
|
|
738
|
+
return true;
|
|
739
|
+
}
|
|
740
|
+
function getIneligibilityMessage(balance) {
|
|
741
|
+
if (isBalanceEligible(balance)) {
|
|
742
|
+
return null;
|
|
743
|
+
}
|
|
744
|
+
switch (balance.ineligibility_reason) {
|
|
745
|
+
case import_core2.IneligibilityReason.MINIMUM_NOT_MET:
|
|
746
|
+
return "Low balance";
|
|
747
|
+
case import_core2.IneligibilityReason.NOT_SUPPORTED_DEPOSIT_FROM:
|
|
748
|
+
return "Not supported";
|
|
749
|
+
default:
|
|
750
|
+
return "Not eligible";
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
function formatTokenAmount(amount, decimals, symbol) {
|
|
754
|
+
const value = Number(amount) / 10 ** decimals;
|
|
755
|
+
const upperSymbol = symbol.toUpperCase();
|
|
756
|
+
let maxDecimals = 4;
|
|
757
|
+
if (upperSymbol === "BTC" || upperSymbol === "WBTC") {
|
|
758
|
+
maxDecimals = 8;
|
|
759
|
+
} else if (upperSymbol === "ETH" || upperSymbol === "WETH" || upperSymbol === "SOL") {
|
|
760
|
+
maxDecimals = 6;
|
|
761
|
+
}
|
|
762
|
+
if (value >= 1) {
|
|
763
|
+
return value.toLocaleString(void 0, {
|
|
764
|
+
minimumFractionDigits: 2,
|
|
765
|
+
maximumFractionDigits: maxDecimals
|
|
766
|
+
});
|
|
767
|
+
} else if (value > 0) {
|
|
768
|
+
return value.toLocaleString(void 0, {
|
|
769
|
+
minimumFractionDigits: 2,
|
|
770
|
+
maximumFractionDigits: maxDecimals,
|
|
771
|
+
minimumSignificantDigits: 2,
|
|
772
|
+
maximumSignificantDigits: 6
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
return "0.00";
|
|
776
|
+
}
|
|
777
|
+
function formatUsdAmount(amountUsd) {
|
|
778
|
+
if (!amountUsd) return null;
|
|
779
|
+
const value = parseFloat(amountUsd);
|
|
780
|
+
if (value <= 0) return null;
|
|
781
|
+
return value.toLocaleString(void 0, {
|
|
782
|
+
minimumFractionDigits: 2,
|
|
783
|
+
maximumFractionDigits: 2
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
function truncateAddress2(address) {
|
|
787
|
+
if (address.length <= 13) return address;
|
|
788
|
+
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
789
|
+
}
|
|
790
|
+
function formatBalanceDisplay(balance, projectName) {
|
|
791
|
+
return projectName ? `${projectName} Balance: ${balance}` : `Balance: ${balance}`;
|
|
792
|
+
}
|
|
793
|
+
function formatProcessingTime(seconds) {
|
|
794
|
+
if (seconds === null || seconds === 0) {
|
|
795
|
+
return "< 1 min";
|
|
796
|
+
}
|
|
797
|
+
const minutes = Math.floor(seconds / 60);
|
|
798
|
+
const remainingSeconds = seconds % 60;
|
|
799
|
+
if (minutes === 0) {
|
|
800
|
+
return `< ${remainingSeconds} sec`;
|
|
801
|
+
} else if (remainingSeconds === 0) {
|
|
802
|
+
return `< ${minutes} min`;
|
|
803
|
+
} else {
|
|
804
|
+
return `< ${minutes} min ${remainingSeconds} sec`;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// src/components/deposits/DepositHeader.tsx
|
|
675
809
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
676
810
|
function DepositHeader({
|
|
677
811
|
title,
|
|
812
|
+
subtitle,
|
|
678
813
|
showBack = false,
|
|
679
814
|
showClose = true,
|
|
680
815
|
onBack,
|
|
@@ -685,20 +820,42 @@ function DepositHeader({
|
|
|
685
820
|
balanceChainType,
|
|
686
821
|
balanceChainId,
|
|
687
822
|
balanceTokenAddress,
|
|
823
|
+
projectName,
|
|
688
824
|
publishableKey
|
|
689
825
|
}) {
|
|
690
826
|
const { colors: colors2, fonts, components } = useTheme();
|
|
691
827
|
const [balance, setBalance] = (0, import_react.useState)(null);
|
|
692
828
|
const [isLoadingBalance, setIsLoadingBalance] = (0, import_react.useState)(false);
|
|
829
|
+
const [showBalanceSkeleton, setShowBalanceSkeleton] = (0, import_react.useState)(false);
|
|
830
|
+
const showBalanceBlock = showBalance === true;
|
|
831
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
832
|
+
if (!showBalanceBlock) {
|
|
833
|
+
setBalance(null);
|
|
834
|
+
setIsLoadingBalance(false);
|
|
835
|
+
setShowBalanceSkeleton(false);
|
|
836
|
+
}
|
|
837
|
+
}, [showBalanceBlock]);
|
|
693
838
|
(0, import_react.useEffect)(() => {
|
|
694
839
|
if (!showBalance || !balanceAddress || !balanceChainType || !balanceChainId || !balanceTokenAddress || !publishableKey) {
|
|
695
840
|
setBalance(null);
|
|
696
841
|
setIsLoadingBalance(false);
|
|
842
|
+
setShowBalanceSkeleton(false);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
const supportedChainTypes = ["ethereum", "solana", "bitcoin"];
|
|
846
|
+
if (!supportedChainTypes.includes(balanceChainType)) {
|
|
847
|
+
setBalance(null);
|
|
848
|
+
setIsLoadingBalance(false);
|
|
849
|
+
setShowBalanceSkeleton(false);
|
|
697
850
|
return;
|
|
698
851
|
}
|
|
699
852
|
let cancelled = false;
|
|
700
853
|
setIsLoadingBalance(true);
|
|
701
|
-
(
|
|
854
|
+
setShowBalanceSkeleton(false);
|
|
855
|
+
const skeletonTimer = window.setTimeout(() => {
|
|
856
|
+
if (!cancelled) setShowBalanceSkeleton(true);
|
|
857
|
+
}, 150);
|
|
858
|
+
(0, import_core3.getAddressBalance)(
|
|
702
859
|
balanceAddress,
|
|
703
860
|
balanceChainType,
|
|
704
861
|
balanceChainId,
|
|
@@ -706,7 +863,7 @@ function DepositHeader({
|
|
|
706
863
|
publishableKey
|
|
707
864
|
).then((response) => {
|
|
708
865
|
if (cancelled) return;
|
|
709
|
-
if (response.balance
|
|
866
|
+
if (response.balance) {
|
|
710
867
|
const token = response.balance.token;
|
|
711
868
|
if (!token) {
|
|
712
869
|
setBalance(null);
|
|
@@ -734,12 +891,12 @@ function DepositHeader({
|
|
|
734
891
|
maximumSignificantDigits: 6
|
|
735
892
|
});
|
|
736
893
|
} else {
|
|
737
|
-
formatted = value.toExponential(2);
|
|
894
|
+
formatted = value === 0 ? "0.00" : value.toExponential(2);
|
|
738
895
|
}
|
|
739
|
-
const
|
|
740
|
-
setBalance(
|
|
896
|
+
const amountPart = response.balance.amount_usd != null && response.balance.amount_usd !== "" ? `$${response.balance.amount_usd} (${formatted} ${response.balance.token.symbol})` : `${formatted} ${response.balance.token.symbol}`;
|
|
897
|
+
setBalance(amountPart);
|
|
741
898
|
} else {
|
|
742
|
-
setBalance(
|
|
899
|
+
setBalance("$0.00");
|
|
743
900
|
}
|
|
744
901
|
}).catch((error) => {
|
|
745
902
|
if (cancelled) return;
|
|
@@ -748,9 +905,11 @@ function DepositHeader({
|
|
|
748
905
|
}).finally(() => {
|
|
749
906
|
if (cancelled) return;
|
|
750
907
|
setIsLoadingBalance(false);
|
|
908
|
+
setShowBalanceSkeleton(false);
|
|
751
909
|
});
|
|
752
910
|
return () => {
|
|
753
911
|
cancelled = true;
|
|
912
|
+
window.clearTimeout(skeletonTimer);
|
|
754
913
|
};
|
|
755
914
|
}, [
|
|
756
915
|
showBalance,
|
|
@@ -806,18 +965,27 @@ function DepositHeader({
|
|
|
806
965
|
children: title
|
|
807
966
|
}
|
|
808
967
|
),
|
|
809
|
-
|
|
968
|
+
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
810
969
|
"div",
|
|
811
970
|
{
|
|
812
|
-
className: "uf-text-xs uf-mt-
|
|
971
|
+
className: "uf-text-xs uf-mt-1",
|
|
813
972
|
style: {
|
|
814
|
-
color: colors2.
|
|
815
|
-
fontFamily: fonts.regular
|
|
816
|
-
|
|
973
|
+
color: colors2.foregroundMuted,
|
|
974
|
+
fontFamily: fonts.regular
|
|
975
|
+
},
|
|
976
|
+
children: subtitle
|
|
977
|
+
}
|
|
978
|
+
) : showBalanceBlock ? isLoadingBalance && showBalanceSkeleton ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-1" }) : balance ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
979
|
+
"div",
|
|
980
|
+
{
|
|
981
|
+
className: "uf-text-xs uf-mt-1",
|
|
982
|
+
style: {
|
|
983
|
+
color: colors2.foregroundMuted,
|
|
984
|
+
fontFamily: fonts.regular
|
|
817
985
|
},
|
|
818
|
-
children: balance
|
|
986
|
+
children: formatBalanceDisplay(balance, projectName)
|
|
819
987
|
}
|
|
820
|
-
) : null
|
|
988
|
+
) : null : null
|
|
821
989
|
] }),
|
|
822
990
|
showClose ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
823
991
|
"button",
|
|
@@ -834,7 +1002,7 @@ function DepositHeader({
|
|
|
834
1002
|
// src/components/currency/CurrencyListItem.tsx
|
|
835
1003
|
var React3 = __toESM(require("react"));
|
|
836
1004
|
var import_lucide_react3 = require("lucide-react");
|
|
837
|
-
var
|
|
1005
|
+
var import_core4 = require("@unifold/core");
|
|
838
1006
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
839
1007
|
function CurrencyListItem({
|
|
840
1008
|
currency,
|
|
@@ -843,7 +1011,7 @@ function CurrencyListItem({
|
|
|
843
1011
|
}) {
|
|
844
1012
|
const { colors: colors2, fonts, components } = useTheme();
|
|
845
1013
|
const [isHovered, setIsHovered] = React3.useState(false);
|
|
846
|
-
const iconUrl = (0,
|
|
1014
|
+
const iconUrl = (0, import_core4.getPreferredIconUrl)(currency.icon_urls, "png") || currency.icon_url;
|
|
847
1015
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
848
1016
|
"button",
|
|
849
1017
|
{
|
|
@@ -1047,7 +1215,7 @@ function CurrencyModal({
|
|
|
1047
1215
|
|
|
1048
1216
|
// src/hooks/use-user-ip.ts
|
|
1049
1217
|
var import_react_query2 = require("@tanstack/react-query");
|
|
1050
|
-
var
|
|
1218
|
+
var import_core5 = require("@unifold/core");
|
|
1051
1219
|
function useUserIp() {
|
|
1052
1220
|
const {
|
|
1053
1221
|
data: userIpInfo,
|
|
@@ -1056,7 +1224,7 @@ function useUserIp() {
|
|
|
1056
1224
|
} = (0, import_react_query2.useQuery)({
|
|
1057
1225
|
queryKey: ["unifold", "userIpInfo"],
|
|
1058
1226
|
queryFn: async () => {
|
|
1059
|
-
const data = await (0,
|
|
1227
|
+
const data = await (0, import_core5.getIpAddress)();
|
|
1060
1228
|
return {
|
|
1061
1229
|
alpha2: data.alpha2.toLowerCase(),
|
|
1062
1230
|
alpha3: data.alpha3?.toLowerCase(),
|
|
@@ -1176,45 +1344,75 @@ function interpolate(template, params) {
|
|
|
1176
1344
|
|
|
1177
1345
|
// src/hooks/use-deposit-polling.ts
|
|
1178
1346
|
var import_react3 = require("react");
|
|
1179
|
-
var
|
|
1347
|
+
var import_core6 = require("@unifold/core");
|
|
1348
|
+
var DEPOSIT_CONFIRM_DELAY_MS = 1e4;
|
|
1349
|
+
var POLL_INTERVAL_MS = 2500;
|
|
1350
|
+
var POLL_ENDPOINT_INTERVAL_MS = 3e3;
|
|
1351
|
+
var CUTOFF_BUFFER_MS = 6e4;
|
|
1180
1352
|
function useDepositPolling({
|
|
1181
1353
|
userId,
|
|
1182
1354
|
publishableKey,
|
|
1355
|
+
depositConfirmationMode = "auto_ui",
|
|
1356
|
+
depositWalletId,
|
|
1183
1357
|
enabled = true,
|
|
1184
1358
|
onDepositSuccess,
|
|
1185
1359
|
onDepositError
|
|
1186
1360
|
}) {
|
|
1187
1361
|
const [executions, setExecutions] = (0, import_react3.useState)([]);
|
|
1188
1362
|
const [isPolling, setIsPolling] = (0, import_react3.useState)(false);
|
|
1189
|
-
const
|
|
1190
|
-
|
|
1191
|
-
);
|
|
1192
|
-
const
|
|
1193
|
-
const
|
|
1363
|
+
const [pollingEnabled, setPollingEnabled] = (0, import_react3.useState)(false);
|
|
1364
|
+
const [showWaitingUi, setShowWaitingUi] = (0, import_react3.useState)(false);
|
|
1365
|
+
const modalOpenedAtRef = (0, import_react3.useRef)(/* @__PURE__ */ new Date());
|
|
1366
|
+
const trackedExecutionsRef = (0, import_react3.useRef)(/* @__PURE__ */ new Map());
|
|
1367
|
+
const onDepositSuccessRef = (0, import_react3.useRef)(onDepositSuccess);
|
|
1368
|
+
const onDepositErrorRef = (0, import_react3.useRef)(onDepositError);
|
|
1194
1369
|
(0, import_react3.useEffect)(() => {
|
|
1195
|
-
|
|
1196
|
-
|
|
1370
|
+
onDepositSuccessRef.current = onDepositSuccess;
|
|
1371
|
+
}, [onDepositSuccess]);
|
|
1372
|
+
(0, import_react3.useEffect)(() => {
|
|
1373
|
+
onDepositErrorRef.current = onDepositError;
|
|
1374
|
+
}, [onDepositError]);
|
|
1375
|
+
(0, import_react3.useEffect)(() => {
|
|
1376
|
+
if (depositConfirmationMode === "manual" || !enabled) return;
|
|
1377
|
+
const timeout = setTimeout(() => {
|
|
1378
|
+
setPollingEnabled(true);
|
|
1379
|
+
if (depositConfirmationMode === "auto_ui") {
|
|
1380
|
+
setShowWaitingUi(true);
|
|
1381
|
+
}
|
|
1382
|
+
}, DEPOSIT_CONFIRM_DELAY_MS);
|
|
1383
|
+
return () => clearTimeout(timeout);
|
|
1384
|
+
}, [depositConfirmationMode, enabled]);
|
|
1385
|
+
(0, import_react3.useEffect)(() => {
|
|
1386
|
+
if (!userId || !enabled) return;
|
|
1387
|
+
const modalOpenedAt = modalOpenedAtRef.current;
|
|
1388
|
+
const poll = async () => {
|
|
1197
1389
|
try {
|
|
1198
|
-
const response = await (0,
|
|
1390
|
+
const response = await (0, import_core6.queryExecutions)(userId, publishableKey);
|
|
1391
|
+
const cutoff = new Date(modalOpenedAt.getTime() - CUTOFF_BUFFER_MS);
|
|
1392
|
+
const sortedExecutions = [...response.data].sort((a, b) => {
|
|
1393
|
+
const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
|
|
1394
|
+
const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
|
|
1395
|
+
return timeB - timeA;
|
|
1396
|
+
});
|
|
1199
1397
|
let executionToShow = null;
|
|
1200
|
-
for (const execution of
|
|
1398
|
+
for (const execution of sortedExecutions) {
|
|
1201
1399
|
const executionTime = execution.created_at ? new Date(execution.created_at) : null;
|
|
1202
|
-
if (!executionTime || executionTime
|
|
1400
|
+
if (!executionTime || executionTime < cutoff) {
|
|
1203
1401
|
continue;
|
|
1204
1402
|
}
|
|
1205
|
-
const trackedStatus =
|
|
1403
|
+
const trackedStatus = trackedExecutionsRef.current.get(execution.id);
|
|
1206
1404
|
if (!trackedStatus) {
|
|
1207
1405
|
executionToShow = execution;
|
|
1208
1406
|
break;
|
|
1209
1407
|
}
|
|
1210
1408
|
const inProgressStatuses = [
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1409
|
+
import_core6.ExecutionStatus.PENDING,
|
|
1410
|
+
import_core6.ExecutionStatus.WAITING,
|
|
1411
|
+
import_core6.ExecutionStatus.DELAYED
|
|
1214
1412
|
];
|
|
1215
1413
|
const terminalStatuses = [
|
|
1216
|
-
|
|
1217
|
-
|
|
1414
|
+
import_core6.ExecutionStatus.SUCCEEDED,
|
|
1415
|
+
import_core6.ExecutionStatus.FAILED
|
|
1218
1416
|
];
|
|
1219
1417
|
if (inProgressStatuses.includes(trackedStatus) && terminalStatuses.includes(execution.status)) {
|
|
1220
1418
|
executionToShow = execution;
|
|
@@ -1223,35 +1421,30 @@ function useDepositPolling({
|
|
|
1223
1421
|
}
|
|
1224
1422
|
if (executionToShow) {
|
|
1225
1423
|
const execution = executionToShow;
|
|
1424
|
+
const previousStatus = trackedExecutionsRef.current.get(execution.id);
|
|
1425
|
+
trackedExecutionsRef.current.set(execution.id, execution.status);
|
|
1226
1426
|
setExecutions((prev) => {
|
|
1227
1427
|
const existingIndex = prev.findIndex((e) => e.id === execution.id);
|
|
1228
1428
|
if (existingIndex >= 0) {
|
|
1229
1429
|
const updated = [...prev];
|
|
1230
1430
|
updated[existingIndex] = execution;
|
|
1231
1431
|
return updated;
|
|
1232
|
-
} else {
|
|
1233
|
-
return [...prev, execution];
|
|
1234
1432
|
}
|
|
1235
|
-
|
|
1236
|
-
const previousStatus = trackedExecutions.get(execution.id);
|
|
1237
|
-
setTrackedExecutions((prev) => {
|
|
1238
|
-
const updated = new Map(prev);
|
|
1239
|
-
updated.set(execution.id, execution.status);
|
|
1240
|
-
return updated;
|
|
1433
|
+
return [...prev, execution];
|
|
1241
1434
|
});
|
|
1242
1435
|
const inProgressStatuses = [
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1436
|
+
import_core6.ExecutionStatus.PENDING,
|
|
1437
|
+
import_core6.ExecutionStatus.WAITING,
|
|
1438
|
+
import_core6.ExecutionStatus.DELAYED
|
|
1246
1439
|
];
|
|
1247
|
-
if (execution.status ===
|
|
1248
|
-
|
|
1440
|
+
if (execution.status === import_core6.ExecutionStatus.SUCCEEDED && (!previousStatus || inProgressStatuses.includes(previousStatus))) {
|
|
1441
|
+
onDepositSuccessRef.current?.({
|
|
1249
1442
|
message: "Deposit completed successfully",
|
|
1250
1443
|
executionId: execution.id,
|
|
1251
1444
|
transaction: execution
|
|
1252
1445
|
});
|
|
1253
|
-
} else if (execution.status ===
|
|
1254
|
-
|
|
1446
|
+
} else if (execution.status === import_core6.ExecutionStatus.FAILED && previousStatus !== import_core6.ExecutionStatus.FAILED) {
|
|
1447
|
+
onDepositErrorRef.current?.({
|
|
1255
1448
|
message: "Deposit failed",
|
|
1256
1449
|
code: "DEPOSIT_FAILED",
|
|
1257
1450
|
error: execution
|
|
@@ -1260,36 +1453,45 @@ function useDepositPolling({
|
|
|
1260
1453
|
}
|
|
1261
1454
|
} catch (error) {
|
|
1262
1455
|
console.error("Failed to fetch executions:", error);
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
});
|
|
1269
|
-
}
|
|
1456
|
+
onDepositErrorRef.current?.({
|
|
1457
|
+
message: "Failed to fetch deposit status",
|
|
1458
|
+
code: "POLLING_ERROR",
|
|
1459
|
+
error
|
|
1460
|
+
});
|
|
1270
1461
|
}
|
|
1271
|
-
}
|
|
1462
|
+
};
|
|
1463
|
+
const pollInterval = setInterval(poll, POLL_INTERVAL_MS);
|
|
1272
1464
|
setIsPolling(true);
|
|
1273
|
-
pollingIntervalRef.current = pollInterval;
|
|
1274
1465
|
return () => {
|
|
1275
|
-
|
|
1276
|
-
clearInterval(pollingIntervalRef.current);
|
|
1277
|
-
pollingIntervalRef.current = null;
|
|
1278
|
-
}
|
|
1466
|
+
clearInterval(pollInterval);
|
|
1279
1467
|
setIsPolling(false);
|
|
1280
1468
|
};
|
|
1281
|
-
}, [
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1469
|
+
}, [userId, publishableKey, enabled]);
|
|
1470
|
+
(0, import_react3.useEffect)(() => {
|
|
1471
|
+
if (!pollingEnabled || !depositWalletId) return;
|
|
1472
|
+
const triggerPoll = async () => {
|
|
1473
|
+
try {
|
|
1474
|
+
await (0, import_core6.pollDirectExecutions)(
|
|
1475
|
+
{ deposit_wallet_id: depositWalletId },
|
|
1476
|
+
publishableKey
|
|
1477
|
+
);
|
|
1478
|
+
} catch {
|
|
1479
|
+
}
|
|
1480
|
+
};
|
|
1481
|
+
triggerPoll();
|
|
1482
|
+
const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
|
|
1483
|
+
return () => clearInterval(interval);
|
|
1484
|
+
}, [pollingEnabled, depositWalletId, publishableKey]);
|
|
1485
|
+
const handleIveDeposited = () => {
|
|
1486
|
+
setPollingEnabled(true);
|
|
1487
|
+
setShowWaitingUi(true);
|
|
1488
|
+
};
|
|
1290
1489
|
return {
|
|
1291
1490
|
executions,
|
|
1292
|
-
isPolling
|
|
1491
|
+
isPolling,
|
|
1492
|
+
pollingEnabled,
|
|
1493
|
+
showWaitingUi,
|
|
1494
|
+
handleIveDeposited
|
|
1293
1495
|
};
|
|
1294
1496
|
}
|
|
1295
1497
|
|
|
@@ -1299,12 +1501,12 @@ var import_react6 = require("react");
|
|
|
1299
1501
|
// src/components/deposits/DepositSuccessToast.tsx
|
|
1300
1502
|
var import_react5 = require("react");
|
|
1301
1503
|
var import_lucide_react5 = require("lucide-react");
|
|
1302
|
-
var
|
|
1504
|
+
var import_core8 = require("@unifold/core");
|
|
1303
1505
|
|
|
1304
1506
|
// src/components/deposits/DepositDetailContent.tsx
|
|
1305
1507
|
var import_react4 = require("react");
|
|
1306
1508
|
var import_lucide_react4 = require("lucide-react");
|
|
1307
|
-
var
|
|
1509
|
+
var import_core7 = require("@unifold/core");
|
|
1308
1510
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1309
1511
|
function formatCurrency(currency) {
|
|
1310
1512
|
if (!currency) return "";
|
|
@@ -1319,12 +1521,12 @@ function DepositDetailContent({ execution }) {
|
|
|
1319
1521
|
const [chains, setChains] = (0, import_react4.useState)([]);
|
|
1320
1522
|
const [showNetworkDetails, setShowNetworkDetails] = (0, import_react4.useState)(false);
|
|
1321
1523
|
(0, import_react4.useEffect)(() => {
|
|
1322
|
-
(0,
|
|
1524
|
+
(0, import_core7.getTokenChains)().then((response) => setChains(response.data)).catch((err) => console.error("Failed to fetch chains:", err));
|
|
1323
1525
|
}, []);
|
|
1324
1526
|
(0, import_react4.useEffect)(() => {
|
|
1325
1527
|
setShowNetworkDetails(false);
|
|
1326
1528
|
}, [execution?.id]);
|
|
1327
|
-
const isPending = execution.status ===
|
|
1529
|
+
const isPending = execution.status === import_core7.ExecutionStatus.PENDING || execution.status === import_core7.ExecutionStatus.WAITING || execution.status === import_core7.ExecutionStatus.DELAYED;
|
|
1328
1530
|
const formatDateTime = (timestamp) => {
|
|
1329
1531
|
try {
|
|
1330
1532
|
const date = new Date(timestamp);
|
|
@@ -1394,7 +1596,7 @@ function DepositDetailContent({ execution }) {
|
|
|
1394
1596
|
return "$0.00";
|
|
1395
1597
|
};
|
|
1396
1598
|
const getNetworkName = (chainType, chainId) => {
|
|
1397
|
-
return (0,
|
|
1599
|
+
return (0, import_core7.getChainName)(chains, chainType, chainId);
|
|
1398
1600
|
};
|
|
1399
1601
|
const formatTransactionHash = (hash) => {
|
|
1400
1602
|
if (!hash || hash.length < 12) return hash;
|
|
@@ -1406,7 +1608,7 @@ function DepositDetailContent({ execution }) {
|
|
|
1406
1608
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1407
1609
|
"img",
|
|
1408
1610
|
{
|
|
1409
|
-
src: execution.destination_token_metadata?.icon_url || (0,
|
|
1611
|
+
src: execution.destination_token_metadata?.icon_url || (0, import_core7.getIconUrl)("/icons/tokens/svg/usdc.svg"),
|
|
1410
1612
|
alt: "Token",
|
|
1411
1613
|
width: 64,
|
|
1412
1614
|
height: 64,
|
|
@@ -1835,7 +2037,7 @@ function DepositSuccessToast({
|
|
|
1835
2037
|
}) {
|
|
1836
2038
|
const [detailModalOpen, setDetailModalOpen] = (0, import_react5.useState)(false);
|
|
1837
2039
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
1838
|
-
const isPending = status ===
|
|
2040
|
+
const isPending = status === import_core8.ExecutionStatus.PENDING || status === import_core8.ExecutionStatus.WAITING || status === import_core8.ExecutionStatus.DELAYED;
|
|
1839
2041
|
const formatDateTime = (timestamp) => {
|
|
1840
2042
|
try {
|
|
1841
2043
|
const date = new Date(timestamp);
|
|
@@ -1913,7 +2115,7 @@ function DepositSuccessToast({
|
|
|
1913
2115
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1914
2116
|
"img",
|
|
1915
2117
|
{
|
|
1916
|
-
src: tokenIconUrl || (0,
|
|
2118
|
+
src: tokenIconUrl || (0, import_core8.getIconUrl)("/icons/tokens/svg/usdc.svg"),
|
|
1917
2119
|
alt: "Token",
|
|
1918
2120
|
width: 36,
|
|
1919
2121
|
height: 36,
|
|
@@ -2204,7 +2406,7 @@ function BuyWithCard({
|
|
|
2204
2406
|
(0, import_react7.useEffect)(() => {
|
|
2205
2407
|
async function fetchFiatCurrencies() {
|
|
2206
2408
|
try {
|
|
2207
|
-
const response = await (0,
|
|
2409
|
+
const response = await (0, import_core9.getFiatCurrencies)(publishableKey);
|
|
2208
2410
|
setFiatCurrencies(response.data);
|
|
2209
2411
|
setPreferredCurrencyCodes(response.preferred || []);
|
|
2210
2412
|
} catch (err) {
|
|
@@ -2258,7 +2460,7 @@ function BuyWithCard({
|
|
|
2258
2460
|
(0, import_react7.useEffect)(() => {
|
|
2259
2461
|
async function fetchDestinationToken() {
|
|
2260
2462
|
try {
|
|
2261
|
-
const response = await (0,
|
|
2463
|
+
const response = await (0, import_core9.getTokenMetadata)(
|
|
2262
2464
|
{
|
|
2263
2465
|
chain_type: destinationChainType || "",
|
|
2264
2466
|
chain_id: destinationChainId || "",
|
|
@@ -2283,7 +2485,7 @@ function BuyWithCard({
|
|
|
2283
2485
|
}
|
|
2284
2486
|
setDefaultTokenLoading(true);
|
|
2285
2487
|
try {
|
|
2286
|
-
const response = await (0,
|
|
2488
|
+
const response = await (0, import_core9.getDefaultOnrampToken)(
|
|
2287
2489
|
{
|
|
2288
2490
|
country_code: userIpInfo?.alpha2?.toUpperCase() || "US",
|
|
2289
2491
|
subdivision_code: userIpInfo?.state || void 0,
|
|
@@ -2371,7 +2573,7 @@ function BuyWithCard({
|
|
|
2371
2573
|
destination_network: defaultToken.destination_network,
|
|
2372
2574
|
subdivision_code: userIpInfo?.state || void 0
|
|
2373
2575
|
};
|
|
2374
|
-
const response = await (0,
|
|
2576
|
+
const response = await (0, import_core9.getOnrampQuotes)(request, publishableKey);
|
|
2375
2577
|
setQuotes(response.data);
|
|
2376
2578
|
const currentHasManualSelection = hasManualSelectionRef.current;
|
|
2377
2579
|
const currentSelectedProvider = selectedProviderRef.current;
|
|
@@ -2455,7 +2657,7 @@ function BuyWithCard({
|
|
|
2455
2657
|
const handleContinue = () => {
|
|
2456
2658
|
if (!selectedProvider) return;
|
|
2457
2659
|
if (!defaultToken) return;
|
|
2458
|
-
const wallet = (0,
|
|
2660
|
+
const wallet = (0, import_core9.getWalletByChainType)(
|
|
2459
2661
|
wallets,
|
|
2460
2662
|
defaultToken.destination_token_metadata.chain_type
|
|
2461
2663
|
);
|
|
@@ -2473,7 +2675,7 @@ function BuyWithCard({
|
|
|
2473
2675
|
wallet_address: wallet.address,
|
|
2474
2676
|
subdivision_code: userIpInfo?.state || void 0
|
|
2475
2677
|
};
|
|
2476
|
-
const sessionStartUrl = (0,
|
|
2678
|
+
const sessionStartUrl = (0, import_core9.getOnrampSessionStartUrl)(
|
|
2477
2679
|
sessionRequest,
|
|
2478
2680
|
publishableKey
|
|
2479
2681
|
);
|
|
@@ -2523,7 +2725,7 @@ function BuyWithCard({
|
|
|
2523
2725
|
selectedCurrencyData && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2524
2726
|
"img",
|
|
2525
2727
|
{
|
|
2526
|
-
src: (0,
|
|
2728
|
+
src: (0, import_core9.getPreferredIconUrl)(
|
|
2527
2729
|
selectedCurrencyData.icon_urls,
|
|
2528
2730
|
"png"
|
|
2529
2731
|
) || selectedCurrencyData.icon_url,
|
|
@@ -2885,7 +3087,7 @@ function BuyWithCard({
|
|
|
2885
3087
|
/* @__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)(
|
|
2886
3088
|
"img",
|
|
2887
3089
|
{
|
|
2888
|
-
src: (0,
|
|
3090
|
+
src: (0, import_core9.getIconUrlWithCdn)(
|
|
2889
3091
|
`/icons/currencies/png/${onrampSession.sourceCurrency.toLowerCase()}.png`,
|
|
2890
3092
|
assetCdnUrl
|
|
2891
3093
|
),
|
|
@@ -2902,7 +3104,7 @@ function BuyWithCard({
|
|
|
2902
3104
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2903
3105
|
"img",
|
|
2904
3106
|
{
|
|
2905
|
-
src: defaultToken?.destination_token_metadata?.icon_url || (0,
|
|
3107
|
+
src: defaultToken?.destination_token_metadata?.icon_url || (0, import_core9.getIconUrlWithCdn)(
|
|
2906
3108
|
"/icons/tokens/png/usdc.png",
|
|
2907
3109
|
assetCdnUrl
|
|
2908
3110
|
),
|
|
@@ -2913,7 +3115,7 @@ function BuyWithCard({
|
|
|
2913
3115
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2914
3116
|
"img",
|
|
2915
3117
|
{
|
|
2916
|
-
src: defaultToken?.destination_token_metadata?.chain.icon_url || (0,
|
|
3118
|
+
src: defaultToken?.destination_token_metadata?.chain.icon_url || (0, import_core9.getIconUrlWithCdn)(
|
|
2917
3119
|
"/icons/networks/png/polygon.png",
|
|
2918
3120
|
assetCdnUrl
|
|
2919
3121
|
),
|
|
@@ -2931,7 +3133,7 @@ function BuyWithCard({
|
|
|
2931
3133
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2932
3134
|
"img",
|
|
2933
3135
|
{
|
|
2934
|
-
src: destinationTokenIcon || (0,
|
|
3136
|
+
src: destinationTokenIcon || (0, import_core9.getIconUrlWithCdn)(
|
|
2935
3137
|
"/icons/tokens/png/usdc.png",
|
|
2936
3138
|
assetCdnUrl
|
|
2937
3139
|
),
|
|
@@ -2989,14 +3191,14 @@ var import_react8 = require("react");
|
|
|
2989
3191
|
|
|
2990
3192
|
// src/components/deposits/DepositExecutionItem.tsx
|
|
2991
3193
|
var import_lucide_react7 = require("lucide-react");
|
|
2992
|
-
var
|
|
3194
|
+
var import_core10 = require("@unifold/core");
|
|
2993
3195
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2994
3196
|
function DepositExecutionItem({
|
|
2995
3197
|
execution,
|
|
2996
3198
|
onClick
|
|
2997
3199
|
}) {
|
|
2998
3200
|
const { colors: colors2, fonts, components } = useTheme();
|
|
2999
|
-
const isPending = execution.status ===
|
|
3201
|
+
const isPending = execution.status === import_core10.ExecutionStatus.PENDING || execution.status === import_core10.ExecutionStatus.WAITING || execution.status === import_core10.ExecutionStatus.DELAYED;
|
|
3000
3202
|
const formatDateTime = (timestamp) => {
|
|
3001
3203
|
try {
|
|
3002
3204
|
const date = new Date(timestamp);
|
|
@@ -3039,7 +3241,7 @@ function DepositExecutionItem({
|
|
|
3039
3241
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3040
3242
|
"img",
|
|
3041
3243
|
{
|
|
3042
|
-
src: execution.destination_token_metadata?.icon_url || (0,
|
|
3244
|
+
src: execution.destination_token_metadata?.icon_url || (0, import_core10.getIconUrl)("/icons/tokens/svg/usdc.svg"),
|
|
3043
3245
|
alt: "Token",
|
|
3044
3246
|
width: 36,
|
|
3045
3247
|
height: 36,
|
|
@@ -3216,7 +3418,7 @@ function ThemeStyleInjector({
|
|
|
3216
3418
|
}
|
|
3217
3419
|
|
|
3218
3420
|
// src/components/deposits/DepositsModal.tsx
|
|
3219
|
-
var
|
|
3421
|
+
var import_core11 = require("@unifold/core");
|
|
3220
3422
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
3221
3423
|
function DepositsModal({
|
|
3222
3424
|
open,
|
|
@@ -3234,7 +3436,7 @@ function DepositsModal({
|
|
|
3234
3436
|
if (!open || !userId) return;
|
|
3235
3437
|
const fetchExecutions = async () => {
|
|
3236
3438
|
try {
|
|
3237
|
-
const response = await (0,
|
|
3439
|
+
const response = await (0, import_core11.queryExecutions)(userId, publishableKey);
|
|
3238
3440
|
const sorted = [...response.data].sort((a, b) => {
|
|
3239
3441
|
const timeA = a.created_at ? new Date(a.created_at).getTime() : 0;
|
|
3240
3442
|
const timeB = b.created_at ? new Date(b.created_at).getTime() : 0;
|
|
@@ -3580,7 +3782,7 @@ function DepositTrackerButton({
|
|
|
3580
3782
|
// src/components/deposits/buttons/BrowserWalletButton.tsx
|
|
3581
3783
|
var React20 = __toESM(require("react"));
|
|
3582
3784
|
var import_lucide_react11 = require("lucide-react");
|
|
3583
|
-
var
|
|
3785
|
+
var import_core12 = require("@unifold/core");
|
|
3584
3786
|
|
|
3585
3787
|
// src/resources/icons/MetamaskIcon.tsx
|
|
3586
3788
|
var React8 = __toESM(require("react"));
|
|
@@ -5150,10 +5352,48 @@ var WALLET_ICON_COMPONENTS = {
|
|
|
5150
5352
|
backpack: BackpackIcon,
|
|
5151
5353
|
glow: GlowIcon
|
|
5152
5354
|
};
|
|
5153
|
-
function
|
|
5355
|
+
function truncateAddress3(address) {
|
|
5154
5356
|
if (address.length <= 10) return address;
|
|
5155
5357
|
return `${address.slice(0, 4)}...${address.slice(-4)}`;
|
|
5156
5358
|
}
|
|
5359
|
+
function identifyEthWallet(provider, _win, hint) {
|
|
5360
|
+
switch (hint) {
|
|
5361
|
+
case "metamask":
|
|
5362
|
+
return { type: "metamask", name: "MetaMask", icon: "metamask" };
|
|
5363
|
+
case "phantom":
|
|
5364
|
+
return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
|
|
5365
|
+
case "coinbase":
|
|
5366
|
+
return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
|
|
5367
|
+
case "okx":
|
|
5368
|
+
return { type: "okx", name: "OKX Wallet", icon: "okx" };
|
|
5369
|
+
case "rabby":
|
|
5370
|
+
return { type: "rabby", name: "Rabby", icon: "rabby" };
|
|
5371
|
+
case "trust":
|
|
5372
|
+
return { type: "trust", name: "Trust Wallet", icon: "trust" };
|
|
5373
|
+
case "rainbow":
|
|
5374
|
+
return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
|
|
5375
|
+
}
|
|
5376
|
+
const anyProvider = provider;
|
|
5377
|
+
if (provider.isPhantom) {
|
|
5378
|
+
return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
|
|
5379
|
+
}
|
|
5380
|
+
if (anyProvider.isCoinbaseWallet) {
|
|
5381
|
+
return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
|
|
5382
|
+
}
|
|
5383
|
+
if (anyProvider.isRabby) {
|
|
5384
|
+
return { type: "rabby", name: "Rabby", icon: "rabby" };
|
|
5385
|
+
}
|
|
5386
|
+
if (anyProvider.isTrust) {
|
|
5387
|
+
return { type: "trust", name: "Trust Wallet", icon: "trust" };
|
|
5388
|
+
}
|
|
5389
|
+
if (anyProvider.isRainbow) {
|
|
5390
|
+
return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
|
|
5391
|
+
}
|
|
5392
|
+
if (provider.isMetaMask && !provider.isPhantom) {
|
|
5393
|
+
return { type: "metamask", name: "MetaMask", icon: "metamask" };
|
|
5394
|
+
}
|
|
5395
|
+
return { type: "metamask", name: "Wallet", icon: "metamask" };
|
|
5396
|
+
}
|
|
5157
5397
|
function BrowserWalletButton({
|
|
5158
5398
|
onClick,
|
|
5159
5399
|
onConnectClick,
|
|
@@ -5170,9 +5410,35 @@ function BrowserWalletButton({
|
|
|
5170
5410
|
const [balanceText, setBalanceText] = React20.useState(null);
|
|
5171
5411
|
const [isLoadingBalance, setIsLoadingBalance] = React20.useState(false);
|
|
5172
5412
|
const iconVariant = mode === "dark" ? "light" : "dark";
|
|
5413
|
+
const onDisconnectRef = React20.useRef(onDisconnect);
|
|
5414
|
+
onDisconnectRef.current = onDisconnect;
|
|
5173
5415
|
React20.useEffect(() => {
|
|
5174
5416
|
setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
5175
5417
|
}, []);
|
|
5418
|
+
const [eip6963ProviderCount, setEip6963ProviderCount] = React20.useState(0);
|
|
5419
|
+
React20.useEffect(() => {
|
|
5420
|
+
if (typeof window === "undefined") return;
|
|
5421
|
+
const anyWin = window;
|
|
5422
|
+
if (!anyWin.__eip6963Providers) {
|
|
5423
|
+
anyWin.__eip6963Providers = [];
|
|
5424
|
+
}
|
|
5425
|
+
const handleAnnouncement = (event) => {
|
|
5426
|
+
const { detail } = event;
|
|
5427
|
+
if (!detail?.info || !detail?.provider) return;
|
|
5428
|
+
const exists = anyWin.__eip6963Providers.some(
|
|
5429
|
+
(p) => p.info.uuid === detail.info.uuid
|
|
5430
|
+
);
|
|
5431
|
+
if (!exists) {
|
|
5432
|
+
anyWin.__eip6963Providers.push(detail);
|
|
5433
|
+
setEip6963ProviderCount(anyWin.__eip6963Providers.length);
|
|
5434
|
+
}
|
|
5435
|
+
};
|
|
5436
|
+
window.addEventListener("eip6963:announceProvider", handleAnnouncement);
|
|
5437
|
+
window.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
5438
|
+
return () => {
|
|
5439
|
+
window.removeEventListener("eip6963:announceProvider", handleAnnouncement);
|
|
5440
|
+
};
|
|
5441
|
+
}, []);
|
|
5176
5442
|
React20.useEffect(() => {
|
|
5177
5443
|
if (!wallet || !publishableKey) {
|
|
5178
5444
|
setBalanceText(null);
|
|
@@ -5181,7 +5447,7 @@ function BrowserWalletButton({
|
|
|
5181
5447
|
let cancelled = false;
|
|
5182
5448
|
const walletChainType = wallet.type === "phantom-solana" || wallet.type === "solflare" || wallet.type === "backpack" || wallet.type === "glow" ? "solana" : "ethereum";
|
|
5183
5449
|
setIsLoadingBalance(true);
|
|
5184
|
-
(0,
|
|
5450
|
+
(0, import_core12.getAddressBalances)(wallet.address, walletChainType, publishableKey).then((response) => {
|
|
5185
5451
|
if (cancelled) return;
|
|
5186
5452
|
if (response.balances && response.balances.length > 0) {
|
|
5187
5453
|
const totalUsd = response.balances.reduce((sum, balance) => {
|
|
@@ -5222,166 +5488,85 @@ function BrowserWalletButton({
|
|
|
5222
5488
|
try {
|
|
5223
5489
|
const win = typeof window !== "undefined" ? window : null;
|
|
5224
5490
|
if (!win) return;
|
|
5491
|
+
if (getUserDisconnectedWallet()) {
|
|
5492
|
+
if (mounted) {
|
|
5493
|
+
setWallet(null);
|
|
5494
|
+
setIsLoading(false);
|
|
5495
|
+
}
|
|
5496
|
+
return;
|
|
5497
|
+
}
|
|
5225
5498
|
if (!chainType || chainType === "solana") {
|
|
5226
|
-
const
|
|
5227
|
-
|
|
5228
|
-
if (
|
|
5499
|
+
const anyWin2 = win;
|
|
5500
|
+
const trySilentSolana = async (provider, type, name, icon) => {
|
|
5501
|
+
if (!provider) return false;
|
|
5502
|
+
if (provider.isConnected && provider.publicKey) {
|
|
5229
5503
|
if (mounted) {
|
|
5230
|
-
setWallet({
|
|
5231
|
-
type: "phantom-solana",
|
|
5232
|
-
name: "Phantom",
|
|
5233
|
-
address: phantomSolana.publicKey.toString(),
|
|
5234
|
-
icon: "phantom"
|
|
5235
|
-
});
|
|
5504
|
+
setWallet({ type, name, address: provider.publicKey.toString(), icon });
|
|
5236
5505
|
setIsLoading(false);
|
|
5237
5506
|
}
|
|
5238
|
-
return;
|
|
5507
|
+
return true;
|
|
5239
5508
|
}
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
icon: "solflare"
|
|
5249
|
-
});
|
|
5250
|
-
setIsLoading(false);
|
|
5509
|
+
try {
|
|
5510
|
+
const resp = await provider.connect({ onlyIfTrusted: true });
|
|
5511
|
+
if (mounted && resp.publicKey) {
|
|
5512
|
+
setWallet({ type, name, address: resp.publicKey.toString(), icon });
|
|
5513
|
+
setIsLoading(false);
|
|
5514
|
+
return true;
|
|
5515
|
+
}
|
|
5516
|
+
} catch {
|
|
5251
5517
|
}
|
|
5252
|
-
return;
|
|
5518
|
+
return false;
|
|
5519
|
+
};
|
|
5520
|
+
if (await trySilentSolana(win.phantom?.solana, "phantom-solana", "Phantom", "phantom")) return;
|
|
5521
|
+
if (await trySilentSolana(anyWin2.solflare, "solflare", "Solflare", "solflare")) return;
|
|
5522
|
+
if (await trySilentSolana(anyWin2.backpack, "backpack", "Backpack", "backpack")) return;
|
|
5523
|
+
if (await trySilentSolana(anyWin2.glow, "glow", "Glow", "glow")) return;
|
|
5524
|
+
}
|
|
5525
|
+
if (!chainType || chainType === "ethereum") {
|
|
5526
|
+
const anyWin2 = win;
|
|
5527
|
+
const allProviders = [];
|
|
5528
|
+
const eip6963Providers = anyWin2.__eip6963Providers || [];
|
|
5529
|
+
for (const { info, provider } of eip6963Providers) {
|
|
5530
|
+
let walletId = "default";
|
|
5531
|
+
if (info.rdns.includes("metamask")) walletId = "metamask";
|
|
5532
|
+
else if (info.rdns.includes("phantom")) walletId = "phantom";
|
|
5533
|
+
else if (info.rdns.includes("coinbase")) walletId = "coinbase";
|
|
5534
|
+
else if (info.rdns.includes("okx")) walletId = "okx";
|
|
5535
|
+
else if (info.rdns.includes("rabby")) walletId = "rabby";
|
|
5536
|
+
else if (info.rdns.includes("trust")) walletId = "trust";
|
|
5537
|
+
else if (info.rdns.includes("rainbow")) walletId = "rainbow";
|
|
5538
|
+
allProviders.push({ provider, walletId });
|
|
5253
5539
|
}
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
setWallet({
|
|
5258
|
-
type: "backpack",
|
|
5259
|
-
name: "Backpack",
|
|
5260
|
-
address: backpack.publicKey.toString(),
|
|
5261
|
-
icon: "backpack"
|
|
5262
|
-
});
|
|
5263
|
-
setIsLoading(false);
|
|
5540
|
+
if (allProviders.length === 0) {
|
|
5541
|
+
if (win.phantom?.ethereum) {
|
|
5542
|
+
allProviders.push({ provider: win.phantom.ethereum, walletId: "phantom" });
|
|
5264
5543
|
}
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
}
|
|
5276
|
-
setIsLoading(false);
|
|
5544
|
+
if (anyWin2.okxwallet) {
|
|
5545
|
+
allProviders.push({ provider: anyWin2.okxwallet, walletId: "okx" });
|
|
5546
|
+
}
|
|
5547
|
+
if (anyWin2.coinbaseWalletExtension) {
|
|
5548
|
+
allProviders.push({ provider: anyWin2.coinbaseWalletExtension, walletId: "coinbase" });
|
|
5549
|
+
}
|
|
5550
|
+
if (win.ethereum) {
|
|
5551
|
+
const isDuplicate = allProviders.some((p) => p.provider === win.ethereum);
|
|
5552
|
+
if (!isDuplicate) {
|
|
5553
|
+
allProviders.push({ provider: win.ethereum, walletId: "default" });
|
|
5554
|
+
}
|
|
5277
5555
|
}
|
|
5278
|
-
return;
|
|
5279
5556
|
}
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
const ethProvider2 = win.ethereum;
|
|
5283
|
-
if (ethProvider2) {
|
|
5557
|
+
for (const { provider, walletId } of allProviders) {
|
|
5558
|
+
if (!provider) continue;
|
|
5284
5559
|
try {
|
|
5285
|
-
const accounts = await
|
|
5286
|
-
if (accounts
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
setWallet({
|
|
5293
|
-
type: "okx",
|
|
5294
|
-
name: "OKX Wallet",
|
|
5295
|
-
address,
|
|
5296
|
-
icon: "okx"
|
|
5297
|
-
});
|
|
5298
|
-
setIsLoading(false);
|
|
5299
|
-
}
|
|
5300
|
-
return;
|
|
5301
|
-
}
|
|
5302
|
-
if (ethProvider2.isRabby) {
|
|
5303
|
-
if (mounted) {
|
|
5304
|
-
setWallet({
|
|
5305
|
-
type: "rabby",
|
|
5306
|
-
name: "Rabby",
|
|
5307
|
-
address,
|
|
5308
|
-
icon: "rabby"
|
|
5309
|
-
});
|
|
5310
|
-
setIsLoading(false);
|
|
5311
|
-
}
|
|
5312
|
-
return;
|
|
5313
|
-
}
|
|
5314
|
-
if (ethProvider2.isTrust || win.trustwallet) {
|
|
5315
|
-
if (mounted) {
|
|
5316
|
-
setWallet({
|
|
5317
|
-
type: "trust",
|
|
5318
|
-
name: "Trust Wallet",
|
|
5319
|
-
address,
|
|
5320
|
-
icon: "trust"
|
|
5321
|
-
});
|
|
5322
|
-
setIsLoading(false);
|
|
5323
|
-
}
|
|
5324
|
-
return;
|
|
5325
|
-
}
|
|
5326
|
-
if (ethProvider2.isRainbow) {
|
|
5327
|
-
if (mounted) {
|
|
5328
|
-
setWallet({
|
|
5329
|
-
type: "rainbow",
|
|
5330
|
-
name: "Rainbow",
|
|
5331
|
-
address,
|
|
5332
|
-
icon: "rainbow"
|
|
5333
|
-
});
|
|
5334
|
-
setIsLoading(false);
|
|
5335
|
-
}
|
|
5336
|
-
return;
|
|
5337
|
-
}
|
|
5338
|
-
if (mounted) {
|
|
5339
|
-
setWallet({
|
|
5340
|
-
type: "metamask",
|
|
5341
|
-
name: "MetaMask",
|
|
5342
|
-
address,
|
|
5343
|
-
icon: "metamask"
|
|
5344
|
-
});
|
|
5345
|
-
setIsLoading(false);
|
|
5346
|
-
}
|
|
5347
|
-
return;
|
|
5348
|
-
}
|
|
5349
|
-
if (ethProvider2.isPhantom) {
|
|
5350
|
-
if (mounted) {
|
|
5351
|
-
setWallet({
|
|
5352
|
-
type: "phantom-ethereum",
|
|
5353
|
-
name: "Phantom",
|
|
5354
|
-
address,
|
|
5355
|
-
icon: "phantom"
|
|
5356
|
-
});
|
|
5357
|
-
setIsLoading(false);
|
|
5358
|
-
}
|
|
5359
|
-
return;
|
|
5360
|
-
}
|
|
5361
|
-
if (ethProvider2.isCoinbaseWallet) {
|
|
5362
|
-
if (mounted) {
|
|
5363
|
-
setWallet({
|
|
5364
|
-
type: "coinbase",
|
|
5365
|
-
name: "Coinbase Wallet",
|
|
5366
|
-
address,
|
|
5367
|
-
icon: "coinbase"
|
|
5368
|
-
});
|
|
5369
|
-
setIsLoading(false);
|
|
5370
|
-
}
|
|
5371
|
-
return;
|
|
5372
|
-
}
|
|
5373
|
-
if (mounted) {
|
|
5374
|
-
setWallet({
|
|
5375
|
-
type: "metamask",
|
|
5376
|
-
name: "Wallet",
|
|
5377
|
-
address,
|
|
5378
|
-
icon: "metamask"
|
|
5379
|
-
});
|
|
5380
|
-
setIsLoading(false);
|
|
5381
|
-
}
|
|
5382
|
-
return;
|
|
5560
|
+
const accounts = await provider.request({ method: "eth_accounts" });
|
|
5561
|
+
if (!accounts || accounts.length === 0) continue;
|
|
5562
|
+
const address = accounts[0];
|
|
5563
|
+
const resolved = identifyEthWallet(provider, anyWin2, walletId);
|
|
5564
|
+
if (mounted) {
|
|
5565
|
+
setWallet({ ...resolved, address });
|
|
5566
|
+
setIsLoading(false);
|
|
5383
5567
|
}
|
|
5384
|
-
|
|
5568
|
+
return;
|
|
5569
|
+
} catch {
|
|
5385
5570
|
}
|
|
5386
5571
|
}
|
|
5387
5572
|
}
|
|
@@ -5402,12 +5587,12 @@ function BrowserWalletButton({
|
|
|
5402
5587
|
detectWallet();
|
|
5403
5588
|
};
|
|
5404
5589
|
const handleDisconnect = () => {
|
|
5405
|
-
|
|
5590
|
+
onDisconnectRef.current?.();
|
|
5406
5591
|
detectWallet();
|
|
5407
5592
|
};
|
|
5408
5593
|
const handleEthAccountsChanged = (accounts) => {
|
|
5409
5594
|
if (Array.isArray(accounts) && accounts.length === 0) {
|
|
5410
|
-
|
|
5595
|
+
onDisconnectRef.current?.();
|
|
5411
5596
|
}
|
|
5412
5597
|
detectWallet();
|
|
5413
5598
|
};
|
|
@@ -5417,10 +5602,24 @@ function BrowserWalletButton({
|
|
|
5417
5602
|
solanaProvider.on("disconnect", handleDisconnect);
|
|
5418
5603
|
solanaProvider.on("accountChanged", handleAccountsChanged);
|
|
5419
5604
|
}
|
|
5420
|
-
const
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5605
|
+
const anyWin = window;
|
|
5606
|
+
const ethProviders = [];
|
|
5607
|
+
if (anyWin.__eip6963Providers) {
|
|
5608
|
+
for (const { provider } of anyWin.__eip6963Providers) {
|
|
5609
|
+
if (provider && !ethProviders.includes(provider)) {
|
|
5610
|
+
ethProviders.push(provider);
|
|
5611
|
+
}
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5614
|
+
if (window.ethereum && !ethProviders.includes(window.ethereum)) {
|
|
5615
|
+
ethProviders.push(window.ethereum);
|
|
5616
|
+
}
|
|
5617
|
+
if (window.phantom?.ethereum && !ethProviders.includes(window.phantom.ethereum)) {
|
|
5618
|
+
ethProviders.push(window.phantom.ethereum);
|
|
5619
|
+
}
|
|
5620
|
+
for (const provider of ethProviders) {
|
|
5621
|
+
provider.on("accountsChanged", handleEthAccountsChanged);
|
|
5622
|
+
provider.on("chainChanged", handleAccountsChanged);
|
|
5424
5623
|
}
|
|
5425
5624
|
return () => {
|
|
5426
5625
|
mounted = false;
|
|
@@ -5429,12 +5628,12 @@ function BrowserWalletButton({
|
|
|
5429
5628
|
solanaProvider.off("disconnect", handleDisconnect);
|
|
5430
5629
|
solanaProvider.off("accountChanged", handleAccountsChanged);
|
|
5431
5630
|
}
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5631
|
+
for (const provider of ethProviders) {
|
|
5632
|
+
provider.removeListener("accountsChanged", handleEthAccountsChanged);
|
|
5633
|
+
provider.removeListener("chainChanged", handleAccountsChanged);
|
|
5435
5634
|
}
|
|
5436
5635
|
};
|
|
5437
|
-
}, [chainType]);
|
|
5636
|
+
}, [chainType, eip6963ProviderCount]);
|
|
5438
5637
|
const handleConnect = async () => {
|
|
5439
5638
|
if (wallet) {
|
|
5440
5639
|
onClick(wallet);
|
|
@@ -5450,6 +5649,7 @@ function BrowserWalletButton({
|
|
|
5450
5649
|
const solanaProvider = window.phantom?.solana || window.solana;
|
|
5451
5650
|
if (solanaProvider?.isPhantom) {
|
|
5452
5651
|
const { publicKey } = await solanaProvider.connect();
|
|
5652
|
+
setUserDisconnectedWallet(false);
|
|
5453
5653
|
setWallet({
|
|
5454
5654
|
type: "phantom-solana",
|
|
5455
5655
|
name: "Phantom",
|
|
@@ -5467,6 +5667,7 @@ function BrowserWalletButton({
|
|
|
5467
5667
|
method: "eth_requestAccounts"
|
|
5468
5668
|
});
|
|
5469
5669
|
if (accounts && accounts.length > 0) {
|
|
5670
|
+
setUserDisconnectedWallet(false);
|
|
5470
5671
|
const isPhantom = ethProvider.isPhantom;
|
|
5471
5672
|
setWallet({
|
|
5472
5673
|
type: isPhantom ? "phantom-ethereum" : "metamask",
|
|
@@ -5478,7 +5679,10 @@ function BrowserWalletButton({
|
|
|
5478
5679
|
}
|
|
5479
5680
|
}
|
|
5480
5681
|
} catch (error) {
|
|
5481
|
-
|
|
5682
|
+
if (error && typeof error === "object" && "code" in error && error.code === 4001) {
|
|
5683
|
+
} else {
|
|
5684
|
+
console.error("Error connecting wallet:", error);
|
|
5685
|
+
}
|
|
5482
5686
|
} finally {
|
|
5483
5687
|
setIsConnecting(false);
|
|
5484
5688
|
}
|
|
@@ -5524,7 +5728,7 @@ function BrowserWalletButton({
|
|
|
5524
5728
|
color: components.card.titleColor,
|
|
5525
5729
|
fontFamily: fonts.regular
|
|
5526
5730
|
},
|
|
5527
|
-
children: wallet ? `${wallet.name} (${
|
|
5731
|
+
children: wallet ? `${wallet.name} (${truncateAddress3(wallet.address)})` : "Connect Wallet"
|
|
5528
5732
|
}
|
|
5529
5733
|
),
|
|
5530
5734
|
isLoadingBalance ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "uf-h-3 uf-w-24 uf-bg-muted uf-rounded uf-animate-pulse" }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
@@ -5577,7 +5781,7 @@ var import_core19 = require("@unifold/core");
|
|
|
5577
5781
|
|
|
5578
5782
|
// src/hooks/use-allowed-country.ts
|
|
5579
5783
|
var import_react_query3 = require("@tanstack/react-query");
|
|
5580
|
-
var
|
|
5784
|
+
var import_core13 = require("@unifold/core");
|
|
5581
5785
|
function useAllowedCountry(publishableKey) {
|
|
5582
5786
|
const {
|
|
5583
5787
|
data: ipData,
|
|
@@ -5585,7 +5789,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
5585
5789
|
error: ipError
|
|
5586
5790
|
} = (0, import_react_query3.useQuery)({
|
|
5587
5791
|
queryKey: ["unifold", "ipAddress"],
|
|
5588
|
-
queryFn: () => (0,
|
|
5792
|
+
queryFn: () => (0, import_core13.getIpAddress)(),
|
|
5589
5793
|
refetchOnMount: false,
|
|
5590
5794
|
refetchOnReconnect: true,
|
|
5591
5795
|
refetchOnWindowFocus: false,
|
|
@@ -5600,7 +5804,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
5600
5804
|
error: configError
|
|
5601
5805
|
} = (0, import_react_query3.useQuery)({
|
|
5602
5806
|
queryKey: ["unifold", "projectConfig", publishableKey],
|
|
5603
|
-
queryFn: () => (0,
|
|
5807
|
+
queryFn: () => (0, import_core13.getProjectConfig)(publishableKey),
|
|
5604
5808
|
refetchOnMount: false,
|
|
5605
5809
|
refetchOnReconnect: true,
|
|
5606
5810
|
refetchOnWindowFocus: false,
|
|
@@ -5631,7 +5835,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
5631
5835
|
|
|
5632
5836
|
// src/hooks/use-address-validation.ts
|
|
5633
5837
|
var import_react_query4 = require("@tanstack/react-query");
|
|
5634
|
-
var
|
|
5838
|
+
var import_core14 = require("@unifold/core");
|
|
5635
5839
|
function useAddressValidation({
|
|
5636
5840
|
recipientAddress,
|
|
5637
5841
|
destinationChainType,
|
|
@@ -5651,7 +5855,7 @@ function useAddressValidation({
|
|
|
5651
5855
|
destinationChainId,
|
|
5652
5856
|
destinationTokenAddress
|
|
5653
5857
|
],
|
|
5654
|
-
queryFn: () => (0,
|
|
5858
|
+
queryFn: () => (0, import_core14.verifyRecipientAddress)(
|
|
5655
5859
|
{
|
|
5656
5860
|
chain_type: destinationChainType,
|
|
5657
5861
|
chain_id: destinationChainId,
|
|
@@ -5689,7 +5893,7 @@ function useAddressValidation({
|
|
|
5689
5893
|
|
|
5690
5894
|
// src/hooks/use-supported-deposit-tokens.ts
|
|
5691
5895
|
var import_react_query5 = require("@tanstack/react-query");
|
|
5692
|
-
var
|
|
5896
|
+
var import_core15 = require("@unifold/core");
|
|
5693
5897
|
function useSupportedDepositTokens(publishableKey, options) {
|
|
5694
5898
|
const filteredOptions = options?.destination_token_address && options?.destination_chain_id && options?.destination_chain_type ? {
|
|
5695
5899
|
destination_token_address: options.destination_token_address,
|
|
@@ -5705,7 +5909,7 @@ function useSupportedDepositTokens(publishableKey, options) {
|
|
|
5705
5909
|
filteredOptions?.destination_chain_id ?? null,
|
|
5706
5910
|
filteredOptions?.destination_chain_type ?? null
|
|
5707
5911
|
],
|
|
5708
|
-
queryFn: () => (0,
|
|
5912
|
+
queryFn: () => (0, import_core15.getSupportedDepositTokens)(publishableKey, filteredOptions),
|
|
5709
5913
|
staleTime: 1e3 * 60 * 5,
|
|
5710
5914
|
// 5 minutes — token list rarely changes
|
|
5711
5915
|
gcTime: 1e3 * 60 * 30,
|
|
@@ -5723,11 +5927,6 @@ var import_lucide_react14 = require("lucide-react");
|
|
|
5723
5927
|
var import_react10 = require("react");
|
|
5724
5928
|
var import_qr_code_styling = __toESM(require("qr-code-styling"));
|
|
5725
5929
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
5726
|
-
var qrCache = /* @__PURE__ */ new Map();
|
|
5727
|
-
var imageCache = /* @__PURE__ */ new Map();
|
|
5728
|
-
function getCacheKey(value, size, imageUrl, darkMode) {
|
|
5729
|
-
return `${value}|${size}|${imageUrl || ""}|${darkMode}`;
|
|
5730
|
-
}
|
|
5731
5930
|
function createQRConfig(value, size, imageUrl, imageSize, darkMode) {
|
|
5732
5931
|
return {
|
|
5733
5932
|
type: "svg",
|
|
@@ -5764,79 +5963,6 @@ function createQRConfig(value, size, imageUrl, imageSize, darkMode) {
|
|
|
5764
5963
|
}
|
|
5765
5964
|
};
|
|
5766
5965
|
}
|
|
5767
|
-
async function preloadImageAsync(url) {
|
|
5768
|
-
if (!url || imageCache.has(url)) return;
|
|
5769
|
-
return new Promise((resolve) => {
|
|
5770
|
-
const img = new Image();
|
|
5771
|
-
img.crossOrigin = "anonymous";
|
|
5772
|
-
img.onload = () => {
|
|
5773
|
-
imageCache.set(url, true);
|
|
5774
|
-
resolve();
|
|
5775
|
-
};
|
|
5776
|
-
img.onerror = () => {
|
|
5777
|
-
imageCache.set(url, false);
|
|
5778
|
-
resolve();
|
|
5779
|
-
};
|
|
5780
|
-
img.src = url;
|
|
5781
|
-
});
|
|
5782
|
-
}
|
|
5783
|
-
function waitForStyledQR(container, maxAttempts = 20) {
|
|
5784
|
-
return new Promise((resolve) => {
|
|
5785
|
-
let attempts = 0;
|
|
5786
|
-
const check = () => {
|
|
5787
|
-
const svg = container.querySelector("svg");
|
|
5788
|
-
if (!svg) {
|
|
5789
|
-
if (attempts++ < maxAttempts) {
|
|
5790
|
-
requestAnimationFrame(check);
|
|
5791
|
-
} else {
|
|
5792
|
-
resolve(null);
|
|
5793
|
-
}
|
|
5794
|
-
return;
|
|
5795
|
-
}
|
|
5796
|
-
const hasCircles = svg.querySelectorAll("circle").length > 0;
|
|
5797
|
-
const hasPaths = svg.querySelectorAll("path").length > 0;
|
|
5798
|
-
if (hasCircles || hasPaths) {
|
|
5799
|
-
resolve(svg.outerHTML);
|
|
5800
|
-
} else if (attempts++ < maxAttempts) {
|
|
5801
|
-
requestAnimationFrame(check);
|
|
5802
|
-
} else {
|
|
5803
|
-
resolve(svg.outerHTML);
|
|
5804
|
-
}
|
|
5805
|
-
};
|
|
5806
|
-
requestAnimationFrame(check);
|
|
5807
|
-
});
|
|
5808
|
-
}
|
|
5809
|
-
async function preloadQRCode(value, size = 180, imageUrl, imageSize = 45, darkMode = false) {
|
|
5810
|
-
if (!value) return;
|
|
5811
|
-
const cacheKey = getCacheKey(value, size, imageUrl, darkMode);
|
|
5812
|
-
if (qrCache.has(cacheKey)) return;
|
|
5813
|
-
if (imageUrl) {
|
|
5814
|
-
await preloadImageAsync(imageUrl);
|
|
5815
|
-
}
|
|
5816
|
-
const tempContainer = document.createElement("div");
|
|
5817
|
-
tempContainer.style.position = "absolute";
|
|
5818
|
-
tempContainer.style.left = "-9999px";
|
|
5819
|
-
tempContainer.style.top = "-9999px";
|
|
5820
|
-
document.body.appendChild(tempContainer);
|
|
5821
|
-
try {
|
|
5822
|
-
const config = createQRConfig(value, size, imageUrl, imageSize, darkMode);
|
|
5823
|
-
const qrInstance = new import_qr_code_styling.default(config);
|
|
5824
|
-
qrInstance.append(tempContainer);
|
|
5825
|
-
const svgString = await waitForStyledQR(tempContainer);
|
|
5826
|
-
if (svgString) {
|
|
5827
|
-
qrCache.set(cacheKey, { svgString });
|
|
5828
|
-
}
|
|
5829
|
-
} finally {
|
|
5830
|
-
document.body.removeChild(tempContainer);
|
|
5831
|
-
}
|
|
5832
|
-
}
|
|
5833
|
-
function isQRCodeCached(value, size = 180, imageUrl, darkMode = false) {
|
|
5834
|
-
const cacheKey = getCacheKey(value, size, imageUrl, darkMode);
|
|
5835
|
-
return qrCache.has(cacheKey);
|
|
5836
|
-
}
|
|
5837
|
-
function clearQRCodeCache() {
|
|
5838
|
-
qrCache.clear();
|
|
5839
|
-
}
|
|
5840
5966
|
function StyledQRCode({
|
|
5841
5967
|
value,
|
|
5842
5968
|
size = 180,
|
|
@@ -5845,107 +5971,28 @@ function StyledQRCode({
|
|
|
5845
5971
|
darkMode = false
|
|
5846
5972
|
}) {
|
|
5847
5973
|
const containerRef = (0, import_react10.useRef)(null);
|
|
5848
|
-
const
|
|
5849
|
-
|
|
5850
|
-
const cacheKey = getCacheKey(value, size, imageUrl, darkMode);
|
|
5851
|
-
const cachedEntry = qrCache.get(cacheKey);
|
|
5852
|
-
const renderQR = (0, import_react10.useCallback)(async () => {
|
|
5974
|
+
const qrRef = (0, import_react10.useRef)(null);
|
|
5975
|
+
(0, import_react10.useEffect)(() => {
|
|
5853
5976
|
if (!containerRef.current || !value) return;
|
|
5854
|
-
const key = getCacheKey(value, size, imageUrl, darkMode);
|
|
5855
|
-
if (currentKeyRef.current === key) {
|
|
5856
|
-
setIsReady(true);
|
|
5857
|
-
return;
|
|
5858
|
-
}
|
|
5859
|
-
currentKeyRef.current = key;
|
|
5860
|
-
containerRef.current.innerHTML = "";
|
|
5861
|
-
const cached = qrCache.get(key);
|
|
5862
|
-
if (cached?.svgString) {
|
|
5863
|
-
containerRef.current.innerHTML = cached.svgString;
|
|
5864
|
-
setIsReady(true);
|
|
5865
|
-
return;
|
|
5866
|
-
}
|
|
5867
|
-
if (imageUrl) {
|
|
5868
|
-
await preloadImageAsync(imageUrl);
|
|
5869
|
-
}
|
|
5870
5977
|
const config = createQRConfig(value, size, imageUrl, imageSize, darkMode);
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5978
|
+
if (!qrRef.current) {
|
|
5979
|
+
qrRef.current = new import_qr_code_styling.default(config);
|
|
5980
|
+
qrRef.current.append(containerRef.current);
|
|
5981
|
+
} else {
|
|
5982
|
+
qrRef.current.update(config);
|
|
5876
5983
|
}
|
|
5877
|
-
setIsReady(true);
|
|
5878
5984
|
}, [value, size, imageUrl, imageSize, darkMode]);
|
|
5879
|
-
(0,
|
|
5880
|
-
let mounted = true;
|
|
5881
|
-
const init = async () => {
|
|
5882
|
-
if (!mounted) return;
|
|
5883
|
-
await renderQR();
|
|
5884
|
-
};
|
|
5885
|
-
setIsReady(false);
|
|
5886
|
-
init();
|
|
5887
|
-
return () => {
|
|
5888
|
-
mounted = false;
|
|
5889
|
-
};
|
|
5890
|
-
}, [renderQR]);
|
|
5891
|
-
const showSkeleton = !isReady && !cachedEntry?.svgString;
|
|
5892
|
-
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5985
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5893
5986
|
"div",
|
|
5894
5987
|
{
|
|
5988
|
+
ref: containerRef,
|
|
5895
5989
|
style: {
|
|
5896
5990
|
width: size,
|
|
5897
5991
|
height: size,
|
|
5898
5992
|
display: "flex",
|
|
5899
5993
|
alignItems: "center",
|
|
5900
|
-
justifyContent: "center"
|
|
5901
|
-
|
|
5902
|
-
},
|
|
5903
|
-
children: [
|
|
5904
|
-
showSkeleton && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5905
|
-
"div",
|
|
5906
|
-
{
|
|
5907
|
-
style: {
|
|
5908
|
-
position: "absolute",
|
|
5909
|
-
inset: 0,
|
|
5910
|
-
display: "flex",
|
|
5911
|
-
alignItems: "center",
|
|
5912
|
-
justifyContent: "center",
|
|
5913
|
-
background: darkMode ? "linear-gradient(135deg, #1a1a1a 0%, #2a2a2a 100%)" : "linear-gradient(135deg, #f0f0f0 0%, #e0e0e0 100%)",
|
|
5914
|
-
borderRadius: 8,
|
|
5915
|
-
animation: "uf-qr-pulse 1.5s ease-in-out infinite"
|
|
5916
|
-
},
|
|
5917
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5918
|
-
"div",
|
|
5919
|
-
{
|
|
5920
|
-
style: {
|
|
5921
|
-
width: size * 0.6,
|
|
5922
|
-
height: size * 0.6,
|
|
5923
|
-
background: darkMode ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)",
|
|
5924
|
-
borderRadius: 4
|
|
5925
|
-
}
|
|
5926
|
-
}
|
|
5927
|
-
)
|
|
5928
|
-
}
|
|
5929
|
-
),
|
|
5930
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5931
|
-
"div",
|
|
5932
|
-
{
|
|
5933
|
-
ref: containerRef,
|
|
5934
|
-
style: {
|
|
5935
|
-
width: size,
|
|
5936
|
-
height: size,
|
|
5937
|
-
opacity: isReady ? 1 : 0,
|
|
5938
|
-
transition: "opacity 0.15s ease-out"
|
|
5939
|
-
}
|
|
5940
|
-
}
|
|
5941
|
-
),
|
|
5942
|
-
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("style", { children: `
|
|
5943
|
-
@keyframes uf-qr-pulse {
|
|
5944
|
-
0%, 100% { opacity: 1; }
|
|
5945
|
-
50% { opacity: 0.6; }
|
|
5946
|
-
}
|
|
5947
|
-
` })
|
|
5948
|
-
]
|
|
5994
|
+
justifyContent: "center"
|
|
5995
|
+
}
|
|
5949
5996
|
}
|
|
5950
5997
|
);
|
|
5951
5998
|
}
|
|
@@ -5962,7 +6009,8 @@ var COMMON_TOKENS = [
|
|
|
5962
6009
|
{ symbol: "USDC", chainType: "solana", chainId: "mainnet" },
|
|
5963
6010
|
{ symbol: "POL", chainType: "ethereum", chainId: "137" },
|
|
5964
6011
|
{ symbol: "BNB", chainType: "ethereum", chainId: "56" },
|
|
5965
|
-
{ symbol: "BTC", chainType: "bitcoin", chainId: "mainnet" }
|
|
6012
|
+
{ symbol: "BTC", chainType: "bitcoin", chainId: "mainnet" },
|
|
6013
|
+
{ symbol: "XRP", chainType: "xrpl", chainId: "mainnet" }
|
|
5966
6014
|
];
|
|
5967
6015
|
function getRecentTokens() {
|
|
5968
6016
|
if (typeof window === "undefined") return [];
|
|
@@ -6411,50 +6459,34 @@ function TokenSelectorSheet({
|
|
|
6411
6459
|
);
|
|
6412
6460
|
}
|
|
6413
6461
|
|
|
6414
|
-
// src/components/deposits/
|
|
6415
|
-
var import_core15 = require("@unifold/core");
|
|
6462
|
+
// src/components/deposits/DepositPollingUi.tsx
|
|
6416
6463
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
6417
|
-
function
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
cooldownRef,
|
|
6423
|
-
buttonText = "Check again"
|
|
6464
|
+
function DepositPollingUi({
|
|
6465
|
+
depositConfirmationMode,
|
|
6466
|
+
showWaitingUi,
|
|
6467
|
+
hasExecution,
|
|
6468
|
+
onIveDeposited
|
|
6424
6469
|
}) {
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
} catch (error) {
|
|
6446
|
-
console.error("Failed to start poll workflow:", error);
|
|
6447
|
-
}
|
|
6448
|
-
};
|
|
6449
|
-
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
6450
|
-
"button",
|
|
6451
|
-
{
|
|
6452
|
-
onClick: handleClick,
|
|
6453
|
-
disabled: !currentWalletId || pollCooldown > 0,
|
|
6454
|
-
className: "uf-w-full uf-rounded-xl uf-py-2.5 uf-px-2 uf-flex uf-items-center uf-gap-3 uf-justify-center uf-text-center uf-text-sm uf-bg-primary hover:uf-bg-primary/80 uf-transition-colors uf-text-left disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
|
|
6455
|
-
children: pollCooldown > 0 ? `${buttonText} in ${pollCooldown}s` : "I've made the deposit"
|
|
6456
|
-
}
|
|
6457
|
-
) });
|
|
6470
|
+
if (depositConfirmationMode === "manual" && !showWaitingUi) {
|
|
6471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
6472
|
+
"button",
|
|
6473
|
+
{
|
|
6474
|
+
onClick: onIveDeposited,
|
|
6475
|
+
className: "uf-w-full uf-rounded-xl uf-py-2.5 uf-px-2 uf-flex uf-items-center uf-justify-center uf-text-sm uf-bg-primary hover:uf-bg-primary/80 uf-transition-colors",
|
|
6476
|
+
children: "I've made the deposit"
|
|
6477
|
+
}
|
|
6478
|
+
);
|
|
6479
|
+
}
|
|
6480
|
+
if (showWaitingUi && !hasExecution) {
|
|
6481
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "uf-bg-secondary uf-rounded-xl uf-p-3 uf-flex uf-items-center uf-gap-3 uf-animate-in uf-fade-in uf-duration-500", children: [
|
|
6482
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "uf-flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "uf-w-9 uf-h-9 uf-rounded-full uf-border-2 uf-border-t-primary uf-border-primary/20 uf-animate-spin" }) }),
|
|
6483
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
|
|
6484
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "uf-text-sm uf-font-medium uf-text-foreground", children: "Processing deposit transactions" }),
|
|
6485
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "uf-text-xs uf-text-muted-foreground", children: "We're checking if your deposit has landed." })
|
|
6486
|
+
] })
|
|
6487
|
+
] });
|
|
6488
|
+
}
|
|
6489
|
+
return null;
|
|
6458
6490
|
}
|
|
6459
6491
|
|
|
6460
6492
|
// src/components/deposits/shared/DepositFooterLinks.tsx
|
|
@@ -6650,6 +6682,7 @@ function TransferCryptoSingleInput({
|
|
|
6650
6682
|
destinationChainType,
|
|
6651
6683
|
destinationChainId,
|
|
6652
6684
|
destinationTokenAddress,
|
|
6685
|
+
depositConfirmationMode = "auto_ui",
|
|
6653
6686
|
onExecutionsChange,
|
|
6654
6687
|
onDepositSuccess,
|
|
6655
6688
|
onDepositError,
|
|
@@ -6662,20 +6695,10 @@ function TransferCryptoSingleInput({
|
|
|
6662
6695
|
const [copied, setCopied] = (0, import_react13.useState)(false);
|
|
6663
6696
|
const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
|
|
6664
6697
|
const [glossaryOpen, setGlossaryOpen] = (0, import_react13.useState)(false);
|
|
6665
|
-
const [pollCooldown, setPollCooldown] = (0, import_react13.useState)(0);
|
|
6666
|
-
const cooldownRef = (0, import_react13.useRef)(null);
|
|
6667
6698
|
const [detailsExpanded, setDetailsExpanded] = (0, import_react13.useState)(false);
|
|
6668
6699
|
const [depositsModalOpen, setDepositsModalOpen] = (0, import_react13.useState)(false);
|
|
6669
6700
|
const [tokenSelectorOpen, setTokenSelectorOpen] = (0, import_react13.useState)(false);
|
|
6670
6701
|
const [initialSelectionDone, setInitialSelectionDone] = (0, import_react13.useState)(false);
|
|
6671
|
-
(0, import_react13.useEffect)(() => {
|
|
6672
|
-
return () => {
|
|
6673
|
-
if (cooldownRef.current) {
|
|
6674
|
-
clearInterval(cooldownRef.current);
|
|
6675
|
-
cooldownRef.current = null;
|
|
6676
|
-
}
|
|
6677
|
-
};
|
|
6678
|
-
}, []);
|
|
6679
6702
|
const {
|
|
6680
6703
|
data: tokensResponse,
|
|
6681
6704
|
isLoading: tokensLoading
|
|
@@ -6702,13 +6725,6 @@ function TransferCryptoSingleInput({
|
|
|
6702
6725
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
6703
6726
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
6704
6727
|
const error = walletsError?.message ?? null;
|
|
6705
|
-
const { executions: depositExecutions, isPolling } = useDepositPolling({
|
|
6706
|
-
userId,
|
|
6707
|
-
publishableKey,
|
|
6708
|
-
enabled: true,
|
|
6709
|
-
onDepositSuccess,
|
|
6710
|
-
onDepositError
|
|
6711
|
-
});
|
|
6712
6728
|
const allAvailableChains = (0, import_react13.useMemo)(() => {
|
|
6713
6729
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
6714
6730
|
supportedTokens.forEach((t6) => {
|
|
@@ -6728,6 +6744,15 @@ function TransferCryptoSingleInput({
|
|
|
6728
6744
|
const currentChainType = currentChainData?.chain_type || "ethereum";
|
|
6729
6745
|
const currentWallet = (0, import_core16.getWalletByChainType)(wallets, currentChainType);
|
|
6730
6746
|
const depositAddress = currentWallet?.address || "";
|
|
6747
|
+
const { executions: depositExecutions, isPolling, showWaitingUi, handleIveDeposited } = useDepositPolling({
|
|
6748
|
+
userId,
|
|
6749
|
+
publishableKey,
|
|
6750
|
+
depositConfirmationMode,
|
|
6751
|
+
depositWalletId: currentWallet?.id,
|
|
6752
|
+
enabled: true,
|
|
6753
|
+
onDepositSuccess,
|
|
6754
|
+
onDepositError
|
|
6755
|
+
});
|
|
6731
6756
|
(0, import_react13.useEffect)(() => {
|
|
6732
6757
|
if (!supportedTokens.length || initialSelectionDone) return;
|
|
6733
6758
|
let selectedTokenData;
|
|
@@ -6777,28 +6802,6 @@ function TransferCryptoSingleInput({
|
|
|
6777
6802
|
onExecutionsChange(depositExecutions);
|
|
6778
6803
|
}
|
|
6779
6804
|
}, [depositExecutions, onExecutionsChange]);
|
|
6780
|
-
(0, import_react13.useEffect)(() => {
|
|
6781
|
-
if (!wallets.length || !allAvailableChains.length) return;
|
|
6782
|
-
const preloadAllQRCodes = async () => {
|
|
6783
|
-
for (const wallet of wallets) {
|
|
6784
|
-
if (!wallet.address) continue;
|
|
6785
|
-
const chainData = allAvailableChains.find(
|
|
6786
|
-
(c) => c.chain_type === wallet.chain_type
|
|
6787
|
-
);
|
|
6788
|
-
const chainIconUrl = chainData?.icon_url;
|
|
6789
|
-
await preloadQRCode(
|
|
6790
|
-
wallet.address,
|
|
6791
|
-
180,
|
|
6792
|
-
// size
|
|
6793
|
-
chainIconUrl,
|
|
6794
|
-
45,
|
|
6795
|
-
// imageSize
|
|
6796
|
-
isDarkMode
|
|
6797
|
-
);
|
|
6798
|
-
}
|
|
6799
|
-
};
|
|
6800
|
-
preloadAllQRCodes();
|
|
6801
|
-
}, [wallets, allAvailableChains, isDarkMode]);
|
|
6802
6805
|
(0, import_react13.useEffect)(() => {
|
|
6803
6806
|
if (!supportedTokens.length) return;
|
|
6804
6807
|
const currentToken = supportedTokens.find((t6) => t6.symbol === token);
|
|
@@ -7071,14 +7074,12 @@ function TransferCryptoSingleInput({
|
|
|
7071
7074
|
] })
|
|
7072
7075
|
] }),
|
|
7073
7076
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7074
|
-
|
|
7077
|
+
DepositPollingUi,
|
|
7075
7078
|
{
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
cooldownRef,
|
|
7081
|
-
buttonText: "Try again"
|
|
7079
|
+
depositConfirmationMode,
|
|
7080
|
+
showWaitingUi,
|
|
7081
|
+
hasExecution: depositExecutions.length > 0,
|
|
7082
|
+
onIveDeposited: handleIveDeposited
|
|
7082
7083
|
}
|
|
7083
7084
|
),
|
|
7084
7085
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(DepositFooterLinks, { onGlossaryClick: () => setGlossaryOpen(true) }),
|
|
@@ -7271,6 +7272,7 @@ function TransferCryptoDoubleInput({
|
|
|
7271
7272
|
destinationChainType,
|
|
7272
7273
|
destinationChainId,
|
|
7273
7274
|
destinationTokenAddress,
|
|
7275
|
+
depositConfirmationMode = "auto_ui",
|
|
7274
7276
|
onExecutionsChange,
|
|
7275
7277
|
onDepositSuccess,
|
|
7276
7278
|
onDepositError,
|
|
@@ -7283,19 +7285,9 @@ function TransferCryptoDoubleInput({
|
|
|
7283
7285
|
const [copied, setCopied] = (0, import_react14.useState)(false);
|
|
7284
7286
|
const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
|
|
7285
7287
|
const [glossaryOpen, setGlossaryOpen] = (0, import_react14.useState)(false);
|
|
7286
|
-
const [pollCooldown, setPollCooldown] = (0, import_react14.useState)(0);
|
|
7287
|
-
const cooldownRef = (0, import_react14.useRef)(null);
|
|
7288
7288
|
const [detailsExpanded, setDetailsExpanded] = (0, import_react14.useState)(false);
|
|
7289
7289
|
const [depositsModalOpen, setDepositsModalOpen] = (0, import_react14.useState)(false);
|
|
7290
7290
|
const [initialSelectionDone, setInitialSelectionDone] = (0, import_react14.useState)(false);
|
|
7291
|
-
(0, import_react14.useEffect)(() => {
|
|
7292
|
-
return () => {
|
|
7293
|
-
if (cooldownRef.current) {
|
|
7294
|
-
clearInterval(cooldownRef.current);
|
|
7295
|
-
cooldownRef.current = null;
|
|
7296
|
-
}
|
|
7297
|
-
};
|
|
7298
|
-
}, []);
|
|
7299
7291
|
const {
|
|
7300
7292
|
data: tokensResponse,
|
|
7301
7293
|
isLoading: tokensLoading
|
|
@@ -7322,13 +7314,6 @@ function TransferCryptoDoubleInput({
|
|
|
7322
7314
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
7323
7315
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
7324
7316
|
const error = walletsError?.message ?? null;
|
|
7325
|
-
const { executions: depositExecutions, isPolling } = useDepositPolling({
|
|
7326
|
-
userId,
|
|
7327
|
-
publishableKey,
|
|
7328
|
-
enabled: true,
|
|
7329
|
-
onDepositSuccess,
|
|
7330
|
-
onDepositError
|
|
7331
|
-
});
|
|
7332
7317
|
const allAvailableChains = (0, import_react14.useMemo)(() => {
|
|
7333
7318
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
7334
7319
|
supportedTokens.forEach((t6) => {
|
|
@@ -7348,6 +7333,15 @@ function TransferCryptoDoubleInput({
|
|
|
7348
7333
|
const currentChainType = currentChainData?.chain_type || "ethereum";
|
|
7349
7334
|
const currentWallet = (0, import_core17.getWalletByChainType)(wallets, currentChainType);
|
|
7350
7335
|
const depositAddress = currentWallet?.address || "";
|
|
7336
|
+
const { executions: depositExecutions, isPolling, showWaitingUi, handleIveDeposited } = useDepositPolling({
|
|
7337
|
+
userId,
|
|
7338
|
+
publishableKey,
|
|
7339
|
+
depositConfirmationMode,
|
|
7340
|
+
depositWalletId: currentWallet?.id,
|
|
7341
|
+
enabled: true,
|
|
7342
|
+
onDepositSuccess,
|
|
7343
|
+
onDepositError
|
|
7344
|
+
});
|
|
7351
7345
|
(0, import_react14.useEffect)(() => {
|
|
7352
7346
|
if (!supportedTokens.length || initialSelectionDone) return;
|
|
7353
7347
|
const allChains = /* @__PURE__ */ new Set();
|
|
@@ -7370,28 +7364,6 @@ function TransferCryptoDoubleInput({
|
|
|
7370
7364
|
onExecutionsChange(depositExecutions);
|
|
7371
7365
|
}
|
|
7372
7366
|
}, [depositExecutions, onExecutionsChange]);
|
|
7373
|
-
(0, import_react14.useEffect)(() => {
|
|
7374
|
-
if (!wallets.length || !allAvailableChains.length) return;
|
|
7375
|
-
const preloadAllQRCodes = async () => {
|
|
7376
|
-
for (const wallet of wallets) {
|
|
7377
|
-
if (!wallet.address) continue;
|
|
7378
|
-
const chainData = allAvailableChains.find(
|
|
7379
|
-
(c) => c.chain_type === wallet.chain_type
|
|
7380
|
-
);
|
|
7381
|
-
const chainIconUrl = chainData?.icon_url;
|
|
7382
|
-
await preloadQRCode(
|
|
7383
|
-
wallet.address,
|
|
7384
|
-
180,
|
|
7385
|
-
// size
|
|
7386
|
-
chainIconUrl,
|
|
7387
|
-
45,
|
|
7388
|
-
// imageSize
|
|
7389
|
-
isDarkMode
|
|
7390
|
-
);
|
|
7391
|
-
}
|
|
7392
|
-
};
|
|
7393
|
-
preloadAllQRCodes();
|
|
7394
|
-
}, [wallets, allAvailableChains, isDarkMode]);
|
|
7395
7367
|
(0, import_react14.useEffect)(() => {
|
|
7396
7368
|
if (!supportedTokens.length) return;
|
|
7397
7369
|
const currentToken = supportedTokens.find((t6) => t6.symbol === token);
|
|
@@ -7698,14 +7670,12 @@ function TransferCryptoDoubleInput({
|
|
|
7698
7670
|
] })
|
|
7699
7671
|
] }),
|
|
7700
7672
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7701
|
-
|
|
7673
|
+
DepositPollingUi,
|
|
7702
7674
|
{
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
cooldownRef,
|
|
7708
|
-
buttonText: "Check again"
|
|
7675
|
+
depositConfirmationMode,
|
|
7676
|
+
showWaitingUi,
|
|
7677
|
+
hasExecution: depositExecutions.length > 0,
|
|
7678
|
+
onIveDeposited: handleIveDeposited
|
|
7709
7679
|
}
|
|
7710
7680
|
),
|
|
7711
7681
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(DepositFooterLinks, { onGlossaryClick: () => setGlossaryOpen(true) }),
|
|
@@ -7759,110 +7729,10 @@ function TransferCryptoDoubleInput({
|
|
|
7759
7729
|
var React24 = __toESM(require("react"));
|
|
7760
7730
|
var import_core18 = require("@unifold/core");
|
|
7761
7731
|
|
|
7762
|
-
// src/components/deposits/browser-wallets/utils.ts
|
|
7763
|
-
function getIconUrl4(iconUrl, assetCdnUrl) {
|
|
7764
|
-
if (!iconUrl) return void 0;
|
|
7765
|
-
if (iconUrl.startsWith("http://") || iconUrl.startsWith("https://")) {
|
|
7766
|
-
return iconUrl;
|
|
7767
|
-
}
|
|
7768
|
-
if (assetCdnUrl) {
|
|
7769
|
-
return `${assetCdnUrl}${iconUrl.startsWith("/") ? "" : "/"}${iconUrl}`;
|
|
7770
|
-
}
|
|
7771
|
-
return iconUrl;
|
|
7772
|
-
}
|
|
7773
|
-
function getTokenFromBalance(balance) {
|
|
7774
|
-
if (balance.token) {
|
|
7775
|
-
return balance.token;
|
|
7776
|
-
}
|
|
7777
|
-
const legacyBalance = balance;
|
|
7778
|
-
if (legacyBalance.symbol && legacyBalance.decimals !== void 0) {
|
|
7779
|
-
return {
|
|
7780
|
-
symbol: legacyBalance.symbol,
|
|
7781
|
-
name: legacyBalance.name,
|
|
7782
|
-
icon_url: legacyBalance.icon_url,
|
|
7783
|
-
icon_urls: [],
|
|
7784
|
-
token_address: legacyBalance.token_address,
|
|
7785
|
-
chain_id: legacyBalance.chain_id,
|
|
7786
|
-
chain_name: legacyBalance.chain_name,
|
|
7787
|
-
chain_type: legacyBalance.chain_type,
|
|
7788
|
-
decimals: legacyBalance.decimals,
|
|
7789
|
-
chain_icon_url: legacyBalance.chain_icon_url,
|
|
7790
|
-
chain_icon_urls: [],
|
|
7791
|
-
minimum_deposit_amount_usd: 0
|
|
7792
|
-
};
|
|
7793
|
-
}
|
|
7794
|
-
return null;
|
|
7795
|
-
}
|
|
7796
|
-
function isBalanceEligible(balance) {
|
|
7797
|
-
if (balance.is_eligible !== void 0) {
|
|
7798
|
-
return balance.is_eligible;
|
|
7799
|
-
}
|
|
7800
|
-
const legacyBalance = balance;
|
|
7801
|
-
if (legacyBalance.is_eligible !== void 0) {
|
|
7802
|
-
return legacyBalance.is_eligible;
|
|
7803
|
-
}
|
|
7804
|
-
return true;
|
|
7805
|
-
}
|
|
7806
|
-
function formatTokenAmount(amount, decimals, symbol) {
|
|
7807
|
-
const value = Number(amount) / 10 ** decimals;
|
|
7808
|
-
const upperSymbol = symbol.toUpperCase();
|
|
7809
|
-
let maxDecimals = 4;
|
|
7810
|
-
if (upperSymbol === "BTC" || upperSymbol === "WBTC") {
|
|
7811
|
-
maxDecimals = 8;
|
|
7812
|
-
} else if (upperSymbol === "ETH" || upperSymbol === "WETH" || upperSymbol === "SOL") {
|
|
7813
|
-
maxDecimals = 6;
|
|
7814
|
-
}
|
|
7815
|
-
if (value >= 1) {
|
|
7816
|
-
return value.toLocaleString(void 0, {
|
|
7817
|
-
minimumFractionDigits: 2,
|
|
7818
|
-
maximumFractionDigits: maxDecimals
|
|
7819
|
-
});
|
|
7820
|
-
} else if (value > 0) {
|
|
7821
|
-
return value.toLocaleString(void 0, {
|
|
7822
|
-
minimumFractionDigits: 2,
|
|
7823
|
-
maximumFractionDigits: maxDecimals,
|
|
7824
|
-
minimumSignificantDigits: 2,
|
|
7825
|
-
maximumSignificantDigits: 6
|
|
7826
|
-
});
|
|
7827
|
-
}
|
|
7828
|
-
return "0.00";
|
|
7829
|
-
}
|
|
7830
|
-
function formatUsdAmount(amountUsd) {
|
|
7831
|
-
if (!amountUsd) return null;
|
|
7832
|
-
const value = parseFloat(amountUsd);
|
|
7833
|
-
if (value <= 0) return null;
|
|
7834
|
-
return value.toLocaleString(void 0, {
|
|
7835
|
-
minimumFractionDigits: 2,
|
|
7836
|
-
maximumFractionDigits: 2
|
|
7837
|
-
});
|
|
7838
|
-
}
|
|
7839
|
-
function truncateAddress3(address) {
|
|
7840
|
-
if (address.length <= 13) return address;
|
|
7841
|
-
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
7842
|
-
}
|
|
7843
|
-
function formatBalanceDisplay(balance, projectName) {
|
|
7844
|
-
return projectName ? `${projectName} Balance: ${balance}` : `Balance: ${balance}`;
|
|
7845
|
-
}
|
|
7846
|
-
function formatProcessingTime(seconds) {
|
|
7847
|
-
if (seconds === null || seconds === 0) {
|
|
7848
|
-
return "< 1 min";
|
|
7849
|
-
}
|
|
7850
|
-
const minutes = Math.floor(seconds / 60);
|
|
7851
|
-
const remainingSeconds = seconds % 60;
|
|
7852
|
-
if (minutes === 0) {
|
|
7853
|
-
return `< ${remainingSeconds} sec`;
|
|
7854
|
-
} else if (remainingSeconds === 0) {
|
|
7855
|
-
return `< ${minutes} min`;
|
|
7856
|
-
} else {
|
|
7857
|
-
return `< ${minutes} min ${remainingSeconds} sec`;
|
|
7858
|
-
}
|
|
7859
|
-
}
|
|
7860
|
-
|
|
7861
7732
|
// src/components/deposits/browser-wallets/SelectTokenView.tsx
|
|
7862
7733
|
var import_lucide_react17 = require("lucide-react");
|
|
7863
7734
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
7864
7735
|
function SelectTokenView({
|
|
7865
|
-
walletInfo,
|
|
7866
7736
|
projectName,
|
|
7867
7737
|
assetCdnUrl,
|
|
7868
7738
|
balances,
|
|
@@ -7881,27 +7751,12 @@ function SelectTokenView({
|
|
|
7881
7751
|
DepositHeader,
|
|
7882
7752
|
{
|
|
7883
7753
|
title: "Select Token",
|
|
7754
|
+
subtitle: formatBalanceDisplay(`$${totalBalanceUsd || "0.00"}`, projectName),
|
|
7884
7755
|
showBack: true,
|
|
7885
7756
|
onBack,
|
|
7886
7757
|
onClose
|
|
7887
7758
|
}
|
|
7888
7759
|
),
|
|
7889
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
7890
|
-
"div",
|
|
7891
|
-
{
|
|
7892
|
-
className: "uf-flex uf-flex-col uf-w-full uf-items-center uf-pb-3",
|
|
7893
|
-
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
7894
|
-
children: [
|
|
7895
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "uf-text-xs", children: [
|
|
7896
|
-
walletInfo.name,
|
|
7897
|
-
" (",
|
|
7898
|
-
truncateAddress3(walletInfo.address),
|
|
7899
|
-
")"
|
|
7900
|
-
] }),
|
|
7901
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "uf-text-xs", children: formatBalanceDisplay(`$${totalBalanceUsd || "0.00"}`, projectName) })
|
|
7902
|
-
]
|
|
7903
|
-
}
|
|
7904
|
-
),
|
|
7905
7760
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "uf-h-[300px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "uf-space-y-2", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-12", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
7906
7761
|
import_lucide_react17.Loader2,
|
|
7907
7762
|
{
|
|
@@ -7912,6 +7767,7 @@ function SelectTokenView({
|
|
|
7912
7767
|
const token = getTokenFromBalance(balance);
|
|
7913
7768
|
if (!token) return null;
|
|
7914
7769
|
const isEligible = isBalanceEligible(balance);
|
|
7770
|
+
const ineligibilityMessage = getIneligibilityMessage(balance);
|
|
7915
7771
|
const isSelected = selectedBalance && getTokenFromBalance(selectedBalance)?.token_address === token.token_address && getTokenFromBalance(selectedBalance)?.chain_id === token.chain_id;
|
|
7916
7772
|
const formattedAmount = formatTokenAmount(balance.amount, token.decimals, token.symbol);
|
|
7917
7773
|
const formattedUsd = formatUsdAmount(balance.amount_usd);
|
|
@@ -7929,10 +7785,10 @@ function SelectTokenView({
|
|
|
7929
7785
|
children: [
|
|
7930
7786
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
|
|
7931
7787
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "uf-relative uf-w-9 uf-h-9", children: [
|
|
7932
|
-
|
|
7788
|
+
getIconUrl(token.icon_url, assetCdnUrl) ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
7933
7789
|
"img",
|
|
7934
7790
|
{
|
|
7935
|
-
src:
|
|
7791
|
+
src: getIconUrl(token.icon_url, assetCdnUrl),
|
|
7936
7792
|
alt: token.symbol,
|
|
7937
7793
|
width: 36,
|
|
7938
7794
|
height: 36,
|
|
@@ -7947,10 +7803,10 @@ function SelectTokenView({
|
|
|
7947
7803
|
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "uf-text-xs uf-font-medium", style: { color: colors2.foreground }, children: token.symbol.slice(0, 2) })
|
|
7948
7804
|
}
|
|
7949
7805
|
),
|
|
7950
|
-
|
|
7806
|
+
getIconUrl(token.chain_icon_url, assetCdnUrl) && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
7951
7807
|
"img",
|
|
7952
7808
|
{
|
|
7953
|
-
src:
|
|
7809
|
+
src: getIconUrl(token.chain_icon_url, assetCdnUrl),
|
|
7954
7810
|
alt: token.chain_name,
|
|
7955
7811
|
width: 16,
|
|
7956
7812
|
height: 16,
|
|
@@ -7981,7 +7837,7 @@ function SelectTokenView({
|
|
|
7981
7837
|
style: { color: components.card.subtitleColor, fontFamily: fonts.regular },
|
|
7982
7838
|
children: [
|
|
7983
7839
|
token.chain_name,
|
|
7984
|
-
|
|
7840
|
+
ineligibilityMessage && ` \u2022 ${ineligibilityMessage}`
|
|
7985
7841
|
]
|
|
7986
7842
|
}
|
|
7987
7843
|
)
|
|
@@ -8040,8 +7896,6 @@ function SelectTokenView({
|
|
|
8040
7896
|
// src/components/deposits/browser-wallets/EnterAmountView.tsx
|
|
8041
7897
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
8042
7898
|
function EnterAmountView({
|
|
8043
|
-
walletInfo,
|
|
8044
|
-
projectName,
|
|
8045
7899
|
selectedBalance,
|
|
8046
7900
|
selectedToken,
|
|
8047
7901
|
amountUsd,
|
|
@@ -8058,54 +7912,20 @@ function EnterAmountView({
|
|
|
8058
7912
|
onClose
|
|
8059
7913
|
}) {
|
|
8060
7914
|
const { colors: colors2, fonts, components } = useTheme();
|
|
8061
|
-
|
|
7915
|
+
const balanceSubtitle = selectedBalance?.amount_usd ? `Balance: $${parseFloat(selectedBalance.amount_usd).toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} (${formatTokenAmount(selectedBalance.amount, selectedToken.decimals, selectedToken.symbol)} ${selectedToken.symbol})` : `Balance: ${formatTokenAmount(selectedBalance.amount, selectedToken.decimals, selectedToken.symbol)} ${selectedToken.symbol}`;
|
|
7916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
|
|
8062
7917
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8063
7918
|
DepositHeader,
|
|
8064
7919
|
{
|
|
8065
7920
|
title: "Enter Amount",
|
|
7921
|
+
subtitle: balanceSubtitle,
|
|
8066
7922
|
showBack: true,
|
|
8067
7923
|
onBack,
|
|
8068
7924
|
onClose
|
|
8069
7925
|
}
|
|
8070
7926
|
),
|
|
8071
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "uf-text-center uf-
|
|
8072
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8073
|
-
"div",
|
|
8074
|
-
{
|
|
8075
|
-
className: "uf-text-xs",
|
|
8076
|
-
style: { color: colors2.foreground, fontFamily: fonts.regular },
|
|
8077
|
-
children: [
|
|
8078
|
-
walletInfo.name,
|
|
8079
|
-
" (",
|
|
8080
|
-
truncateAddress3(walletInfo.address),
|
|
8081
|
-
")"
|
|
8082
|
-
]
|
|
8083
|
-
}
|
|
8084
|
-
),
|
|
8085
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8086
|
-
"div",
|
|
8087
|
-
{
|
|
8088
|
-
className: "uf-text-sm uf-mt-1",
|
|
8089
|
-
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
8090
|
-
children: selectedBalance?.amount_usd ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
|
|
8091
|
-
"Balance: $",
|
|
8092
|
-
parseFloat(selectedBalance.amount_usd).toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
|
|
8093
|
-
" (",
|
|
8094
|
-
formatTokenAmount(selectedBalance.amount, selectedToken.decimals, selectedToken.symbol),
|
|
8095
|
-
" ",
|
|
8096
|
-
selectedToken.symbol,
|
|
8097
|
-
")"
|
|
8098
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
|
|
8099
|
-
"Balance: ",
|
|
8100
|
-
formatTokenAmount(selectedBalance.amount, selectedToken.decimals, selectedToken.symbol),
|
|
8101
|
-
" ",
|
|
8102
|
-
selectedToken.symbol
|
|
8103
|
-
] })
|
|
8104
|
-
}
|
|
8105
|
-
)
|
|
8106
|
-
] }),
|
|
8107
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "uf-flex-1 uf-overflow-y-auto", children: [
|
|
8108
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "uf-text-center uf-h-[100px] uf-flex uf-flex-col uf-justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-center", children: [
|
|
7927
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "uf-text-center uf-py-6", children: [
|
|
7928
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-center", children: [
|
|
8109
7929
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8110
7930
|
"span",
|
|
8111
7931
|
{
|
|
@@ -8141,60 +7961,57 @@ function EnterAmountView({
|
|
|
8141
7961
|
}
|
|
8142
7962
|
}
|
|
8143
7963
|
)
|
|
8144
|
-
] })
|
|
8145
|
-
formattedTokenAmount && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "uf-text-sm uf-
|
|
7964
|
+
] }),
|
|
7965
|
+
formattedTokenAmount && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: [
|
|
8146
7966
|
"\u2248 ",
|
|
8147
7967
|
formattedTokenAmount
|
|
8148
|
-
] })
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
onClick: () => onAmountChange(quickAmount.toString()),
|
|
8154
|
-
className: "uf-flex-1 uf-py-2 uf-rounded-lg uf-text-sm uf-font-medium uf-transition-colors hover:uf-opacity-80",
|
|
8155
|
-
style: {
|
|
8156
|
-
backgroundColor: components.card.backgroundColor,
|
|
8157
|
-
color: colors2.foreground,
|
|
8158
|
-
fontFamily: fonts.medium
|
|
8159
|
-
},
|
|
8160
|
-
children: [
|
|
8161
|
-
"$",
|
|
8162
|
-
quickAmount
|
|
8163
|
-
]
|
|
8164
|
-
},
|
|
8165
|
-
quickAmount
|
|
8166
|
-
)),
|
|
8167
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8168
|
-
"button",
|
|
8169
|
-
{
|
|
8170
|
-
onClick: onMaxClick,
|
|
8171
|
-
className: "uf-flex-1 uf-py-2 uf-rounded-lg uf-text-sm uf-font-medium uf-transition-colors hover:uf-opacity-80",
|
|
8172
|
-
style: {
|
|
8173
|
-
backgroundColor: colors2.primary + "20",
|
|
8174
|
-
color: colors2.primary,
|
|
8175
|
-
fontFamily: fonts.medium
|
|
8176
|
-
},
|
|
8177
|
-
children: "MAX"
|
|
8178
|
-
}
|
|
8179
|
-
)
|
|
8180
|
-
] }),
|
|
8181
|
-
tokenChainDetails && tokenChainDetails.minimum_deposit_amount_usd > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8182
|
-
"div",
|
|
7968
|
+
] })
|
|
7969
|
+
] }),
|
|
7970
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "uf-flex uf-gap-2 uf-mb-4", children: [
|
|
7971
|
+
[25, 50, 100, 500].map((quickAmount) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
7972
|
+
"button",
|
|
8183
7973
|
{
|
|
8184
|
-
|
|
7974
|
+
onClick: () => onAmountChange(quickAmount.toString()),
|
|
7975
|
+
className: "uf-flex-1 uf-py-2 uf-rounded-lg uf-text-sm uf-font-medium uf-transition-colors hover:uf-opacity-80",
|
|
8185
7976
|
style: {
|
|
8186
|
-
|
|
8187
|
-
|
|
7977
|
+
backgroundColor: components.card.backgroundColor,
|
|
7978
|
+
color: colors2.foreground,
|
|
7979
|
+
fontFamily: fonts.medium
|
|
8188
7980
|
},
|
|
8189
7981
|
children: [
|
|
8190
|
-
"
|
|
8191
|
-
|
|
7982
|
+
"$",
|
|
7983
|
+
quickAmount
|
|
8192
7984
|
]
|
|
7985
|
+
},
|
|
7986
|
+
quickAmount
|
|
7987
|
+
)),
|
|
7988
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7989
|
+
"button",
|
|
7990
|
+
{
|
|
7991
|
+
onClick: onMaxClick,
|
|
7992
|
+
className: "uf-flex-1 uf-py-2 uf-rounded-lg uf-text-sm uf-font-medium uf-transition-colors hover:uf-opacity-80",
|
|
7993
|
+
style: {
|
|
7994
|
+
backgroundColor: colors2.primary + "20",
|
|
7995
|
+
color: colors2.primary,
|
|
7996
|
+
fontFamily: fonts.medium
|
|
7997
|
+
},
|
|
7998
|
+
children: "MAX"
|
|
8193
7999
|
}
|
|
8194
|
-
)
|
|
8195
|
-
inputUsdNum > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_jsx_runtime41.Fragment, { children: inputUsdNum > maxUsdAmount ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "uf-text-center uf-text-sm uf-mb-2", style: { color: colors2.error }, children: "Insufficient balance" }) : error && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "uf-text-center uf-text-sm uf-mb-2 uf-px-2", style: { color: colors2.error }, children: error }) })
|
|
8000
|
+
)
|
|
8196
8001
|
] }),
|
|
8197
|
-
|
|
8002
|
+
tokenChainDetails && tokenChainDetails.minimum_deposit_amount_usd > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8003
|
+
"div",
|
|
8004
|
+
{
|
|
8005
|
+
className: "uf-text-center uf-text-xs uf-mb-3",
|
|
8006
|
+
style: { color: colors2.warning, fontFamily: fonts.regular },
|
|
8007
|
+
children: [
|
|
8008
|
+
"Minimum deposit: $",
|
|
8009
|
+
tokenChainDetails.minimum_deposit_amount_usd.toFixed(2)
|
|
8010
|
+
]
|
|
8011
|
+
}
|
|
8012
|
+
),
|
|
8013
|
+
inputUsdNum > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_jsx_runtime41.Fragment, { children: inputUsdNum > maxUsdAmount ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "uf-text-center uf-text-sm uf-mb-3", style: { color: colors2.error }, children: "Insufficient balance" }) : error && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "uf-text-center uf-text-sm uf-mb-3 uf-px-2", style: { color: colors2.error }, children: error }) }),
|
|
8014
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8198
8015
|
"button",
|
|
8199
8016
|
{
|
|
8200
8017
|
onClick: onReview,
|
|
@@ -8207,7 +8024,7 @@ function EnterAmountView({
|
|
|
8207
8024
|
},
|
|
8208
8025
|
children: "Review"
|
|
8209
8026
|
}
|
|
8210
|
-
)
|
|
8027
|
+
)
|
|
8211
8028
|
] });
|
|
8212
8029
|
}
|
|
8213
8030
|
|
|
@@ -8275,10 +8092,10 @@ function ReviewView({
|
|
|
8275
8092
|
}
|
|
8276
8093
|
),
|
|
8277
8094
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
|
|
8278
|
-
|
|
8095
|
+
getIconUrl(selectedToken.icon_url, assetCdnUrl) && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8279
8096
|
"img",
|
|
8280
8097
|
{
|
|
8281
|
-
src:
|
|
8098
|
+
src: getIconUrl(selectedToken.icon_url, assetCdnUrl),
|
|
8282
8099
|
alt: selectedToken.symbol,
|
|
8283
8100
|
className: "uf-w-5 uf-h-5 uf-rounded-full"
|
|
8284
8101
|
}
|
|
@@ -8291,7 +8108,7 @@ function ReviewView({
|
|
|
8291
8108
|
children: [
|
|
8292
8109
|
walletInfo.name,
|
|
8293
8110
|
" (",
|
|
8294
|
-
|
|
8111
|
+
truncateAddress2(walletInfo.address),
|
|
8295
8112
|
")"
|
|
8296
8113
|
]
|
|
8297
8114
|
}
|
|
@@ -8312,7 +8129,7 @@ function ReviewView({
|
|
|
8312
8129
|
{
|
|
8313
8130
|
className: "uf-text-sm uf-font-medium",
|
|
8314
8131
|
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
8315
|
-
children:
|
|
8132
|
+
children: truncateAddress2(recipientAddress)
|
|
8316
8133
|
}
|
|
8317
8134
|
)
|
|
8318
8135
|
] }),
|
|
@@ -8516,7 +8333,7 @@ function BrowserWalletModal({
|
|
|
8516
8333
|
const themeClass = theme === "dark" ? "uf-dark" : "";
|
|
8517
8334
|
const chainType = depositWallet.chain_type;
|
|
8518
8335
|
const recipientAddress = depositWallet.address;
|
|
8519
|
-
const supportedChainType = chainType === "algorand" ? "ethereum" : chainType;
|
|
8336
|
+
const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
|
|
8520
8337
|
const { executions: depositExecutions, isPolling } = useDepositPolling({
|
|
8521
8338
|
userId,
|
|
8522
8339
|
publishableKey,
|
|
@@ -8927,20 +8744,6 @@ function BrowserWalletModal({
|
|
|
8927
8744
|
if (tokenAmount === 0 || !selectedToken) return null;
|
|
8928
8745
|
return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
|
|
8929
8746
|
}, [tokenAmount, selectedToken]);
|
|
8930
|
-
const getTitle = () => {
|
|
8931
|
-
switch (step) {
|
|
8932
|
-
case "select-token":
|
|
8933
|
-
return "Select Token";
|
|
8934
|
-
case "input-amount":
|
|
8935
|
-
return "Enter Amount";
|
|
8936
|
-
case "review":
|
|
8937
|
-
return "Review";
|
|
8938
|
-
case "confirming":
|
|
8939
|
-
return "Confirming...";
|
|
8940
|
-
default:
|
|
8941
|
-
return "Browser Wallet";
|
|
8942
|
-
}
|
|
8943
|
-
};
|
|
8944
8747
|
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_jsx_runtime44.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8945
8748
|
Dialog,
|
|
8946
8749
|
{
|
|
@@ -8962,7 +8765,6 @@ function BrowserWalletModal({
|
|
|
8962
8765
|
step === "select-token" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8963
8766
|
SelectTokenView,
|
|
8964
8767
|
{
|
|
8965
|
-
walletInfo,
|
|
8966
8768
|
projectName,
|
|
8967
8769
|
assetCdnUrl,
|
|
8968
8770
|
balances,
|
|
@@ -8979,8 +8781,6 @@ function BrowserWalletModal({
|
|
|
8979
8781
|
step === "input-amount" && selectedToken && selectedBalance && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
8980
8782
|
EnterAmountView,
|
|
8981
8783
|
{
|
|
8982
|
-
walletInfo,
|
|
8983
|
-
projectName,
|
|
8984
8784
|
selectedBalance,
|
|
8985
8785
|
selectedToken,
|
|
8986
8786
|
amountUsd,
|
|
@@ -9332,6 +9132,7 @@ function WalletSelectionModal({
|
|
|
9332
9132
|
if (!accounts || accounts.length === 0) {
|
|
9333
9133
|
throw new Error("No accounts returned from wallet");
|
|
9334
9134
|
}
|
|
9135
|
+
setUserDisconnectedWallet(false);
|
|
9335
9136
|
const address = accounts[0];
|
|
9336
9137
|
const walletType = wallet.id === "phantom" ? "phantom-ethereum" : wallet.id === "coinbase" ? "coinbase" : "metamask";
|
|
9337
9138
|
onWalletConnected({
|
|
@@ -9371,6 +9172,7 @@ function WalletSelectionModal({
|
|
|
9371
9172
|
}
|
|
9372
9173
|
const response = await provider.connect();
|
|
9373
9174
|
const address = response.publicKey.toString();
|
|
9175
|
+
setUserDisconnectedWallet(false);
|
|
9374
9176
|
const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
|
|
9375
9177
|
onWalletConnected({
|
|
9376
9178
|
type: walletType,
|
|
@@ -9678,6 +9480,7 @@ function DepositModal({
|
|
|
9678
9480
|
hideDepositTracker = false,
|
|
9679
9481
|
showBalanceHeader = false,
|
|
9680
9482
|
transferInputVariant = "double_input",
|
|
9483
|
+
depositConfirmationMode = "auto_ui",
|
|
9681
9484
|
enableConnectWallet = false,
|
|
9682
9485
|
onDepositSuccess,
|
|
9683
9486
|
onDepositError,
|
|
@@ -9769,6 +9572,7 @@ function DepositModal({
|
|
|
9769
9572
|
};
|
|
9770
9573
|
const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
|
|
9771
9574
|
const handleWalletDisconnect = () => {
|
|
9575
|
+
setUserDisconnectedWallet(true);
|
|
9772
9576
|
clearStoredWalletChainType();
|
|
9773
9577
|
setBrowserWalletChainType(void 0);
|
|
9774
9578
|
setBrowserWalletInfo(null);
|
|
@@ -9860,6 +9664,7 @@ function DepositModal({
|
|
|
9860
9664
|
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
|
|
9861
9665
|
balanceChainId: destinationChainId,
|
|
9862
9666
|
balanceTokenAddress: destinationTokenAddress,
|
|
9667
|
+
projectName: projectConfig?.project_name,
|
|
9863
9668
|
publishableKey
|
|
9864
9669
|
}
|
|
9865
9670
|
),
|
|
@@ -9940,7 +9745,14 @@ function DepositModal({
|
|
|
9940
9745
|
title: t5.transferCrypto.title,
|
|
9941
9746
|
showBack: true,
|
|
9942
9747
|
onBack: handleBack,
|
|
9943
|
-
onClose: handleClose
|
|
9748
|
+
onClose: handleClose,
|
|
9749
|
+
showBalance: showBalanceHeader,
|
|
9750
|
+
balanceAddress: recipientAddress,
|
|
9751
|
+
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
|
|
9752
|
+
balanceChainId: destinationChainId,
|
|
9753
|
+
balanceTokenAddress: destinationTokenAddress,
|
|
9754
|
+
projectName: projectConfig?.project_name,
|
|
9755
|
+
publishableKey
|
|
9944
9756
|
}
|
|
9945
9757
|
),
|
|
9946
9758
|
transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
@@ -9952,6 +9764,7 @@ function DepositModal({
|
|
|
9952
9764
|
destinationChainType,
|
|
9953
9765
|
destinationChainId,
|
|
9954
9766
|
destinationTokenAddress,
|
|
9767
|
+
depositConfirmationMode,
|
|
9955
9768
|
onExecutionsChange: setDepositExecutions,
|
|
9956
9769
|
onDepositSuccess,
|
|
9957
9770
|
onDepositError,
|
|
@@ -9966,6 +9779,7 @@ function DepositModal({
|
|
|
9966
9779
|
destinationChainType,
|
|
9967
9780
|
destinationChainId,
|
|
9968
9781
|
destinationTokenAddress,
|
|
9782
|
+
depositConfirmationMode,
|
|
9969
9783
|
onExecutionsChange: setDepositExecutions,
|
|
9970
9784
|
onDepositSuccess,
|
|
9971
9785
|
onDepositError,
|
|
@@ -9980,7 +9794,14 @@ function DepositModal({
|
|
|
9980
9794
|
showBack: true,
|
|
9981
9795
|
onBack: handleBack,
|
|
9982
9796
|
onClose: handleClose,
|
|
9983
|
-
badge: cardView === "quotes" ? { count: quotesCount } : void 0
|
|
9797
|
+
badge: cardView === "quotes" ? { count: quotesCount } : void 0,
|
|
9798
|
+
showBalance: showBalanceHeader,
|
|
9799
|
+
balanceAddress: recipientAddress,
|
|
9800
|
+
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
|
|
9801
|
+
balanceChainId: destinationChainId,
|
|
9802
|
+
balanceTokenAddress: destinationTokenAddress,
|
|
9803
|
+
projectName: projectConfig?.project_name,
|
|
9804
|
+
publishableKey
|
|
9984
9805
|
}
|
|
9985
9806
|
),
|
|
9986
9807
|
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
@@ -10131,6 +9952,7 @@ Button.displayName = "Button";
|
|
|
10131
9952
|
DepositExecutionItem,
|
|
10132
9953
|
DepositHeader,
|
|
10133
9954
|
DepositModal,
|
|
9955
|
+
DepositPollingUi,
|
|
10134
9956
|
DepositSuccessToast,
|
|
10135
9957
|
DepositTrackerButton,
|
|
10136
9958
|
DepositWithCardButton,
|
|
@@ -10165,16 +9987,14 @@ Button.displayName = "Button";
|
|
|
10165
9987
|
TransferCryptoDoubleInput,
|
|
10166
9988
|
TransferCryptoSingleInput,
|
|
10167
9989
|
buttonVariants,
|
|
10168
|
-
clearQRCodeCache,
|
|
10169
9990
|
cn,
|
|
10170
9991
|
colors,
|
|
10171
9992
|
defaultColors,
|
|
10172
9993
|
getColors,
|
|
10173
|
-
isQRCodeCached,
|
|
10174
9994
|
mergeColors,
|
|
10175
|
-
preloadQRCode,
|
|
10176
9995
|
resolveComponentTokens,
|
|
10177
9996
|
truncateAddress,
|
|
10178
9997
|
useAllowedCountry,
|
|
9998
|
+
useDepositPolling,
|
|
10179
9999
|
useTheme
|
|
10180
10000
|
});
|