@unifold/ui-react 0.1.69 → 0.1.70-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +52 -17
- package/dist/index.d.ts +52 -17
- package/dist/index.js +680 -284
- package/dist/index.mjs +639 -242
- package/dist/styles-base.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
useState as useState40,
|
|
4
4
|
useEffect as useEffect34,
|
|
5
5
|
useLayoutEffect as useLayoutEffect2,
|
|
6
|
-
useCallback as
|
|
6
|
+
useCallback as useCallback11,
|
|
7
7
|
useRef as useRef13,
|
|
8
8
|
useMemo as useMemo14
|
|
9
9
|
} from "react";
|
|
10
|
-
import { ChevronRight as ChevronRight18, MapPinOff as MapPinOff2, AlertTriangle as
|
|
10
|
+
import { ChevronRight as ChevronRight18, MapPinOff as MapPinOff2, AlertTriangle as AlertTriangle4, Bitcoin, DollarSign as DollarSign3 } from "lucide-react";
|
|
11
11
|
|
|
12
12
|
// src/components/shared/dialog.tsx
|
|
13
13
|
import * as React3 from "react";
|
|
@@ -600,7 +600,8 @@ import {
|
|
|
600
600
|
// src/hooks/use-deposit-address.ts
|
|
601
601
|
import { useQuery } from "@tanstack/react-query";
|
|
602
602
|
import {
|
|
603
|
-
createDepositAddress
|
|
603
|
+
createDepositAddress,
|
|
604
|
+
isDepositAddressValidationError
|
|
604
605
|
} from "@unifold/core";
|
|
605
606
|
function useDepositAddress(params) {
|
|
606
607
|
const {
|
|
@@ -646,7 +647,13 @@ function useDepositAddress(params) {
|
|
|
646
647
|
// 24 hours in cache
|
|
647
648
|
refetchOnMount: false,
|
|
648
649
|
refetchOnWindowFocus: false,
|
|
649
|
-
retry
|
|
650
|
+
// Don't retry recipient-address validation errors — they're deterministic
|
|
651
|
+
// (a 400 won't succeed on retry) and we want to surface the invalid-address
|
|
652
|
+
// screen immediately rather than after 3 backoff attempts.
|
|
653
|
+
retry: (failureCount, error) => {
|
|
654
|
+
if (isDepositAddressValidationError(error)) return false;
|
|
655
|
+
return failureCount < 3;
|
|
656
|
+
},
|
|
650
657
|
retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
|
|
651
658
|
// 1s, 2s, 4s (max 10s)
|
|
652
659
|
});
|
|
@@ -667,7 +674,7 @@ function useDebounce(value, delay) {
|
|
|
667
674
|
import { useState as useState5 } from "react";
|
|
668
675
|
|
|
669
676
|
// src/components/deposits/DepositHeader.tsx
|
|
670
|
-
import { ArrowLeft, X as X2 } from "lucide-react";
|
|
677
|
+
import { AlertTriangle, ArrowLeft, Info, X as X2 } from "lucide-react";
|
|
671
678
|
import { useEffect as useEffect3, useLayoutEffect, useState as useState3 } from "react";
|
|
672
679
|
import { getAddressBalance } from "@unifold/core";
|
|
673
680
|
|
|
@@ -873,7 +880,8 @@ function DepositHeader({
|
|
|
873
880
|
balanceChainId,
|
|
874
881
|
balanceTokenAddress,
|
|
875
882
|
projectName,
|
|
876
|
-
publishableKey
|
|
883
|
+
publishableKey,
|
|
884
|
+
incident
|
|
877
885
|
}) {
|
|
878
886
|
const { colors: colors2, fonts, components } = useTheme();
|
|
879
887
|
const [balance, setBalance] = useState3(null);
|
|
@@ -971,19 +979,64 @@ function DepositHeader({
|
|
|
971
979
|
balanceTokenAddress,
|
|
972
980
|
publishableKey
|
|
973
981
|
]);
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
982
|
+
const incidentMessages = incident?.messages ?? [];
|
|
983
|
+
const showIncident = incident?.enabled && incidentMessages.length > 0;
|
|
984
|
+
const incidentSeverity = incident?.severity ?? "degraded";
|
|
985
|
+
const incidentSeverityLabel = incidentSeverity === "outage" ? "Outage" : incidentSeverity === "info" ? "Info" : "Degraded service";
|
|
986
|
+
const incidentStyles = incidentSeverity === "outage" ? {
|
|
987
|
+
bg: "rgba(239, 68, 68, 0.12)",
|
|
988
|
+
border: "rgba(239, 68, 68, 0.35)",
|
|
989
|
+
text: "#fca5a5",
|
|
990
|
+
link: "#fca5a5"
|
|
991
|
+
} : incidentSeverity === "info" ? {
|
|
992
|
+
bg: "rgba(59, 130, 246, 0.12)",
|
|
993
|
+
border: "rgba(59, 130, 246, 0.35)",
|
|
994
|
+
text: "#93c5fd",
|
|
995
|
+
link: "#93c5fd"
|
|
996
|
+
} : {
|
|
997
|
+
bg: "rgba(245, 158, 11, 0.12)",
|
|
998
|
+
border: "rgba(245, 158, 11, 0.35)",
|
|
999
|
+
text: "#fcd34d",
|
|
1000
|
+
link: "#fcd34d"
|
|
1001
|
+
};
|
|
1002
|
+
const IncidentIcon = incidentSeverity === "info" ? Info : AlertTriangle;
|
|
1003
|
+
return /* @__PURE__ */ jsxs3("div", { children: [
|
|
1004
|
+
/* @__PURE__ */ jsxs3("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-6", children: [
|
|
1005
|
+
showBack ? /* @__PURE__ */ jsx4(
|
|
1006
|
+
"button",
|
|
1007
|
+
{
|
|
1008
|
+
onClick: onBack,
|
|
1009
|
+
className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
|
|
1010
|
+
style: { color: components.header.buttonColor },
|
|
1011
|
+
children: /* @__PURE__ */ jsx4(ArrowLeft, { className: "uf-w-5 uf-h-5" })
|
|
1012
|
+
}
|
|
1013
|
+
) : /* @__PURE__ */ jsx4("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
|
|
1014
|
+
/* @__PURE__ */ jsxs3("div", { className: "uf-flex uf-flex-col uf-items-center", children: [
|
|
1015
|
+
badge ? /* @__PURE__ */ jsxs3("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
|
|
1016
|
+
/* @__PURE__ */ jsx4(
|
|
1017
|
+
DialogTitle,
|
|
1018
|
+
{
|
|
1019
|
+
className: "uf-text-center uf-text-base",
|
|
1020
|
+
style: {
|
|
1021
|
+
color: components.header.titleColor,
|
|
1022
|
+
fontFamily: fonts.medium
|
|
1023
|
+
},
|
|
1024
|
+
children: title
|
|
1025
|
+
}
|
|
1026
|
+
),
|
|
1027
|
+
/* @__PURE__ */ jsx4(
|
|
1028
|
+
"div",
|
|
1029
|
+
{
|
|
1030
|
+
className: "uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px]",
|
|
1031
|
+
style: {
|
|
1032
|
+
backgroundColor: colors2.card,
|
|
1033
|
+
color: colors2.foregroundMuted,
|
|
1034
|
+
fontFamily: fonts.regular
|
|
1035
|
+
},
|
|
1036
|
+
children: badge.count
|
|
1037
|
+
}
|
|
1038
|
+
)
|
|
1039
|
+
] }) : /* @__PURE__ */ jsx4(
|
|
987
1040
|
DialogTitle,
|
|
988
1041
|
{
|
|
989
1042
|
className: "uf-text-center uf-text-base",
|
|
@@ -994,61 +1047,91 @@ function DepositHeader({
|
|
|
994
1047
|
children: title
|
|
995
1048
|
}
|
|
996
1049
|
),
|
|
997
|
-
/* @__PURE__ */ jsx4(
|
|
1050
|
+
subtitle ? /* @__PURE__ */ jsx4(
|
|
998
1051
|
"div",
|
|
999
1052
|
{
|
|
1000
|
-
className: "uf-
|
|
1053
|
+
className: "uf-text-xs uf-mt-1",
|
|
1001
1054
|
style: {
|
|
1002
|
-
backgroundColor: colors2.card,
|
|
1003
1055
|
color: colors2.foregroundMuted,
|
|
1004
1056
|
fontFamily: fonts.regular
|
|
1005
1057
|
},
|
|
1006
|
-
children:
|
|
1058
|
+
children: subtitle
|
|
1007
1059
|
}
|
|
1008
|
-
)
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
),
|
|
1020
|
-
|
|
1021
|
-
"
|
|
1022
|
-
{
|
|
1023
|
-
className: "uf-text-xs uf-mt-1",
|
|
1024
|
-
style: {
|
|
1025
|
-
color: colors2.foregroundMuted,
|
|
1026
|
-
fontFamily: fonts.regular
|
|
1027
|
-
},
|
|
1028
|
-
children: subtitle
|
|
1029
|
-
}
|
|
1030
|
-
) : showBalanceBlock ? isLoadingBalance && showBalanceSkeleton ? /* @__PURE__ */ jsx4("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-1" }) : balance ? /* @__PURE__ */ jsx4(
|
|
1031
|
-
"div",
|
|
1060
|
+
) : showBalanceBlock ? isLoadingBalance && showBalanceSkeleton ? /* @__PURE__ */ jsx4("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-1" }) : balance ? /* @__PURE__ */ jsx4(
|
|
1061
|
+
"div",
|
|
1062
|
+
{
|
|
1063
|
+
className: "uf-text-xs uf-mt-1",
|
|
1064
|
+
style: {
|
|
1065
|
+
color: colors2.foregroundMuted,
|
|
1066
|
+
fontFamily: fonts.regular
|
|
1067
|
+
},
|
|
1068
|
+
children: formatBalanceDisplay(balance, projectName)
|
|
1069
|
+
}
|
|
1070
|
+
) : null : null
|
|
1071
|
+
] }),
|
|
1072
|
+
showClose ? /* @__PURE__ */ jsx4(
|
|
1073
|
+
"button",
|
|
1032
1074
|
{
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
},
|
|
1038
|
-
children: formatBalanceDisplay(balance, projectName)
|
|
1075
|
+
onClick: onClose,
|
|
1076
|
+
className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
|
|
1077
|
+
style: { color: components.header.buttonColor },
|
|
1078
|
+
children: /* @__PURE__ */ jsx4(X2, { className: "uf-w-5 uf-h-5" })
|
|
1039
1079
|
}
|
|
1040
|
-
) :
|
|
1080
|
+
) : /* @__PURE__ */ jsx4("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
|
|
1041
1081
|
] }),
|
|
1042
|
-
|
|
1043
|
-
"
|
|
1082
|
+
showIncident && /* @__PURE__ */ jsx4(
|
|
1083
|
+
"div",
|
|
1044
1084
|
{
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1085
|
+
className: "uf-rounded-lg uf-px-3 uf-py-2.5 uf-mb-4",
|
|
1086
|
+
style: {
|
|
1087
|
+
backgroundColor: incidentStyles.bg,
|
|
1088
|
+
border: `1px solid ${incidentStyles.border}`
|
|
1089
|
+
},
|
|
1090
|
+
children: /* @__PURE__ */ jsxs3("div", { className: "uf-flex uf-items-start uf-gap-2.5", children: [
|
|
1091
|
+
/* @__PURE__ */ jsx4(
|
|
1092
|
+
IncidentIcon,
|
|
1093
|
+
{
|
|
1094
|
+
className: "uf-w-4 uf-h-4 uf-mt-0.5 uf-shrink-0",
|
|
1095
|
+
style: { color: incidentStyles.text }
|
|
1096
|
+
}
|
|
1097
|
+
),
|
|
1098
|
+
/* @__PURE__ */ jsxs3("div", { className: "uf-min-w-0 uf-flex-1", children: [
|
|
1099
|
+
/* @__PURE__ */ jsx4("div", { className: "uf-flex uf-items-center uf-gap-2 uf-mb-1.5", children: /* @__PURE__ */ jsx4(
|
|
1100
|
+
"span",
|
|
1101
|
+
{
|
|
1102
|
+
className: "uf-text-[11px] uf-leading-none uf-px-1.5 uf-py-1 uf-rounded-md",
|
|
1103
|
+
style: {
|
|
1104
|
+
color: incidentStyles.text,
|
|
1105
|
+
border: `1px solid ${incidentStyles.border}`,
|
|
1106
|
+
fontFamily: fonts.medium
|
|
1107
|
+
},
|
|
1108
|
+
children: incidentSeverityLabel
|
|
1109
|
+
}
|
|
1110
|
+
) }),
|
|
1111
|
+
/* @__PURE__ */ jsx4(
|
|
1112
|
+
"div",
|
|
1113
|
+
{
|
|
1114
|
+
className: "uf-space-y-1",
|
|
1115
|
+
style: { color: incidentStyles.text, fontFamily: fonts.regular },
|
|
1116
|
+
children: incidentMessages.map((message, index) => /* @__PURE__ */ jsx4("p", { className: "uf-text-xs uf-leading-relaxed", children: message }, `${message}-${index}`))
|
|
1117
|
+
}
|
|
1118
|
+
),
|
|
1119
|
+
incident.statusPageUrl && /* @__PURE__ */ jsx4(
|
|
1120
|
+
"a",
|
|
1121
|
+
{
|
|
1122
|
+
href: incident.statusPageUrl,
|
|
1123
|
+
target: "_blank",
|
|
1124
|
+
rel: "noreferrer",
|
|
1125
|
+
className: "uf-inline-block uf-mt-1.5 uf-text-xs uf-underline uf-underline-offset-2",
|
|
1126
|
+
style: { color: incidentStyles.link, fontFamily: fonts.medium },
|
|
1127
|
+
children: "View status"
|
|
1128
|
+
}
|
|
1129
|
+
)
|
|
1130
|
+
] })
|
|
1131
|
+
] })
|
|
1049
1132
|
}
|
|
1050
|
-
)
|
|
1051
|
-
] })
|
|
1133
|
+
)
|
|
1134
|
+
] });
|
|
1052
1135
|
}
|
|
1053
1136
|
|
|
1054
1137
|
// src/components/currency/CurrencyListItem.tsx
|
|
@@ -1386,7 +1469,8 @@ var en_default = {
|
|
|
1386
1469
|
},
|
|
1387
1470
|
stripeLink: {
|
|
1388
1471
|
title: "Pay with Link",
|
|
1389
|
-
subtitle: "Buy with card or bank"
|
|
1472
|
+
subtitle: "Buy with card or bank",
|
|
1473
|
+
unavailableInRegionMessage: "Pay with Link is currently unavailable in your region."
|
|
1390
1474
|
},
|
|
1391
1475
|
browserWallet: {
|
|
1392
1476
|
title: "Connect Wallet",
|
|
@@ -7885,7 +7969,7 @@ function AppleLogo({ className, style }) {
|
|
|
7885
7969
|
}
|
|
7886
7970
|
);
|
|
7887
7971
|
}
|
|
7888
|
-
function ApplePayButton({ onClick, title, subtitle }) {
|
|
7972
|
+
function ApplePayButton({ onClick, title, subtitle, iconUrl }) {
|
|
7889
7973
|
const { colors: colors2, fonts, components } = useTheme();
|
|
7890
7974
|
const [isHovered, setIsHovered] = React14.useState(false);
|
|
7891
7975
|
const [isTouchDevice, setIsTouchDevice] = React14.useState(false);
|
|
@@ -7907,7 +7991,14 @@ function ApplePayButton({ onClick, title, subtitle }) {
|
|
|
7907
7991
|
},
|
|
7908
7992
|
children: [
|
|
7909
7993
|
/* @__PURE__ */ jsxs23("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
|
|
7910
|
-
/* @__PURE__ */ jsx26("div", { className: "uf-rounded-lg uf-
|
|
7994
|
+
/* @__PURE__ */ jsx26("div", { className: "uf-rounded-lg uf-overflow-hidden uf-w-9 uf-h-9 uf-flex uf-items-center uf-justify-center", children: iconUrl ? /* @__PURE__ */ jsx26("img", { src: iconUrl, alt: "Apple Pay", width: 36, height: 36, className: "uf-rounded-lg" }) : /* @__PURE__ */ jsx26(
|
|
7995
|
+
"div",
|
|
7996
|
+
{
|
|
7997
|
+
className: "uf-w-9 uf-h-9 uf-rounded-lg uf-flex uf-items-center uf-justify-center",
|
|
7998
|
+
style: { backgroundColor: "#000" },
|
|
7999
|
+
children: /* @__PURE__ */ jsx26(AppleLogo, { className: "uf-w-5 uf-h-5", style: { color: "#fff" } })
|
|
8000
|
+
}
|
|
8001
|
+
) }),
|
|
7911
8002
|
/* @__PURE__ */ jsxs23("div", { className: "uf-text-left", children: [
|
|
7912
8003
|
/* @__PURE__ */ jsx26(
|
|
7913
8004
|
"div",
|
|
@@ -8141,13 +8232,6 @@ function solanaCandidate(provider, type, name, icon) {
|
|
|
8141
8232
|
if (provider.isConnected && provider.publicKey) {
|
|
8142
8233
|
return { type, name, address: provider.publicKey.toString(), icon };
|
|
8143
8234
|
}
|
|
8144
|
-
try {
|
|
8145
|
-
const resp = await provider.connect({ onlyIfTrusted: true });
|
|
8146
|
-
if (resp.publicKey) {
|
|
8147
|
-
return { type, name, address: resp.publicKey.toString(), icon };
|
|
8148
|
-
}
|
|
8149
|
-
} catch {
|
|
8150
|
-
}
|
|
8151
8235
|
return null;
|
|
8152
8236
|
}
|
|
8153
8237
|
};
|
|
@@ -8376,6 +8460,180 @@ async function disconnectInjectedBrowserWallet(wallet) {
|
|
|
8376
8460
|
);
|
|
8377
8461
|
}
|
|
8378
8462
|
|
|
8463
|
+
// src/components/deposits/browser-wallets/providerResolvers.ts
|
|
8464
|
+
var STORED_TYPE_TO_EIP6963_WALLET_ID = {
|
|
8465
|
+
metamask: "metamask",
|
|
8466
|
+
"phantom-ethereum": "phantom",
|
|
8467
|
+
coinbase: "coinbase",
|
|
8468
|
+
trust: "trust",
|
|
8469
|
+
rainbow: "rainbow",
|
|
8470
|
+
rabby: "rabby",
|
|
8471
|
+
okx: "okx"
|
|
8472
|
+
};
|
|
8473
|
+
var EIP6963_WALLET_ID_TO_INFO = {
|
|
8474
|
+
metamask: { walletType: "metamask", name: "MetaMask", icon: "metamask" },
|
|
8475
|
+
phantom: { walletType: "phantom-ethereum", name: "Phantom", icon: "phantom" },
|
|
8476
|
+
coinbase: { walletType: "coinbase", name: "Coinbase Wallet", icon: "coinbase" },
|
|
8477
|
+
trust: { walletType: "trust", name: "Trust Wallet", icon: "trust" },
|
|
8478
|
+
rainbow: { walletType: "rainbow", name: "Rainbow", icon: "rainbow" },
|
|
8479
|
+
rabby: { walletType: "rabby", name: "Rabby", icon: "rabby" },
|
|
8480
|
+
okx: { walletType: "okx", name: "OKX Wallet", icon: "okx" }
|
|
8481
|
+
};
|
|
8482
|
+
var WALLET_ID_TO_WALLET_TYPE = {
|
|
8483
|
+
phantom: "phantom-ethereum",
|
|
8484
|
+
coinbase: "coinbase",
|
|
8485
|
+
trust: "trust",
|
|
8486
|
+
rainbow: "rainbow",
|
|
8487
|
+
rabby: "rabby",
|
|
8488
|
+
okx: "okx",
|
|
8489
|
+
metamask: "metamask"
|
|
8490
|
+
};
|
|
8491
|
+
var WALLET_TYPE_TO_WALLET_ID = {
|
|
8492
|
+
"phantom-ethereum": "phantom",
|
|
8493
|
+
coinbase: "coinbase",
|
|
8494
|
+
trust: "trust",
|
|
8495
|
+
okx: "okx",
|
|
8496
|
+
rainbow: "rainbow",
|
|
8497
|
+
rabby: "rabby",
|
|
8498
|
+
metamask: "metamask"
|
|
8499
|
+
};
|
|
8500
|
+
function isWalletType(value) {
|
|
8501
|
+
return value === "phantom-solana" || value === "phantom-ethereum" || value === "metamask" || value === "coinbase" || value === "solflare" || value === "backpack" || value === "glow" || value === "trust" || value === "rainbow" || value === "rabby" || value === "okx";
|
|
8502
|
+
}
|
|
8503
|
+
function walletIdToWalletType(walletId) {
|
|
8504
|
+
return WALLET_ID_TO_WALLET_TYPE[walletId] || "metamask";
|
|
8505
|
+
}
|
|
8506
|
+
function walletTypeToWalletId(walletType) {
|
|
8507
|
+
return WALLET_TYPE_TO_WALLET_ID[walletType] || walletType;
|
|
8508
|
+
}
|
|
8509
|
+
function getLegacyEvmProviders(win) {
|
|
8510
|
+
if (!win) return {};
|
|
8511
|
+
const anyWin = win;
|
|
8512
|
+
return {
|
|
8513
|
+
ethereum: anyWin.ethereum,
|
|
8514
|
+
phantomEthereum: anyWin.phantom?.ethereum,
|
|
8515
|
+
coinbaseEthereum: anyWin.coinbaseWalletExtension,
|
|
8516
|
+
trustEthereum: anyWin.trustwallet?.ethereum,
|
|
8517
|
+
okxEthereum: anyWin.okxwallet
|
|
8518
|
+
};
|
|
8519
|
+
}
|
|
8520
|
+
function getInjectedSolanaProviders(win) {
|
|
8521
|
+
if (!win) return {};
|
|
8522
|
+
const anyWin = win;
|
|
8523
|
+
return {
|
|
8524
|
+
phantomSolana: anyWin.phantom?.solana,
|
|
8525
|
+
solflare: anyWin.solflare,
|
|
8526
|
+
backpack: anyWin.backpack,
|
|
8527
|
+
glow: anyWin.glow,
|
|
8528
|
+
coinbaseSolana: anyWin.coinbaseSolana || anyWin.coinbaseWalletExtension?.solana,
|
|
8529
|
+
trustSolana: anyWin.trustwallet?.solana
|
|
8530
|
+
};
|
|
8531
|
+
}
|
|
8532
|
+
function describeEip6963Provider(wp) {
|
|
8533
|
+
const mapped = EIP6963_WALLET_ID_TO_INFO[wp.walletId];
|
|
8534
|
+
return {
|
|
8535
|
+
provider: wp.provider,
|
|
8536
|
+
walletType: mapped?.walletType ?? "metamask",
|
|
8537
|
+
name: mapped?.name ?? wp.info.name,
|
|
8538
|
+
icon: mapped?.icon ?? wp.info.icon
|
|
8539
|
+
};
|
|
8540
|
+
}
|
|
8541
|
+
function resolveQuickConnectEvmProvider(win) {
|
|
8542
|
+
const eip6963Providers = getEip6963Providers();
|
|
8543
|
+
if (eip6963Providers.length > 0) {
|
|
8544
|
+
const stored = getStoredWalletState();
|
|
8545
|
+
const preferredWalletId = stored?.walletType && isWalletType(stored.walletType) ? STORED_TYPE_TO_EIP6963_WALLET_ID[stored.walletType] : void 0;
|
|
8546
|
+
if (preferredWalletId) {
|
|
8547
|
+
const preferred = findProviderByWalletId(preferredWalletId);
|
|
8548
|
+
if (preferred) return describeEip6963Provider(preferred);
|
|
8549
|
+
}
|
|
8550
|
+
if (eip6963Providers.length === 1) {
|
|
8551
|
+
return describeEip6963Provider(eip6963Providers[0]);
|
|
8552
|
+
}
|
|
8553
|
+
return void 0;
|
|
8554
|
+
}
|
|
8555
|
+
const anyWin = win;
|
|
8556
|
+
const legacy = anyWin.phantom?.ethereum || anyWin.ethereum;
|
|
8557
|
+
if (!legacy) return void 0;
|
|
8558
|
+
const isPhantom = legacy.isPhantom;
|
|
8559
|
+
return {
|
|
8560
|
+
provider: legacy,
|
|
8561
|
+
walletType: isPhantom ? "phantom-ethereum" : "metamask",
|
|
8562
|
+
name: isPhantom ? "Phantom" : "MetaMask",
|
|
8563
|
+
icon: isPhantom ? "phantom" : "metamask"
|
|
8564
|
+
};
|
|
8565
|
+
}
|
|
8566
|
+
function resolveSolanaPublicKey(provider, response) {
|
|
8567
|
+
if (response?.publicKey) return { publicKey: response.publicKey };
|
|
8568
|
+
if (provider.publicKey) return { publicKey: provider.publicKey };
|
|
8569
|
+
return null;
|
|
8570
|
+
}
|
|
8571
|
+
function isUserRejectedSolanaConnectError(error) {
|
|
8572
|
+
if (!error || typeof error !== "object") return false;
|
|
8573
|
+
const maybeCode = "code" in error ? error.code : void 0;
|
|
8574
|
+
if (maybeCode === 4001) return true;
|
|
8575
|
+
const msg = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
|
|
8576
|
+
return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("rejected the request") || msg.includes("declined");
|
|
8577
|
+
}
|
|
8578
|
+
function isSolanaConnectTimeoutError(error) {
|
|
8579
|
+
return error instanceof Error && error.message.toLowerCase().includes("did not respond to the connection request");
|
|
8580
|
+
}
|
|
8581
|
+
async function connectSolanaProviderWithRecovery(provider, walletId, walletName) {
|
|
8582
|
+
if (provider.isConnected && provider.publicKey) {
|
|
8583
|
+
return { publicKey: provider.publicKey };
|
|
8584
|
+
}
|
|
8585
|
+
const connectOnce = () => provider.connect(walletId === "solflare" ? { onlyIfTrusted: false } : void 0);
|
|
8586
|
+
const withTimeout = async (ms = 2e4) => await Promise.race([
|
|
8587
|
+
connectOnce(),
|
|
8588
|
+
new Promise(
|
|
8589
|
+
(resolve, reject) => setTimeout(() => {
|
|
8590
|
+
const connected = resolveSolanaPublicKey(provider);
|
|
8591
|
+
if (connected) {
|
|
8592
|
+
resolve(connected);
|
|
8593
|
+
return;
|
|
8594
|
+
}
|
|
8595
|
+
reject(
|
|
8596
|
+
new Error(
|
|
8597
|
+
`${walletName} did not respond to the connection request. Please unlock the wallet and try again.`
|
|
8598
|
+
)
|
|
8599
|
+
);
|
|
8600
|
+
}, ms)
|
|
8601
|
+
)
|
|
8602
|
+
]);
|
|
8603
|
+
if (walletId === "solflare") {
|
|
8604
|
+
await provider.disconnect?.().catch(() => {
|
|
8605
|
+
});
|
|
8606
|
+
}
|
|
8607
|
+
const connectAndResolve = async () => {
|
|
8608
|
+
try {
|
|
8609
|
+
const response = await withTimeout();
|
|
8610
|
+
const resolved = resolveSolanaPublicKey(provider, response);
|
|
8611
|
+
if (resolved) return resolved;
|
|
8612
|
+
await new Promise((resolve) => setTimeout(resolve, 120));
|
|
8613
|
+
const delayedResolved = resolveSolanaPublicKey(provider);
|
|
8614
|
+
if (delayedResolved) return delayedResolved;
|
|
8615
|
+
throw new Error(`${walletName} connected but did not expose a public key.`);
|
|
8616
|
+
} catch (error) {
|
|
8617
|
+
const connected = resolveSolanaPublicKey(provider);
|
|
8618
|
+
if (connected) return connected;
|
|
8619
|
+
throw error;
|
|
8620
|
+
}
|
|
8621
|
+
};
|
|
8622
|
+
try {
|
|
8623
|
+
return await connectAndResolve();
|
|
8624
|
+
} catch (err) {
|
|
8625
|
+
if (isUserRejectedSolanaConnectError(err)) throw err;
|
|
8626
|
+
if (isSolanaConnectTimeoutError(err)) throw err;
|
|
8627
|
+
if (walletId === "solflare") {
|
|
8628
|
+
await provider.disconnect?.().catch(() => {
|
|
8629
|
+
});
|
|
8630
|
+
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
8631
|
+
return await connectAndResolve();
|
|
8632
|
+
}
|
|
8633
|
+
throw err;
|
|
8634
|
+
}
|
|
8635
|
+
}
|
|
8636
|
+
|
|
8379
8637
|
// src/resources/icons/MetamaskIcon.tsx
|
|
8380
8638
|
import * as React17 from "react";
|
|
8381
8639
|
import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
@@ -10288,21 +10546,19 @@ function BrowserWalletButton({
|
|
|
10288
10546
|
}
|
|
10289
10547
|
}
|
|
10290
10548
|
if (!chainType || chainType === "ethereum") {
|
|
10291
|
-
const
|
|
10292
|
-
if (
|
|
10293
|
-
const accounts = await
|
|
10549
|
+
const resolved = resolveQuickConnectEvmProvider(window);
|
|
10550
|
+
if (resolved) {
|
|
10551
|
+
const accounts = await resolved.provider.request({
|
|
10294
10552
|
method: "eth_requestAccounts"
|
|
10295
10553
|
});
|
|
10296
10554
|
if (accounts && accounts.length > 0) {
|
|
10297
10555
|
setUserDisconnectedWallet(false);
|
|
10298
|
-
|
|
10299
|
-
const walletType = isPhantom ? "phantom-ethereum" : "metamask";
|
|
10300
|
-
setStoredWalletState(walletType);
|
|
10556
|
+
setStoredWalletState(resolved.walletType);
|
|
10301
10557
|
setWallet({
|
|
10302
|
-
type: walletType,
|
|
10303
|
-
name:
|
|
10558
|
+
type: resolved.walletType,
|
|
10559
|
+
name: resolved.name,
|
|
10304
10560
|
address: accounts[0],
|
|
10305
|
-
icon:
|
|
10561
|
+
icon: resolved.icon
|
|
10306
10562
|
});
|
|
10307
10563
|
}
|
|
10308
10564
|
}
|
|
@@ -10336,7 +10592,10 @@ function BrowserWalletButton({
|
|
|
10336
10592
|
if (isLoading) {
|
|
10337
10593
|
return null;
|
|
10338
10594
|
}
|
|
10339
|
-
const
|
|
10595
|
+
const eip6963EvmProviderCount = getEip6963Providers().length;
|
|
10596
|
+
const legacyEvmProviders = getLegacyEvmProviders(window);
|
|
10597
|
+
const hasLegacyEvmProvider = eip6963EvmProviderCount === 0 && !!(legacyEvmProviders.ethereum || legacyEvmProviders.phantomEthereum || legacyEvmProviders.coinbaseEthereum || legacyEvmProviders.trustEthereum || legacyEvmProviders.okxEthereum);
|
|
10598
|
+
const hasWalletExtension = (!chainType || chainType === "ethereum") && eip6963EvmProviderCount > 0 || (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) || (!chainType || chainType === "ethereum") && hasLegacyEvmProvider;
|
|
10340
10599
|
if (!onConnectClick && !wallet && !hasWalletExtension) {
|
|
10341
10600
|
return null;
|
|
10342
10601
|
}
|
|
@@ -10346,11 +10605,25 @@ function BrowserWalletButton({
|
|
|
10346
10605
|
border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
|
|
10347
10606
|
};
|
|
10348
10607
|
const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
|
|
10608
|
+
const isImageIcon = !!wallet && (wallet.icon.startsWith("data:") || wallet.icon.startsWith("http"));
|
|
10349
10609
|
const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React29.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
|
|
10350
10610
|
size: 36,
|
|
10351
10611
|
className: "uf-rounded-lg",
|
|
10352
10612
|
variant: "color"
|
|
10353
|
-
}) :
|
|
10613
|
+
}) : isImageIcon ? (
|
|
10614
|
+
// Wallet announced via EIP-6963 with no internal icon component: render its
|
|
10615
|
+
// own advertised icon (`info.icon`) rather than a generic placeholder.
|
|
10616
|
+
/* @__PURE__ */ jsx41(
|
|
10617
|
+
"img",
|
|
10618
|
+
{
|
|
10619
|
+
src: wallet.icon,
|
|
10620
|
+
alt: wallet.name,
|
|
10621
|
+
width: 36,
|
|
10622
|
+
height: 36,
|
|
10623
|
+
className: "uf-rounded-lg uf-w-9 uf-h-9"
|
|
10624
|
+
}
|
|
10625
|
+
)
|
|
10626
|
+
) : /* @__PURE__ */ jsx41("div", { className: "uf-w-9 uf-h-9 uf-rounded-lg uf-bg-gray-500" }) : /* @__PURE__ */ jsx41("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ jsx41(Wallet, { className: "uf-w-5 uf-h-5", style: { color: components.card.iconColor } }) });
|
|
10354
10627
|
const titleSubtitleBlock = /* @__PURE__ */ jsxs38("div", { className: "uf-text-left uf-min-w-0", children: [
|
|
10355
10628
|
/* @__PURE__ */ jsx41(
|
|
10356
10629
|
"div",
|
|
@@ -10579,7 +10852,7 @@ import {
|
|
|
10579
10852
|
Loader2 as Loader25,
|
|
10580
10853
|
CreditCard as CreditCard3,
|
|
10581
10854
|
CheckCircle2 as CheckCircle22,
|
|
10582
|
-
AlertTriangle,
|
|
10855
|
+
AlertTriangle as AlertTriangle2,
|
|
10583
10856
|
ArrowRight,
|
|
10584
10857
|
Zap as Zap2,
|
|
10585
10858
|
ChevronDown as ChevronDown3
|
|
@@ -12625,7 +12898,7 @@ function PayWithStripeLink({
|
|
|
12625
12898
|
};
|
|
12626
12899
|
if (configError) {
|
|
12627
12900
|
return /* @__PURE__ */ jsxs41("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-12 uf-px-4", children: [
|
|
12628
|
-
/* @__PURE__ */ jsx44(
|
|
12901
|
+
/* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10 uf-mb-3", style: { color: colors2.error } }),
|
|
12629
12902
|
/* @__PURE__ */ jsx44(
|
|
12630
12903
|
"p",
|
|
12631
12904
|
{
|
|
@@ -12639,7 +12912,7 @@ function PayWithStripeLink({
|
|
|
12639
12912
|
if (step === "kyc" || step === "wallet") {
|
|
12640
12913
|
if (error && !loading) {
|
|
12641
12914
|
return /* @__PURE__ */ jsxs41("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-12 uf-px-4", children: [
|
|
12642
|
-
/* @__PURE__ */ jsx44(
|
|
12915
|
+
/* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10 uf-mb-3", style: { color: colors2.error } }),
|
|
12643
12916
|
/* @__PURE__ */ jsx44(
|
|
12644
12917
|
"p",
|
|
12645
12918
|
{
|
|
@@ -12778,7 +13051,7 @@ function PayWithStripeLink({
|
|
|
12778
13051
|
},
|
|
12779
13052
|
children: [
|
|
12780
13053
|
/* @__PURE__ */ jsx44(
|
|
12781
|
-
|
|
13054
|
+
AlertTriangle2,
|
|
12782
13055
|
{
|
|
12783
13056
|
className: "uf-w-4 uf-h-4 uf-mt-0.5 uf-shrink-0",
|
|
12784
13057
|
style: { color: colors2.error }
|
|
@@ -13683,7 +13956,7 @@ function PayWithStripeLink({
|
|
|
13683
13956
|
const fatalError = sdkError || configError;
|
|
13684
13957
|
if (fatalError) {
|
|
13685
13958
|
return /* @__PURE__ */ jsxs41("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-12 uf-px-4", children: [
|
|
13686
|
-
/* @__PURE__ */ jsx44(
|
|
13959
|
+
/* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10 uf-mb-3", style: { color: colors2.error } }),
|
|
13687
13960
|
/* @__PURE__ */ jsx44(
|
|
13688
13961
|
"p",
|
|
13689
13962
|
{
|
|
@@ -14238,7 +14511,7 @@ function PayWithStripeLink({
|
|
|
14238
14511
|
backgroundColor: isSessionFulfilled ? colors2.success : isSessionFailed ? colors2.error : "#f59e0b",
|
|
14239
14512
|
border: `2px solid ${colors2.background}`
|
|
14240
14513
|
},
|
|
14241
|
-
children: isSessionFulfilled ? /* @__PURE__ */ jsx44(CheckCircle22, { className: "uf-w-4 uf-h-4 uf-text-white" }) : isSessionFailed ? /* @__PURE__ */ jsx44(
|
|
14514
|
+
children: isSessionFulfilled ? /* @__PURE__ */ jsx44(CheckCircle22, { className: "uf-w-4 uf-h-4 uf-text-white" }) : isSessionFailed ? /* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-3.5 uf-h-3.5 uf-text-white" }) : /* @__PURE__ */ jsx44(Loader25, { className: "uf-w-3.5 uf-h-3.5 uf-text-white uf-animate-spin" })
|
|
14242
14515
|
}
|
|
14243
14516
|
)
|
|
14244
14517
|
] }),
|
|
@@ -14267,7 +14540,7 @@ function PayWithStripeLink({
|
|
|
14267
14540
|
{
|
|
14268
14541
|
className: "uf-w-20 uf-h-20 uf-rounded-full uf-flex uf-items-center uf-justify-center uf-mb-6",
|
|
14269
14542
|
style: { backgroundColor: `${colors2.error}20` },
|
|
14270
|
-
children: /* @__PURE__ */ jsx44(
|
|
14543
|
+
children: /* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10", style: { color: colors2.error } })
|
|
14271
14544
|
}
|
|
14272
14545
|
),
|
|
14273
14546
|
/* @__PURE__ */ jsx44(
|
|
@@ -16406,14 +16679,36 @@ function useExchanges({
|
|
|
16406
16679
|
return { exchanges, isLoading };
|
|
16407
16680
|
}
|
|
16408
16681
|
|
|
16409
|
-
// src/hooks/use-
|
|
16682
|
+
// src/hooks/use-public-incident.ts
|
|
16410
16683
|
import { useQuery as useQuery13 } from "@tanstack/react-query";
|
|
16684
|
+
import { getPublicIncident } from "@unifold/core";
|
|
16685
|
+
function usePublicIncident({
|
|
16686
|
+
publishableKey,
|
|
16687
|
+
enabled = true
|
|
16688
|
+
}) {
|
|
16689
|
+
const {
|
|
16690
|
+
data: incident,
|
|
16691
|
+
isLoading,
|
|
16692
|
+
error
|
|
16693
|
+
} = useQuery13({
|
|
16694
|
+
queryKey: ["unifold", "publicIncident", publishableKey],
|
|
16695
|
+
queryFn: () => getPublicIncident(publishableKey),
|
|
16696
|
+
enabled,
|
|
16697
|
+
staleTime: 1e3 * 30,
|
|
16698
|
+
refetchInterval: 1e3 * 30,
|
|
16699
|
+
refetchOnWindowFocus: true
|
|
16700
|
+
});
|
|
16701
|
+
return { incident, isLoading, error: error ?? null };
|
|
16702
|
+
}
|
|
16703
|
+
|
|
16704
|
+
// src/hooks/use-apple-pay-providers.ts
|
|
16705
|
+
import { useQuery as useQuery14 } from "@tanstack/react-query";
|
|
16411
16706
|
import { getApplePayProviders } from "@unifold/core";
|
|
16412
16707
|
function useApplePayProviders({
|
|
16413
16708
|
publishableKey,
|
|
16414
16709
|
enabled = true
|
|
16415
16710
|
}) {
|
|
16416
|
-
const { data: providers, isLoading } =
|
|
16711
|
+
const { data: providers, isLoading } = useQuery14({
|
|
16417
16712
|
queryKey: ["unifold", "applePayProviders", publishableKey],
|
|
16418
16713
|
queryFn: () => getApplePayProviders(publishableKey),
|
|
16419
16714
|
enabled,
|
|
@@ -16432,7 +16727,8 @@ import {
|
|
|
16432
16727
|
refreshIntegrationToken as refreshIntegrationToken2,
|
|
16433
16728
|
revokeIntegrationToken,
|
|
16434
16729
|
IntegrationProvider as IntegrationProvider2,
|
|
16435
|
-
ActionType as ActionType3
|
|
16730
|
+
ActionType as ActionType3,
|
|
16731
|
+
isDepositAddressValidationError as isDepositAddressValidationError2
|
|
16436
16732
|
} from "@unifold/core";
|
|
16437
16733
|
|
|
16438
16734
|
// src/hooks/use-allowed-country.ts
|
|
@@ -16478,7 +16774,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
16478
16774
|
}
|
|
16479
16775
|
|
|
16480
16776
|
// src/hooks/use-address-validation.ts
|
|
16481
|
-
import { useQuery as
|
|
16777
|
+
import { useQuery as useQuery15 } from "@tanstack/react-query";
|
|
16482
16778
|
import {
|
|
16483
16779
|
verifyRecipientAddress
|
|
16484
16780
|
} from "@unifold/core";
|
|
@@ -16492,7 +16788,7 @@ function useAddressValidation({
|
|
|
16492
16788
|
refetchOnMount = false
|
|
16493
16789
|
}) {
|
|
16494
16790
|
const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
16495
|
-
const { data, isLoading, error } =
|
|
16791
|
+
const { data, isLoading, error } = useQuery15({
|
|
16496
16792
|
queryKey: [
|
|
16497
16793
|
"unifold",
|
|
16498
16794
|
"addressValidation",
|
|
@@ -16523,6 +16819,7 @@ function useAddressValidation({
|
|
|
16523
16819
|
return {
|
|
16524
16820
|
isValid: null,
|
|
16525
16821
|
failureCode: null,
|
|
16822
|
+
message: null,
|
|
16526
16823
|
metadata: null,
|
|
16527
16824
|
isLoading: false,
|
|
16528
16825
|
error: null
|
|
@@ -16531,6 +16828,7 @@ function useAddressValidation({
|
|
|
16531
16828
|
return {
|
|
16532
16829
|
isValid: data?.valid ?? null,
|
|
16533
16830
|
failureCode: data?.failure_code ?? null,
|
|
16831
|
+
message: data?.message ?? null,
|
|
16534
16832
|
metadata: data?.metadata ?? null,
|
|
16535
16833
|
isLoading,
|
|
16536
16834
|
error: error ?? null
|
|
@@ -16542,7 +16840,7 @@ import { useState as useState36, useEffect as useEffect30, useMemo as useMemo11
|
|
|
16542
16840
|
import {
|
|
16543
16841
|
ChevronDown as ChevronDown5,
|
|
16544
16842
|
ChevronUp as ChevronUp3,
|
|
16545
|
-
Info,
|
|
16843
|
+
Info as Info2,
|
|
16546
16844
|
Check as Check4,
|
|
16547
16845
|
DollarSign,
|
|
16548
16846
|
ShieldCheck,
|
|
@@ -17390,10 +17688,41 @@ function TokenSelectorSheet({
|
|
|
17390
17688
|
}
|
|
17391
17689
|
|
|
17392
17690
|
// src/hooks/use-default-token.ts
|
|
17393
|
-
import { useState as useState33, useEffect as useEffect29, useRef as useRef11 } from "react";
|
|
17691
|
+
import { useState as useState33, useEffect as useEffect29, useRef as useRef11, useCallback as useCallback8 } from "react";
|
|
17394
17692
|
var getChainKey = (chainId, chainType) => {
|
|
17395
17693
|
return `${chainType}:${chainId}`;
|
|
17396
17694
|
};
|
|
17695
|
+
function getStoredSelection(key) {
|
|
17696
|
+
if (typeof window === "undefined") return null;
|
|
17697
|
+
try {
|
|
17698
|
+
const raw = localStorage.getItem(key);
|
|
17699
|
+
if (!raw) return null;
|
|
17700
|
+
const parsed = JSON.parse(raw);
|
|
17701
|
+
if (parsed && typeof parsed.symbol === "string" && typeof parsed.chainType === "string" && typeof parsed.chainId === "string") {
|
|
17702
|
+
return parsed;
|
|
17703
|
+
}
|
|
17704
|
+
} catch {
|
|
17705
|
+
}
|
|
17706
|
+
return null;
|
|
17707
|
+
}
|
|
17708
|
+
function saveStoredSelection(key, symbol, chainType, chainId) {
|
|
17709
|
+
if (typeof window === "undefined") return;
|
|
17710
|
+
try {
|
|
17711
|
+
localStorage.setItem(key, JSON.stringify({ symbol, chainType, chainId }));
|
|
17712
|
+
} catch {
|
|
17713
|
+
}
|
|
17714
|
+
}
|
|
17715
|
+
function resolveFromStorage(tokens, stored) {
|
|
17716
|
+
for (const t13 of tokens) {
|
|
17717
|
+
if (t13.symbol !== stored.symbol) continue;
|
|
17718
|
+
const matchedChain = t13.chains.find(
|
|
17719
|
+
(c) => c.chain_type === stored.chainType && c.chain_id === stored.chainId
|
|
17720
|
+
);
|
|
17721
|
+
if (matchedChain) return { token: t13, chain: matchedChain };
|
|
17722
|
+
if (t13.chains.length > 0) return { token: t13, chain: t13.chains[0] };
|
|
17723
|
+
}
|
|
17724
|
+
return null;
|
|
17725
|
+
}
|
|
17397
17726
|
function resolveToken(tokens, defaultChainType, defaultChainId, defaultTokenAddress, defaultSymbol) {
|
|
17398
17727
|
if (!tokens.length) return null;
|
|
17399
17728
|
let selectedToken;
|
|
@@ -17443,27 +17772,73 @@ function useDefaultToken({
|
|
|
17443
17772
|
defaultChainType,
|
|
17444
17773
|
defaultChainId,
|
|
17445
17774
|
defaultTokenAddress,
|
|
17446
|
-
defaultSymbol
|
|
17775
|
+
defaultSymbol,
|
|
17776
|
+
storageKey: storageKey2
|
|
17447
17777
|
}) {
|
|
17448
|
-
const [token,
|
|
17449
|
-
const [chain,
|
|
17778
|
+
const [token, setTokenState] = useState33(null);
|
|
17779
|
+
const [chain, setChainState] = useState33(null);
|
|
17450
17780
|
const [initialSelectionDone, setInitialSelectionDone] = useState33(false);
|
|
17451
17781
|
const appliedDefaultsRef = useRef11("");
|
|
17782
|
+
const tokenRef = useRef11(null);
|
|
17783
|
+
const chainRef = useRef11(null);
|
|
17784
|
+
tokenRef.current = token;
|
|
17785
|
+
chainRef.current = chain;
|
|
17786
|
+
const setToken = useCallback8(
|
|
17787
|
+
(newToken) => {
|
|
17788
|
+
tokenRef.current = newToken;
|
|
17789
|
+
setTokenState(newToken);
|
|
17790
|
+
if (storageKey2 && chainRef.current) {
|
|
17791
|
+
const [chainType, chainId] = chainRef.current.split(":");
|
|
17792
|
+
saveStoredSelection(storageKey2, newToken, chainType, chainId);
|
|
17793
|
+
}
|
|
17794
|
+
},
|
|
17795
|
+
[storageKey2]
|
|
17796
|
+
);
|
|
17797
|
+
const setChain = useCallback8(
|
|
17798
|
+
(newChain) => {
|
|
17799
|
+
chainRef.current = newChain;
|
|
17800
|
+
setChainState(newChain);
|
|
17801
|
+
if (storageKey2 && tokenRef.current) {
|
|
17802
|
+
const [chainType, chainId] = newChain.split(":");
|
|
17803
|
+
saveStoredSelection(storageKey2, tokenRef.current, chainType, chainId);
|
|
17804
|
+
}
|
|
17805
|
+
},
|
|
17806
|
+
[storageKey2]
|
|
17807
|
+
);
|
|
17452
17808
|
useEffect29(() => {
|
|
17453
17809
|
if (!tokens.length) return;
|
|
17454
17810
|
const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
|
|
17455
17811
|
const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
|
|
17456
17812
|
if (initialSelectionDone && !defaultsChanged) return;
|
|
17457
|
-
const
|
|
17458
|
-
|
|
17459
|
-
|
|
17460
|
-
|
|
17461
|
-
|
|
17462
|
-
|
|
17463
|
-
|
|
17813
|
+
const hasExplicitDefaults = defaultTokenAddress && defaultChainType && defaultChainId || defaultSymbol && defaultChainType && defaultChainId;
|
|
17814
|
+
let result = null;
|
|
17815
|
+
if (hasExplicitDefaults) {
|
|
17816
|
+
result = resolveToken(
|
|
17817
|
+
tokens,
|
|
17818
|
+
defaultChainType,
|
|
17819
|
+
defaultChainId,
|
|
17820
|
+
defaultTokenAddress,
|
|
17821
|
+
defaultSymbol
|
|
17822
|
+
);
|
|
17823
|
+
if (result) {
|
|
17824
|
+
const matched = defaultTokenAddress && result.chain.token_address.toLowerCase() === defaultTokenAddress.toLowerCase() && result.chain.chain_type === defaultChainType && result.chain.chain_id === defaultChainId || defaultSymbol && result.token.symbol === defaultSymbol && result.chain.chain_type === defaultChainType && result.chain.chain_id === defaultChainId;
|
|
17825
|
+
if (!matched) {
|
|
17826
|
+
result = null;
|
|
17827
|
+
}
|
|
17828
|
+
}
|
|
17829
|
+
}
|
|
17830
|
+
if (!result && storageKey2) {
|
|
17831
|
+
const stored = getStoredSelection(storageKey2);
|
|
17832
|
+
if (stored) {
|
|
17833
|
+
result = resolveFromStorage(tokens, stored);
|
|
17834
|
+
}
|
|
17835
|
+
}
|
|
17836
|
+
if (!result) {
|
|
17837
|
+
result = resolveToken(tokens);
|
|
17838
|
+
}
|
|
17464
17839
|
if (result) {
|
|
17465
|
-
|
|
17466
|
-
|
|
17840
|
+
setTokenState(result.token.symbol);
|
|
17841
|
+
setChainState(getChainKey(result.chain.chain_id, result.chain.chain_type));
|
|
17467
17842
|
appliedDefaultsRef.current = defaultsKey;
|
|
17468
17843
|
setInitialSelectionDone(true);
|
|
17469
17844
|
}
|
|
@@ -17473,7 +17848,8 @@ function useDefaultToken({
|
|
|
17473
17848
|
defaultSymbol,
|
|
17474
17849
|
defaultChainType,
|
|
17475
17850
|
defaultChainId,
|
|
17476
|
-
initialSelectionDone
|
|
17851
|
+
initialSelectionDone,
|
|
17852
|
+
storageKey2
|
|
17477
17853
|
]);
|
|
17478
17854
|
useEffect29(() => {
|
|
17479
17855
|
if (!tokens.length || !token) return;
|
|
@@ -17484,13 +17860,14 @@ function useDefaultToken({
|
|
|
17484
17860
|
});
|
|
17485
17861
|
if (!isChainAvailable) {
|
|
17486
17862
|
const firstChain = currentToken.chains[0];
|
|
17487
|
-
|
|
17863
|
+
setChainState(getChainKey(firstChain.chain_id, firstChain.chain_type));
|
|
17488
17864
|
}
|
|
17489
17865
|
}, [token, tokens, chain]);
|
|
17490
17866
|
return { token, chain, setToken, setChain, initialSelectionDone };
|
|
17491
17867
|
}
|
|
17492
17868
|
|
|
17493
17869
|
// src/hooks/use-default-source-token.ts
|
|
17870
|
+
var STORAGE_KEY2 = "unifold_last_deposit_from_token";
|
|
17494
17871
|
function useDefaultSourceToken({
|
|
17495
17872
|
supportedTokens,
|
|
17496
17873
|
defaultSourceChainType,
|
|
@@ -17503,7 +17880,8 @@ function useDefaultSourceToken({
|
|
|
17503
17880
|
defaultChainType: defaultSourceChainType,
|
|
17504
17881
|
defaultChainId: defaultSourceChainId,
|
|
17505
17882
|
defaultTokenAddress: defaultSourceTokenAddress,
|
|
17506
|
-
defaultSymbol: defaultSourceSymbol
|
|
17883
|
+
defaultSymbol: defaultSourceSymbol,
|
|
17884
|
+
storageKey: STORAGE_KEY2
|
|
17507
17885
|
});
|
|
17508
17886
|
}
|
|
17509
17887
|
|
|
@@ -17854,7 +18232,7 @@ import {
|
|
|
17854
18232
|
} from "@unifold/core";
|
|
17855
18233
|
|
|
17856
18234
|
// src/hooks/use-hypercore-activation.ts
|
|
17857
|
-
import { useQuery as
|
|
18235
|
+
import { useQuery as useQuery16 } from "@tanstack/react-query";
|
|
17858
18236
|
import { checkHypercoreActivation } from "@unifold/core";
|
|
17859
18237
|
|
|
17860
18238
|
// src/lib/constants.ts
|
|
@@ -17873,7 +18251,7 @@ function useHypercoreActivation(params) {
|
|
|
17873
18251
|
const recipient = recipientAddress?.trim() ?? "";
|
|
17874
18252
|
const source = sourceAddress?.trim() ?? "";
|
|
17875
18253
|
const hasAddresses = !!recipient && !!source;
|
|
17876
|
-
const { data, isLoading } =
|
|
18254
|
+
const { data, isLoading } = useQuery16({
|
|
17877
18255
|
queryKey: ["unifold", "hypercoreActivation", source, recipient, publishableKey],
|
|
17878
18256
|
queryFn: () => checkHypercoreActivation(
|
|
17879
18257
|
{
|
|
@@ -17901,7 +18279,7 @@ function useHypercoreActivation(params) {
|
|
|
17901
18279
|
}
|
|
17902
18280
|
|
|
17903
18281
|
// src/components/shared/HypercoreActivationWarning.tsx
|
|
17904
|
-
import { AlertTriangle as
|
|
18282
|
+
import { AlertTriangle as AlertTriangle3 } from "lucide-react";
|
|
17905
18283
|
import { jsx as jsx53, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
17906
18284
|
function HypercoreActivationWarning({
|
|
17907
18285
|
activationFee,
|
|
@@ -17919,7 +18297,7 @@ function HypercoreActivationWarning({
|
|
|
17919
18297
|
},
|
|
17920
18298
|
children: [
|
|
17921
18299
|
/* @__PURE__ */ jsx53(
|
|
17922
|
-
|
|
18300
|
+
AlertTriangle3,
|
|
17923
18301
|
{
|
|
17924
18302
|
className: "uf-w-4 uf-h-4 uf-flex-shrink-0 uf-mt-0.5",
|
|
17925
18303
|
style: { color: colors2.warning }
|
|
@@ -18234,7 +18612,7 @@ function TransferCryptoSingleInput({
|
|
|
18234
18612
|
),
|
|
18235
18613
|
error && !loading && /* @__PURE__ */ jsxs49("div", { className: "uf-bg-destructive/10 uf-border uf-border-destructive/20 uf-rounded-xl uf-p-3 uf-space-y-2", children: [
|
|
18236
18614
|
/* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-start uf-gap-2", children: [
|
|
18237
|
-
/* @__PURE__ */ jsx54(
|
|
18615
|
+
/* @__PURE__ */ jsx54(Info2, { className: "uf-w-4 uf-h-4 uf-text-destructive uf-flex-shrink-0 uf-mt-0.5" }),
|
|
18238
18616
|
/* @__PURE__ */ jsxs49("div", { className: "uf-flex-1 uf-min-w-0", children: [
|
|
18239
18617
|
/* @__PURE__ */ jsx54("div", { className: "uf-text-xs uf-font-medium uf-text-destructive uf-mb-1", children: "Failed to create deposit address" }),
|
|
18240
18618
|
/* @__PURE__ */ jsx54("div", { className: "uf-text-xs uf-text-muted-foreground", children: error })
|
|
@@ -18629,7 +19007,7 @@ import { useState as useState37, useEffect as useEffect31, useMemo as useMemo12
|
|
|
18629
19007
|
import {
|
|
18630
19008
|
ChevronDown as ChevronDown7,
|
|
18631
19009
|
ChevronUp as ChevronUp5,
|
|
18632
|
-
Info as
|
|
19010
|
+
Info as Info3,
|
|
18633
19011
|
Check as Check6,
|
|
18634
19012
|
DollarSign as DollarSign2,
|
|
18635
19013
|
ShieldCheck as ShieldCheck2,
|
|
@@ -19098,7 +19476,7 @@ function TransferCryptoDoubleInput({
|
|
|
19098
19476
|
] }),
|
|
19099
19477
|
error && !loading && /* @__PURE__ */ jsxs51("div", { className: "uf-bg-destructive/10 uf-border uf-border-destructive/20 uf-rounded-xl uf-p-3 uf-space-y-2", children: [
|
|
19100
19478
|
/* @__PURE__ */ jsxs51("div", { className: "uf-flex uf-items-start uf-gap-2", children: [
|
|
19101
|
-
/* @__PURE__ */ jsx56(
|
|
19479
|
+
/* @__PURE__ */ jsx56(Info3, { className: "uf-w-4 uf-h-4 uf-text-destructive uf-flex-shrink-0 uf-mt-0.5" }),
|
|
19102
19480
|
/* @__PURE__ */ jsxs51("div", { className: "uf-flex-1 uf-min-w-0", children: [
|
|
19103
19481
|
/* @__PURE__ */ jsx56("div", { className: "uf-text-xs uf-font-medium uf-text-destructive uf-mb-1", children: "Failed to create deposit address" }),
|
|
19104
19482
|
/* @__PURE__ */ jsx56("div", { className: "uf-text-xs uf-text-muted-foreground", children: error })
|
|
@@ -19472,7 +19850,7 @@ async function sendHypercoreEvmTransfer(params) {
|
|
|
19472
19850
|
}
|
|
19473
19851
|
|
|
19474
19852
|
// src/hooks/use-deposit-quote.ts
|
|
19475
|
-
import { useQuery as
|
|
19853
|
+
import { useQuery as useQuery17 } from "@tanstack/react-query";
|
|
19476
19854
|
import { getDepositQuote } from "@unifold/core";
|
|
19477
19855
|
function useDepositQuote(params) {
|
|
19478
19856
|
const {
|
|
@@ -19499,7 +19877,7 @@ function useDepositQuote(params) {
|
|
|
19499
19877
|
...adjustForSlippage ? { adjust_for_slippage: true } : {},
|
|
19500
19878
|
...stablecoinParity ? { stablecoin_parity: true } : {}
|
|
19501
19879
|
};
|
|
19502
|
-
return
|
|
19880
|
+
return useQuery17({
|
|
19503
19881
|
queryKey: [
|
|
19504
19882
|
"unifold",
|
|
19505
19883
|
"depositQuote",
|
|
@@ -19527,13 +19905,13 @@ function useDepositQuote(params) {
|
|
|
19527
19905
|
}
|
|
19528
19906
|
|
|
19529
19907
|
// src/hooks/use-external-wallets.ts
|
|
19530
|
-
import { useQuery as
|
|
19908
|
+
import { useQuery as useQuery18 } from "@tanstack/react-query";
|
|
19531
19909
|
import { getExternalWallets } from "@unifold/core";
|
|
19532
19910
|
function useExternalWallets({
|
|
19533
19911
|
publishableKey,
|
|
19534
19912
|
enabled = true
|
|
19535
19913
|
}) {
|
|
19536
|
-
const { data: wallets = [], isLoading } =
|
|
19914
|
+
const { data: wallets = [], isLoading } = useQuery18({
|
|
19537
19915
|
queryKey: ["unifold", "external-wallets", publishableKey],
|
|
19538
19916
|
queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
|
|
19539
19917
|
enabled: enabled && !!publishableKey,
|
|
@@ -20644,33 +21022,11 @@ function balancesRepresentSameToken(a, b) {
|
|
|
20644
21022
|
if (!tokenA || !tokenB) return false;
|
|
20645
21023
|
return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
|
|
20646
21024
|
}
|
|
20647
|
-
function getSolanaProviders() {
|
|
20648
|
-
if (typeof window === "undefined") return {};
|
|
20649
|
-
const win = window;
|
|
20650
|
-
return {
|
|
20651
|
-
phantomSolana: win.phantom?.solana,
|
|
20652
|
-
solflare: win.solflare,
|
|
20653
|
-
backpack: win.backpack,
|
|
20654
|
-
glow: win.glow,
|
|
20655
|
-
coinbaseSolana: win.coinbaseSolana || win.coinbaseWalletExtension?.solana
|
|
20656
|
-
};
|
|
20657
|
-
}
|
|
20658
|
-
function getLegacyEvmProviders() {
|
|
20659
|
-
if (typeof window === "undefined") return {};
|
|
20660
|
-
const win = window;
|
|
20661
|
-
return {
|
|
20662
|
-
ethereum: win.ethereum,
|
|
20663
|
-
phantomEthereum: win.phantom?.ethereum,
|
|
20664
|
-
coinbaseEthereum: win.coinbaseWalletExtension,
|
|
20665
|
-
trustEthereum: win.trustwallet?.ethereum,
|
|
20666
|
-
okxEthereum: win.okxwallet
|
|
20667
|
-
};
|
|
20668
|
-
}
|
|
20669
21025
|
function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
|
|
20670
|
-
const solProviders = getSolanaProviders();
|
|
20671
|
-
const legacyEvm = getLegacyEvmProviders();
|
|
20672
|
-
const eip6963List = getEip6963Providers();
|
|
20673
21026
|
const win = typeof window !== "undefined" ? window : null;
|
|
21027
|
+
const solProviders = getInjectedSolanaProviders(win);
|
|
21028
|
+
const legacyEvm = getLegacyEvmProviders(win);
|
|
21029
|
+
const eip6963List = getEip6963Providers();
|
|
20674
21030
|
const hasEip6963 = (walletId) => eip6963List.some((d) => {
|
|
20675
21031
|
const rdns = d.info?.rdns || "";
|
|
20676
21032
|
switch (walletId) {
|
|
@@ -20939,10 +21295,13 @@ function WalletConnect({
|
|
|
20939
21295
|
};
|
|
20940
21296
|
const openMobileWalletBrowse = async (wallet, depositAddresses) => {
|
|
20941
21297
|
try {
|
|
21298
|
+
const cleanedAmountUsd = amountUsd?.replace(/[^0-9.]/g, "") ?? "";
|
|
21299
|
+
const forwardedAmountUsd = parseFloat(cleanedAmountUsd) > 0 ? cleanedAmountUsd : void 0;
|
|
20942
21300
|
const res = await getWalletMobileDeepLink(
|
|
20943
21301
|
wallet.id,
|
|
20944
21302
|
depositAddresses,
|
|
20945
|
-
publishableKey
|
|
21303
|
+
publishableKey,
|
|
21304
|
+
forwardedAmountUsd
|
|
20946
21305
|
);
|
|
20947
21306
|
if (res.deeplink) {
|
|
20948
21307
|
setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
|
|
@@ -21031,7 +21390,7 @@ function WalletConnect({
|
|
|
21031
21390
|
const eip6963Match = findProviderByWalletId(wallet.id);
|
|
21032
21391
|
let provider = eip6963Match?.provider;
|
|
21033
21392
|
if (!provider) {
|
|
21034
|
-
const legacyEvm = getLegacyEvmProviders();
|
|
21393
|
+
const legacyEvm = getLegacyEvmProviders(win);
|
|
21035
21394
|
switch (wallet.id) {
|
|
21036
21395
|
case "metamask":
|
|
21037
21396
|
if (legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom)
|
|
@@ -21063,16 +21422,7 @@ function WalletConnect({
|
|
|
21063
21422
|
const accounts = await provider.request({ method: "eth_requestAccounts" });
|
|
21064
21423
|
if (!accounts?.length) throw new Error("No accounts returned from wallet");
|
|
21065
21424
|
setUserDisconnectedWallet(false);
|
|
21066
|
-
const
|
|
21067
|
-
phantom: "phantom-ethereum",
|
|
21068
|
-
coinbase: "coinbase",
|
|
21069
|
-
trust: "trust",
|
|
21070
|
-
rainbow: "rainbow",
|
|
21071
|
-
rabby: "rabby",
|
|
21072
|
-
okx: "okx",
|
|
21073
|
-
metamask: "metamask"
|
|
21074
|
-
};
|
|
21075
|
-
const walletType = walletIdToType[wallet.id] || "metamask";
|
|
21425
|
+
const walletType = walletIdToWalletType(wallet.id);
|
|
21076
21426
|
setStoredWalletState(walletType);
|
|
21077
21427
|
connectedInfo = {
|
|
21078
21428
|
type: walletType,
|
|
@@ -21081,7 +21431,7 @@ function WalletConnect({
|
|
|
21081
21431
|
icon: wallet.id
|
|
21082
21432
|
};
|
|
21083
21433
|
} else {
|
|
21084
|
-
const solProviders =
|
|
21434
|
+
const solProviders = getInjectedSolanaProviders(win);
|
|
21085
21435
|
let provider;
|
|
21086
21436
|
switch (wallet.id) {
|
|
21087
21437
|
case "phantom":
|
|
@@ -21100,11 +21450,11 @@ function WalletConnect({
|
|
|
21100
21450
|
provider = solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
|
|
21101
21451
|
break;
|
|
21102
21452
|
case "trust":
|
|
21103
|
-
provider =
|
|
21453
|
+
provider = solProviders.trustSolana;
|
|
21104
21454
|
break;
|
|
21105
21455
|
}
|
|
21106
21456
|
if (!provider) throw new Error(`${wallet.name} Solana wallet not found.`);
|
|
21107
|
-
const response = await provider.
|
|
21457
|
+
const response = await connectSolanaProviderWithRecovery(provider, wallet.id, wallet.name);
|
|
21108
21458
|
setUserDisconnectedWallet(false);
|
|
21109
21459
|
const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
|
|
21110
21460
|
setStoredWalletState(walletType);
|
|
@@ -21455,16 +21805,7 @@ function WalletConnect({
|
|
|
21455
21805
|
return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
|
|
21456
21806
|
};
|
|
21457
21807
|
const resolveEvmProvider = () => {
|
|
21458
|
-
const
|
|
21459
|
-
"phantom-ethereum": "phantom",
|
|
21460
|
-
coinbase: "coinbase",
|
|
21461
|
-
trust: "trust",
|
|
21462
|
-
okx: "okx",
|
|
21463
|
-
rainbow: "rainbow",
|
|
21464
|
-
rabby: "rabby",
|
|
21465
|
-
metamask: "metamask"
|
|
21466
|
-
};
|
|
21467
|
-
const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
|
|
21808
|
+
const lookupId = walletTypeToWalletId(walletInfo.type);
|
|
21468
21809
|
const eip6963Match = findProviderByWalletId(lookupId);
|
|
21469
21810
|
let provider = eip6963Match?.provider;
|
|
21470
21811
|
if (!provider) {
|
|
@@ -22196,6 +22537,7 @@ function DepositModal({
|
|
|
22196
22537
|
applePayTitle = "Pay with Apple Pay",
|
|
22197
22538
|
applePaySubTitle = "Instant",
|
|
22198
22539
|
enableBankTransfer,
|
|
22540
|
+
enableIncidentBanner = false,
|
|
22199
22541
|
// No default: left undefined so the backend `stripe_link.enabled` can govern
|
|
22200
22542
|
// (via the `??` chain in showStripeLink) once a dashboard toggle exists.
|
|
22201
22543
|
enableStripeLink,
|
|
@@ -22220,7 +22562,7 @@ function DepositModal({
|
|
|
22220
22562
|
() => normalizePrefilledUsdAmount(prefilledAmountUsd),
|
|
22221
22563
|
[prefilledAmountUsd]
|
|
22222
22564
|
);
|
|
22223
|
-
const onDepositSuccessFor =
|
|
22565
|
+
const onDepositSuccessFor = useCallback11(
|
|
22224
22566
|
(method) => onDepositSuccess || onEvent ? (data) => {
|
|
22225
22567
|
const payload = { ...data, method };
|
|
22226
22568
|
onDepositSuccess?.(payload);
|
|
@@ -22233,7 +22575,7 @@ function DepositModal({
|
|
|
22233
22575
|
} : void 0,
|
|
22234
22576
|
[onDepositSuccess, onEvent]
|
|
22235
22577
|
);
|
|
22236
|
-
const onDepositErrorFor =
|
|
22578
|
+
const onDepositErrorFor = useCallback11(
|
|
22237
22579
|
(method) => onDepositError ? (error) => onDepositError({ ...error, method }) : void 0,
|
|
22238
22580
|
[onDepositError]
|
|
22239
22581
|
);
|
|
@@ -22241,7 +22583,7 @@ function DepositModal({
|
|
|
22241
22583
|
const s = initialScreen ?? "main";
|
|
22242
22584
|
if (s === "tracker" && hideDepositTracker === true) return "main";
|
|
22243
22585
|
if (s === "cashapp" && enableCashApp === false) return "main";
|
|
22244
|
-
if (s === "stripe_link" &&
|
|
22586
|
+
if (s === "stripe_link" && enableStripeLink === false) return "main";
|
|
22245
22587
|
if (s === "apple_pay" && enableApplePay === false) return "main";
|
|
22246
22588
|
if (s === "card" && enableFiatOnramp === false) return "main";
|
|
22247
22589
|
if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
|
|
@@ -22263,7 +22605,7 @@ function DepositModal({
|
|
|
22263
22605
|
enableStripeLink
|
|
22264
22606
|
]);
|
|
22265
22607
|
const [containerEl, setContainerEl] = useState40(null);
|
|
22266
|
-
const containerCallbackRef =
|
|
22608
|
+
const containerCallbackRef = useCallback11((el) => {
|
|
22267
22609
|
setContainerEl(el);
|
|
22268
22610
|
}, []);
|
|
22269
22611
|
const [view, setView] = useState40(effectiveInitialScreen);
|
|
@@ -22300,6 +22642,16 @@ function DepositModal({
|
|
|
22300
22642
|
const showApplePay = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
|
|
22301
22643
|
const showBankTransfer = enableBankTransfer ?? projectConfig?.bank_transfer?.enabled ?? true;
|
|
22302
22644
|
const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
|
|
22645
|
+
const { incident: publicIncident } = usePublicIncident({
|
|
22646
|
+
publishableKey,
|
|
22647
|
+
enabled: open && enableIncidentBanner
|
|
22648
|
+
});
|
|
22649
|
+
const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
|
|
22650
|
+
enabled: true,
|
|
22651
|
+
messages: publicIncident.messages,
|
|
22652
|
+
severity: publicIncident.severity,
|
|
22653
|
+
statusPageUrl: publicIncident.status_page_url
|
|
22654
|
+
} : void 0;
|
|
22303
22655
|
const [integrationExchanges, setIntegrationExchanges] = useState40([]);
|
|
22304
22656
|
useEffect34(() => {
|
|
22305
22657
|
if (!showConnectExchange || !open) return;
|
|
@@ -22366,7 +22718,11 @@ function DepositModal({
|
|
|
22366
22718
|
setConnectedExchange((prev) => prev ? { ...prev, iconUrl } : prev);
|
|
22367
22719
|
}
|
|
22368
22720
|
}, [integrationExchanges, connectedExchange]);
|
|
22369
|
-
const {
|
|
22721
|
+
const {
|
|
22722
|
+
data: depositAddressResponse,
|
|
22723
|
+
isLoading: walletsLoading,
|
|
22724
|
+
error: walletsError
|
|
22725
|
+
} = useDepositAddress({
|
|
22370
22726
|
userId,
|
|
22371
22727
|
publishableKey,
|
|
22372
22728
|
recipientAddress,
|
|
@@ -22499,6 +22855,7 @@ function DepositModal({
|
|
|
22499
22855
|
const {
|
|
22500
22856
|
isValid: isAddressValid,
|
|
22501
22857
|
failureCode: addressFailureCode,
|
|
22858
|
+
message: addressFailureMessage,
|
|
22502
22859
|
metadata: addressFailureMetadata,
|
|
22503
22860
|
isLoading: isAddressValidationLoading
|
|
22504
22861
|
} = useAddressValidation({
|
|
@@ -22512,17 +22869,31 @@ function DepositModal({
|
|
|
22512
22869
|
refetchOnMount: "always"
|
|
22513
22870
|
});
|
|
22514
22871
|
const addressValidationMessages = i18n.transferCrypto.addressValidation;
|
|
22515
|
-
const getAddressValidationErrorMessage = (code, metadata) => {
|
|
22872
|
+
const getAddressValidationErrorMessage = (message, code, metadata) => {
|
|
22873
|
+
if (message && message.trim().length > 0) return message;
|
|
22516
22874
|
if (!code) return addressValidationMessages.defaultError;
|
|
22517
22875
|
const errors = addressValidationMessages.errors;
|
|
22518
22876
|
const template = errors[code] ?? addressValidationMessages.defaultError;
|
|
22519
22877
|
return interpolate(template, metadata);
|
|
22520
22878
|
};
|
|
22879
|
+
const walletsRecipientError = isDepositAddressValidationError2(walletsError) ? walletsError.message : null;
|
|
22880
|
+
const isRecipientAddressInvalid = isAddressValid === false || walletsRecipientError !== null;
|
|
22881
|
+
const recipientInvalidMessage = getAddressValidationErrorMessage(
|
|
22882
|
+
addressFailureMessage ?? walletsRecipientError,
|
|
22883
|
+
addressFailureCode,
|
|
22884
|
+
addressFailureMetadata
|
|
22885
|
+
);
|
|
22521
22886
|
const openingScreen = effectiveInitialScreen;
|
|
22522
22887
|
const sessionOpenedFromMenu = openingScreen === "main";
|
|
22523
22888
|
const standaloneNeedsDepositPrereq = openingScreen !== "main" && (view === "transfer" || view === "card");
|
|
22524
22889
|
let depositPrerequisiteBody;
|
|
22525
|
-
if (
|
|
22890
|
+
if (isRecipientAddressInvalid) {
|
|
22891
|
+
depositPrerequisiteBody = /* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
22892
|
+
/* @__PURE__ */ jsx63("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx63(AlertTriangle4, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
22893
|
+
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
|
|
22894
|
+
/* @__PURE__ */ jsx63("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: recipientInvalidMessage })
|
|
22895
|
+
] });
|
|
22896
|
+
} else if (isCountryLoading || isAddressValidationLoading || tokensLoading || walletsLoading || !projectConfig || // Bank-transfer row visibility depends on the country-gated providers
|
|
22526
22897
|
// fetch — block the menu on it so the row never flashes in or out.
|
|
22527
22898
|
showBankTransfer && bankTransferProvidersLoading || // Same for Apple Pay: row visibility depends on the geo/platform-gated
|
|
22528
22899
|
// providers fetch — block the menu so the row doesn't pop in or out.
|
|
@@ -22534,7 +22905,7 @@ function DepositModal({
|
|
|
22534
22905
|
] });
|
|
22535
22906
|
} else if (countryError) {
|
|
22536
22907
|
depositPrerequisiteBody = /* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
22537
|
-
/* @__PURE__ */ jsx63("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx63(
|
|
22908
|
+
/* @__PURE__ */ jsx63("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx63(AlertTriangle4, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
22538
22909
|
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "Unable to Verify Location" }),
|
|
22539
22910
|
/* @__PURE__ */ jsx63("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: "We couldn't verify your location. Please check your connection and try again." })
|
|
22540
22911
|
] });
|
|
@@ -22544,12 +22915,6 @@ function DepositModal({
|
|
|
22544
22915
|
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "No Tokens Available" }),
|
|
22545
22916
|
/* @__PURE__ */ jsx63("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: "There are no supported tokens available from your current location." })
|
|
22546
22917
|
] });
|
|
22547
|
-
} else if (isAddressValid === false) {
|
|
22548
|
-
depositPrerequisiteBody = /* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
22549
|
-
/* @__PURE__ */ jsx63("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx63(AlertTriangle3, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
22550
|
-
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
|
|
22551
|
-
/* @__PURE__ */ jsx63("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: getAddressValidationErrorMessage(addressFailureCode, addressFailureMetadata) })
|
|
22552
|
-
] });
|
|
22553
22918
|
} else {
|
|
22554
22919
|
depositPrerequisiteBody = null;
|
|
22555
22920
|
}
|
|
@@ -23043,6 +23408,7 @@ function DepositModal({
|
|
|
23043
23408
|
title: modalTitle || "Deposit",
|
|
23044
23409
|
showClose: !hideOverlay,
|
|
23045
23410
|
onClose: handleClose,
|
|
23411
|
+
incident: activeIncident,
|
|
23046
23412
|
showBalance: showBalanceHeader,
|
|
23047
23413
|
balanceAddress: recipientAddress,
|
|
23048
23414
|
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
|
|
@@ -23062,6 +23428,7 @@ function DepositModal({
|
|
|
23062
23428
|
showBack: showBackTransfer,
|
|
23063
23429
|
onBack: handleBack,
|
|
23064
23430
|
onClose: handleClose,
|
|
23431
|
+
incident: activeIncident,
|
|
23065
23432
|
showBalance: showBalanceHeader,
|
|
23066
23433
|
balanceAddress: recipientAddress,
|
|
23067
23434
|
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
|
|
@@ -23122,7 +23489,8 @@ function DepositModal({
|
|
|
23122
23489
|
title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
|
|
23123
23490
|
showBack: showBackTracker,
|
|
23124
23491
|
onBack: handleBack,
|
|
23125
|
-
onClose: handleClose
|
|
23492
|
+
onClose: handleClose,
|
|
23493
|
+
incident: activeIncident
|
|
23126
23494
|
}
|
|
23127
23495
|
),
|
|
23128
23496
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23154,6 +23522,7 @@ function DepositModal({
|
|
|
23154
23522
|
showBack: showBackCard,
|
|
23155
23523
|
onBack: handleBack,
|
|
23156
23524
|
onClose: handleClose,
|
|
23525
|
+
incident: activeIncident,
|
|
23157
23526
|
badge: cardView === "quotes" ? { count: quotesCount } : void 0,
|
|
23158
23527
|
showBalance: showBalanceHeader,
|
|
23159
23528
|
balanceAddress: recipientAddress,
|
|
@@ -23203,7 +23572,8 @@ function DepositModal({
|
|
|
23203
23572
|
title: payWithExchangeTitle,
|
|
23204
23573
|
showBack: exchangeView === "pending" || sessionOpenedFromMenu,
|
|
23205
23574
|
onBack: handleBack,
|
|
23206
|
-
onClose: handleClose
|
|
23575
|
+
onClose: handleClose,
|
|
23576
|
+
incident: activeIncident
|
|
23207
23577
|
}
|
|
23208
23578
|
),
|
|
23209
23579
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23317,7 +23687,8 @@ function DepositModal({
|
|
|
23317
23687
|
title: t8.bankTransfer.title,
|
|
23318
23688
|
showBack: bankTransferView !== "providers" || sessionOpenedFromMenu,
|
|
23319
23689
|
onBack: handleBack,
|
|
23320
|
-
onClose: handleClose
|
|
23690
|
+
onClose: handleClose,
|
|
23691
|
+
incident: activeIncident
|
|
23321
23692
|
}
|
|
23322
23693
|
),
|
|
23323
23694
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23351,26 +23722,24 @@ function DepositModal({
|
|
|
23351
23722
|
title: "Deposit with Link",
|
|
23352
23723
|
showBack: stripeLinkStep !== "checkout" && stripeLinkStep !== "success",
|
|
23353
23724
|
onBack: handleBack,
|
|
23725
|
+
incident: activeIncident,
|
|
23354
23726
|
showClose: stripeLinkStep !== "checkout" && stripeLinkStep !== "auth",
|
|
23355
23727
|
onClose: handleClose
|
|
23356
23728
|
}
|
|
23357
23729
|
),
|
|
23358
23730
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
23359
23731
|
isLoadingIp ? (
|
|
23360
|
-
//
|
|
23361
|
-
// PayWithStripeLink (which kicks off config/OAuth work) for a
|
|
23362
|
-
// deep-link user who turns out to be outside the US.
|
|
23732
|
+
// Wait for location so the first config fetch is region-aware.
|
|
23363
23733
|
/* @__PURE__ */ jsx63(SkeletonButton, { variant: "with-icons" })
|
|
23364
23734
|
) : !showStripeLink ? (
|
|
23365
|
-
//
|
|
23366
|
-
//
|
|
23367
|
-
//
|
|
23368
|
-
// the Link UI.
|
|
23735
|
+
// Direct opens (initialScreen="stripe_link") have no menu row
|
|
23736
|
+
// to fall back to, so render an unavailable state when backend
|
|
23737
|
+
// config resolves Stripe Link disabled/hidden.
|
|
23369
23738
|
/* @__PURE__ */ jsx63(
|
|
23370
23739
|
GeoRestrictionScreen,
|
|
23371
23740
|
{
|
|
23372
23741
|
methodName: t8.stripeLink.title,
|
|
23373
|
-
message:
|
|
23742
|
+
message: t8.stripeLink.unavailableInRegionMessage
|
|
23374
23743
|
}
|
|
23375
23744
|
)
|
|
23376
23745
|
) : /* @__PURE__ */ jsx63(
|
|
@@ -23403,7 +23772,8 @@ function DepositModal({
|
|
|
23403
23772
|
title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
|
|
23404
23773
|
showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
|
|
23405
23774
|
onBack: handleBack,
|
|
23406
|
-
onClose: handleClose
|
|
23775
|
+
onClose: handleClose,
|
|
23776
|
+
incident: activeIncident
|
|
23407
23777
|
}
|
|
23408
23778
|
),
|
|
23409
23779
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23439,7 +23809,8 @@ function DepositModal({
|
|
|
23439
23809
|
const handled = applePayHandleRef.current?.requestBack() ?? false;
|
|
23440
23810
|
if (!handled) handleBack();
|
|
23441
23811
|
},
|
|
23442
|
-
onClose: handleClose
|
|
23812
|
+
onClose: handleClose,
|
|
23813
|
+
incident: activeIncident
|
|
23443
23814
|
}
|
|
23444
23815
|
),
|
|
23445
23816
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23481,16 +23852,16 @@ function DepositModal({
|
|
|
23481
23852
|
}
|
|
23482
23853
|
|
|
23483
23854
|
// src/components/checkout/CheckoutModal.tsx
|
|
23484
|
-
import { useState as useState41, useEffect as useEffect35, useLayoutEffect as useLayoutEffect3, useCallback as
|
|
23485
|
-
import { AlertTriangle as
|
|
23855
|
+
import { useState as useState41, useEffect as useEffect35, useLayoutEffect as useLayoutEffect3, useCallback as useCallback12, useRef as useRef14, useMemo as useMemo15 } from "react";
|
|
23856
|
+
import { AlertTriangle as AlertTriangle5, ChevronRight as ChevronRight19 } from "lucide-react";
|
|
23486
23857
|
|
|
23487
23858
|
// src/hooks/use-payment-intent.ts
|
|
23488
|
-
import { useQuery as
|
|
23859
|
+
import { useQuery as useQuery19 } from "@tanstack/react-query";
|
|
23489
23860
|
import { retrievePaymentIntent } from "@unifold/core";
|
|
23490
23861
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["succeeded", "expired", "refunded", "canceled"]);
|
|
23491
23862
|
function usePaymentIntent(params) {
|
|
23492
23863
|
const { clientSecret, publishableKey, enabled = true, pollingInterval = 3e3 } = params;
|
|
23493
|
-
return
|
|
23864
|
+
return useQuery19({
|
|
23494
23865
|
queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
|
|
23495
23866
|
queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
|
|
23496
23867
|
enabled: enabled && !!clientSecret && !!publishableKey,
|
|
@@ -23569,6 +23940,7 @@ function CheckoutModal({
|
|
|
23569
23940
|
modalTitle,
|
|
23570
23941
|
enableTransferCrypto,
|
|
23571
23942
|
enableConnectWallet,
|
|
23943
|
+
enableIncidentBanner = false,
|
|
23572
23944
|
defaultSourceChainType,
|
|
23573
23945
|
defaultSourceChainId,
|
|
23574
23946
|
defaultSourceTokenAddress,
|
|
@@ -23584,7 +23956,7 @@ function CheckoutModal({
|
|
|
23584
23956
|
const [browserWalletInfo, setBrowserWalletInfo] = useState41(null);
|
|
23585
23957
|
const [browserWalletChainType, setBrowserWalletChainType] = useState41(() => getStoredWalletState()?.chainType);
|
|
23586
23958
|
const lastCheckoutMethodRef = useRef14(void 0);
|
|
23587
|
-
const emitCheckoutSuccess =
|
|
23959
|
+
const emitCheckoutSuccess = useCallback12(
|
|
23588
23960
|
(data, method) => {
|
|
23589
23961
|
const isSucceeded = data.status === "succeeded";
|
|
23590
23962
|
const richIntent = isSucceeded && data.paymentIntent ? mapToCheckoutPaymentIntent(data.paymentIntent) : void 0;
|
|
@@ -23640,6 +24012,16 @@ function CheckoutModal({
|
|
|
23640
24012
|
});
|
|
23641
24013
|
const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
|
|
23642
24014
|
const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
|
|
24015
|
+
const { incident: publicIncident } = usePublicIncident({
|
|
24016
|
+
publishableKey,
|
|
24017
|
+
enabled: open && enableIncidentBanner
|
|
24018
|
+
});
|
|
24019
|
+
const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
|
|
24020
|
+
enabled: true,
|
|
24021
|
+
messages: publicIncident.messages,
|
|
24022
|
+
severity: publicIncident.severity,
|
|
24023
|
+
statusPageUrl: publicIncident.status_page_url
|
|
24024
|
+
} : void 0;
|
|
23643
24025
|
useEffect35(() => {
|
|
23644
24026
|
if (view === "transfer" && !showTransferCrypto) {
|
|
23645
24027
|
setView("main");
|
|
@@ -23735,7 +24117,7 @@ function CheckoutModal({
|
|
|
23735
24117
|
sourceAmountUsd: minUsd.toFixed(2)
|
|
23736
24118
|
};
|
|
23737
24119
|
}, [sourceQuote, selectedSource]);
|
|
23738
|
-
const handleBrowserWalletClick =
|
|
24120
|
+
const handleBrowserWalletClick = useCallback12(
|
|
23739
24121
|
(walletInfo) => {
|
|
23740
24122
|
const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
|
|
23741
24123
|
setStoredWalletState(walletInfo.type);
|
|
@@ -23758,19 +24140,19 @@ function CheckoutModal({
|
|
|
23758
24140
|
},
|
|
23759
24141
|
[wallets, onCheckoutError]
|
|
23760
24142
|
);
|
|
23761
|
-
const handleWalletConnectClick =
|
|
24143
|
+
const handleWalletConnectClick = useCallback12(() => {
|
|
23762
24144
|
setBrowserWalletInfo(null);
|
|
23763
24145
|
lastCheckoutMethodRef.current = "wallet_connect";
|
|
23764
24146
|
setView("wallet_connect");
|
|
23765
24147
|
}, []);
|
|
23766
|
-
const handleWalletDisconnect =
|
|
24148
|
+
const handleWalletDisconnect = useCallback12(() => {
|
|
23767
24149
|
setUserDisconnectedWallet(true);
|
|
23768
24150
|
clearStoredWalletState();
|
|
23769
24151
|
setBrowserWalletChainType(void 0);
|
|
23770
24152
|
setBrowserWalletInfo(null);
|
|
23771
24153
|
setView("main");
|
|
23772
24154
|
}, []);
|
|
23773
|
-
const handleClose =
|
|
24155
|
+
const handleClose = useCallback12(() => {
|
|
23774
24156
|
onOpenChange(false);
|
|
23775
24157
|
if (resetViewTimeoutRef.current) {
|
|
23776
24158
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -23800,7 +24182,7 @@ function CheckoutModal({
|
|
|
23800
24182
|
},
|
|
23801
24183
|
[]
|
|
23802
24184
|
);
|
|
23803
|
-
const handleBack =
|
|
24185
|
+
const handleBack = useCallback12(() => {
|
|
23804
24186
|
setView("main");
|
|
23805
24187
|
}, []);
|
|
23806
24188
|
const poweredByFooter = /* @__PURE__ */ jsx64("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx64(
|
|
@@ -23941,7 +24323,15 @@ function CheckoutModal({
|
|
|
23941
24323
|
{
|
|
23942
24324
|
className: view === "wallet_connect" ? "uf-flex uf-min-h-0 uf-flex-col" : void 0,
|
|
23943
24325
|
children: view === "main" ? /* @__PURE__ */ jsxs58(Fragment15, { children: [
|
|
23944
|
-
/* @__PURE__ */ jsx64(
|
|
24326
|
+
/* @__PURE__ */ jsx64(
|
|
24327
|
+
DepositHeader,
|
|
24328
|
+
{
|
|
24329
|
+
title: modalTitle || "Checkout",
|
|
24330
|
+
showClose: true,
|
|
24331
|
+
onClose: handleClose,
|
|
24332
|
+
incident: activeIncident
|
|
24333
|
+
}
|
|
24334
|
+
),
|
|
23945
24335
|
/* @__PURE__ */ jsxs58("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
23946
24336
|
piLoading ? /* @__PURE__ */ jsxs58("div", { className: "uf-space-y-3", children: [
|
|
23947
24337
|
/* @__PURE__ */ jsx64(
|
|
@@ -23978,7 +24368,7 @@ function CheckoutModal({
|
|
|
23978
24368
|
/* @__PURE__ */ jsx64(SkeletonButton2, {}),
|
|
23979
24369
|
/* @__PURE__ */ jsx64(SkeletonButton2, {})
|
|
23980
24370
|
] }) : piError ? /* @__PURE__ */ jsxs58("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
23981
|
-
/* @__PURE__ */ jsx64("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx64(
|
|
24371
|
+
/* @__PURE__ */ jsx64("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx64(AlertTriangle5, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
23982
24372
|
/* @__PURE__ */ jsx64(
|
|
23983
24373
|
"h3",
|
|
23984
24374
|
{
|
|
@@ -24039,7 +24429,8 @@ function CheckoutModal({
|
|
|
24039
24429
|
title: modalTitle || "Checkout",
|
|
24040
24430
|
showBack: true,
|
|
24041
24431
|
onBack: handleBack,
|
|
24042
|
-
onClose: handleClose
|
|
24432
|
+
onClose: handleClose,
|
|
24433
|
+
incident: activeIncident
|
|
24043
24434
|
}
|
|
24044
24435
|
),
|
|
24045
24436
|
/* @__PURE__ */ jsxs58("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -24200,16 +24591,16 @@ function CheckoutModal({
|
|
|
24200
24591
|
}
|
|
24201
24592
|
|
|
24202
24593
|
// src/components/withdrawals/WithdrawModal.tsx
|
|
24203
|
-
import { useState as useState45, useEffect as useEffect39, useLayoutEffect as useLayoutEffect4, useCallback as
|
|
24204
|
-
import { AlertTriangle as
|
|
24594
|
+
import { useState as useState45, useEffect as useEffect39, useLayoutEffect as useLayoutEffect4, useCallback as useCallback14, useRef as useRef16 } from "react";
|
|
24595
|
+
import { AlertTriangle as AlertTriangle7, ChevronRight as ChevronRight21, Clock as Clock6 } from "lucide-react";
|
|
24205
24596
|
|
|
24206
24597
|
// src/hooks/use-supported-destination-tokens.ts
|
|
24207
|
-
import { useQuery as
|
|
24598
|
+
import { useQuery as useQuery20 } from "@tanstack/react-query";
|
|
24208
24599
|
import {
|
|
24209
24600
|
getSupportedDestinationTokens
|
|
24210
24601
|
} from "@unifold/core";
|
|
24211
24602
|
function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
24212
|
-
return
|
|
24603
|
+
return useQuery20({
|
|
24213
24604
|
queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
|
|
24214
24605
|
queryFn: () => getSupportedDestinationTokens(publishableKey),
|
|
24215
24606
|
staleTime: 1e3 * 60 * 5,
|
|
@@ -24221,6 +24612,7 @@ function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
|
24221
24612
|
}
|
|
24222
24613
|
|
|
24223
24614
|
// src/hooks/use-default-destination-token.ts
|
|
24615
|
+
var STORAGE_KEY3 = "unifold_last_withdraw_to_token";
|
|
24224
24616
|
function useDefaultDestinationToken({
|
|
24225
24617
|
destinationTokens,
|
|
24226
24618
|
defaultDestinationChainType,
|
|
@@ -24233,12 +24625,13 @@ function useDefaultDestinationToken({
|
|
|
24233
24625
|
defaultChainType: defaultDestinationChainType,
|
|
24234
24626
|
defaultChainId: defaultDestinationChainId,
|
|
24235
24627
|
defaultTokenAddress: defaultDestinationTokenAddress,
|
|
24236
|
-
defaultSymbol: defaultDestinationSymbol
|
|
24628
|
+
defaultSymbol: defaultDestinationSymbol,
|
|
24629
|
+
storageKey: STORAGE_KEY3
|
|
24237
24630
|
});
|
|
24238
24631
|
}
|
|
24239
24632
|
|
|
24240
24633
|
// src/hooks/use-source-token-validation.ts
|
|
24241
|
-
import { useQuery as
|
|
24634
|
+
import { useQuery as useQuery21 } from "@tanstack/react-query";
|
|
24242
24635
|
import { getSupportedDepositTokens as getSupportedDepositTokens3 } from "@unifold/core";
|
|
24243
24636
|
function useSourceTokenValidation(params) {
|
|
24244
24637
|
const {
|
|
@@ -24250,7 +24643,7 @@ function useSourceTokenValidation(params) {
|
|
|
24250
24643
|
enabled = true
|
|
24251
24644
|
} = params;
|
|
24252
24645
|
const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
|
|
24253
|
-
return
|
|
24646
|
+
return useQuery21({
|
|
24254
24647
|
queryKey: [
|
|
24255
24648
|
"unifold",
|
|
24256
24649
|
"sourceTokenValidation",
|
|
@@ -24298,12 +24691,12 @@ function useSourceTokenValidation(params) {
|
|
|
24298
24691
|
}
|
|
24299
24692
|
|
|
24300
24693
|
// src/hooks/use-address-balance.ts
|
|
24301
|
-
import { useQuery as
|
|
24694
|
+
import { useQuery as useQuery22 } from "@tanstack/react-query";
|
|
24302
24695
|
import { getAddressBalance as getAddressBalance2 } from "@unifold/core";
|
|
24303
24696
|
function useAddressBalance(params) {
|
|
24304
24697
|
const { address, chainType, chainId, tokenAddress, publishableKey, enabled = true } = params;
|
|
24305
24698
|
const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
|
|
24306
|
-
return
|
|
24699
|
+
return useQuery22({
|
|
24307
24700
|
queryKey: [
|
|
24308
24701
|
"unifold",
|
|
24309
24702
|
"addressBalance",
|
|
@@ -24359,11 +24752,11 @@ function useAddressBalance(params) {
|
|
|
24359
24752
|
}
|
|
24360
24753
|
|
|
24361
24754
|
// src/hooks/use-executions.ts
|
|
24362
|
-
import { useQuery as
|
|
24755
|
+
import { useQuery as useQuery23 } from "@tanstack/react-query";
|
|
24363
24756
|
import { queryExecutions as queryExecutions4, ActionType as ActionType4 } from "@unifold/core";
|
|
24364
24757
|
function useExecutions(userId, publishableKey, options) {
|
|
24365
24758
|
const actionType = options?.actionType ?? ActionType4.Deposit;
|
|
24366
|
-
return
|
|
24759
|
+
return useQuery23({
|
|
24367
24760
|
queryKey: ["unifold", "executions", actionType, userId, publishableKey],
|
|
24368
24761
|
queryFn: () => queryExecutions4(userId, publishableKey, actionType),
|
|
24369
24762
|
enabled: (options?.enabled ?? true) && !!userId,
|
|
@@ -24694,9 +25087,9 @@ function WithdrawDoubleInput({
|
|
|
24694
25087
|
}
|
|
24695
25088
|
|
|
24696
25089
|
// src/components/withdrawals/WithdrawForm.tsx
|
|
24697
|
-
import { useState as useState43, useCallback as
|
|
25090
|
+
import { useState as useState43, useCallback as useCallback13, useMemo as useMemo17, useEffect as useEffect37 } from "react";
|
|
24698
25091
|
import {
|
|
24699
|
-
AlertTriangle as
|
|
25092
|
+
AlertTriangle as AlertTriangle6,
|
|
24700
25093
|
ArrowUpDown,
|
|
24701
25094
|
ChevronDown as ChevronDown9,
|
|
24702
25095
|
ChevronUp as ChevronUp7,
|
|
@@ -24712,7 +25105,7 @@ import {
|
|
|
24712
25105
|
} from "@unifold/core";
|
|
24713
25106
|
|
|
24714
25107
|
// src/hooks/use-verify-recipient-address.ts
|
|
24715
|
-
import { useQuery as
|
|
25108
|
+
import { useQuery as useQuery24 } from "@tanstack/react-query";
|
|
24716
25109
|
import { verifyRecipientAddress as verifyRecipientAddress2 } from "@unifold/core";
|
|
24717
25110
|
function useVerifyRecipientAddress(params) {
|
|
24718
25111
|
const {
|
|
@@ -24725,7 +25118,7 @@ function useVerifyRecipientAddress(params) {
|
|
|
24725
25118
|
} = params;
|
|
24726
25119
|
const trimmedAddress = recipientAddress?.trim() || "";
|
|
24727
25120
|
const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
|
|
24728
|
-
return
|
|
25121
|
+
return useQuery24({
|
|
24729
25122
|
queryKey: [
|
|
24730
25123
|
"unifold",
|
|
24731
25124
|
"verifyRecipientAddress",
|
|
@@ -24976,7 +25369,7 @@ import { useMemo as useMemo16 } from "react";
|
|
|
24976
25369
|
import { ActionType as ActionType6 } from "@unifold/core";
|
|
24977
25370
|
|
|
24978
25371
|
// src/hooks/use-get-deposit-address.ts
|
|
24979
|
-
import { useQuery as
|
|
25372
|
+
import { useQuery as useQuery25 } from "@tanstack/react-query";
|
|
24980
25373
|
import { getDepositAddress } from "@unifold/core";
|
|
24981
25374
|
function useGetDepositAddress(params) {
|
|
24982
25375
|
const {
|
|
@@ -24990,7 +25383,7 @@ function useGetDepositAddress(params) {
|
|
|
24990
25383
|
enabled = true
|
|
24991
25384
|
} = params;
|
|
24992
25385
|
const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
24993
|
-
return
|
|
25386
|
+
return useQuery25({
|
|
24994
25387
|
queryKey: [
|
|
24995
25388
|
"unifold",
|
|
24996
25389
|
"getDepositAddress",
|
|
@@ -25186,6 +25579,9 @@ function WithdrawForm({
|
|
|
25186
25579
|
if (isDebouncing || isVerifyingAddress) return null;
|
|
25187
25580
|
if (verifyError) return t10.invalidAddress;
|
|
25188
25581
|
if (addressVerification && !addressVerification.valid) {
|
|
25582
|
+
if (addressVerification.message && addressVerification.message.trim().length > 0) {
|
|
25583
|
+
return addressVerification.message;
|
|
25584
|
+
}
|
|
25189
25585
|
if (addressVerification.failure_code === "account_not_found")
|
|
25190
25586
|
return `Account not found on ${selectedChain?.chain_name}`;
|
|
25191
25587
|
if (addressVerification.failure_code === "not_opted_in")
|
|
@@ -25283,7 +25679,7 @@ function WithdrawForm({
|
|
|
25283
25679
|
tokenSymbol,
|
|
25284
25680
|
isStablecoin
|
|
25285
25681
|
]);
|
|
25286
|
-
const handleSwitchUnit =
|
|
25682
|
+
const handleSwitchUnit = useCallback13(() => {
|
|
25287
25683
|
if (isMaxed && balanceData) {
|
|
25288
25684
|
if (inputUnit === "crypto") {
|
|
25289
25685
|
setAmount((Math.round(balanceUsdNum * 100) / 100).toFixed(2));
|
|
@@ -25310,7 +25706,7 @@ function WithdrawForm({
|
|
|
25310
25706
|
setInputUnit("crypto");
|
|
25311
25707
|
}
|
|
25312
25708
|
}, [amount, inputUnit, exchangeRate, sourceDecimals, isMaxed, balanceData, balanceUsdNum]);
|
|
25313
|
-
const handleMaxClick =
|
|
25709
|
+
const handleMaxClick = useCallback13(() => {
|
|
25314
25710
|
if (inputUnit === "crypto") {
|
|
25315
25711
|
if (balanceCrypto <= 0) return;
|
|
25316
25712
|
setAmount(balanceData?.balanceHuman ?? "0");
|
|
@@ -25324,7 +25720,7 @@ function WithdrawForm({
|
|
|
25324
25720
|
const isBelowMinimum = minimumWithdrawAmountUsd !== null && fiatAmountFromInput > 0 && Math.round(fiatAmountFromInput * 100) / 100 < minimumWithdrawAmountUsd;
|
|
25325
25721
|
const isOverBalance = inputUnit === "crypto" ? cryptoAmountFromInput > 0 && balanceCrypto > 0 && cryptoAmountFromInput > balanceCrypto : fiatAmountFromInput > 0 && balanceUsdNum > 0 && Math.round(fiatAmountFromInput * 100) / 100 > Math.round(balanceUsdNum * 100) / 100;
|
|
25326
25722
|
const isFormValid = trimmedAddress.length > 0 && amount.trim().length > 0 && cryptoAmountFromInput > 0 && isAddressValid && !isBelowMinimum && !isOverBalance && !isBalanceBelowMinimum && !!balanceData;
|
|
25327
|
-
const handleWithdraw =
|
|
25723
|
+
const handleWithdraw = useCallback13(async () => {
|
|
25328
25724
|
if (!selectedToken || !selectedChain) return;
|
|
25329
25725
|
if (!isFormValid) return;
|
|
25330
25726
|
setIsSubmitting(true);
|
|
@@ -25521,7 +25917,7 @@ function WithdrawForm({
|
|
|
25521
25917
|
)
|
|
25522
25918
|
] }),
|
|
25523
25919
|
addressError && /* @__PURE__ */ jsxs60("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-1.5", children: [
|
|
25524
|
-
/* @__PURE__ */ jsx66(
|
|
25920
|
+
/* @__PURE__ */ jsx66(AlertTriangle6, { className: "uf-w-3 uf-h-3", style: { color: colors2.error } }),
|
|
25525
25921
|
/* @__PURE__ */ jsx66("span", { className: "uf-text-xs", style: { color: colors2.error, fontFamily: fonts.regular }, children: addressError })
|
|
25526
25922
|
] })
|
|
25527
25923
|
] }),
|
|
@@ -26110,7 +26506,7 @@ function WithdrawModal({
|
|
|
26110
26506
|
theme = "dark",
|
|
26111
26507
|
hideOverlay = false
|
|
26112
26508
|
}) {
|
|
26113
|
-
const onWithdrawSuccessFor =
|
|
26509
|
+
const onWithdrawSuccessFor = useCallback14(
|
|
26114
26510
|
(data) => {
|
|
26115
26511
|
onWithdrawSuccess?.(data);
|
|
26116
26512
|
if (data.execution) {
|
|
@@ -26121,7 +26517,7 @@ function WithdrawModal({
|
|
|
26121
26517
|
);
|
|
26122
26518
|
const { colors: colors2, fonts, components } = useTheme();
|
|
26123
26519
|
const [containerEl, setContainerEl] = useState45(null);
|
|
26124
|
-
const containerCallbackRef =
|
|
26520
|
+
const containerCallbackRef = useCallback14((el) => {
|
|
26125
26521
|
setContainerEl(el);
|
|
26126
26522
|
}, []);
|
|
26127
26523
|
const [resolvedTheme, setResolvedTheme] = useState45(
|
|
@@ -26194,7 +26590,7 @@ function WithdrawModal({
|
|
|
26194
26590
|
refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
|
|
26195
26591
|
});
|
|
26196
26592
|
const allWithdrawals = allWithdrawalsData?.data ?? [];
|
|
26197
|
-
const handleDepositWalletCreation =
|
|
26593
|
+
const handleDepositWalletCreation = useCallback14(
|
|
26198
26594
|
async (params) => {
|
|
26199
26595
|
const { data: wallets } = await createDepositAddress2(
|
|
26200
26596
|
{
|
|
@@ -26217,12 +26613,12 @@ function WithdrawModal({
|
|
|
26217
26613
|
},
|
|
26218
26614
|
[externalUserId, publishableKey, sourceChainType]
|
|
26219
26615
|
);
|
|
26220
|
-
const handleWithdrawSubmitted =
|
|
26616
|
+
const handleWithdrawSubmitted = useCallback14((txInfo) => {
|
|
26221
26617
|
setSubmittedTxInfo(txInfo);
|
|
26222
26618
|
setView("confirming");
|
|
26223
26619
|
}, []);
|
|
26224
26620
|
const resetViewTimeoutRef = useRef16(null);
|
|
26225
|
-
const handleClose =
|
|
26621
|
+
const handleClose = useCallback14(() => {
|
|
26226
26622
|
onOpenChange(false);
|
|
26227
26623
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
26228
26624
|
resetViewTimeoutRef.current = setTimeout(() => {
|
|
@@ -26250,13 +26646,13 @@ function WithdrawModal({
|
|
|
26250
26646
|
},
|
|
26251
26647
|
[]
|
|
26252
26648
|
);
|
|
26253
|
-
const handleTokenSymbolChange =
|
|
26649
|
+
const handleTokenSymbolChange = useCallback14(
|
|
26254
26650
|
(symbol) => {
|
|
26255
26651
|
setSelectedTokenSymbol(symbol);
|
|
26256
26652
|
},
|
|
26257
26653
|
[setSelectedTokenSymbol]
|
|
26258
26654
|
);
|
|
26259
|
-
const handleChainKeyChange =
|
|
26655
|
+
const handleChainKeyChange = useCallback14(
|
|
26260
26656
|
(chainKey) => {
|
|
26261
26657
|
setSelectedChainKey(chainKey);
|
|
26262
26658
|
},
|
|
@@ -26363,7 +26759,7 @@ function WithdrawModal({
|
|
|
26363
26759
|
},
|
|
26364
26760
|
i
|
|
26365
26761
|
)) }) : isSourceSupported === false ? /* @__PURE__ */ jsxs63("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
|
|
26366
|
-
/* @__PURE__ */ jsx69("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx69(
|
|
26762
|
+
/* @__PURE__ */ jsx69("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ jsx69(AlertTriangle7, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
|
|
26367
26763
|
/* @__PURE__ */ jsx69(
|
|
26368
26764
|
"h3",
|
|
26369
26765
|
{
|
|
@@ -26732,6 +27128,7 @@ export {
|
|
|
26732
27128
|
useDepositPolling,
|
|
26733
27129
|
useDepositQuote,
|
|
26734
27130
|
usePaymentIntent,
|
|
27131
|
+
usePublicIncident,
|
|
26735
27132
|
useSourceTokenValidation,
|
|
26736
27133
|
useSupportedDepositTokens,
|
|
26737
27134
|
useSupportedDestinationTokens,
|