@unifold/ui-react 0.1.69 → 0.1.70
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 +880 -357
- package/dist/index.mjs +839 -315
- 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",
|
|
@@ -6554,7 +6638,7 @@ function BankTransfer({
|
|
|
6554
6638
|
subdivision_code: userIpInfo?.subdivisionCode || void 0,
|
|
6555
6639
|
// A provider may advertise multiple rails; default to the first.
|
|
6556
6640
|
// UIs that want per-rail rows would need to render one entry per element.
|
|
6557
|
-
|
|
6641
|
+
payment_method_type: provider.payment_methods[0]
|
|
6558
6642
|
});
|
|
6559
6643
|
setActiveProvider(provider);
|
|
6560
6644
|
const convertedPrefilled = await resolvePrefilledSourceAmount(provider.source_currency);
|
|
@@ -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
|
|
@@ -10945,6 +11218,13 @@ function setStoredSelectedToken(customerId, token) {
|
|
|
10945
11218
|
} catch {
|
|
10946
11219
|
}
|
|
10947
11220
|
}
|
|
11221
|
+
function clearStoredSelectedToken(customerId) {
|
|
11222
|
+
try {
|
|
11223
|
+
if (typeof window === "undefined" || !customerId) return;
|
|
11224
|
+
localStorage.removeItem(selectedTokenKey(customerId));
|
|
11225
|
+
} catch {
|
|
11226
|
+
}
|
|
11227
|
+
}
|
|
10948
11228
|
|
|
10949
11229
|
// src/components/deposits/stripe-link/PayWithStripeLink.tsx
|
|
10950
11230
|
import { Fragment as Fragment6, jsx as jsx44, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
@@ -10962,6 +11242,31 @@ var STRIPE_SESSION_STATUS = {
|
|
|
10962
11242
|
EXPIRED: "expired"
|
|
10963
11243
|
};
|
|
10964
11244
|
var STRIPE_SESSION_POLL_INTERVAL_MS = 3e3;
|
|
11245
|
+
var STRIPE_CONSUMED_PAYMENT_METHOD_CODE = "payment_method_unexpected_state";
|
|
11246
|
+
function isConsumedPaymentMethodError(err) {
|
|
11247
|
+
return err instanceof StripeApiResponseError && (err.errorType === "stripe_onramp_payment_method_consumed" || err.stripeCode === STRIPE_CONSUMED_PAYMENT_METHOD_CODE);
|
|
11248
|
+
}
|
|
11249
|
+
var STRIPE_PAYMENT_FAILURE_MESSAGES = {
|
|
11250
|
+
card_declined: "Your card was declined. Try again or use a different payment method.",
|
|
11251
|
+
insufficient_funds: "Your card has insufficient funds. Try a different payment method.",
|
|
11252
|
+
expired_card: "Your card has expired. Use a different payment method.",
|
|
11253
|
+
incorrect_cvc: "Your card\u2019s security code is incorrect. Try again or use a different card.",
|
|
11254
|
+
incorrect_number: "Your card number is incorrect. Try again or use a different card.",
|
|
11255
|
+
card_not_supported: "This card isn\u2019t supported for this purchase. Try a different payment method.",
|
|
11256
|
+
processing_error: "We couldn\u2019t process your card. Please try again in a moment.",
|
|
11257
|
+
authentication_required: "Your bank requires authentication for this payment. Please try again.",
|
|
11258
|
+
payment_intent_authentication_failure: "Card authentication failed. Try again or use a different card.",
|
|
11259
|
+
payment_method_provider_decline: "Your payment provider declined the charge. Try a different payment method.",
|
|
11260
|
+
payment_failed: "Your payment didn\u2019t go through. Try again or use a different payment method."
|
|
11261
|
+
};
|
|
11262
|
+
function describeStripePaymentFailure(reason) {
|
|
11263
|
+
if (!reason) return null;
|
|
11264
|
+
return STRIPE_PAYMENT_FAILURE_MESSAGES[reason] ?? null;
|
|
11265
|
+
}
|
|
11266
|
+
var PAYMENT_FAILED_LEAD = "We couldn\u2019t complete your payment.";
|
|
11267
|
+
function unmappedPaymentFailureMessage(stripeMessage) {
|
|
11268
|
+
return stripeMessage ? `${PAYMENT_FAILED_LEAD} ${stripeMessage}` : `${PAYMENT_FAILED_LEAD} Please try again.`;
|
|
11269
|
+
}
|
|
10965
11270
|
var NO_AUTOFILL = {
|
|
10966
11271
|
autoComplete: "off",
|
|
10967
11272
|
"data-lpignore": "true",
|
|
@@ -11063,7 +11368,11 @@ function PayWithStripeLink({
|
|
|
11063
11368
|
}, [controlledStep]);
|
|
11064
11369
|
useEffect24(() => {
|
|
11065
11370
|
setLoading(false);
|
|
11066
|
-
|
|
11371
|
+
if (preserveErrorOnNextStepRef.current) {
|
|
11372
|
+
preserveErrorOnNextStepRef.current = false;
|
|
11373
|
+
} else {
|
|
11374
|
+
setError(null);
|
|
11375
|
+
}
|
|
11067
11376
|
setKycPendingMessage(null);
|
|
11068
11377
|
setQuoteLoading(false);
|
|
11069
11378
|
if (step !== "checkout") {
|
|
@@ -11152,7 +11461,10 @@ function PayWithStripeLink({
|
|
|
11152
11461
|
const pendingAddPaymentRef = useRef9(false);
|
|
11153
11462
|
const autoOpenedAddPaymentRef = useRef9(false);
|
|
11154
11463
|
const checkoutGenRef = useRef9(0);
|
|
11464
|
+
const preserveErrorOnNextStepRef = useRef9(false);
|
|
11465
|
+
const spentSessionIdsRef = useRef9(/* @__PURE__ */ new Set());
|
|
11155
11466
|
const [stripePaymentUIReady, setStripePaymentUIReady] = useState29(false);
|
|
11467
|
+
const [addPaymentHovered, setAddPaymentHovered] = useState29(false);
|
|
11156
11468
|
const [oauthToken, setOauthToken] = useState29(null);
|
|
11157
11469
|
const [refreshTokenValue, setRefreshTokenValue] = useState29(null);
|
|
11158
11470
|
const [customerId, setCustomerId] = useState29(null);
|
|
@@ -11301,7 +11613,7 @@ function PayWithStripeLink({
|
|
|
11301
11613
|
const merged = [
|
|
11302
11614
|
...pmResult.data.map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) })),
|
|
11303
11615
|
...persistedNotInApi ? [persisted] : []
|
|
11304
|
-
];
|
|
11616
|
+
].filter((t13) => !deadPaymentTokenIdsRef.current.has(t13.id));
|
|
11305
11617
|
if (merged.length > 0) {
|
|
11306
11618
|
const preferred = persisted && merged.find((m) => m.id === persisted.id) || merged[0];
|
|
11307
11619
|
selectPaymentToken(preferred);
|
|
@@ -11366,6 +11678,7 @@ function PayWithStripeLink({
|
|
|
11366
11678
|
const [selectedPaymentToken, setSelectedPaymentToken] = useState29(null);
|
|
11367
11679
|
const [paymentDisplay, setPaymentDisplay] = useState29(null);
|
|
11368
11680
|
const selectedTokenSingleUseRef = useRef9(false);
|
|
11681
|
+
const deadPaymentTokenIdsRef = useRef9(/* @__PURE__ */ new Set());
|
|
11369
11682
|
const selectPaymentToken = useCallback6(
|
|
11370
11683
|
(token) => {
|
|
11371
11684
|
selectedTokenSingleUseRef.current = !!token.singleUse;
|
|
@@ -11393,9 +11706,25 @@ function PayWithStripeLink({
|
|
|
11393
11706
|
setStoredSelectedTokenState(null);
|
|
11394
11707
|
}
|
|
11395
11708
|
}, [customerId]);
|
|
11709
|
+
const forgetSelectedPaymentToken = useCallback6(
|
|
11710
|
+
(tokenId) => {
|
|
11711
|
+
selectedTokenSingleUseRef.current = false;
|
|
11712
|
+
if (customerId) {
|
|
11713
|
+
const persisted = getStoredSelectedToken(customerId);
|
|
11714
|
+
if (!tokenId || persisted?.id === tokenId) {
|
|
11715
|
+
clearStoredSelectedToken(customerId);
|
|
11716
|
+
}
|
|
11717
|
+
}
|
|
11718
|
+
setSelectedPaymentToken((prev) => !tokenId || prev === tokenId ? null : prev);
|
|
11719
|
+
setPaymentDisplay((prev) => !tokenId || !prev ? null : prev);
|
|
11720
|
+
setStoredSelectedTokenState((prev) => !tokenId || prev?.id === tokenId ? null : prev);
|
|
11721
|
+
},
|
|
11722
|
+
[customerId]
|
|
11723
|
+
);
|
|
11396
11724
|
const displayPaymentTokens = (() => {
|
|
11397
|
-
const
|
|
11398
|
-
|
|
11725
|
+
const isDead = (id) => deadPaymentTokenIdsRef.current.has(id);
|
|
11726
|
+
const apiDisplay = paymentTokens.filter((t13) => !isDead(t13.id)).map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) }));
|
|
11727
|
+
if (storedSelectedToken && !isDead(storedSelectedToken.id) && !paymentTokens.some((t13) => t13.id === storedSelectedToken.id)) {
|
|
11399
11728
|
return [...apiDisplay, storedSelectedToken];
|
|
11400
11729
|
}
|
|
11401
11730
|
return apiDisplay;
|
|
@@ -12044,7 +12373,7 @@ function PayWithStripeLink({
|
|
|
12044
12373
|
const merged = [
|
|
12045
12374
|
...existing.data.map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) })),
|
|
12046
12375
|
...storedNotInApi ? [stored] : []
|
|
12047
|
-
];
|
|
12376
|
+
].filter((t13) => !deadPaymentTokenIdsRef.current.has(t13.id));
|
|
12048
12377
|
if (merged.length === 0) {
|
|
12049
12378
|
if (!autoOpenedAddPaymentRef.current) {
|
|
12050
12379
|
autoOpenedAddPaymentRef.current = true;
|
|
@@ -12086,6 +12415,9 @@ function PayWithStripeLink({
|
|
|
12086
12415
|
paymentInnerRef.current.replaceChildren();
|
|
12087
12416
|
};
|
|
12088
12417
|
}, [step, oauthToken, customerId, publishableKey, coordinator]);
|
|
12418
|
+
useEffect24(() => {
|
|
12419
|
+
if (step !== "payment") setAddPaymentHovered(false);
|
|
12420
|
+
}, [step]);
|
|
12089
12421
|
useEffect24(() => {
|
|
12090
12422
|
if (step !== "add_payment") return;
|
|
12091
12423
|
if (!isCustomerVerified(customer)) {
|
|
@@ -12236,6 +12568,17 @@ function PayWithStripeLink({
|
|
|
12236
12568
|
}
|
|
12237
12569
|
if (message) onDepositError?.({ message, error: err });
|
|
12238
12570
|
};
|
|
12571
|
+
const isRetriablePaymentToken = (id) => !!id && paymentTokens.some((t13) => t13.id === id);
|
|
12572
|
+
const dropConsumedToken = (message, cause) => {
|
|
12573
|
+
if (selectedPaymentToken) deadPaymentTokenIdsRef.current.add(selectedPaymentToken);
|
|
12574
|
+
setSessionForCheckout(null);
|
|
12575
|
+
forgetSelectedPaymentToken(selectedPaymentToken);
|
|
12576
|
+
preserveErrorOnNextStepRef.current = true;
|
|
12577
|
+
setError(message);
|
|
12578
|
+
setStep("amount");
|
|
12579
|
+
onDepositError?.({ message, error: cause });
|
|
12580
|
+
};
|
|
12581
|
+
const CONSUMED_TOKEN_MESSAGE = "That payment method can\u2019t be used. Please choose another.";
|
|
12239
12582
|
if (!sessionForCheckout || sessionForCheckout.amount !== amount || sessionForCheckout.paymentToken !== selectedPaymentToken) {
|
|
12240
12583
|
return;
|
|
12241
12584
|
}
|
|
@@ -12243,19 +12586,29 @@ function PayWithStripeLink({
|
|
|
12243
12586
|
setLoading(true);
|
|
12244
12587
|
setError(null);
|
|
12245
12588
|
setStep("checkout");
|
|
12589
|
+
let lastConfirmError = null;
|
|
12246
12590
|
try {
|
|
12247
|
-
const runCheckout = (sid) =>
|
|
12248
|
-
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
|
|
12257
|
-
|
|
12258
|
-
|
|
12591
|
+
const runCheckout = (sid) => {
|
|
12592
|
+
spentSessionIdsRef.current.add(sid);
|
|
12593
|
+
return coordinator.performCheckout(sid, async (onrampSessionId) => {
|
|
12594
|
+
try {
|
|
12595
|
+
await withTokenRefresh(
|
|
12596
|
+
(tok) => stripeRefreshQuote(onrampSessionId, tok, publishableKey)
|
|
12597
|
+
);
|
|
12598
|
+
} catch {
|
|
12599
|
+
}
|
|
12600
|
+
try {
|
|
12601
|
+
const confirmResponse = await withTokenRefresh(
|
|
12602
|
+
(tok) => stripeConfirmSession(onrampSessionId, tok, {}, publishableKey)
|
|
12603
|
+
);
|
|
12604
|
+
lastConfirmError = null;
|
|
12605
|
+
return confirmResponse.client_secret ?? "";
|
|
12606
|
+
} catch (confirmErr) {
|
|
12607
|
+
lastConfirmError = confirmErr;
|
|
12608
|
+
throw confirmErr;
|
|
12609
|
+
}
|
|
12610
|
+
});
|
|
12611
|
+
};
|
|
12259
12612
|
const lastErrorFor = async (sid) => {
|
|
12260
12613
|
const sessionState = await withTokenRefresh(
|
|
12261
12614
|
(tok) => stripeGetSession(sid, tok, publishableKey)
|
|
@@ -12315,8 +12668,9 @@ function PayWithStripeLink({
|
|
|
12315
12668
|
setStep("success");
|
|
12316
12669
|
} else if (lastError === "quote_rate_drifted" || lastError === "charged_with_expired_quote") {
|
|
12317
12670
|
setSessionForCheckout(null);
|
|
12318
|
-
|
|
12671
|
+
preserveErrorOnNextStepRef.current = true;
|
|
12319
12672
|
setError("Pricing updated. Please try again.");
|
|
12673
|
+
setStep("amount");
|
|
12320
12674
|
} else if (lastError === "missing_document_verification") {
|
|
12321
12675
|
surfaceStepUpOnAmount(void 0, void 0, "l2");
|
|
12322
12676
|
} else if (lastError === "transaction_limit_reached") {
|
|
@@ -12327,28 +12681,52 @@ function PayWithStripeLink({
|
|
|
12327
12681
|
} else if (lastError === "missing_consumer_wallet") {
|
|
12328
12682
|
setStep("wallet");
|
|
12329
12683
|
setError(null);
|
|
12684
|
+
} else if (isConsumedPaymentMethodError(lastConfirmError)) {
|
|
12685
|
+
dropConsumedToken(CONSUMED_TOKEN_MESSAGE, lastConfirmError);
|
|
12330
12686
|
} else {
|
|
12331
|
-
|
|
12332
|
-
|
|
12333
|
-
|
|
12687
|
+
const confirmErr = lastConfirmError instanceof StripeApiResponseError ? lastConfirmError : void 0;
|
|
12688
|
+
const reason = describeStripePaymentFailure(lastError) ?? describeStripePaymentFailure(confirmErr?.stripeCode) ?? unmappedPaymentFailureMessage(confirmErr?.stripeMessage);
|
|
12689
|
+
if (!isRetriablePaymentToken(selectedPaymentToken)) {
|
|
12690
|
+
dropConsumedToken(reason, lastConfirmError ?? void 0);
|
|
12691
|
+
} else {
|
|
12692
|
+
setSessionForCheckout(null);
|
|
12693
|
+
preserveErrorOnNextStepRef.current = true;
|
|
12694
|
+
setError(reason);
|
|
12695
|
+
setStep("amount");
|
|
12696
|
+
onDepositError?.({
|
|
12697
|
+
message: lastError ?? confirmErr?.stripeCode ?? "checkout_failed",
|
|
12698
|
+
error: lastConfirmError ?? void 0
|
|
12699
|
+
});
|
|
12700
|
+
}
|
|
12334
12701
|
}
|
|
12335
12702
|
} catch (err) {
|
|
12336
12703
|
if (isStale()) return;
|
|
12337
|
-
const
|
|
12338
|
-
const
|
|
12339
|
-
|
|
12704
|
+
const stripeErr = lastConfirmError instanceof StripeApiResponseError ? lastConfirmError : err instanceof StripeApiResponseError ? err : void 0;
|
|
12705
|
+
const effectiveError = stripeErr ?? err;
|
|
12706
|
+
const msg = stripeErr?.message ?? (err instanceof Error ? err.message : "Checkout failed");
|
|
12707
|
+
const errorType = stripeErr?.errorType;
|
|
12708
|
+
if (isConsumedPaymentMethodError(effectiveError)) {
|
|
12709
|
+
dropConsumedToken(CONSUMED_TOKEN_MESSAGE, effectiveError);
|
|
12710
|
+
} else if (errorType === "stripe_onramp_missing_minimum_identity_verification") {
|
|
12340
12711
|
setStep("kyc");
|
|
12341
12712
|
setError(null);
|
|
12342
12713
|
} else if (errorType === "stripe_onramp_missing_identity_verification") {
|
|
12343
|
-
surfaceStepUpOnAmount(
|
|
12714
|
+
surfaceStepUpOnAmount(effectiveError, msg, "l1");
|
|
12344
12715
|
} else if (errorType === "stripe_onramp_missing_document_verification") {
|
|
12345
|
-
surfaceStepUpOnAmount(
|
|
12716
|
+
surfaceStepUpOnAmount(effectiveError, msg, "l2");
|
|
12346
12717
|
} else if (errorType === "stripe_onramp_purchase_limit_reached") {
|
|
12347
|
-
surfaceStepUpOnAmount(
|
|
12718
|
+
surfaceStepUpOnAmount(effectiveError, msg, null);
|
|
12348
12719
|
} else {
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12720
|
+
const reason = describeStripePaymentFailure(stripeErr?.stripeCode) ?? (stripeErr?.stripeMessage ? unmappedPaymentFailureMessage(stripeErr.stripeMessage) : msg || unmappedPaymentFailureMessage());
|
|
12721
|
+
if (!isRetriablePaymentToken(selectedPaymentToken)) {
|
|
12722
|
+
dropConsumedToken(reason, effectiveError);
|
|
12723
|
+
} else {
|
|
12724
|
+
setSessionForCheckout(null);
|
|
12725
|
+
preserveErrorOnNextStepRef.current = true;
|
|
12726
|
+
setError(reason);
|
|
12727
|
+
setStep("amount");
|
|
12728
|
+
onDepositError?.({ message: msg || "checkout_failed", error: effectiveError });
|
|
12729
|
+
}
|
|
12352
12730
|
}
|
|
12353
12731
|
} finally {
|
|
12354
12732
|
setLoading(false);
|
|
@@ -12374,7 +12752,7 @@ function PayWithStripeLink({
|
|
|
12374
12752
|
const merged = [
|
|
12375
12753
|
...existing.data.map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) })),
|
|
12376
12754
|
...stored && !existing.data.some((t13) => t13.id === stored.id) ? [stored] : []
|
|
12377
|
-
];
|
|
12755
|
+
].filter((t13) => !deadPaymentTokenIdsRef.current.has(t13.id));
|
|
12378
12756
|
if (merged.length > 0) {
|
|
12379
12757
|
const preferred = stored && merged.find((m) => m.id === stored.id) || merged[0];
|
|
12380
12758
|
selectPaymentToken(preferred);
|
|
@@ -12453,7 +12831,7 @@ function PayWithStripeLink({
|
|
|
12453
12831
|
useEffect24(() => {
|
|
12454
12832
|
if (step === "review") {
|
|
12455
12833
|
const existing = sessionForCheckoutRef.current;
|
|
12456
|
-
const hasFreshSession = !!(existing && existing.amount === amount && existing.paymentToken === selectedPaymentToken);
|
|
12834
|
+
const hasFreshSession = !!(existing && existing.amount === amount && existing.paymentToken === selectedPaymentToken && !spentSessionIdsRef.current.has(existing.id));
|
|
12457
12835
|
if (quoteNonce === quoteNonceAtReviewRef.current && hasFreshSession) return;
|
|
12458
12836
|
quoteNonceAtReviewRef.current = quoteNonce;
|
|
12459
12837
|
} else if (step !== "amount") {
|
|
@@ -12477,7 +12855,9 @@ function PayWithStripeLink({
|
|
|
12477
12855
|
const hasPaymentMethod = !!(isAuthenticated && selectedPaymentToken && onrampWalletAddress && isOnrampWalletRegistered);
|
|
12478
12856
|
if (hasPaymentMethod) {
|
|
12479
12857
|
const existing = sessionForCheckoutRef.current;
|
|
12480
|
-
const canRefreshExisting = step === "review" && existing != null && existing.amount === amount && existing.paymentToken === selectedPaymentToken
|
|
12858
|
+
const canRefreshExisting = step === "review" && existing != null && existing.amount === amount && existing.paymentToken === selectedPaymentToken && // Never refresh (and thereby reuse) a session already checked out —
|
|
12859
|
+
// its PaymentIntent is spent. Build a fresh one instead.
|
|
12860
|
+
!spentSessionIdsRef.current.has(existing.id);
|
|
12481
12861
|
const session = canRefreshExisting ? await withTokenRefresh((tok) => stripeRefreshQuote(existing.id, tok, publishableKey)) : await withTokenRefresh(
|
|
12482
12862
|
(tok) => stripeCreateSession(
|
|
12483
12863
|
{
|
|
@@ -12605,7 +12985,7 @@ function PayWithStripeLink({
|
|
|
12605
12985
|
const exceedsReachedLimit = limitReachedAmount !== null && hasInput && amountNum >= limitReachedAmount;
|
|
12606
12986
|
const exceedsLimit = exceedsKnownLimit || exceedsReachedLimit || requiredStepUp !== null;
|
|
12607
12987
|
const isValidAmount = hasInput && amountNum >= 5 && !exceedsLimit;
|
|
12608
|
-
const hasValidSession = !!(sessionForCheckout && sessionForCheckout.amount === amount && sessionForCheckout.paymentToken === selectedPaymentToken);
|
|
12988
|
+
const hasValidSession = !!(sessionForCheckout && sessionForCheckout.amount === amount && sessionForCheckout.paymentToken === selectedPaymentToken && !spentSessionIdsRef.current.has(sessionForCheckout.id));
|
|
12609
12989
|
const canCheckoutDirectly = !!(oauthToken && customerId && selectedPaymentToken && isOnrampWalletRegistered);
|
|
12610
12990
|
const isPreparingSession = canCheckoutDirectly && isValidAmount && !quoteError && (quoteLoading || !hasValidSession);
|
|
12611
12991
|
const custTiers = customer?.kyc_tiers ?? [];
|
|
@@ -12625,7 +13005,7 @@ function PayWithStripeLink({
|
|
|
12625
13005
|
};
|
|
12626
13006
|
if (configError) {
|
|
12627
13007
|
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(
|
|
13008
|
+
/* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10 uf-mb-3", style: { color: colors2.error } }),
|
|
12629
13009
|
/* @__PURE__ */ jsx44(
|
|
12630
13010
|
"p",
|
|
12631
13011
|
{
|
|
@@ -12639,7 +13019,7 @@ function PayWithStripeLink({
|
|
|
12639
13019
|
if (step === "kyc" || step === "wallet") {
|
|
12640
13020
|
if (error && !loading) {
|
|
12641
13021
|
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(
|
|
13022
|
+
/* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10 uf-mb-3", style: { color: colors2.error } }),
|
|
12643
13023
|
/* @__PURE__ */ jsx44(
|
|
12644
13024
|
"p",
|
|
12645
13025
|
{
|
|
@@ -12778,7 +13158,7 @@ function PayWithStripeLink({
|
|
|
12778
13158
|
},
|
|
12779
13159
|
children: [
|
|
12780
13160
|
/* @__PURE__ */ jsx44(
|
|
12781
|
-
|
|
13161
|
+
AlertTriangle2,
|
|
12782
13162
|
{
|
|
12783
13163
|
className: "uf-w-4 uf-h-4 uf-mt-0.5 uf-shrink-0",
|
|
12784
13164
|
style: { color: colors2.error }
|
|
@@ -13122,7 +13502,7 @@ function PayWithStripeLink({
|
|
|
13122
13502
|
{
|
|
13123
13503
|
onClick: kycFormMode === "name" ? handleNameNext : handleKycSubmit,
|
|
13124
13504
|
disabled: loading || (kycFormMode === "name" ? !kycForm.givenName || !kycForm.surname : kycFormMode === "address" ? !kycForm.addressLine1 || !kycForm.addressCity || !kycForm.addressState || !kycForm.addressPostalCode : !kycForm.ssn || !kycForm.dob.day || !kycForm.dob.month || !kycForm.dob.year),
|
|
13125
|
-
className: "uf-flex-1 uf-py-3.5 uf-text-white uf-font-medium uf-transition-
|
|
13505
|
+
className: "uf-flex-1 uf-py-3.5 uf-text-white uf-font-medium uf-transition-all hover:uf-opacity-90 disabled:uf-opacity-40",
|
|
13126
13506
|
style: {
|
|
13127
13507
|
backgroundColor: components.button.primaryBackground,
|
|
13128
13508
|
fontFamily: fonts.medium,
|
|
@@ -13181,7 +13561,17 @@ function PayWithStripeLink({
|
|
|
13181
13561
|
className: "uf-w-full uf-flex-1 uf-overflow-y-auto uf-overflow-x-hidden"
|
|
13182
13562
|
}
|
|
13183
13563
|
),
|
|
13184
|
-
!stripePaymentUIReady && /* @__PURE__ */
|
|
13564
|
+
!stripePaymentUIReady && /* @__PURE__ */ jsxs41("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-gap-3 uf-py-10", children: [
|
|
13565
|
+
/* @__PURE__ */ jsx44(Loader25, { className: "uf-w-8 uf-h-8 uf-animate-spin", style: { color: colors2.primary } }),
|
|
13566
|
+
/* @__PURE__ */ jsx44(
|
|
13567
|
+
"p",
|
|
13568
|
+
{
|
|
13569
|
+
className: "uf-text-sm uf-text-center",
|
|
13570
|
+
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
13571
|
+
children: "Setting up secure payment\u2026"
|
|
13572
|
+
}
|
|
13573
|
+
)
|
|
13574
|
+
] }),
|
|
13185
13575
|
error && /* @__PURE__ */ jsx44(
|
|
13186
13576
|
"div",
|
|
13187
13577
|
{
|
|
@@ -13288,35 +13678,14 @@ function PayWithStripeLink({
|
|
|
13288
13678
|
isCustomerVerified(customer) && /* @__PURE__ */ jsx44("div", { className: "uf-px-1", children: /* @__PURE__ */ jsxs41(
|
|
13289
13679
|
"button",
|
|
13290
13680
|
{
|
|
13291
|
-
onClick:
|
|
13292
|
-
|
|
13293
|
-
setStep("add_payment");
|
|
13294
|
-
return;
|
|
13295
|
-
}
|
|
13296
|
-
pendingAddPaymentRef.current = true;
|
|
13297
|
-
if (accessTokenRef.current && email) {
|
|
13298
|
-
setLoading(true);
|
|
13299
|
-
try {
|
|
13300
|
-
await withTokenRefresh(
|
|
13301
|
-
(tok) => stripeGetCustomer(customerId, tok, publishableKey)
|
|
13302
|
-
);
|
|
13303
|
-
const sdk = await initialize();
|
|
13304
|
-
if (!sdk) throw new Error("SDK failed to load");
|
|
13305
|
-
const authResult = await stripeCreateAuthIntent(email, publishableKey);
|
|
13306
|
-
setAuthIntentId(authResult.auth_intent_id);
|
|
13307
|
-
setStep("auth");
|
|
13308
|
-
} catch {
|
|
13309
|
-
setStep("email");
|
|
13310
|
-
} finally {
|
|
13311
|
-
setLoading(false);
|
|
13312
|
-
}
|
|
13313
|
-
return;
|
|
13314
|
-
}
|
|
13315
|
-
setStep("email");
|
|
13681
|
+
onClick: () => {
|
|
13682
|
+
setStep("add_payment");
|
|
13316
13683
|
},
|
|
13684
|
+
onMouseEnter: () => setAddPaymentHovered(true),
|
|
13685
|
+
onMouseLeave: () => setAddPaymentHovered(false),
|
|
13317
13686
|
className: "uf-w-full uf-p-3 uf-flex uf-items-center uf-gap-3 uf-transition-colors",
|
|
13318
13687
|
style: {
|
|
13319
|
-
backgroundColor: components.card.backgroundColor,
|
|
13688
|
+
backgroundColor: addPaymentHovered ? colors2.cardHover : components.card.backgroundColor,
|
|
13320
13689
|
borderRadius: components.card.borderRadius,
|
|
13321
13690
|
border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
|
|
13322
13691
|
},
|
|
@@ -13431,7 +13800,7 @@ function PayWithStripeLink({
|
|
|
13431
13800
|
{
|
|
13432
13801
|
onClick: () => handleEmailSubmit(),
|
|
13433
13802
|
disabled: loading || !email.trim(),
|
|
13434
|
-
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-
|
|
13803
|
+
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-all hover:uf-opacity-90 disabled:uf-opacity-40",
|
|
13435
13804
|
style: {
|
|
13436
13805
|
backgroundColor: components.button.primaryBackground,
|
|
13437
13806
|
fontFamily: fonts.medium,
|
|
@@ -13660,7 +14029,7 @@ function PayWithStripeLink({
|
|
|
13660
14029
|
{
|
|
13661
14030
|
onClick: handleRegisterSubmit,
|
|
13662
14031
|
disabled: loading || phone.length !== 10,
|
|
13663
|
-
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-
|
|
14032
|
+
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-all hover:uf-opacity-90 disabled:uf-opacity-40",
|
|
13664
14033
|
style: {
|
|
13665
14034
|
backgroundColor: components.button.primaryBackground,
|
|
13666
14035
|
fontFamily: fonts.medium,
|
|
@@ -13683,7 +14052,7 @@ function PayWithStripeLink({
|
|
|
13683
14052
|
const fatalError = sdkError || configError;
|
|
13684
14053
|
if (fatalError) {
|
|
13685
14054
|
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(
|
|
14055
|
+
/* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10 uf-mb-3", style: { color: colors2.error } }),
|
|
13687
14056
|
/* @__PURE__ */ jsx44(
|
|
13688
14057
|
"p",
|
|
13689
14058
|
{
|
|
@@ -13794,7 +14163,9 @@ function PayWithStripeLink({
|
|
|
13794
14163
|
);
|
|
13795
14164
|
}
|
|
13796
14165
|
if (step === "amount") {
|
|
13797
|
-
const
|
|
14166
|
+
const canSelectPaymentMethod = !!(oauthToken && customerId && isCustomerVerified(customer));
|
|
14167
|
+
const needsPaymentMethodSelection = canSelectPaymentMethod && !selectedPaymentToken;
|
|
14168
|
+
const paymentSelector = canSelectPaymentMethod ? /* @__PURE__ */ jsxs41(
|
|
13798
14169
|
"button",
|
|
13799
14170
|
{
|
|
13800
14171
|
onClick: () => setStep("payment"),
|
|
@@ -13868,6 +14239,35 @@ function PayWithStripeLink({
|
|
|
13868
14239
|
style: { backgroundColor: colors2.background },
|
|
13869
14240
|
children: [
|
|
13870
14241
|
/* @__PURE__ */ jsxs41("div", { className: "uf-mb-6 uf-pt-2", children: [
|
|
14242
|
+
error && /* @__PURE__ */ jsxs41(
|
|
14243
|
+
"div",
|
|
14244
|
+
{
|
|
14245
|
+
className: "uf-flex uf-items-start uf-gap-2 uf-mx-1 uf-mb-4 uf-px-3 uf-py-2.5",
|
|
14246
|
+
role: "alert",
|
|
14247
|
+
style: {
|
|
14248
|
+
backgroundColor: `${colors2.error}14`,
|
|
14249
|
+
border: `1px solid ${colors2.error}40`,
|
|
14250
|
+
borderRadius: components.card.borderRadius
|
|
14251
|
+
},
|
|
14252
|
+
children: [
|
|
14253
|
+
/* @__PURE__ */ jsx44(
|
|
14254
|
+
AlertTriangle2,
|
|
14255
|
+
{
|
|
14256
|
+
className: "uf-w-4 uf-h-4 uf-mt-0.5 uf-shrink-0",
|
|
14257
|
+
style: { color: colors2.error }
|
|
14258
|
+
}
|
|
14259
|
+
),
|
|
14260
|
+
/* @__PURE__ */ jsx44(
|
|
14261
|
+
"span",
|
|
14262
|
+
{
|
|
14263
|
+
className: "uf-text-xs uf-text-left",
|
|
14264
|
+
style: { color: colors2.error, fontFamily: fonts.regular },
|
|
14265
|
+
children: error
|
|
14266
|
+
}
|
|
14267
|
+
)
|
|
14268
|
+
]
|
|
14269
|
+
}
|
|
14270
|
+
),
|
|
13871
14271
|
paymentSelector,
|
|
13872
14272
|
/* @__PURE__ */ jsxs41("div", { className: "uf-text-center uf-mb-4", children: [
|
|
13873
14273
|
/* @__PURE__ */ jsx44(
|
|
@@ -13904,7 +14304,7 @@ function PayWithStripeLink({
|
|
|
13904
14304
|
children: amount && amountNum < 5 && !error ? /* @__PURE__ */ jsx44("span", { style: { color: colors2.error }, children: "Minimum amount is $5" }) : exceedsLimit && canRaiseLimit && !error ? /* @__PURE__ */ jsxs41("span", { style: { color: colors2.foregroundMuted }, children: [
|
|
13905
14305
|
purchaseLimit !== null ? `Limit $${purchaseLimit.toLocaleString()} \xB7 ` : "Limit reached \xB7 ",
|
|
13906
14306
|
"Verify to raise"
|
|
13907
|
-
] }) : exceedsLimit && !error ? /* @__PURE__ */ jsx44("span", { style: { color: colors2.error }, children: purchaseLimit !== null ? `Limit $${purchaseLimit.toLocaleString()} \xB7 Try less` : "Limit reached \xB7 Try less" }) :
|
|
14307
|
+
] }) : exceedsLimit && !error ? /* @__PURE__ */ jsx44("span", { style: { color: colors2.error }, children: purchaseLimit !== null ? `Limit $${purchaseLimit.toLocaleString()} \xB7 Try less` : "Limit reached \xB7 Try less" }) : quoteError ? /* @__PURE__ */ jsx44("span", { style: { color: colors2.error }, children: quoteError }) : quoteLoading ? /* @__PURE__ */ jsxs41(Fragment6, { children: [
|
|
13908
14308
|
/* @__PURE__ */ jsx44(
|
|
13909
14309
|
Loader25,
|
|
13910
14310
|
{
|
|
@@ -13994,7 +14394,7 @@ function PayWithStripeLink({
|
|
|
13994
14394
|
{
|
|
13995
14395
|
onClick: startLimitStepUp,
|
|
13996
14396
|
disabled: loading,
|
|
13997
|
-
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-
|
|
14397
|
+
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-all hover:uf-opacity-90 disabled:uf-opacity-40",
|
|
13998
14398
|
style: {
|
|
13999
14399
|
backgroundColor: components.button.primaryBackground,
|
|
14000
14400
|
fontFamily: fonts.medium,
|
|
@@ -14006,8 +14406,8 @@ function PayWithStripeLink({
|
|
|
14006
14406
|
"button",
|
|
14007
14407
|
{
|
|
14008
14408
|
onClick: handleAmountContinue,
|
|
14009
|
-
disabled: loading || !isValidAmount || !quote || isPreparingSession,
|
|
14010
|
-
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-
|
|
14409
|
+
disabled: loading || !isValidAmount || !quote || isPreparingSession || needsPaymentMethodSelection,
|
|
14410
|
+
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-all hover:uf-opacity-90 disabled:uf-opacity-40",
|
|
14011
14411
|
style: {
|
|
14012
14412
|
backgroundColor: components.button.primaryBackground,
|
|
14013
14413
|
fontFamily: fonts.medium,
|
|
@@ -14137,7 +14537,7 @@ function PayWithStripeLink({
|
|
|
14137
14537
|
{
|
|
14138
14538
|
onClick: isBuyNow ? handleCheckout : handleReviewContinue,
|
|
14139
14539
|
disabled: loading || !quote || isBuyNow && !hasValidSession,
|
|
14140
|
-
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-
|
|
14540
|
+
className: "uf-w-full uf-py-3.5 uf-text-white uf-font-medium uf-transition-all hover:uf-opacity-90 disabled:uf-opacity-40",
|
|
14141
14541
|
style: {
|
|
14142
14542
|
backgroundColor: components.button.primaryBackground,
|
|
14143
14543
|
fontFamily: fonts.medium,
|
|
@@ -14238,7 +14638,7 @@ function PayWithStripeLink({
|
|
|
14238
14638
|
backgroundColor: isSessionFulfilled ? colors2.success : isSessionFailed ? colors2.error : "#f59e0b",
|
|
14239
14639
|
border: `2px solid ${colors2.background}`
|
|
14240
14640
|
},
|
|
14241
|
-
children: isSessionFulfilled ? /* @__PURE__ */ jsx44(CheckCircle22, { className: "uf-w-4 uf-h-4 uf-text-white" }) : isSessionFailed ? /* @__PURE__ */ jsx44(
|
|
14641
|
+
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
14642
|
}
|
|
14243
14643
|
)
|
|
14244
14644
|
] }),
|
|
@@ -14267,7 +14667,7 @@ function PayWithStripeLink({
|
|
|
14267
14667
|
{
|
|
14268
14668
|
className: "uf-w-20 uf-h-20 uf-rounded-full uf-flex uf-items-center uf-justify-center uf-mb-6",
|
|
14269
14669
|
style: { backgroundColor: `${colors2.error}20` },
|
|
14270
|
-
children: /* @__PURE__ */ jsx44(
|
|
14670
|
+
children: /* @__PURE__ */ jsx44(AlertTriangle2, { className: "uf-w-10 uf-h-10", style: { color: colors2.error } })
|
|
14271
14671
|
}
|
|
14272
14672
|
),
|
|
14273
14673
|
/* @__PURE__ */ jsx44(
|
|
@@ -16406,14 +16806,36 @@ function useExchanges({
|
|
|
16406
16806
|
return { exchanges, isLoading };
|
|
16407
16807
|
}
|
|
16408
16808
|
|
|
16409
|
-
// src/hooks/use-
|
|
16809
|
+
// src/hooks/use-public-incident.ts
|
|
16410
16810
|
import { useQuery as useQuery13 } from "@tanstack/react-query";
|
|
16811
|
+
import { getPublicIncident } from "@unifold/core";
|
|
16812
|
+
function usePublicIncident({
|
|
16813
|
+
publishableKey,
|
|
16814
|
+
enabled = true
|
|
16815
|
+
}) {
|
|
16816
|
+
const {
|
|
16817
|
+
data: incident,
|
|
16818
|
+
isLoading,
|
|
16819
|
+
error
|
|
16820
|
+
} = useQuery13({
|
|
16821
|
+
queryKey: ["unifold", "publicIncident", publishableKey],
|
|
16822
|
+
queryFn: () => getPublicIncident(publishableKey),
|
|
16823
|
+
enabled,
|
|
16824
|
+
staleTime: 1e3 * 30,
|
|
16825
|
+
refetchInterval: 1e3 * 30,
|
|
16826
|
+
refetchOnWindowFocus: true
|
|
16827
|
+
});
|
|
16828
|
+
return { incident, isLoading, error: error ?? null };
|
|
16829
|
+
}
|
|
16830
|
+
|
|
16831
|
+
// src/hooks/use-apple-pay-providers.ts
|
|
16832
|
+
import { useQuery as useQuery14 } from "@tanstack/react-query";
|
|
16411
16833
|
import { getApplePayProviders } from "@unifold/core";
|
|
16412
16834
|
function useApplePayProviders({
|
|
16413
16835
|
publishableKey,
|
|
16414
16836
|
enabled = true
|
|
16415
16837
|
}) {
|
|
16416
|
-
const { data: providers, isLoading } =
|
|
16838
|
+
const { data: providers, isLoading } = useQuery14({
|
|
16417
16839
|
queryKey: ["unifold", "applePayProviders", publishableKey],
|
|
16418
16840
|
queryFn: () => getApplePayProviders(publishableKey),
|
|
16419
16841
|
enabled,
|
|
@@ -16432,7 +16854,8 @@ import {
|
|
|
16432
16854
|
refreshIntegrationToken as refreshIntegrationToken2,
|
|
16433
16855
|
revokeIntegrationToken,
|
|
16434
16856
|
IntegrationProvider as IntegrationProvider2,
|
|
16435
|
-
ActionType as ActionType3
|
|
16857
|
+
ActionType as ActionType3,
|
|
16858
|
+
isDepositAddressValidationError as isDepositAddressValidationError2
|
|
16436
16859
|
} from "@unifold/core";
|
|
16437
16860
|
|
|
16438
16861
|
// src/hooks/use-allowed-country.ts
|
|
@@ -16478,7 +16901,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
16478
16901
|
}
|
|
16479
16902
|
|
|
16480
16903
|
// src/hooks/use-address-validation.ts
|
|
16481
|
-
import { useQuery as
|
|
16904
|
+
import { useQuery as useQuery15 } from "@tanstack/react-query";
|
|
16482
16905
|
import {
|
|
16483
16906
|
verifyRecipientAddress
|
|
16484
16907
|
} from "@unifold/core";
|
|
@@ -16492,7 +16915,7 @@ function useAddressValidation({
|
|
|
16492
16915
|
refetchOnMount = false
|
|
16493
16916
|
}) {
|
|
16494
16917
|
const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
16495
|
-
const { data, isLoading, error } =
|
|
16918
|
+
const { data, isLoading, error } = useQuery15({
|
|
16496
16919
|
queryKey: [
|
|
16497
16920
|
"unifold",
|
|
16498
16921
|
"addressValidation",
|
|
@@ -16523,6 +16946,7 @@ function useAddressValidation({
|
|
|
16523
16946
|
return {
|
|
16524
16947
|
isValid: null,
|
|
16525
16948
|
failureCode: null,
|
|
16949
|
+
message: null,
|
|
16526
16950
|
metadata: null,
|
|
16527
16951
|
isLoading: false,
|
|
16528
16952
|
error: null
|
|
@@ -16531,6 +16955,7 @@ function useAddressValidation({
|
|
|
16531
16955
|
return {
|
|
16532
16956
|
isValid: data?.valid ?? null,
|
|
16533
16957
|
failureCode: data?.failure_code ?? null,
|
|
16958
|
+
message: data?.message ?? null,
|
|
16534
16959
|
metadata: data?.metadata ?? null,
|
|
16535
16960
|
isLoading,
|
|
16536
16961
|
error: error ?? null
|
|
@@ -16542,7 +16967,7 @@ import { useState as useState36, useEffect as useEffect30, useMemo as useMemo11
|
|
|
16542
16967
|
import {
|
|
16543
16968
|
ChevronDown as ChevronDown5,
|
|
16544
16969
|
ChevronUp as ChevronUp3,
|
|
16545
|
-
Info,
|
|
16970
|
+
Info as Info2,
|
|
16546
16971
|
Check as Check4,
|
|
16547
16972
|
DollarSign,
|
|
16548
16973
|
ShieldCheck,
|
|
@@ -17390,10 +17815,41 @@ function TokenSelectorSheet({
|
|
|
17390
17815
|
}
|
|
17391
17816
|
|
|
17392
17817
|
// src/hooks/use-default-token.ts
|
|
17393
|
-
import { useState as useState33, useEffect as useEffect29, useRef as useRef11 } from "react";
|
|
17818
|
+
import { useState as useState33, useEffect as useEffect29, useRef as useRef11, useCallback as useCallback8 } from "react";
|
|
17394
17819
|
var getChainKey = (chainId, chainType) => {
|
|
17395
17820
|
return `${chainType}:${chainId}`;
|
|
17396
17821
|
};
|
|
17822
|
+
function getStoredSelection(key) {
|
|
17823
|
+
if (typeof window === "undefined") return null;
|
|
17824
|
+
try {
|
|
17825
|
+
const raw = localStorage.getItem(key);
|
|
17826
|
+
if (!raw) return null;
|
|
17827
|
+
const parsed = JSON.parse(raw);
|
|
17828
|
+
if (parsed && typeof parsed.symbol === "string" && typeof parsed.chainType === "string" && typeof parsed.chainId === "string") {
|
|
17829
|
+
return parsed;
|
|
17830
|
+
}
|
|
17831
|
+
} catch {
|
|
17832
|
+
}
|
|
17833
|
+
return null;
|
|
17834
|
+
}
|
|
17835
|
+
function saveStoredSelection(key, symbol, chainType, chainId) {
|
|
17836
|
+
if (typeof window === "undefined") return;
|
|
17837
|
+
try {
|
|
17838
|
+
localStorage.setItem(key, JSON.stringify({ symbol, chainType, chainId }));
|
|
17839
|
+
} catch {
|
|
17840
|
+
}
|
|
17841
|
+
}
|
|
17842
|
+
function resolveFromStorage(tokens, stored) {
|
|
17843
|
+
for (const t13 of tokens) {
|
|
17844
|
+
if (t13.symbol !== stored.symbol) continue;
|
|
17845
|
+
const matchedChain = t13.chains.find(
|
|
17846
|
+
(c) => c.chain_type === stored.chainType && c.chain_id === stored.chainId
|
|
17847
|
+
);
|
|
17848
|
+
if (matchedChain) return { token: t13, chain: matchedChain };
|
|
17849
|
+
if (t13.chains.length > 0) return { token: t13, chain: t13.chains[0] };
|
|
17850
|
+
}
|
|
17851
|
+
return null;
|
|
17852
|
+
}
|
|
17397
17853
|
function resolveToken(tokens, defaultChainType, defaultChainId, defaultTokenAddress, defaultSymbol) {
|
|
17398
17854
|
if (!tokens.length) return null;
|
|
17399
17855
|
let selectedToken;
|
|
@@ -17443,27 +17899,73 @@ function useDefaultToken({
|
|
|
17443
17899
|
defaultChainType,
|
|
17444
17900
|
defaultChainId,
|
|
17445
17901
|
defaultTokenAddress,
|
|
17446
|
-
defaultSymbol
|
|
17902
|
+
defaultSymbol,
|
|
17903
|
+
storageKey: storageKey2
|
|
17447
17904
|
}) {
|
|
17448
|
-
const [token,
|
|
17449
|
-
const [chain,
|
|
17905
|
+
const [token, setTokenState] = useState33(null);
|
|
17906
|
+
const [chain, setChainState] = useState33(null);
|
|
17450
17907
|
const [initialSelectionDone, setInitialSelectionDone] = useState33(false);
|
|
17451
17908
|
const appliedDefaultsRef = useRef11("");
|
|
17909
|
+
const tokenRef = useRef11(null);
|
|
17910
|
+
const chainRef = useRef11(null);
|
|
17911
|
+
tokenRef.current = token;
|
|
17912
|
+
chainRef.current = chain;
|
|
17913
|
+
const setToken = useCallback8(
|
|
17914
|
+
(newToken) => {
|
|
17915
|
+
tokenRef.current = newToken;
|
|
17916
|
+
setTokenState(newToken);
|
|
17917
|
+
if (storageKey2 && chainRef.current) {
|
|
17918
|
+
const [chainType, chainId] = chainRef.current.split(":");
|
|
17919
|
+
saveStoredSelection(storageKey2, newToken, chainType, chainId);
|
|
17920
|
+
}
|
|
17921
|
+
},
|
|
17922
|
+
[storageKey2]
|
|
17923
|
+
);
|
|
17924
|
+
const setChain = useCallback8(
|
|
17925
|
+
(newChain) => {
|
|
17926
|
+
chainRef.current = newChain;
|
|
17927
|
+
setChainState(newChain);
|
|
17928
|
+
if (storageKey2 && tokenRef.current) {
|
|
17929
|
+
const [chainType, chainId] = newChain.split(":");
|
|
17930
|
+
saveStoredSelection(storageKey2, tokenRef.current, chainType, chainId);
|
|
17931
|
+
}
|
|
17932
|
+
},
|
|
17933
|
+
[storageKey2]
|
|
17934
|
+
);
|
|
17452
17935
|
useEffect29(() => {
|
|
17453
17936
|
if (!tokens.length) return;
|
|
17454
17937
|
const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
|
|
17455
17938
|
const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
|
|
17456
17939
|
if (initialSelectionDone && !defaultsChanged) return;
|
|
17457
|
-
const
|
|
17458
|
-
|
|
17459
|
-
|
|
17460
|
-
|
|
17461
|
-
|
|
17462
|
-
|
|
17463
|
-
|
|
17940
|
+
const hasExplicitDefaults = defaultTokenAddress && defaultChainType && defaultChainId || defaultSymbol && defaultChainType && defaultChainId;
|
|
17941
|
+
let result = null;
|
|
17942
|
+
if (hasExplicitDefaults) {
|
|
17943
|
+
result = resolveToken(
|
|
17944
|
+
tokens,
|
|
17945
|
+
defaultChainType,
|
|
17946
|
+
defaultChainId,
|
|
17947
|
+
defaultTokenAddress,
|
|
17948
|
+
defaultSymbol
|
|
17949
|
+
);
|
|
17950
|
+
if (result) {
|
|
17951
|
+
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;
|
|
17952
|
+
if (!matched) {
|
|
17953
|
+
result = null;
|
|
17954
|
+
}
|
|
17955
|
+
}
|
|
17956
|
+
}
|
|
17957
|
+
if (!result && storageKey2) {
|
|
17958
|
+
const stored = getStoredSelection(storageKey2);
|
|
17959
|
+
if (stored) {
|
|
17960
|
+
result = resolveFromStorage(tokens, stored);
|
|
17961
|
+
}
|
|
17962
|
+
}
|
|
17963
|
+
if (!result) {
|
|
17964
|
+
result = resolveToken(tokens);
|
|
17965
|
+
}
|
|
17464
17966
|
if (result) {
|
|
17465
|
-
|
|
17466
|
-
|
|
17967
|
+
setTokenState(result.token.symbol);
|
|
17968
|
+
setChainState(getChainKey(result.chain.chain_id, result.chain.chain_type));
|
|
17467
17969
|
appliedDefaultsRef.current = defaultsKey;
|
|
17468
17970
|
setInitialSelectionDone(true);
|
|
17469
17971
|
}
|
|
@@ -17473,7 +17975,8 @@ function useDefaultToken({
|
|
|
17473
17975
|
defaultSymbol,
|
|
17474
17976
|
defaultChainType,
|
|
17475
17977
|
defaultChainId,
|
|
17476
|
-
initialSelectionDone
|
|
17978
|
+
initialSelectionDone,
|
|
17979
|
+
storageKey2
|
|
17477
17980
|
]);
|
|
17478
17981
|
useEffect29(() => {
|
|
17479
17982
|
if (!tokens.length || !token) return;
|
|
@@ -17484,13 +17987,14 @@ function useDefaultToken({
|
|
|
17484
17987
|
});
|
|
17485
17988
|
if (!isChainAvailable) {
|
|
17486
17989
|
const firstChain = currentToken.chains[0];
|
|
17487
|
-
|
|
17990
|
+
setChainState(getChainKey(firstChain.chain_id, firstChain.chain_type));
|
|
17488
17991
|
}
|
|
17489
17992
|
}, [token, tokens, chain]);
|
|
17490
17993
|
return { token, chain, setToken, setChain, initialSelectionDone };
|
|
17491
17994
|
}
|
|
17492
17995
|
|
|
17493
17996
|
// src/hooks/use-default-source-token.ts
|
|
17997
|
+
var STORAGE_KEY2 = "unifold_last_deposit_from_token";
|
|
17494
17998
|
function useDefaultSourceToken({
|
|
17495
17999
|
supportedTokens,
|
|
17496
18000
|
defaultSourceChainType,
|
|
@@ -17503,7 +18007,8 @@ function useDefaultSourceToken({
|
|
|
17503
18007
|
defaultChainType: defaultSourceChainType,
|
|
17504
18008
|
defaultChainId: defaultSourceChainId,
|
|
17505
18009
|
defaultTokenAddress: defaultSourceTokenAddress,
|
|
17506
|
-
defaultSymbol: defaultSourceSymbol
|
|
18010
|
+
defaultSymbol: defaultSourceSymbol,
|
|
18011
|
+
storageKey: STORAGE_KEY2
|
|
17507
18012
|
});
|
|
17508
18013
|
}
|
|
17509
18014
|
|
|
@@ -17854,7 +18359,7 @@ import {
|
|
|
17854
18359
|
} from "@unifold/core";
|
|
17855
18360
|
|
|
17856
18361
|
// src/hooks/use-hypercore-activation.ts
|
|
17857
|
-
import { useQuery as
|
|
18362
|
+
import { useQuery as useQuery16 } from "@tanstack/react-query";
|
|
17858
18363
|
import { checkHypercoreActivation } from "@unifold/core";
|
|
17859
18364
|
|
|
17860
18365
|
// src/lib/constants.ts
|
|
@@ -17873,7 +18378,7 @@ function useHypercoreActivation(params) {
|
|
|
17873
18378
|
const recipient = recipientAddress?.trim() ?? "";
|
|
17874
18379
|
const source = sourceAddress?.trim() ?? "";
|
|
17875
18380
|
const hasAddresses = !!recipient && !!source;
|
|
17876
|
-
const { data, isLoading } =
|
|
18381
|
+
const { data, isLoading } = useQuery16({
|
|
17877
18382
|
queryKey: ["unifold", "hypercoreActivation", source, recipient, publishableKey],
|
|
17878
18383
|
queryFn: () => checkHypercoreActivation(
|
|
17879
18384
|
{
|
|
@@ -17901,7 +18406,7 @@ function useHypercoreActivation(params) {
|
|
|
17901
18406
|
}
|
|
17902
18407
|
|
|
17903
18408
|
// src/components/shared/HypercoreActivationWarning.tsx
|
|
17904
|
-
import { AlertTriangle as
|
|
18409
|
+
import { AlertTriangle as AlertTriangle3 } from "lucide-react";
|
|
17905
18410
|
import { jsx as jsx53, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
17906
18411
|
function HypercoreActivationWarning({
|
|
17907
18412
|
activationFee,
|
|
@@ -17919,7 +18424,7 @@ function HypercoreActivationWarning({
|
|
|
17919
18424
|
},
|
|
17920
18425
|
children: [
|
|
17921
18426
|
/* @__PURE__ */ jsx53(
|
|
17922
|
-
|
|
18427
|
+
AlertTriangle3,
|
|
17923
18428
|
{
|
|
17924
18429
|
className: "uf-w-4 uf-h-4 uf-flex-shrink-0 uf-mt-0.5",
|
|
17925
18430
|
style: { color: colors2.warning }
|
|
@@ -18234,7 +18739,7 @@ function TransferCryptoSingleInput({
|
|
|
18234
18739
|
),
|
|
18235
18740
|
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
18741
|
/* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-items-start uf-gap-2", children: [
|
|
18237
|
-
/* @__PURE__ */ jsx54(
|
|
18742
|
+
/* @__PURE__ */ jsx54(Info2, { className: "uf-w-4 uf-h-4 uf-text-destructive uf-flex-shrink-0 uf-mt-0.5" }),
|
|
18238
18743
|
/* @__PURE__ */ jsxs49("div", { className: "uf-flex-1 uf-min-w-0", children: [
|
|
18239
18744
|
/* @__PURE__ */ jsx54("div", { className: "uf-text-xs uf-font-medium uf-text-destructive uf-mb-1", children: "Failed to create deposit address" }),
|
|
18240
18745
|
/* @__PURE__ */ jsx54("div", { className: "uf-text-xs uf-text-muted-foreground", children: error })
|
|
@@ -18629,7 +19134,7 @@ import { useState as useState37, useEffect as useEffect31, useMemo as useMemo12
|
|
|
18629
19134
|
import {
|
|
18630
19135
|
ChevronDown as ChevronDown7,
|
|
18631
19136
|
ChevronUp as ChevronUp5,
|
|
18632
|
-
Info as
|
|
19137
|
+
Info as Info3,
|
|
18633
19138
|
Check as Check6,
|
|
18634
19139
|
DollarSign as DollarSign2,
|
|
18635
19140
|
ShieldCheck as ShieldCheck2,
|
|
@@ -19098,7 +19603,7 @@ function TransferCryptoDoubleInput({
|
|
|
19098
19603
|
] }),
|
|
19099
19604
|
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
19605
|
/* @__PURE__ */ jsxs51("div", { className: "uf-flex uf-items-start uf-gap-2", children: [
|
|
19101
|
-
/* @__PURE__ */ jsx56(
|
|
19606
|
+
/* @__PURE__ */ jsx56(Info3, { className: "uf-w-4 uf-h-4 uf-text-destructive uf-flex-shrink-0 uf-mt-0.5" }),
|
|
19102
19607
|
/* @__PURE__ */ jsxs51("div", { className: "uf-flex-1 uf-min-w-0", children: [
|
|
19103
19608
|
/* @__PURE__ */ jsx56("div", { className: "uf-text-xs uf-font-medium uf-text-destructive uf-mb-1", children: "Failed to create deposit address" }),
|
|
19104
19609
|
/* @__PURE__ */ jsx56("div", { className: "uf-text-xs uf-text-muted-foreground", children: error })
|
|
@@ -19472,7 +19977,7 @@ async function sendHypercoreEvmTransfer(params) {
|
|
|
19472
19977
|
}
|
|
19473
19978
|
|
|
19474
19979
|
// src/hooks/use-deposit-quote.ts
|
|
19475
|
-
import { useQuery as
|
|
19980
|
+
import { useQuery as useQuery17 } from "@tanstack/react-query";
|
|
19476
19981
|
import { getDepositQuote } from "@unifold/core";
|
|
19477
19982
|
function useDepositQuote(params) {
|
|
19478
19983
|
const {
|
|
@@ -19499,7 +20004,7 @@ function useDepositQuote(params) {
|
|
|
19499
20004
|
...adjustForSlippage ? { adjust_for_slippage: true } : {},
|
|
19500
20005
|
...stablecoinParity ? { stablecoin_parity: true } : {}
|
|
19501
20006
|
};
|
|
19502
|
-
return
|
|
20007
|
+
return useQuery17({
|
|
19503
20008
|
queryKey: [
|
|
19504
20009
|
"unifold",
|
|
19505
20010
|
"depositQuote",
|
|
@@ -19527,13 +20032,13 @@ function useDepositQuote(params) {
|
|
|
19527
20032
|
}
|
|
19528
20033
|
|
|
19529
20034
|
// src/hooks/use-external-wallets.ts
|
|
19530
|
-
import { useQuery as
|
|
20035
|
+
import { useQuery as useQuery18 } from "@tanstack/react-query";
|
|
19531
20036
|
import { getExternalWallets } from "@unifold/core";
|
|
19532
20037
|
function useExternalWallets({
|
|
19533
20038
|
publishableKey,
|
|
19534
20039
|
enabled = true
|
|
19535
20040
|
}) {
|
|
19536
|
-
const { data: wallets = [], isLoading } =
|
|
20041
|
+
const { data: wallets = [], isLoading } = useQuery18({
|
|
19537
20042
|
queryKey: ["unifold", "external-wallets", publishableKey],
|
|
19538
20043
|
queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
|
|
19539
20044
|
enabled: enabled && !!publishableKey,
|
|
@@ -20644,33 +21149,11 @@ function balancesRepresentSameToken(a, b) {
|
|
|
20644
21149
|
if (!tokenA || !tokenB) return false;
|
|
20645
21150
|
return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
|
|
20646
21151
|
}
|
|
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
21152
|
function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
|
|
20670
|
-
const solProviders = getSolanaProviders();
|
|
20671
|
-
const legacyEvm = getLegacyEvmProviders();
|
|
20672
|
-
const eip6963List = getEip6963Providers();
|
|
20673
21153
|
const win = typeof window !== "undefined" ? window : null;
|
|
21154
|
+
const solProviders = getInjectedSolanaProviders(win);
|
|
21155
|
+
const legacyEvm = getLegacyEvmProviders(win);
|
|
21156
|
+
const eip6963List = getEip6963Providers();
|
|
20674
21157
|
const hasEip6963 = (walletId) => eip6963List.some((d) => {
|
|
20675
21158
|
const rdns = d.info?.rdns || "";
|
|
20676
21159
|
switch (walletId) {
|
|
@@ -20922,7 +21405,7 @@ function WalletConnect({
|
|
|
20922
21405
|
const chainType = activeDepositWallet?.chain_type ?? "ethereum";
|
|
20923
21406
|
const recipientAddress = activeDepositWallet?.address ?? "";
|
|
20924
21407
|
const isCheckoutMode = !!checkoutAmountUsd;
|
|
20925
|
-
const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
|
|
21408
|
+
const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" || chainType === "tron" ? "ethereum" : chainType;
|
|
20926
21409
|
const transitionTo = React35.useCallback((nextView) => {
|
|
20927
21410
|
if (nextView === viewRef.current) return;
|
|
20928
21411
|
setIsTransitioning(true);
|
|
@@ -20939,10 +21422,13 @@ function WalletConnect({
|
|
|
20939
21422
|
};
|
|
20940
21423
|
const openMobileWalletBrowse = async (wallet, depositAddresses) => {
|
|
20941
21424
|
try {
|
|
21425
|
+
const cleanedAmountUsd = amountUsd?.replace(/[^0-9.]/g, "") ?? "";
|
|
21426
|
+
const forwardedAmountUsd = parseFloat(cleanedAmountUsd) > 0 ? cleanedAmountUsd : void 0;
|
|
20942
21427
|
const res = await getWalletMobileDeepLink(
|
|
20943
21428
|
wallet.id,
|
|
20944
21429
|
depositAddresses,
|
|
20945
|
-
publishableKey
|
|
21430
|
+
publishableKey,
|
|
21431
|
+
forwardedAmountUsd
|
|
20946
21432
|
);
|
|
20947
21433
|
if (res.deeplink) {
|
|
20948
21434
|
setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
|
|
@@ -21031,7 +21517,7 @@ function WalletConnect({
|
|
|
21031
21517
|
const eip6963Match = findProviderByWalletId(wallet.id);
|
|
21032
21518
|
let provider = eip6963Match?.provider;
|
|
21033
21519
|
if (!provider) {
|
|
21034
|
-
const legacyEvm = getLegacyEvmProviders();
|
|
21520
|
+
const legacyEvm = getLegacyEvmProviders(win);
|
|
21035
21521
|
switch (wallet.id) {
|
|
21036
21522
|
case "metamask":
|
|
21037
21523
|
if (legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom)
|
|
@@ -21063,16 +21549,7 @@ function WalletConnect({
|
|
|
21063
21549
|
const accounts = await provider.request({ method: "eth_requestAccounts" });
|
|
21064
21550
|
if (!accounts?.length) throw new Error("No accounts returned from wallet");
|
|
21065
21551
|
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";
|
|
21552
|
+
const walletType = walletIdToWalletType(wallet.id);
|
|
21076
21553
|
setStoredWalletState(walletType);
|
|
21077
21554
|
connectedInfo = {
|
|
21078
21555
|
type: walletType,
|
|
@@ -21081,7 +21558,7 @@ function WalletConnect({
|
|
|
21081
21558
|
icon: wallet.id
|
|
21082
21559
|
};
|
|
21083
21560
|
} else {
|
|
21084
|
-
const solProviders =
|
|
21561
|
+
const solProviders = getInjectedSolanaProviders(win);
|
|
21085
21562
|
let provider;
|
|
21086
21563
|
switch (wallet.id) {
|
|
21087
21564
|
case "phantom":
|
|
@@ -21100,11 +21577,11 @@ function WalletConnect({
|
|
|
21100
21577
|
provider = solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
|
|
21101
21578
|
break;
|
|
21102
21579
|
case "trust":
|
|
21103
|
-
provider =
|
|
21580
|
+
provider = solProviders.trustSolana;
|
|
21104
21581
|
break;
|
|
21105
21582
|
}
|
|
21106
21583
|
if (!provider) throw new Error(`${wallet.name} Solana wallet not found.`);
|
|
21107
|
-
const response = await provider.
|
|
21584
|
+
const response = await connectSolanaProviderWithRecovery(provider, wallet.id, wallet.name);
|
|
21108
21585
|
setUserDisconnectedWallet(false);
|
|
21109
21586
|
const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
|
|
21110
21587
|
setStoredWalletState(walletType);
|
|
@@ -21277,7 +21754,7 @@ function WalletConnect({
|
|
|
21277
21754
|
let cancelled = false;
|
|
21278
21755
|
setIsLoading(true);
|
|
21279
21756
|
setError(null);
|
|
21280
|
-
const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" ? "ethereum" : activeDepositWallet.chain_type;
|
|
21757
|
+
const sct = activeDepositWallet.chain_type === "algorand" || activeDepositWallet.chain_type === "xrpl" || activeDepositWallet.chain_type === "cardano" || activeDepositWallet.chain_type === "n1" || activeDepositWallet.chain_type === "tron" ? "ethereum" : activeDepositWallet.chain_type;
|
|
21281
21758
|
getAddressBalances2(activeWalletInfo.address, sct, publishableKey).then((response) => {
|
|
21282
21759
|
if (cancelled) return;
|
|
21283
21760
|
const nonZero = response.balances.filter((b) => b.amount !== "0");
|
|
@@ -21455,16 +21932,7 @@ function WalletConnect({
|
|
|
21455
21932
|
return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
|
|
21456
21933
|
};
|
|
21457
21934
|
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;
|
|
21935
|
+
const lookupId = walletTypeToWalletId(walletInfo.type);
|
|
21468
21936
|
const eip6963Match = findProviderByWalletId(lookupId);
|
|
21469
21937
|
let provider = eip6963Match?.provider;
|
|
21470
21938
|
if (!provider) {
|
|
@@ -22196,6 +22664,7 @@ function DepositModal({
|
|
|
22196
22664
|
applePayTitle = "Pay with Apple Pay",
|
|
22197
22665
|
applePaySubTitle = "Instant",
|
|
22198
22666
|
enableBankTransfer,
|
|
22667
|
+
enableIncidentBanner = false,
|
|
22199
22668
|
// No default: left undefined so the backend `stripe_link.enabled` can govern
|
|
22200
22669
|
// (via the `??` chain in showStripeLink) once a dashboard toggle exists.
|
|
22201
22670
|
enableStripeLink,
|
|
@@ -22220,7 +22689,7 @@ function DepositModal({
|
|
|
22220
22689
|
() => normalizePrefilledUsdAmount(prefilledAmountUsd),
|
|
22221
22690
|
[prefilledAmountUsd]
|
|
22222
22691
|
);
|
|
22223
|
-
const onDepositSuccessFor =
|
|
22692
|
+
const onDepositSuccessFor = useCallback11(
|
|
22224
22693
|
(method) => onDepositSuccess || onEvent ? (data) => {
|
|
22225
22694
|
const payload = { ...data, method };
|
|
22226
22695
|
onDepositSuccess?.(payload);
|
|
@@ -22233,7 +22702,7 @@ function DepositModal({
|
|
|
22233
22702
|
} : void 0,
|
|
22234
22703
|
[onDepositSuccess, onEvent]
|
|
22235
22704
|
);
|
|
22236
|
-
const onDepositErrorFor =
|
|
22705
|
+
const onDepositErrorFor = useCallback11(
|
|
22237
22706
|
(method) => onDepositError ? (error) => onDepositError({ ...error, method }) : void 0,
|
|
22238
22707
|
[onDepositError]
|
|
22239
22708
|
);
|
|
@@ -22241,7 +22710,7 @@ function DepositModal({
|
|
|
22241
22710
|
const s = initialScreen ?? "main";
|
|
22242
22711
|
if (s === "tracker" && hideDepositTracker === true) return "main";
|
|
22243
22712
|
if (s === "cashapp" && enableCashApp === false) return "main";
|
|
22244
|
-
if (s === "stripe_link" &&
|
|
22713
|
+
if (s === "stripe_link" && enableStripeLink === false) return "main";
|
|
22245
22714
|
if (s === "apple_pay" && enableApplePay === false) return "main";
|
|
22246
22715
|
if (s === "card" && enableFiatOnramp === false) return "main";
|
|
22247
22716
|
if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
|
|
@@ -22263,7 +22732,7 @@ function DepositModal({
|
|
|
22263
22732
|
enableStripeLink
|
|
22264
22733
|
]);
|
|
22265
22734
|
const [containerEl, setContainerEl] = useState40(null);
|
|
22266
|
-
const containerCallbackRef =
|
|
22735
|
+
const containerCallbackRef = useCallback11((el) => {
|
|
22267
22736
|
setContainerEl(el);
|
|
22268
22737
|
}, []);
|
|
22269
22738
|
const [view, setView] = useState40(effectiveInitialScreen);
|
|
@@ -22300,6 +22769,16 @@ function DepositModal({
|
|
|
22300
22769
|
const showApplePay = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
|
|
22301
22770
|
const showBankTransfer = enableBankTransfer ?? projectConfig?.bank_transfer?.enabled ?? true;
|
|
22302
22771
|
const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
|
|
22772
|
+
const { incident: publicIncident } = usePublicIncident({
|
|
22773
|
+
publishableKey,
|
|
22774
|
+
enabled: open && enableIncidentBanner
|
|
22775
|
+
});
|
|
22776
|
+
const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
|
|
22777
|
+
enabled: true,
|
|
22778
|
+
messages: publicIncident.messages,
|
|
22779
|
+
severity: publicIncident.severity,
|
|
22780
|
+
statusPageUrl: publicIncident.status_page_url
|
|
22781
|
+
} : void 0;
|
|
22303
22782
|
const [integrationExchanges, setIntegrationExchanges] = useState40([]);
|
|
22304
22783
|
useEffect34(() => {
|
|
22305
22784
|
if (!showConnectExchange || !open) return;
|
|
@@ -22366,7 +22845,11 @@ function DepositModal({
|
|
|
22366
22845
|
setConnectedExchange((prev) => prev ? { ...prev, iconUrl } : prev);
|
|
22367
22846
|
}
|
|
22368
22847
|
}, [integrationExchanges, connectedExchange]);
|
|
22369
|
-
const {
|
|
22848
|
+
const {
|
|
22849
|
+
data: depositAddressResponse,
|
|
22850
|
+
isLoading: walletsLoading,
|
|
22851
|
+
error: walletsError
|
|
22852
|
+
} = useDepositAddress({
|
|
22370
22853
|
userId,
|
|
22371
22854
|
publishableKey,
|
|
22372
22855
|
recipientAddress,
|
|
@@ -22499,6 +22982,7 @@ function DepositModal({
|
|
|
22499
22982
|
const {
|
|
22500
22983
|
isValid: isAddressValid,
|
|
22501
22984
|
failureCode: addressFailureCode,
|
|
22985
|
+
message: addressFailureMessage,
|
|
22502
22986
|
metadata: addressFailureMetadata,
|
|
22503
22987
|
isLoading: isAddressValidationLoading
|
|
22504
22988
|
} = useAddressValidation({
|
|
@@ -22512,17 +22996,31 @@ function DepositModal({
|
|
|
22512
22996
|
refetchOnMount: "always"
|
|
22513
22997
|
});
|
|
22514
22998
|
const addressValidationMessages = i18n.transferCrypto.addressValidation;
|
|
22515
|
-
const getAddressValidationErrorMessage = (code, metadata) => {
|
|
22999
|
+
const getAddressValidationErrorMessage = (message, code, metadata) => {
|
|
23000
|
+
if (message && message.trim().length > 0) return message;
|
|
22516
23001
|
if (!code) return addressValidationMessages.defaultError;
|
|
22517
23002
|
const errors = addressValidationMessages.errors;
|
|
22518
23003
|
const template = errors[code] ?? addressValidationMessages.defaultError;
|
|
22519
23004
|
return interpolate(template, metadata);
|
|
22520
23005
|
};
|
|
23006
|
+
const walletsRecipientError = isDepositAddressValidationError2(walletsError) ? walletsError.message : null;
|
|
23007
|
+
const isRecipientAddressInvalid = isAddressValid === false || walletsRecipientError !== null;
|
|
23008
|
+
const recipientInvalidMessage = getAddressValidationErrorMessage(
|
|
23009
|
+
addressFailureMessage ?? walletsRecipientError,
|
|
23010
|
+
addressFailureCode,
|
|
23011
|
+
addressFailureMetadata
|
|
23012
|
+
);
|
|
22521
23013
|
const openingScreen = effectiveInitialScreen;
|
|
22522
23014
|
const sessionOpenedFromMenu = openingScreen === "main";
|
|
22523
23015
|
const standaloneNeedsDepositPrereq = openingScreen !== "main" && (view === "transfer" || view === "card");
|
|
22524
23016
|
let depositPrerequisiteBody;
|
|
22525
|
-
if (
|
|
23017
|
+
if (isRecipientAddressInvalid) {
|
|
23018
|
+
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: [
|
|
23019
|
+
/* @__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" }) }),
|
|
23020
|
+
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
|
|
23021
|
+
/* @__PURE__ */ jsx63("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: recipientInvalidMessage })
|
|
23022
|
+
] });
|
|
23023
|
+
} else if (isCountryLoading || isAddressValidationLoading || tokensLoading || walletsLoading || !projectConfig || // Bank-transfer row visibility depends on the country-gated providers
|
|
22526
23024
|
// fetch — block the menu on it so the row never flashes in or out.
|
|
22527
23025
|
showBankTransfer && bankTransferProvidersLoading || // Same for Apple Pay: row visibility depends on the geo/platform-gated
|
|
22528
23026
|
// providers fetch — block the menu so the row doesn't pop in or out.
|
|
@@ -22534,7 +23032,7 @@ function DepositModal({
|
|
|
22534
23032
|
] });
|
|
22535
23033
|
} else if (countryError) {
|
|
22536
23034
|
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(
|
|
23035
|
+
/* @__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
23036
|
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "Unable to Verify Location" }),
|
|
22539
23037
|
/* @__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
23038
|
] });
|
|
@@ -22544,12 +23042,6 @@ function DepositModal({
|
|
|
22544
23042
|
/* @__PURE__ */ jsx63("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "No Tokens Available" }),
|
|
22545
23043
|
/* @__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
23044
|
] });
|
|
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
23045
|
} else {
|
|
22554
23046
|
depositPrerequisiteBody = null;
|
|
22555
23047
|
}
|
|
@@ -23043,6 +23535,7 @@ function DepositModal({
|
|
|
23043
23535
|
title: modalTitle || "Deposit",
|
|
23044
23536
|
showClose: !hideOverlay,
|
|
23045
23537
|
onClose: handleClose,
|
|
23538
|
+
incident: activeIncident,
|
|
23046
23539
|
showBalance: showBalanceHeader,
|
|
23047
23540
|
balanceAddress: recipientAddress,
|
|
23048
23541
|
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
|
|
@@ -23062,6 +23555,7 @@ function DepositModal({
|
|
|
23062
23555
|
showBack: showBackTransfer,
|
|
23063
23556
|
onBack: handleBack,
|
|
23064
23557
|
onClose: handleClose,
|
|
23558
|
+
incident: activeIncident,
|
|
23065
23559
|
showBalance: showBalanceHeader,
|
|
23066
23560
|
balanceAddress: recipientAddress,
|
|
23067
23561
|
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
|
|
@@ -23122,7 +23616,8 @@ function DepositModal({
|
|
|
23122
23616
|
title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
|
|
23123
23617
|
showBack: showBackTracker,
|
|
23124
23618
|
onBack: handleBack,
|
|
23125
|
-
onClose: handleClose
|
|
23619
|
+
onClose: handleClose,
|
|
23620
|
+
incident: activeIncident
|
|
23126
23621
|
}
|
|
23127
23622
|
),
|
|
23128
23623
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23154,6 +23649,7 @@ function DepositModal({
|
|
|
23154
23649
|
showBack: showBackCard,
|
|
23155
23650
|
onBack: handleBack,
|
|
23156
23651
|
onClose: handleClose,
|
|
23652
|
+
incident: activeIncident,
|
|
23157
23653
|
badge: cardView === "quotes" ? { count: quotesCount } : void 0,
|
|
23158
23654
|
showBalance: showBalanceHeader,
|
|
23159
23655
|
balanceAddress: recipientAddress,
|
|
@@ -23203,7 +23699,8 @@ function DepositModal({
|
|
|
23203
23699
|
title: payWithExchangeTitle,
|
|
23204
23700
|
showBack: exchangeView === "pending" || sessionOpenedFromMenu,
|
|
23205
23701
|
onBack: handleBack,
|
|
23206
|
-
onClose: handleClose
|
|
23702
|
+
onClose: handleClose,
|
|
23703
|
+
incident: activeIncident
|
|
23207
23704
|
}
|
|
23208
23705
|
),
|
|
23209
23706
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23317,7 +23814,8 @@ function DepositModal({
|
|
|
23317
23814
|
title: t8.bankTransfer.title,
|
|
23318
23815
|
showBack: bankTransferView !== "providers" || sessionOpenedFromMenu,
|
|
23319
23816
|
onBack: handleBack,
|
|
23320
|
-
onClose: handleClose
|
|
23817
|
+
onClose: handleClose,
|
|
23818
|
+
incident: activeIncident
|
|
23321
23819
|
}
|
|
23322
23820
|
),
|
|
23323
23821
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23351,26 +23849,24 @@ function DepositModal({
|
|
|
23351
23849
|
title: "Deposit with Link",
|
|
23352
23850
|
showBack: stripeLinkStep !== "checkout" && stripeLinkStep !== "success",
|
|
23353
23851
|
onBack: handleBack,
|
|
23852
|
+
incident: activeIncident,
|
|
23354
23853
|
showClose: stripeLinkStep !== "checkout" && stripeLinkStep !== "auth",
|
|
23355
23854
|
onClose: handleClose
|
|
23356
23855
|
}
|
|
23357
23856
|
),
|
|
23358
23857
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
23359
23858
|
isLoadingIp ? (
|
|
23360
|
-
//
|
|
23361
|
-
// PayWithStripeLink (which kicks off config/OAuth work) for a
|
|
23362
|
-
// deep-link user who turns out to be outside the US.
|
|
23859
|
+
// Wait for location so the first config fetch is region-aware.
|
|
23363
23860
|
/* @__PURE__ */ jsx63(SkeletonButton, { variant: "with-icons" })
|
|
23364
23861
|
) : !showStripeLink ? (
|
|
23365
|
-
//
|
|
23366
|
-
//
|
|
23367
|
-
//
|
|
23368
|
-
// the Link UI.
|
|
23862
|
+
// Direct opens (initialScreen="stripe_link") have no menu row
|
|
23863
|
+
// to fall back to, so render an unavailable state when backend
|
|
23864
|
+
// config resolves Stripe Link disabled/hidden.
|
|
23369
23865
|
/* @__PURE__ */ jsx63(
|
|
23370
23866
|
GeoRestrictionScreen,
|
|
23371
23867
|
{
|
|
23372
23868
|
methodName: t8.stripeLink.title,
|
|
23373
|
-
message:
|
|
23869
|
+
message: t8.stripeLink.unavailableInRegionMessage
|
|
23374
23870
|
}
|
|
23375
23871
|
)
|
|
23376
23872
|
) : /* @__PURE__ */ jsx63(
|
|
@@ -23403,7 +23899,8 @@ function DepositModal({
|
|
|
23403
23899
|
title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
|
|
23404
23900
|
showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
|
|
23405
23901
|
onBack: handleBack,
|
|
23406
|
-
onClose: handleClose
|
|
23902
|
+
onClose: handleClose,
|
|
23903
|
+
incident: activeIncident
|
|
23407
23904
|
}
|
|
23408
23905
|
),
|
|
23409
23906
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23439,7 +23936,8 @@ function DepositModal({
|
|
|
23439
23936
|
const handled = applePayHandleRef.current?.requestBack() ?? false;
|
|
23440
23937
|
if (!handled) handleBack();
|
|
23441
23938
|
},
|
|
23442
|
-
onClose: handleClose
|
|
23939
|
+
onClose: handleClose,
|
|
23940
|
+
incident: activeIncident
|
|
23443
23941
|
}
|
|
23444
23942
|
),
|
|
23445
23943
|
/* @__PURE__ */ jsxs57("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -23481,16 +23979,16 @@ function DepositModal({
|
|
|
23481
23979
|
}
|
|
23482
23980
|
|
|
23483
23981
|
// src/components/checkout/CheckoutModal.tsx
|
|
23484
|
-
import { useState as useState41, useEffect as useEffect35, useLayoutEffect as useLayoutEffect3, useCallback as
|
|
23485
|
-
import { AlertTriangle as
|
|
23982
|
+
import { useState as useState41, useEffect as useEffect35, useLayoutEffect as useLayoutEffect3, useCallback as useCallback12, useRef as useRef14, useMemo as useMemo15 } from "react";
|
|
23983
|
+
import { AlertTriangle as AlertTriangle5, ChevronRight as ChevronRight19 } from "lucide-react";
|
|
23486
23984
|
|
|
23487
23985
|
// src/hooks/use-payment-intent.ts
|
|
23488
|
-
import { useQuery as
|
|
23986
|
+
import { useQuery as useQuery19 } from "@tanstack/react-query";
|
|
23489
23987
|
import { retrievePaymentIntent } from "@unifold/core";
|
|
23490
23988
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["succeeded", "expired", "refunded", "canceled"]);
|
|
23491
23989
|
function usePaymentIntent(params) {
|
|
23492
23990
|
const { clientSecret, publishableKey, enabled = true, pollingInterval = 3e3 } = params;
|
|
23493
|
-
return
|
|
23991
|
+
return useQuery19({
|
|
23494
23992
|
queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
|
|
23495
23993
|
queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
|
|
23496
23994
|
enabled: enabled && !!clientSecret && !!publishableKey,
|
|
@@ -23569,6 +24067,7 @@ function CheckoutModal({
|
|
|
23569
24067
|
modalTitle,
|
|
23570
24068
|
enableTransferCrypto,
|
|
23571
24069
|
enableConnectWallet,
|
|
24070
|
+
enableIncidentBanner = false,
|
|
23572
24071
|
defaultSourceChainType,
|
|
23573
24072
|
defaultSourceChainId,
|
|
23574
24073
|
defaultSourceTokenAddress,
|
|
@@ -23584,7 +24083,7 @@ function CheckoutModal({
|
|
|
23584
24083
|
const [browserWalletInfo, setBrowserWalletInfo] = useState41(null);
|
|
23585
24084
|
const [browserWalletChainType, setBrowserWalletChainType] = useState41(() => getStoredWalletState()?.chainType);
|
|
23586
24085
|
const lastCheckoutMethodRef = useRef14(void 0);
|
|
23587
|
-
const emitCheckoutSuccess =
|
|
24086
|
+
const emitCheckoutSuccess = useCallback12(
|
|
23588
24087
|
(data, method) => {
|
|
23589
24088
|
const isSucceeded = data.status === "succeeded";
|
|
23590
24089
|
const richIntent = isSucceeded && data.paymentIntent ? mapToCheckoutPaymentIntent(data.paymentIntent) : void 0;
|
|
@@ -23640,6 +24139,16 @@ function CheckoutModal({
|
|
|
23640
24139
|
});
|
|
23641
24140
|
const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
|
|
23642
24141
|
const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
|
|
24142
|
+
const { incident: publicIncident } = usePublicIncident({
|
|
24143
|
+
publishableKey,
|
|
24144
|
+
enabled: open && enableIncidentBanner
|
|
24145
|
+
});
|
|
24146
|
+
const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
|
|
24147
|
+
enabled: true,
|
|
24148
|
+
messages: publicIncident.messages,
|
|
24149
|
+
severity: publicIncident.severity,
|
|
24150
|
+
statusPageUrl: publicIncident.status_page_url
|
|
24151
|
+
} : void 0;
|
|
23643
24152
|
useEffect35(() => {
|
|
23644
24153
|
if (view === "transfer" && !showTransferCrypto) {
|
|
23645
24154
|
setView("main");
|
|
@@ -23735,7 +24244,7 @@ function CheckoutModal({
|
|
|
23735
24244
|
sourceAmountUsd: minUsd.toFixed(2)
|
|
23736
24245
|
};
|
|
23737
24246
|
}, [sourceQuote, selectedSource]);
|
|
23738
|
-
const handleBrowserWalletClick =
|
|
24247
|
+
const handleBrowserWalletClick = useCallback12(
|
|
23739
24248
|
(walletInfo) => {
|
|
23740
24249
|
const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
|
|
23741
24250
|
setStoredWalletState(walletInfo.type);
|
|
@@ -23758,19 +24267,19 @@ function CheckoutModal({
|
|
|
23758
24267
|
},
|
|
23759
24268
|
[wallets, onCheckoutError]
|
|
23760
24269
|
);
|
|
23761
|
-
const handleWalletConnectClick =
|
|
24270
|
+
const handleWalletConnectClick = useCallback12(() => {
|
|
23762
24271
|
setBrowserWalletInfo(null);
|
|
23763
24272
|
lastCheckoutMethodRef.current = "wallet_connect";
|
|
23764
24273
|
setView("wallet_connect");
|
|
23765
24274
|
}, []);
|
|
23766
|
-
const handleWalletDisconnect =
|
|
24275
|
+
const handleWalletDisconnect = useCallback12(() => {
|
|
23767
24276
|
setUserDisconnectedWallet(true);
|
|
23768
24277
|
clearStoredWalletState();
|
|
23769
24278
|
setBrowserWalletChainType(void 0);
|
|
23770
24279
|
setBrowserWalletInfo(null);
|
|
23771
24280
|
setView("main");
|
|
23772
24281
|
}, []);
|
|
23773
|
-
const handleClose =
|
|
24282
|
+
const handleClose = useCallback12(() => {
|
|
23774
24283
|
onOpenChange(false);
|
|
23775
24284
|
if (resetViewTimeoutRef.current) {
|
|
23776
24285
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -23800,7 +24309,7 @@ function CheckoutModal({
|
|
|
23800
24309
|
},
|
|
23801
24310
|
[]
|
|
23802
24311
|
);
|
|
23803
|
-
const handleBack =
|
|
24312
|
+
const handleBack = useCallback12(() => {
|
|
23804
24313
|
setView("main");
|
|
23805
24314
|
}, []);
|
|
23806
24315
|
const poweredByFooter = /* @__PURE__ */ jsx64("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx64(
|
|
@@ -23941,7 +24450,15 @@ function CheckoutModal({
|
|
|
23941
24450
|
{
|
|
23942
24451
|
className: view === "wallet_connect" ? "uf-flex uf-min-h-0 uf-flex-col" : void 0,
|
|
23943
24452
|
children: view === "main" ? /* @__PURE__ */ jsxs58(Fragment15, { children: [
|
|
23944
|
-
/* @__PURE__ */ jsx64(
|
|
24453
|
+
/* @__PURE__ */ jsx64(
|
|
24454
|
+
DepositHeader,
|
|
24455
|
+
{
|
|
24456
|
+
title: modalTitle || "Checkout",
|
|
24457
|
+
showClose: true,
|
|
24458
|
+
onClose: handleClose,
|
|
24459
|
+
incident: activeIncident
|
|
24460
|
+
}
|
|
24461
|
+
),
|
|
23945
24462
|
/* @__PURE__ */ jsxs58("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
23946
24463
|
piLoading ? /* @__PURE__ */ jsxs58("div", { className: "uf-space-y-3", children: [
|
|
23947
24464
|
/* @__PURE__ */ jsx64(
|
|
@@ -23978,7 +24495,7 @@ function CheckoutModal({
|
|
|
23978
24495
|
/* @__PURE__ */ jsx64(SkeletonButton2, {}),
|
|
23979
24496
|
/* @__PURE__ */ jsx64(SkeletonButton2, {})
|
|
23980
24497
|
] }) : 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(
|
|
24498
|
+
/* @__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
24499
|
/* @__PURE__ */ jsx64(
|
|
23983
24500
|
"h3",
|
|
23984
24501
|
{
|
|
@@ -24039,7 +24556,8 @@ function CheckoutModal({
|
|
|
24039
24556
|
title: modalTitle || "Checkout",
|
|
24040
24557
|
showBack: true,
|
|
24041
24558
|
onBack: handleBack,
|
|
24042
|
-
onClose: handleClose
|
|
24559
|
+
onClose: handleClose,
|
|
24560
|
+
incident: activeIncident
|
|
24043
24561
|
}
|
|
24044
24562
|
),
|
|
24045
24563
|
/* @__PURE__ */ jsxs58("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -24200,16 +24718,16 @@ function CheckoutModal({
|
|
|
24200
24718
|
}
|
|
24201
24719
|
|
|
24202
24720
|
// src/components/withdrawals/WithdrawModal.tsx
|
|
24203
|
-
import { useState as useState45, useEffect as useEffect39, useLayoutEffect as useLayoutEffect4, useCallback as
|
|
24204
|
-
import { AlertTriangle as
|
|
24721
|
+
import { useState as useState45, useEffect as useEffect39, useLayoutEffect as useLayoutEffect4, useCallback as useCallback14, useRef as useRef16 } from "react";
|
|
24722
|
+
import { AlertTriangle as AlertTriangle7, ChevronRight as ChevronRight21, Clock as Clock6 } from "lucide-react";
|
|
24205
24723
|
|
|
24206
24724
|
// src/hooks/use-supported-destination-tokens.ts
|
|
24207
|
-
import { useQuery as
|
|
24725
|
+
import { useQuery as useQuery20 } from "@tanstack/react-query";
|
|
24208
24726
|
import {
|
|
24209
24727
|
getSupportedDestinationTokens
|
|
24210
24728
|
} from "@unifold/core";
|
|
24211
24729
|
function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
24212
|
-
return
|
|
24730
|
+
return useQuery20({
|
|
24213
24731
|
queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
|
|
24214
24732
|
queryFn: () => getSupportedDestinationTokens(publishableKey),
|
|
24215
24733
|
staleTime: 1e3 * 60 * 5,
|
|
@@ -24221,6 +24739,7 @@ function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
|
24221
24739
|
}
|
|
24222
24740
|
|
|
24223
24741
|
// src/hooks/use-default-destination-token.ts
|
|
24742
|
+
var STORAGE_KEY3 = "unifold_last_withdraw_to_token";
|
|
24224
24743
|
function useDefaultDestinationToken({
|
|
24225
24744
|
destinationTokens,
|
|
24226
24745
|
defaultDestinationChainType,
|
|
@@ -24233,12 +24752,13 @@ function useDefaultDestinationToken({
|
|
|
24233
24752
|
defaultChainType: defaultDestinationChainType,
|
|
24234
24753
|
defaultChainId: defaultDestinationChainId,
|
|
24235
24754
|
defaultTokenAddress: defaultDestinationTokenAddress,
|
|
24236
|
-
defaultSymbol: defaultDestinationSymbol
|
|
24755
|
+
defaultSymbol: defaultDestinationSymbol,
|
|
24756
|
+
storageKey: STORAGE_KEY3
|
|
24237
24757
|
});
|
|
24238
24758
|
}
|
|
24239
24759
|
|
|
24240
24760
|
// src/hooks/use-source-token-validation.ts
|
|
24241
|
-
import { useQuery as
|
|
24761
|
+
import { useQuery as useQuery21 } from "@tanstack/react-query";
|
|
24242
24762
|
import { getSupportedDepositTokens as getSupportedDepositTokens3 } from "@unifold/core";
|
|
24243
24763
|
function useSourceTokenValidation(params) {
|
|
24244
24764
|
const {
|
|
@@ -24250,7 +24770,7 @@ function useSourceTokenValidation(params) {
|
|
|
24250
24770
|
enabled = true
|
|
24251
24771
|
} = params;
|
|
24252
24772
|
const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
|
|
24253
|
-
return
|
|
24773
|
+
return useQuery21({
|
|
24254
24774
|
queryKey: [
|
|
24255
24775
|
"unifold",
|
|
24256
24776
|
"sourceTokenValidation",
|
|
@@ -24298,12 +24818,12 @@ function useSourceTokenValidation(params) {
|
|
|
24298
24818
|
}
|
|
24299
24819
|
|
|
24300
24820
|
// src/hooks/use-address-balance.ts
|
|
24301
|
-
import { useQuery as
|
|
24821
|
+
import { useQuery as useQuery22 } from "@tanstack/react-query";
|
|
24302
24822
|
import { getAddressBalance as getAddressBalance2 } from "@unifold/core";
|
|
24303
24823
|
function useAddressBalance(params) {
|
|
24304
24824
|
const { address, chainType, chainId, tokenAddress, publishableKey, enabled = true } = params;
|
|
24305
24825
|
const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
|
|
24306
|
-
return
|
|
24826
|
+
return useQuery22({
|
|
24307
24827
|
queryKey: [
|
|
24308
24828
|
"unifold",
|
|
24309
24829
|
"addressBalance",
|
|
@@ -24359,11 +24879,11 @@ function useAddressBalance(params) {
|
|
|
24359
24879
|
}
|
|
24360
24880
|
|
|
24361
24881
|
// src/hooks/use-executions.ts
|
|
24362
|
-
import { useQuery as
|
|
24882
|
+
import { useQuery as useQuery23 } from "@tanstack/react-query";
|
|
24363
24883
|
import { queryExecutions as queryExecutions4, ActionType as ActionType4 } from "@unifold/core";
|
|
24364
24884
|
function useExecutions(userId, publishableKey, options) {
|
|
24365
24885
|
const actionType = options?.actionType ?? ActionType4.Deposit;
|
|
24366
|
-
return
|
|
24886
|
+
return useQuery23({
|
|
24367
24887
|
queryKey: ["unifold", "executions", actionType, userId, publishableKey],
|
|
24368
24888
|
queryFn: () => queryExecutions4(userId, publishableKey, actionType),
|
|
24369
24889
|
enabled: (options?.enabled ?? true) && !!userId,
|
|
@@ -24694,9 +25214,9 @@ function WithdrawDoubleInput({
|
|
|
24694
25214
|
}
|
|
24695
25215
|
|
|
24696
25216
|
// src/components/withdrawals/WithdrawForm.tsx
|
|
24697
|
-
import { useState as useState43, useCallback as
|
|
25217
|
+
import { useState as useState43, useCallback as useCallback13, useMemo as useMemo17, useEffect as useEffect37 } from "react";
|
|
24698
25218
|
import {
|
|
24699
|
-
AlertTriangle as
|
|
25219
|
+
AlertTriangle as AlertTriangle6,
|
|
24700
25220
|
ArrowUpDown,
|
|
24701
25221
|
ChevronDown as ChevronDown9,
|
|
24702
25222
|
ChevronUp as ChevronUp7,
|
|
@@ -24712,7 +25232,7 @@ import {
|
|
|
24712
25232
|
} from "@unifold/core";
|
|
24713
25233
|
|
|
24714
25234
|
// src/hooks/use-verify-recipient-address.ts
|
|
24715
|
-
import { useQuery as
|
|
25235
|
+
import { useQuery as useQuery24 } from "@tanstack/react-query";
|
|
24716
25236
|
import { verifyRecipientAddress as verifyRecipientAddress2 } from "@unifold/core";
|
|
24717
25237
|
function useVerifyRecipientAddress(params) {
|
|
24718
25238
|
const {
|
|
@@ -24725,7 +25245,7 @@ function useVerifyRecipientAddress(params) {
|
|
|
24725
25245
|
} = params;
|
|
24726
25246
|
const trimmedAddress = recipientAddress?.trim() || "";
|
|
24727
25247
|
const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
|
|
24728
|
-
return
|
|
25248
|
+
return useQuery24({
|
|
24729
25249
|
queryKey: [
|
|
24730
25250
|
"unifold",
|
|
24731
25251
|
"verifyRecipientAddress",
|
|
@@ -24976,7 +25496,7 @@ import { useMemo as useMemo16 } from "react";
|
|
|
24976
25496
|
import { ActionType as ActionType6 } from "@unifold/core";
|
|
24977
25497
|
|
|
24978
25498
|
// src/hooks/use-get-deposit-address.ts
|
|
24979
|
-
import { useQuery as
|
|
25499
|
+
import { useQuery as useQuery25 } from "@tanstack/react-query";
|
|
24980
25500
|
import { getDepositAddress } from "@unifold/core";
|
|
24981
25501
|
function useGetDepositAddress(params) {
|
|
24982
25502
|
const {
|
|
@@ -24990,7 +25510,7 @@ function useGetDepositAddress(params) {
|
|
|
24990
25510
|
enabled = true
|
|
24991
25511
|
} = params;
|
|
24992
25512
|
const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
24993
|
-
return
|
|
25513
|
+
return useQuery25({
|
|
24994
25514
|
queryKey: [
|
|
24995
25515
|
"unifold",
|
|
24996
25516
|
"getDepositAddress",
|
|
@@ -25186,6 +25706,9 @@ function WithdrawForm({
|
|
|
25186
25706
|
if (isDebouncing || isVerifyingAddress) return null;
|
|
25187
25707
|
if (verifyError) return t10.invalidAddress;
|
|
25188
25708
|
if (addressVerification && !addressVerification.valid) {
|
|
25709
|
+
if (addressVerification.message && addressVerification.message.trim().length > 0) {
|
|
25710
|
+
return addressVerification.message;
|
|
25711
|
+
}
|
|
25189
25712
|
if (addressVerification.failure_code === "account_not_found")
|
|
25190
25713
|
return `Account not found on ${selectedChain?.chain_name}`;
|
|
25191
25714
|
if (addressVerification.failure_code === "not_opted_in")
|
|
@@ -25283,7 +25806,7 @@ function WithdrawForm({
|
|
|
25283
25806
|
tokenSymbol,
|
|
25284
25807
|
isStablecoin
|
|
25285
25808
|
]);
|
|
25286
|
-
const handleSwitchUnit =
|
|
25809
|
+
const handleSwitchUnit = useCallback13(() => {
|
|
25287
25810
|
if (isMaxed && balanceData) {
|
|
25288
25811
|
if (inputUnit === "crypto") {
|
|
25289
25812
|
setAmount((Math.round(balanceUsdNum * 100) / 100).toFixed(2));
|
|
@@ -25310,7 +25833,7 @@ function WithdrawForm({
|
|
|
25310
25833
|
setInputUnit("crypto");
|
|
25311
25834
|
}
|
|
25312
25835
|
}, [amount, inputUnit, exchangeRate, sourceDecimals, isMaxed, balanceData, balanceUsdNum]);
|
|
25313
|
-
const handleMaxClick =
|
|
25836
|
+
const handleMaxClick = useCallback13(() => {
|
|
25314
25837
|
if (inputUnit === "crypto") {
|
|
25315
25838
|
if (balanceCrypto <= 0) return;
|
|
25316
25839
|
setAmount(balanceData?.balanceHuman ?? "0");
|
|
@@ -25324,7 +25847,7 @@ function WithdrawForm({
|
|
|
25324
25847
|
const isBelowMinimum = minimumWithdrawAmountUsd !== null && fiatAmountFromInput > 0 && Math.round(fiatAmountFromInput * 100) / 100 < minimumWithdrawAmountUsd;
|
|
25325
25848
|
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
25849
|
const isFormValid = trimmedAddress.length > 0 && amount.trim().length > 0 && cryptoAmountFromInput > 0 && isAddressValid && !isBelowMinimum && !isOverBalance && !isBalanceBelowMinimum && !!balanceData;
|
|
25327
|
-
const handleWithdraw =
|
|
25850
|
+
const handleWithdraw = useCallback13(async () => {
|
|
25328
25851
|
if (!selectedToken || !selectedChain) return;
|
|
25329
25852
|
if (!isFormValid) return;
|
|
25330
25853
|
setIsSubmitting(true);
|
|
@@ -25521,7 +26044,7 @@ function WithdrawForm({
|
|
|
25521
26044
|
)
|
|
25522
26045
|
] }),
|
|
25523
26046
|
addressError && /* @__PURE__ */ jsxs60("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-1.5", children: [
|
|
25524
|
-
/* @__PURE__ */ jsx66(
|
|
26047
|
+
/* @__PURE__ */ jsx66(AlertTriangle6, { className: "uf-w-3 uf-h-3", style: { color: colors2.error } }),
|
|
25525
26048
|
/* @__PURE__ */ jsx66("span", { className: "uf-text-xs", style: { color: colors2.error, fontFamily: fonts.regular }, children: addressError })
|
|
25526
26049
|
] })
|
|
25527
26050
|
] }),
|
|
@@ -26110,7 +26633,7 @@ function WithdrawModal({
|
|
|
26110
26633
|
theme = "dark",
|
|
26111
26634
|
hideOverlay = false
|
|
26112
26635
|
}) {
|
|
26113
|
-
const onWithdrawSuccessFor =
|
|
26636
|
+
const onWithdrawSuccessFor = useCallback14(
|
|
26114
26637
|
(data) => {
|
|
26115
26638
|
onWithdrawSuccess?.(data);
|
|
26116
26639
|
if (data.execution) {
|
|
@@ -26121,7 +26644,7 @@ function WithdrawModal({
|
|
|
26121
26644
|
);
|
|
26122
26645
|
const { colors: colors2, fonts, components } = useTheme();
|
|
26123
26646
|
const [containerEl, setContainerEl] = useState45(null);
|
|
26124
|
-
const containerCallbackRef =
|
|
26647
|
+
const containerCallbackRef = useCallback14((el) => {
|
|
26125
26648
|
setContainerEl(el);
|
|
26126
26649
|
}, []);
|
|
26127
26650
|
const [resolvedTheme, setResolvedTheme] = useState45(
|
|
@@ -26194,7 +26717,7 @@ function WithdrawModal({
|
|
|
26194
26717
|
refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
|
|
26195
26718
|
});
|
|
26196
26719
|
const allWithdrawals = allWithdrawalsData?.data ?? [];
|
|
26197
|
-
const handleDepositWalletCreation =
|
|
26720
|
+
const handleDepositWalletCreation = useCallback14(
|
|
26198
26721
|
async (params) => {
|
|
26199
26722
|
const { data: wallets } = await createDepositAddress2(
|
|
26200
26723
|
{
|
|
@@ -26217,12 +26740,12 @@ function WithdrawModal({
|
|
|
26217
26740
|
},
|
|
26218
26741
|
[externalUserId, publishableKey, sourceChainType]
|
|
26219
26742
|
);
|
|
26220
|
-
const handleWithdrawSubmitted =
|
|
26743
|
+
const handleWithdrawSubmitted = useCallback14((txInfo) => {
|
|
26221
26744
|
setSubmittedTxInfo(txInfo);
|
|
26222
26745
|
setView("confirming");
|
|
26223
26746
|
}, []);
|
|
26224
26747
|
const resetViewTimeoutRef = useRef16(null);
|
|
26225
|
-
const handleClose =
|
|
26748
|
+
const handleClose = useCallback14(() => {
|
|
26226
26749
|
onOpenChange(false);
|
|
26227
26750
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
26228
26751
|
resetViewTimeoutRef.current = setTimeout(() => {
|
|
@@ -26250,13 +26773,13 @@ function WithdrawModal({
|
|
|
26250
26773
|
},
|
|
26251
26774
|
[]
|
|
26252
26775
|
);
|
|
26253
|
-
const handleTokenSymbolChange =
|
|
26776
|
+
const handleTokenSymbolChange = useCallback14(
|
|
26254
26777
|
(symbol) => {
|
|
26255
26778
|
setSelectedTokenSymbol(symbol);
|
|
26256
26779
|
},
|
|
26257
26780
|
[setSelectedTokenSymbol]
|
|
26258
26781
|
);
|
|
26259
|
-
const handleChainKeyChange =
|
|
26782
|
+
const handleChainKeyChange = useCallback14(
|
|
26260
26783
|
(chainKey) => {
|
|
26261
26784
|
setSelectedChainKey(chainKey);
|
|
26262
26785
|
},
|
|
@@ -26363,7 +26886,7 @@ function WithdrawModal({
|
|
|
26363
26886
|
},
|
|
26364
26887
|
i
|
|
26365
26888
|
)) }) : 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(
|
|
26889
|
+
/* @__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
26890
|
/* @__PURE__ */ jsx69(
|
|
26368
26891
|
"h3",
|
|
26369
26892
|
{
|
|
@@ -26732,6 +27255,7 @@ export {
|
|
|
26732
27255
|
useDepositPolling,
|
|
26733
27256
|
useDepositQuote,
|
|
26734
27257
|
usePaymentIntent,
|
|
27258
|
+
usePublicIncident,
|
|
26735
27259
|
useSourceTokenValidation,
|
|
26736
27260
|
useSupportedDepositTokens,
|
|
26737
27261
|
useSupportedDestinationTokens,
|