@unifold/connect-react 0.1.68-beta.1 → 0.1.68-beta.2
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 +14 -9
- package/dist/index.d.ts +14 -9
- package/dist/index.js +1600 -832
- package/dist/index.mjs +1308 -540
- package/dist/styles-base.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1205,7 +1205,7 @@ __export(index_exports, {
|
|
|
1205
1205
|
module.exports = __toCommonJS(index_exports);
|
|
1206
1206
|
|
|
1207
1207
|
// src/provider.tsx
|
|
1208
|
-
var
|
|
1208
|
+
var import_react41 = __toESM(require("react"));
|
|
1209
1209
|
|
|
1210
1210
|
// ../react-provider/dist/index.mjs
|
|
1211
1211
|
var import_react = require("react");
|
|
@@ -7588,6 +7588,59 @@ async function exchangeOnrampVerificationToken(id, clientSecret, publishableKey)
|
|
|
7588
7588
|
"Failed to exchange verification token"
|
|
7589
7589
|
);
|
|
7590
7590
|
}
|
|
7591
|
+
function isApplePayLimitReached(response) {
|
|
7592
|
+
return response.limits.some((l) => l.remaining === "0");
|
|
7593
|
+
}
|
|
7594
|
+
function getApplePayLimitUpgradeStatus(response) {
|
|
7595
|
+
const opt = response.limit_upgrade_options?.[0];
|
|
7596
|
+
if (!opt || typeof opt.status !== "string") return null;
|
|
7597
|
+
return opt.status;
|
|
7598
|
+
}
|
|
7599
|
+
async function getCoinbaseApplePayLimits(phone, publishableKey, signal) {
|
|
7600
|
+
const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
|
|
7601
|
+
validatePublishableKey(pk);
|
|
7602
|
+
const response = await fetch(
|
|
7603
|
+
`${API_BASE_URL}/v1/public/onramps/headless/coinbase/apple_pay/limits`,
|
|
7604
|
+
{
|
|
7605
|
+
method: "POST",
|
|
7606
|
+
headers: {
|
|
7607
|
+
accept: "application/json",
|
|
7608
|
+
"x-publishable-key": pk,
|
|
7609
|
+
"Content-Type": "application/json"
|
|
7610
|
+
},
|
|
7611
|
+
body: JSON.stringify({ phone }),
|
|
7612
|
+
signal
|
|
7613
|
+
}
|
|
7614
|
+
);
|
|
7615
|
+
const raw = await jsonOrThrow(response, "Failed to fetch Apple Pay limits");
|
|
7616
|
+
return {
|
|
7617
|
+
limits: raw.limits,
|
|
7618
|
+
limit_upgrade_options: raw.limit_upgrade_options,
|
|
7619
|
+
limit_reached: isApplePayLimitReached(raw),
|
|
7620
|
+
upgrade_status: getApplePayLimitUpgradeStatus(raw)
|
|
7621
|
+
};
|
|
7622
|
+
}
|
|
7623
|
+
async function requestCoinbaseApplePayLimitUpgrade(request, publishableKey, signal) {
|
|
7624
|
+
const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
|
|
7625
|
+
validatePublishableKey(pk);
|
|
7626
|
+
const response = await fetch(
|
|
7627
|
+
`${API_BASE_URL}/v1/public/onramps/headless/coinbase/apple_pay/limits/upgrade`,
|
|
7628
|
+
{
|
|
7629
|
+
method: "POST",
|
|
7630
|
+
headers: {
|
|
7631
|
+
accept: "application/json",
|
|
7632
|
+
"x-publishable-key": pk,
|
|
7633
|
+
"Content-Type": "application/json"
|
|
7634
|
+
},
|
|
7635
|
+
body: JSON.stringify(request),
|
|
7636
|
+
signal
|
|
7637
|
+
}
|
|
7638
|
+
);
|
|
7639
|
+
return jsonOrThrow(
|
|
7640
|
+
response,
|
|
7641
|
+
"Failed to request Apple Pay limit upgrade"
|
|
7642
|
+
);
|
|
7643
|
+
}
|
|
7591
7644
|
async function createCoinbaseApplePaySession(request, onrampToken, publishableKey, signal) {
|
|
7592
7645
|
const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
|
|
7593
7646
|
validatePublishableKey(pk);
|
|
@@ -7772,19 +7825,20 @@ var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
|
7772
7825
|
var React52 = __toESM(require("react"), 1);
|
|
7773
7826
|
var import_react17 = require("react");
|
|
7774
7827
|
var import_react_query5 = require("@tanstack/react-query");
|
|
7828
|
+
var import_react18 = require("react");
|
|
7775
7829
|
var import_react_query6 = require("@tanstack/react-query");
|
|
7830
|
+
var import_react_query7 = require("@tanstack/react-query");
|
|
7776
7831
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
7777
|
-
var import_react18 = require("react");
|
|
7778
|
-
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
7779
7832
|
var import_react19 = require("react");
|
|
7833
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
7780
7834
|
var import_react20 = require("react");
|
|
7835
|
+
var import_react21 = require("react");
|
|
7781
7836
|
var import_qr_code_styling = __toESM(require_qr_code_styling(), 1);
|
|
7782
7837
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
7783
|
-
var import_react21 = require("react");
|
|
7784
|
-
var import_react_query7 = require("@tanstack/react-query");
|
|
7785
|
-
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
7786
7838
|
var import_react22 = require("react");
|
|
7787
7839
|
var import_react_query8 = require("@tanstack/react-query");
|
|
7840
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
7841
|
+
var import_react23 = require("react");
|
|
7788
7842
|
var import_react_query9 = require("@tanstack/react-query");
|
|
7789
7843
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7790
7844
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
@@ -8037,25 +8091,26 @@ var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
|
8037
8091
|
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
8038
8092
|
var React292 = __toESM(require("react"), 1);
|
|
8039
8093
|
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
8040
|
-
var import_react23 = require("react");
|
|
8041
|
-
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
8042
8094
|
var import_react24 = require("react");
|
|
8043
|
-
var
|
|
8095
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
8044
8096
|
var import_react25 = require("react");
|
|
8097
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
8098
|
+
var import_react26 = require("react");
|
|
8045
8099
|
var import_react_query10 = require("@tanstack/react-query");
|
|
8046
8100
|
var import_react_query11 = require("@tanstack/react-query");
|
|
8047
|
-
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
8048
8101
|
var import_react_query12 = require("@tanstack/react-query");
|
|
8102
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
8049
8103
|
var import_react_query13 = require("@tanstack/react-query");
|
|
8050
8104
|
var import_react_query14 = require("@tanstack/react-query");
|
|
8051
8105
|
var import_react_query15 = require("@tanstack/react-query");
|
|
8052
|
-
var
|
|
8106
|
+
var import_react_query16 = require("@tanstack/react-query");
|
|
8053
8107
|
var import_react27 = require("react");
|
|
8108
|
+
var import_react28 = require("react");
|
|
8054
8109
|
var React312 = __toESM(require("react"), 1);
|
|
8055
8110
|
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
8056
8111
|
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
8057
8112
|
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
8058
|
-
var
|
|
8113
|
+
var import_react29 = require("react");
|
|
8059
8114
|
|
|
8060
8115
|
// ../../node_modules/.pnpm/fuse.js@7.4.0/node_modules/fuse.js/dist/fuse.mjs
|
|
8061
8116
|
function isArray(value) {
|
|
@@ -10057,10 +10112,10 @@ Fuse.use = function(...plugins) {
|
|
|
10057
10112
|
|
|
10058
10113
|
// ../ui-react/dist/index.mjs
|
|
10059
10114
|
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
10060
|
-
var
|
|
10115
|
+
var import_react30 = require("react");
|
|
10061
10116
|
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
10062
10117
|
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
10063
|
-
var
|
|
10118
|
+
var import_react31 = require("react");
|
|
10064
10119
|
var React322 = __toESM(require("react"), 1);
|
|
10065
10120
|
|
|
10066
10121
|
// ../../node_modules/.pnpm/@radix-ui+react-tooltip@1.2.8_@types+react-dom@19.2.3_@types+react@19.2.9__@types+react@19.2._udyjcec5g7ve3mpsxbgla63vgi/node_modules/@radix-ui/react-tooltip/dist/index.mjs
|
|
@@ -12799,10 +12854,10 @@ var Content22 = TooltipContent;
|
|
|
12799
12854
|
|
|
12800
12855
|
// ../ui-react/dist/index.mjs
|
|
12801
12856
|
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
12802
|
-
var
|
|
12857
|
+
var import_react_query17 = require("@tanstack/react-query");
|
|
12803
12858
|
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
12804
12859
|
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
12805
|
-
var
|
|
12860
|
+
var import_react32 = require("react");
|
|
12806
12861
|
var React332 = __toESM(require("react"), 1);
|
|
12807
12862
|
|
|
12808
12863
|
// ../../node_modules/.pnpm/@radix-ui+react-select@2.2.6_@types+react-dom@19.2.3_@types+react@19.2.9__@types+react@19.2.9_cot3leusltbsophitaz3dgdqdm/node_modules/@radix-ui/react-select/dist/index.mjs
|
|
@@ -14041,36 +14096,36 @@ var Separator = SelectSeparator;
|
|
|
14041
14096
|
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
14042
14097
|
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
14043
14098
|
var React342 = __toESM(require("react"), 1);
|
|
14044
|
-
var import_react_query17 = require("@tanstack/react-query");
|
|
14045
14099
|
var import_react_query18 = require("@tanstack/react-query");
|
|
14100
|
+
var import_react_query19 = require("@tanstack/react-query");
|
|
14046
14101
|
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
14047
14102
|
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
14048
14103
|
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
14049
14104
|
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
14050
|
-
var
|
|
14105
|
+
var import_react33 = require("react");
|
|
14051
14106
|
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
14052
14107
|
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
14053
14108
|
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
14054
|
-
var import_react33 = require("react");
|
|
14055
|
-
var import_react_query19 = require("@tanstack/react-query");
|
|
14056
|
-
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
14057
14109
|
var import_react34 = require("react");
|
|
14058
14110
|
var import_react_query20 = require("@tanstack/react-query");
|
|
14111
|
+
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
14112
|
+
var import_react35 = require("react");
|
|
14059
14113
|
var import_react_query21 = require("@tanstack/react-query");
|
|
14060
14114
|
var import_react_query22 = require("@tanstack/react-query");
|
|
14061
14115
|
var import_react_query23 = require("@tanstack/react-query");
|
|
14062
|
-
var import_react35 = require("react");
|
|
14063
|
-
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
14064
|
-
var import_react36 = require("react");
|
|
14065
14116
|
var import_react_query24 = require("@tanstack/react-query");
|
|
14117
|
+
var import_react36 = require("react");
|
|
14118
|
+
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
14066
14119
|
var import_react37 = require("react");
|
|
14067
14120
|
var import_react_query25 = require("@tanstack/react-query");
|
|
14121
|
+
var import_react38 = require("react");
|
|
14122
|
+
var import_react_query26 = require("@tanstack/react-query");
|
|
14068
14123
|
var import_jsx_runtime83 = require("react/jsx-runtime");
|
|
14069
14124
|
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
14070
|
-
var
|
|
14125
|
+
var import_react39 = require("react");
|
|
14071
14126
|
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
14072
14127
|
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
14073
|
-
var
|
|
14128
|
+
var import_react40 = require("react");
|
|
14074
14129
|
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
14075
14130
|
function cn(...inputs) {
|
|
14076
14131
|
return twMerge(clsx(inputs));
|
|
@@ -15460,7 +15515,7 @@ var en_default2 = {
|
|
|
15460
15515
|
payWithStripeLink: {
|
|
15461
15516
|
success: {
|
|
15462
15517
|
processingTitle: "Payment confirmed",
|
|
15463
|
-
processingSubtitle: "We\u2019ve received your payment and are
|
|
15518
|
+
processingSubtitle: "We\u2019ve received your payment and are sending your purchase to your wallet. This usually takes just a few minutes.",
|
|
15464
15519
|
completeTitle: "Your purchase is on the way",
|
|
15465
15520
|
completeSubtitle: "Your purchase is complete and is being sent to your wallet.",
|
|
15466
15521
|
failedTitle: "Purchase didn\u2019t go through",
|
|
@@ -17444,20 +17499,6 @@ function BuyWithCard({
|
|
|
17444
17499
|
}
|
|
17445
17500
|
);
|
|
17446
17501
|
}
|
|
17447
|
-
function useProjectConfig({
|
|
17448
|
-
publishableKey,
|
|
17449
|
-
enabled = true
|
|
17450
|
-
}) {
|
|
17451
|
-
const { data: projectConfig, isLoading } = (0, import_react_query5.useQuery)({
|
|
17452
|
-
queryKey: ["unifold", "projectConfig", publishableKey],
|
|
17453
|
-
queryFn: () => getProjectConfig(publishableKey),
|
|
17454
|
-
enabled,
|
|
17455
|
-
staleTime: 1e3 * 60 * 30,
|
|
17456
|
-
refetchOnMount: true,
|
|
17457
|
-
refetchOnWindowFocus: true
|
|
17458
|
-
});
|
|
17459
|
-
return { projectConfig, isLoading };
|
|
17460
|
-
}
|
|
17461
17502
|
var STORAGE_KEY_PREFIX = "unifold:apple-pay:session";
|
|
17462
17503
|
var PHONE_FRESH_MS = 55 * 24 * 60 * 60 * 1e3;
|
|
17463
17504
|
function isBrowser() {
|
|
@@ -17494,7 +17535,7 @@ function useCoinbaseLegalAgreements({
|
|
|
17494
17535
|
publishableKey,
|
|
17495
17536
|
enabled = true
|
|
17496
17537
|
}) {
|
|
17497
|
-
return (0,
|
|
17538
|
+
return (0, import_react_query5.useQuery)({
|
|
17498
17539
|
queryKey: ["unifold", "coinbaseLegalAgreements", publishableKey],
|
|
17499
17540
|
queryFn: () => getCoinbaseLegalAgreements(publishableKey),
|
|
17500
17541
|
enabled: enabled && !!publishableKey,
|
|
@@ -17505,47 +17546,200 @@ function useCoinbaseLegalAgreements({
|
|
|
17505
17546
|
retry: 1
|
|
17506
17547
|
});
|
|
17507
17548
|
}
|
|
17508
|
-
var
|
|
17509
|
-
|
|
17510
|
-
|
|
17511
|
-
|
|
17549
|
+
var US_E164_REGEX = /^\+1\d{10}$/;
|
|
17550
|
+
function useApplePayLimits({
|
|
17551
|
+
phone,
|
|
17552
|
+
publishableKey,
|
|
17553
|
+
enabled = true
|
|
17554
|
+
}) {
|
|
17555
|
+
const phoneValid = US_E164_REGEX.test(phone);
|
|
17556
|
+
return (0, import_react_query6.useQuery)({
|
|
17557
|
+
queryKey: ["unifold", "applePayLimits", phone, publishableKey],
|
|
17558
|
+
queryFn: ({ signal }) => getCoinbaseApplePayLimits(phone, publishableKey, signal),
|
|
17559
|
+
enabled: enabled && phoneValid && !!publishableKey,
|
|
17560
|
+
// Coinbase's caps don't change second-to-second; 30s is plenty fresh
|
|
17561
|
+
// for the "user opened the modal, edited their phone, opened it
|
|
17562
|
+
// again" usage pattern, while keeping us off their API on rapid
|
|
17563
|
+
// tap-throughs.
|
|
17564
|
+
staleTime: 3e4,
|
|
17565
|
+
gcTime: 5 * 6e4,
|
|
17566
|
+
refetchOnWindowFocus: false,
|
|
17567
|
+
retry: false
|
|
17568
|
+
});
|
|
17569
|
+
}
|
|
17512
17570
|
var PHONE_REGEX = /^\+1\d{10}$/;
|
|
17513
17571
|
var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
17514
|
-
function
|
|
17515
|
-
|
|
17516
|
-
|
|
17517
|
-
|
|
17572
|
+
function getViewForLimitStatus(limits) {
|
|
17573
|
+
if (!limits.limit_reached) return void 0;
|
|
17574
|
+
switch (limits.upgrade_status) {
|
|
17575
|
+
case "unrequested":
|
|
17576
|
+
return "limit_upgrade_intro";
|
|
17577
|
+
case "resubmit":
|
|
17578
|
+
return "limit_upgrade_form";
|
|
17579
|
+
case "pending":
|
|
17580
|
+
return "limit_upgrade_submitting";
|
|
17581
|
+
case "active":
|
|
17582
|
+
return void 0;
|
|
17583
|
+
default:
|
|
17584
|
+
return "guest_limit_reached";
|
|
17518
17585
|
}
|
|
17519
|
-
if (digits.length === 10) return `+1${digits}`;
|
|
17520
|
-
if (digits.length === 11 && digits.startsWith("1")) return `+${digits}`;
|
|
17521
|
-
return digits.length > 0 ? `+${digits}` : "";
|
|
17522
17586
|
}
|
|
17523
|
-
function
|
|
17524
|
-
|
|
17525
|
-
|
|
17526
|
-
|
|
17527
|
-
|
|
17587
|
+
function useApplePayInitialScreen({
|
|
17588
|
+
userId,
|
|
17589
|
+
publishableKey,
|
|
17590
|
+
normalizedPhone,
|
|
17591
|
+
userEmail,
|
|
17592
|
+
sessionPhoneVerified,
|
|
17593
|
+
isWaiting
|
|
17594
|
+
}) {
|
|
17595
|
+
const initialStoredSession = (0, import_react18.useMemo)(() => getStoredApplePaySession(userId), [userId]);
|
|
17596
|
+
const phoneVerified = PHONE_REGEX.test(normalizedPhone) && (sessionPhoneVerified || initialStoredSession?.phone === normalizedPhone && !!initialStoredSession?.phoneVerifiedAt);
|
|
17597
|
+
const {
|
|
17598
|
+
data: applePayLimits,
|
|
17599
|
+
isLoading: applePayLimitsLoading,
|
|
17600
|
+
refetch: refetchApplePayLimits
|
|
17601
|
+
} = useApplePayLimits({
|
|
17602
|
+
phone: normalizedPhone,
|
|
17603
|
+
publishableKey,
|
|
17604
|
+
enabled: phoneVerified
|
|
17605
|
+
});
|
|
17606
|
+
const action = (0, import_react18.useMemo)(() => {
|
|
17607
|
+
if (isWaiting || applePayLimitsLoading) return { kind: "pending" };
|
|
17608
|
+
const stored = initialStoredSession;
|
|
17609
|
+
const hasUserEmail = !!userEmail && EMAIL_REGEX.test(userEmail);
|
|
17610
|
+
if (!stored) {
|
|
17611
|
+
return { kind: "navigate", view: hasUserEmail ? "phone_input" : "email_input" };
|
|
17612
|
+
}
|
|
17613
|
+
if (hasUserEmail && stored.email.toLowerCase() !== userEmail.toLowerCase()) {
|
|
17614
|
+
return { kind: "navigate", view: "phone_input" };
|
|
17615
|
+
}
|
|
17616
|
+
if (applePayLimits) {
|
|
17617
|
+
const limitView = getViewForLimitStatus(applePayLimits);
|
|
17618
|
+
if (limitView) {
|
|
17619
|
+
return { kind: "limit_upgrade", view: limitView, status: applePayLimits.upgrade_status };
|
|
17620
|
+
}
|
|
17621
|
+
}
|
|
17622
|
+
if (isOnrampTokenFresh(stored) && stored.onrampToken && stored.onrampTokenExpiresAtMs) {
|
|
17623
|
+
return {
|
|
17624
|
+
kind: "resume_with_token",
|
|
17625
|
+
token: {
|
|
17626
|
+
token: stored.onrampToken,
|
|
17627
|
+
token_type: "Bearer",
|
|
17628
|
+
expires_in: Math.max(0, Math.floor((stored.onrampTokenExpiresAtMs - Date.now()) / 1e3))
|
|
17629
|
+
}
|
|
17630
|
+
};
|
|
17631
|
+
}
|
|
17632
|
+
return { kind: "resume_send_sms" };
|
|
17633
|
+
}, [isWaiting, applePayLimitsLoading, initialStoredSession, userEmail, applePayLimits]);
|
|
17634
|
+
return {
|
|
17635
|
+
action,
|
|
17636
|
+
applePayLimits,
|
|
17637
|
+
applePayLimitsLoading,
|
|
17638
|
+
refetchApplePayLimits,
|
|
17639
|
+
phoneVerified
|
|
17640
|
+
};
|
|
17528
17641
|
}
|
|
17529
|
-
function
|
|
17530
|
-
|
|
17531
|
-
|
|
17642
|
+
function useDefaultOnrampToken({
|
|
17643
|
+
publishableKey,
|
|
17644
|
+
tokenAddress,
|
|
17645
|
+
chainId,
|
|
17646
|
+
chainType,
|
|
17647
|
+
countryCode,
|
|
17648
|
+
subdivisionCode,
|
|
17649
|
+
enabled = true
|
|
17650
|
+
}) {
|
|
17651
|
+
const {
|
|
17652
|
+
data: defaultToken,
|
|
17653
|
+
isLoading,
|
|
17654
|
+
isError,
|
|
17655
|
+
error
|
|
17656
|
+
} = (0, import_react_query7.useQuery)({
|
|
17657
|
+
queryKey: [
|
|
17658
|
+
"unifold",
|
|
17659
|
+
"defaultOnrampToken",
|
|
17660
|
+
publishableKey,
|
|
17661
|
+
tokenAddress,
|
|
17662
|
+
chainId,
|
|
17663
|
+
chainType,
|
|
17664
|
+
countryCode,
|
|
17665
|
+
subdivisionCode
|
|
17666
|
+
],
|
|
17667
|
+
queryFn: () => getDefaultOnrampToken(
|
|
17668
|
+
{
|
|
17669
|
+
token_address: tokenAddress,
|
|
17670
|
+
chain_id: chainId,
|
|
17671
|
+
chain_type: chainType,
|
|
17672
|
+
country_code: countryCode,
|
|
17673
|
+
subdivision_code: subdivisionCode
|
|
17674
|
+
},
|
|
17675
|
+
publishableKey
|
|
17676
|
+
),
|
|
17677
|
+
enabled: enabled && !!tokenAddress && !!chainId && !!chainType,
|
|
17678
|
+
staleTime: 1e3 * 60 * 60,
|
|
17679
|
+
refetchOnMount: false,
|
|
17680
|
+
refetchOnWindowFocus: false
|
|
17681
|
+
});
|
|
17682
|
+
return { defaultToken, isLoading, isError, error: error ?? null };
|
|
17683
|
+
}
|
|
17684
|
+
var COINBASE_PAY_ORIGIN = "https://pay.coinbase.com";
|
|
17685
|
+
var COINBASE_ALLOWED_POSTMESSAGE_ORIGINS = /* @__PURE__ */ new Set([
|
|
17686
|
+
COINBASE_PAY_ORIGIN,
|
|
17687
|
+
"https://www.coinbase.com"
|
|
17688
|
+
]);
|
|
17689
|
+
var UNIFOLD_SUPPORT_URL = "https://unifold.io/support";
|
|
17690
|
+
var DEFAULT_MIN_USD = 5;
|
|
17691
|
+
var DEFAULT_MAX_USD = 500;
|
|
17692
|
+
var DEFAULT_SUGGESTED = [25, 50, 100];
|
|
17693
|
+
var PHONE_REGEX2 = /^\+1\d{10}$/;
|
|
17694
|
+
var EMAIL_REGEX2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
17695
|
+
function parseCoinbasePostMessage(raw) {
|
|
17696
|
+
const parseString = (s) => {
|
|
17697
|
+
try {
|
|
17698
|
+
return JSON.parse(s);
|
|
17699
|
+
} catch {
|
|
17700
|
+
return null;
|
|
17701
|
+
}
|
|
17702
|
+
};
|
|
17703
|
+
const asObject = (value) => value && typeof value === "object" ? value : null;
|
|
17704
|
+
let candidate = raw;
|
|
17705
|
+
if (typeof candidate === "string") {
|
|
17706
|
+
candidate = parseString(candidate);
|
|
17707
|
+
}
|
|
17708
|
+
const obj = asObject(candidate);
|
|
17709
|
+
if (!obj) return null;
|
|
17710
|
+
const nestedData = obj.data;
|
|
17711
|
+
let eventName = typeof obj.eventName === "string" && obj.eventName || typeof obj.event_name === "string" && obj.event_name || typeof obj.type === "string" && obj.type || null;
|
|
17712
|
+
let dataObj = asObject(nestedData);
|
|
17713
|
+
if (!eventName && typeof nestedData === "string") {
|
|
17714
|
+
const nestedParsed = parseString(nestedData);
|
|
17715
|
+
const nestedObj = asObject(nestedParsed);
|
|
17716
|
+
if (nestedObj) {
|
|
17717
|
+
eventName = typeof nestedObj.eventName === "string" && nestedObj.eventName || typeof nestedObj.event_name === "string" && nestedObj.event_name || typeof nestedObj.type === "string" && nestedObj.type || null;
|
|
17718
|
+
dataObj = asObject(nestedObj.data);
|
|
17719
|
+
}
|
|
17720
|
+
}
|
|
17721
|
+
if (!eventName || !/^onramp_api\./i.test(eventName)) return null;
|
|
17722
|
+
return {
|
|
17723
|
+
eventName,
|
|
17724
|
+
data: dataObj ? {
|
|
17725
|
+
errorCode: typeof dataObj.errorCode === "string" ? dataObj.errorCode : typeof dataObj.error_code === "string" ? dataObj.error_code : void 0,
|
|
17726
|
+
errorMessage: typeof dataObj.errorMessage === "string" ? dataObj.errorMessage : typeof dataObj.error_message === "string" ? dataObj.error_message : void 0
|
|
17727
|
+
} : void 0
|
|
17728
|
+
};
|
|
17532
17729
|
}
|
|
17533
17730
|
var BuyWithApplePay = React52.forwardRef(
|
|
17534
17731
|
function BuyWithApplePay2({
|
|
17535
17732
|
userId,
|
|
17536
17733
|
publishableKey,
|
|
17537
|
-
recipientAddress,
|
|
17538
17734
|
destinationChainType,
|
|
17539
17735
|
destinationChainId,
|
|
17540
17736
|
destinationTokenAddress,
|
|
17541
|
-
|
|
17542
|
-
externalUserEmail,
|
|
17543
|
-
enableApplePay,
|
|
17737
|
+
userEmail,
|
|
17544
17738
|
amountUsd,
|
|
17545
17739
|
minAmountUsd = DEFAULT_MIN_USD,
|
|
17546
17740
|
maxAmountUsd = DEFAULT_MAX_USD,
|
|
17547
17741
|
suggestedAmountsUsd = DEFAULT_SUGGESTED,
|
|
17548
|
-
wallets:
|
|
17742
|
+
wallets: depositWallets,
|
|
17549
17743
|
onDepositSuccess,
|
|
17550
17744
|
onDepositError,
|
|
17551
17745
|
onEvent,
|
|
@@ -17554,48 +17748,61 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17554
17748
|
onExit
|
|
17555
17749
|
}, ref) {
|
|
17556
17750
|
const { colors: colors2, fonts, components } = useTheme();
|
|
17557
|
-
const { projectConfig, isLoading: configLoading } = useProjectConfig({ publishableKey });
|
|
17558
|
-
const applePayEnabled = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
|
|
17559
17751
|
const [view, setView] = (0, import_react17.useState)("loading_config");
|
|
17560
17752
|
const [errorMessage, setErrorMessage] = (0, import_react17.useState)("");
|
|
17561
|
-
const [email, setEmail] = (0, import_react17.useState)(
|
|
17562
|
-
|
|
17563
|
-
|
|
17753
|
+
const [email, setEmail] = (0, import_react17.useState)(() => {
|
|
17754
|
+
if (userEmail && EMAIL_REGEX2.test(userEmail)) return userEmail;
|
|
17755
|
+
return getStoredApplePaySession(userId)?.email ?? "";
|
|
17756
|
+
});
|
|
17757
|
+
const [phoneInput, setPhoneInput] = (0, import_react17.useState)(() => {
|
|
17758
|
+
const stored = getStoredApplePaySession(userId);
|
|
17759
|
+
if (!stored) return "";
|
|
17760
|
+
if (userEmail && EMAIL_REGEX2.test(userEmail) && stored.email.toLowerCase() !== userEmail.toLowerCase()) {
|
|
17761
|
+
return "";
|
|
17762
|
+
}
|
|
17763
|
+
return stored.phone;
|
|
17764
|
+
});
|
|
17564
17765
|
const { data: legalAgreementsData, isLoading: legalAgreementsLoading } = useCoinbaseLegalAgreements({
|
|
17565
|
-
publishableKey
|
|
17566
|
-
enabled: applePayEnabled
|
|
17766
|
+
publishableKey
|
|
17567
17767
|
});
|
|
17568
17768
|
const legalAgreements = legalAgreementsData ?? null;
|
|
17569
17769
|
const [verificationSession, setVerificationSession] = (0, import_react17.useState)(null);
|
|
17570
17770
|
const [clientSecret, setClientSecret] = (0, import_react17.useState)(null);
|
|
17571
|
-
const [emailCode, setEmailCode] = (0, import_react17.useState)("");
|
|
17572
17771
|
const [phoneCode, setPhoneCode] = (0, import_react17.useState)("");
|
|
17573
17772
|
const [otpError, setOtpError] = (0, import_react17.useState)(null);
|
|
17574
17773
|
const [otpSubmitting, setOtpSubmitting] = (0, import_react17.useState)(false);
|
|
17575
17774
|
const [resendCooldown, setResendCooldown] = (0, import_react17.useState)(0);
|
|
17775
|
+
const [dobInput, setDobInput] = (0, import_react17.useState)("");
|
|
17776
|
+
const [ssnLast4, setSsnLast4] = (0, import_react17.useState)("");
|
|
17777
|
+
const [limitUpgradeError, setLimitUpgradeError] = (0, import_react17.useState)(null);
|
|
17778
|
+
const [upgradeSubmitting, setUpgradeSubmitting] = (0, import_react17.useState)(false);
|
|
17779
|
+
const upgradeFlowAbortRef = (0, import_react17.useRef)(null);
|
|
17576
17780
|
const [amount, setAmount] = (0, import_react17.useState)(amountUsd ?? "");
|
|
17577
17781
|
const [paymentSession, setPaymentSession] = (0, import_react17.useState)(
|
|
17578
17782
|
null
|
|
17579
17783
|
);
|
|
17580
17784
|
const [paymentSessionAmount, setPaymentSessionAmount] = (0, import_react17.useState)(null);
|
|
17581
|
-
const [preparingSession, setPreparingSession] = (0, import_react17.useState)(false);
|
|
17582
17785
|
const popupRef = (0, import_react17.useRef)(null);
|
|
17583
17786
|
const sessionAbortRef = (0, import_react17.useRef)(null);
|
|
17584
17787
|
const [onrampToken, setOnrampToken] = (0, import_react17.useState)(null);
|
|
17585
|
-
const {
|
|
17586
|
-
|
|
17788
|
+
const { userIpInfo, isLoading: userIpInfoLoading } = useUserIp2();
|
|
17789
|
+
const {
|
|
17790
|
+
defaultToken,
|
|
17791
|
+
isLoading: defaultTokenLoading,
|
|
17792
|
+
isError: defaultTokenError
|
|
17793
|
+
} = useDefaultOnrampToken({
|
|
17587
17794
|
publishableKey,
|
|
17588
|
-
|
|
17589
|
-
|
|
17590
|
-
|
|
17591
|
-
|
|
17592
|
-
|
|
17795
|
+
tokenAddress: destinationTokenAddress,
|
|
17796
|
+
chainId: destinationChainId,
|
|
17797
|
+
chainType: destinationChainType,
|
|
17798
|
+
countryCode: userIpInfo?.alpha2,
|
|
17799
|
+
subdivisionCode: userIpInfo?.subdivisionCode ?? void 0
|
|
17593
17800
|
});
|
|
17594
|
-
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
17595
17801
|
const depositWallet = (0, import_react17.useMemo)(() => {
|
|
17596
|
-
|
|
17597
|
-
|
|
17598
|
-
|
|
17802
|
+
const routingChainType = defaultToken?.destination_token_metadata?.chain_type;
|
|
17803
|
+
if (!routingChainType) return void 0;
|
|
17804
|
+
return getWalletByChainType(depositWallets ?? [], routingChainType);
|
|
17805
|
+
}, [depositWallets, defaultToken]);
|
|
17599
17806
|
const depositWalletId = depositWallet?.id;
|
|
17600
17807
|
const { executions } = useDepositPolling({
|
|
17601
17808
|
userId,
|
|
@@ -17619,49 +17826,10 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17619
17826
|
onDepositError(error);
|
|
17620
17827
|
} : void 0
|
|
17621
17828
|
});
|
|
17622
|
-
const [emailLocked, setEmailLocked] = (0, import_react17.useState)(
|
|
17623
|
-
|
|
17624
|
-
|
|
17625
|
-
|
|
17626
|
-
setView("disabled");
|
|
17627
|
-
return;
|
|
17628
|
-
}
|
|
17629
|
-
setTosAccepted(true);
|
|
17630
|
-
const applyStoredOnrampToken = (stored2) => {
|
|
17631
|
-
if (!isOnrampTokenFresh(stored2) || !stored2.onrampToken || !stored2.onrampTokenExpiresAtMs) {
|
|
17632
|
-
return false;
|
|
17633
|
-
}
|
|
17634
|
-
setOnrampToken({
|
|
17635
|
-
token: stored2.onrampToken,
|
|
17636
|
-
token_type: "Bearer",
|
|
17637
|
-
expires_in: Math.max(0, Math.floor((stored2.onrampTokenExpiresAtMs - Date.now()) / 1e3))
|
|
17638
|
-
});
|
|
17639
|
-
setView("amount");
|
|
17640
|
-
return true;
|
|
17641
|
-
};
|
|
17642
|
-
if (externalUserEmail && EMAIL_REGEX.test(externalUserEmail)) {
|
|
17643
|
-
setEmail(externalUserEmail);
|
|
17644
|
-
setEmailLocked(true);
|
|
17645
|
-
const stored2 = getStoredApplePaySession(userId);
|
|
17646
|
-
if (stored2?.email?.toLowerCase() === externalUserEmail.toLowerCase()) {
|
|
17647
|
-
setPhoneInput(stored2.phone);
|
|
17648
|
-
if (applyStoredOnrampToken(stored2)) return;
|
|
17649
|
-
}
|
|
17650
|
-
setView("phone_input");
|
|
17651
|
-
return;
|
|
17652
|
-
}
|
|
17653
|
-
const stored = getStoredApplePaySession(userId);
|
|
17654
|
-
if (stored) {
|
|
17655
|
-
setEmail(stored.email);
|
|
17656
|
-
setPhoneInput(stored.phone);
|
|
17657
|
-
setEmailLocked(true);
|
|
17658
|
-
if (applyStoredOnrampToken(stored)) return;
|
|
17659
|
-
setView("phone_input");
|
|
17660
|
-
return;
|
|
17661
|
-
}
|
|
17662
|
-
setEmailLocked(false);
|
|
17663
|
-
setView("email_input");
|
|
17664
|
-
}, [configLoading, applePayEnabled, externalUserEmail, userId]);
|
|
17829
|
+
const [emailLocked, setEmailLocked] = (0, import_react17.useState)(() => {
|
|
17830
|
+
if (userEmail && EMAIL_REGEX2.test(userEmail)) return true;
|
|
17831
|
+
return !!getStoredApplePaySession(userId);
|
|
17832
|
+
});
|
|
17665
17833
|
(0, import_react17.useEffect)(() => {
|
|
17666
17834
|
if (resendCooldown <= 0) return;
|
|
17667
17835
|
const t13 = setInterval(() => setResendCooldown((c) => Math.max(0, c - 1)), 1e3);
|
|
@@ -17670,19 +17838,10 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17670
17838
|
(0, import_react17.useEffect)(() => {
|
|
17671
17839
|
if (view !== "checking_deposit") return;
|
|
17672
17840
|
const onMessage = (event) => {
|
|
17673
|
-
if (event.origin
|
|
17674
|
-
|
|
17675
|
-
const data = event.data;
|
|
17676
|
-
if (typeof data === "string") {
|
|
17677
|
-
try {
|
|
17678
|
-
parsed = JSON.parse(data);
|
|
17679
|
-
} catch {
|
|
17680
|
-
return;
|
|
17681
|
-
}
|
|
17682
|
-
} else if (data && typeof data === "object" && "eventName" in data) {
|
|
17683
|
-
parsed = data;
|
|
17684
|
-
}
|
|
17841
|
+
if (!COINBASE_ALLOWED_POSTMESSAGE_ORIGINS.has(event.origin)) return;
|
|
17842
|
+
const parsed = parseCoinbasePostMessage(event.data);
|
|
17685
17843
|
if (!parsed) return;
|
|
17844
|
+
const eventName = parsed.eventName.toLowerCase();
|
|
17686
17845
|
const code = parsed.data?.errorCode;
|
|
17687
17846
|
const closePopup = () => {
|
|
17688
17847
|
try {
|
|
@@ -17691,16 +17850,20 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17691
17850
|
}
|
|
17692
17851
|
popupRef.current = null;
|
|
17693
17852
|
};
|
|
17694
|
-
switch (
|
|
17853
|
+
switch (eventName) {
|
|
17695
17854
|
case "onramp_api.commit_success":
|
|
17696
17855
|
case "onramp_api.polling_success":
|
|
17856
|
+
case "onramp_api.cancel":
|
|
17697
17857
|
closePopup();
|
|
17698
17858
|
break;
|
|
17699
17859
|
case "onramp_api.commit_error":
|
|
17860
|
+
case "onramp_api.polling_failed":
|
|
17700
17861
|
if (code === "ERROR_CODE_GUEST_TRANSACTION_COUNT" || code === "ERROR_CODE_GUEST_DAILY_TRANSACTION_COUNT" || code === "ERROR_CODE_GUEST_TRANSACTION_LIMIT") {
|
|
17701
17862
|
closePopup();
|
|
17702
17863
|
setView("guest_limit_reached");
|
|
17864
|
+
return;
|
|
17703
17865
|
}
|
|
17866
|
+
closePopup();
|
|
17704
17867
|
break;
|
|
17705
17868
|
default:
|
|
17706
17869
|
break;
|
|
@@ -17712,17 +17875,17 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17712
17875
|
(0, import_react17.useEffect)(() => {
|
|
17713
17876
|
onViewChange?.(view);
|
|
17714
17877
|
}, [view, onViewChange]);
|
|
17715
|
-
(0, import_react17.useEffect)(
|
|
17716
|
-
|
|
17878
|
+
(0, import_react17.useEffect)(() => {
|
|
17879
|
+
return () => {
|
|
17717
17880
|
sessionAbortRef.current?.abort();
|
|
17881
|
+
upgradeFlowAbortRef.current?.abort();
|
|
17718
17882
|
try {
|
|
17719
17883
|
popupRef.current?.close();
|
|
17720
17884
|
} catch {
|
|
17721
17885
|
}
|
|
17722
17886
|
popupRef.current = null;
|
|
17723
|
-
}
|
|
17724
|
-
|
|
17725
|
-
);
|
|
17887
|
+
};
|
|
17888
|
+
}, []);
|
|
17726
17889
|
React52.useImperativeHandle(
|
|
17727
17890
|
ref,
|
|
17728
17891
|
() => ({
|
|
@@ -17732,14 +17895,20 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17732
17895
|
setView("email_input");
|
|
17733
17896
|
return true;
|
|
17734
17897
|
}
|
|
17735
|
-
if (view === "email_otp") {
|
|
17736
|
-
setView("phone_input");
|
|
17737
|
-
setEmailCode("");
|
|
17738
|
-
return true;
|
|
17739
|
-
}
|
|
17740
17898
|
if (view === "phone_otp") {
|
|
17741
17899
|
setView("phone_input");
|
|
17742
17900
|
setPhoneCode("");
|
|
17901
|
+
setOtpSubmitting(false);
|
|
17902
|
+
return true;
|
|
17903
|
+
}
|
|
17904
|
+
if (view === "limit_upgrade_intro" || view === "limit_upgrade_failed") {
|
|
17905
|
+
return false;
|
|
17906
|
+
}
|
|
17907
|
+
if (view === "limit_upgrade_form") {
|
|
17908
|
+
setView("limit_upgrade_intro");
|
|
17909
|
+
return true;
|
|
17910
|
+
}
|
|
17911
|
+
if (view === "limit_upgrade_submitting") {
|
|
17743
17912
|
return true;
|
|
17744
17913
|
}
|
|
17745
17914
|
if (view === "checking_deposit") {
|
|
@@ -17760,21 +17929,20 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17760
17929
|
[view, emailLocked]
|
|
17761
17930
|
);
|
|
17762
17931
|
const normalizedPhone = (0, import_react17.useMemo)(() => formatPhoneInput(phoneInput), [phoneInput]);
|
|
17763
|
-
const isContactValid =
|
|
17764
|
-
const
|
|
17932
|
+
const isContactValid = EMAIL_REGEX2.test(email) && PHONE_REGEX2.test(normalizedPhone);
|
|
17933
|
+
const storeApplePaySession = (0, import_react17.useCallback)(
|
|
17765
17934
|
(patch = {}) => {
|
|
17766
|
-
const
|
|
17935
|
+
const session = {
|
|
17767
17936
|
email,
|
|
17768
17937
|
phone: normalizedPhone,
|
|
17769
17938
|
termsAcceptedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17770
17939
|
...patch
|
|
17771
17940
|
};
|
|
17772
|
-
setStoredApplePaySession(userId,
|
|
17941
|
+
setStoredApplePaySession(userId, session);
|
|
17773
17942
|
},
|
|
17774
17943
|
[email, normalizedPhone, userId]
|
|
17775
17944
|
);
|
|
17776
|
-
const
|
|
17777
|
-
if (!isContactValid) return;
|
|
17945
|
+
const createSessionAndSendOtp = (0, import_react17.useCallback)(async () => {
|
|
17778
17946
|
setView("submitting_session");
|
|
17779
17947
|
setErrorMessage("");
|
|
17780
17948
|
try {
|
|
@@ -17792,71 +17960,192 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17792
17960
|
throw new Error("Server did not return a client_secret");
|
|
17793
17961
|
}
|
|
17794
17962
|
setClientSecret(session.client_secret);
|
|
17795
|
-
|
|
17796
|
-
|
|
17797
|
-
|
|
17798
|
-
|
|
17799
|
-
"phone",
|
|
17800
|
-
session.client_secret,
|
|
17801
|
-
publishableKey
|
|
17802
|
-
);
|
|
17803
|
-
setResendCooldown(30);
|
|
17804
|
-
setView("phone_otp");
|
|
17805
|
-
} else {
|
|
17806
|
-
await sendOnrampVerificationOtp(
|
|
17807
|
-
session.id,
|
|
17808
|
-
"email",
|
|
17809
|
-
session.client_secret,
|
|
17810
|
-
publishableKey
|
|
17811
|
-
);
|
|
17812
|
-
setResendCooldown(30);
|
|
17813
|
-
setView("email_otp");
|
|
17814
|
-
}
|
|
17963
|
+
storeApplePaySession();
|
|
17964
|
+
await sendOnrampVerificationOtp(session.id, "phone", session.client_secret, publishableKey);
|
|
17965
|
+
setResendCooldown(30);
|
|
17966
|
+
setView("phone_otp");
|
|
17815
17967
|
} catch (err) {
|
|
17816
17968
|
const raw = err instanceof Error ? err.message : "Failed to start verification";
|
|
17817
17969
|
setErrorMessage(prettifyVerificationError(raw));
|
|
17818
17970
|
setView("phone_input");
|
|
17819
17971
|
}
|
|
17820
|
-
}, [
|
|
17821
|
-
const
|
|
17822
|
-
|
|
17823
|
-
|
|
17824
|
-
|
|
17825
|
-
|
|
17972
|
+
}, [email, normalizedPhone, publishableKey, storeApplePaySession]);
|
|
17973
|
+
const clearUpgradeFields = (0, import_react17.useCallback)(() => {
|
|
17974
|
+
setSsnLast4("");
|
|
17975
|
+
setDobInput("");
|
|
17976
|
+
}, []);
|
|
17977
|
+
const { action: initialAction, refetchApplePayLimits } = useApplePayInitialScreen({
|
|
17978
|
+
userId,
|
|
17979
|
+
publishableKey,
|
|
17980
|
+
normalizedPhone,
|
|
17981
|
+
userEmail,
|
|
17982
|
+
sessionPhoneVerified: verificationSession?.phone?.status === "verified",
|
|
17983
|
+
isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
|
|
17984
|
+
});
|
|
17985
|
+
const pollLimitUpgradeStatus = (0, import_react17.useCallback)(
|
|
17986
|
+
async (signal) => {
|
|
17987
|
+
const POLL_INTERVAL_MS4 = 1500;
|
|
17988
|
+
const POLL_TIMEOUT_MS = 3e4;
|
|
17989
|
+
const startedAt = Date.now();
|
|
17990
|
+
let firstIteration = true;
|
|
17991
|
+
while (Date.now() - startedAt < POLL_TIMEOUT_MS) {
|
|
17992
|
+
if (signal.aborted) return;
|
|
17993
|
+
if (!firstIteration) {
|
|
17994
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS4));
|
|
17995
|
+
}
|
|
17996
|
+
firstIteration = false;
|
|
17997
|
+
if (signal.aborted) return;
|
|
17998
|
+
let fresh;
|
|
17999
|
+
try {
|
|
18000
|
+
fresh = await getCoinbaseApplePayLimits(normalizedPhone, publishableKey, signal);
|
|
18001
|
+
} catch {
|
|
18002
|
+
if (signal.aborted) return;
|
|
18003
|
+
continue;
|
|
18004
|
+
}
|
|
18005
|
+
const { upgrade_status: status, limit_reached: stillCapped } = fresh;
|
|
18006
|
+
if (status === "active" || !stillCapped) {
|
|
18007
|
+
await refetchApplePayLimits();
|
|
18008
|
+
clearUpgradeFields();
|
|
18009
|
+
setLimitUpgradeError(null);
|
|
18010
|
+
if (onrampToken) {
|
|
18011
|
+
setView("amount");
|
|
18012
|
+
} else {
|
|
18013
|
+
if (signal.aborted) return;
|
|
18014
|
+
await createSessionAndSendOtp();
|
|
18015
|
+
}
|
|
18016
|
+
return;
|
|
18017
|
+
}
|
|
18018
|
+
if (status === "inactive") {
|
|
18019
|
+
await refetchApplePayLimits();
|
|
18020
|
+
clearUpgradeFields();
|
|
18021
|
+
setLimitUpgradeError(null);
|
|
18022
|
+
setView("guest_limit_reached");
|
|
18023
|
+
return;
|
|
18024
|
+
}
|
|
18025
|
+
if (status === "resubmit") {
|
|
18026
|
+
await refetchApplePayLimits();
|
|
18027
|
+
setSsnLast4("");
|
|
18028
|
+
setLimitUpgradeError(
|
|
18029
|
+
"We couldn't verify your information. Please check your SSN and date of birth and try again."
|
|
18030
|
+
);
|
|
18031
|
+
setView("limit_upgrade_form");
|
|
18032
|
+
return;
|
|
18033
|
+
}
|
|
18034
|
+
}
|
|
18035
|
+
setLimitUpgradeError(null);
|
|
18036
|
+
setView("limit_upgrade_failed");
|
|
18037
|
+
},
|
|
18038
|
+
[
|
|
18039
|
+
normalizedPhone,
|
|
18040
|
+
publishableKey,
|
|
18041
|
+
refetchApplePayLimits,
|
|
18042
|
+
onrampToken,
|
|
18043
|
+
createSessionAndSendOtp,
|
|
18044
|
+
clearUpgradeFields
|
|
18045
|
+
]
|
|
18046
|
+
);
|
|
18047
|
+
const startUpgradePolling = (0, import_react17.useCallback)(async () => {
|
|
18048
|
+
upgradeFlowAbortRef.current?.abort();
|
|
18049
|
+
const controller = new AbortController();
|
|
18050
|
+
upgradeFlowAbortRef.current = controller;
|
|
17826
18051
|
try {
|
|
17827
|
-
|
|
17828
|
-
|
|
17829
|
-
|
|
17830
|
-
|
|
17831
|
-
|
|
17832
|
-
|
|
17833
|
-
|
|
17834
|
-
|
|
17835
|
-
|
|
17836
|
-
|
|
17837
|
-
|
|
17838
|
-
|
|
17839
|
-
|
|
17840
|
-
setView("phone_otp");
|
|
18052
|
+
await pollLimitUpgradeStatus(controller.signal);
|
|
18053
|
+
} finally {
|
|
18054
|
+
if (upgradeFlowAbortRef.current === controller) {
|
|
18055
|
+
upgradeFlowAbortRef.current = null;
|
|
18056
|
+
}
|
|
18057
|
+
}
|
|
18058
|
+
}, [pollLimitUpgradeStatus]);
|
|
18059
|
+
const applyLimitRouting = (0, import_react17.useCallback)(
|
|
18060
|
+
(nextView, status) => {
|
|
18061
|
+
if (nextView === "limit_upgrade_form" && status === "resubmit") {
|
|
18062
|
+
setLimitUpgradeError(
|
|
18063
|
+
"We couldn't verify your information. Please check your SSN and date of birth and try again."
|
|
18064
|
+
);
|
|
17841
18065
|
} else {
|
|
17842
|
-
|
|
17843
|
-
setEmailCode("");
|
|
18066
|
+
setLimitUpgradeError(null);
|
|
17844
18067
|
}
|
|
17845
|
-
|
|
17846
|
-
|
|
17847
|
-
|
|
17848
|
-
|
|
17849
|
-
|
|
18068
|
+
setView(nextView);
|
|
18069
|
+
if (nextView === "limit_upgrade_submitting") {
|
|
18070
|
+
void startUpgradePolling();
|
|
18071
|
+
}
|
|
18072
|
+
},
|
|
18073
|
+
[startUpgradePolling]
|
|
18074
|
+
);
|
|
18075
|
+
const hasInitializedRef = (0, import_react17.useRef)(false);
|
|
18076
|
+
(0, import_react17.useEffect)(() => {
|
|
18077
|
+
if (hasInitializedRef.current) return;
|
|
18078
|
+
if (initialAction.kind === "pending") return;
|
|
18079
|
+
hasInitializedRef.current = true;
|
|
18080
|
+
switch (initialAction.kind) {
|
|
18081
|
+
case "navigate":
|
|
18082
|
+
setView(initialAction.view);
|
|
18083
|
+
break;
|
|
18084
|
+
case "limit_upgrade":
|
|
18085
|
+
applyLimitRouting(initialAction.view, initialAction.status);
|
|
18086
|
+
break;
|
|
18087
|
+
case "resume_with_token":
|
|
18088
|
+
setOnrampToken(initialAction.token);
|
|
18089
|
+
setView("amount");
|
|
18090
|
+
break;
|
|
18091
|
+
case "resume_send_sms":
|
|
18092
|
+
void createSessionAndSendOtp();
|
|
18093
|
+
break;
|
|
18094
|
+
}
|
|
18095
|
+
}, [initialAction, applyLimitRouting, createSessionAndSendOtp]);
|
|
18096
|
+
const startVerification = (0, import_react17.useCallback)(async () => {
|
|
18097
|
+
if (!isContactValid) return;
|
|
18098
|
+
await createSessionAndSendOtp();
|
|
18099
|
+
}, [isContactValid, createSessionAndSendOtp]);
|
|
18100
|
+
const submitLimitUpgrade = (0, import_react17.useCallback)(async () => {
|
|
18101
|
+
if (upgradeSubmitting) return;
|
|
18102
|
+
try {
|
|
18103
|
+
const dob = parseDobInput(dobInput);
|
|
18104
|
+
if (!dob || !/^\d{4}$/.test(ssnLast4)) return;
|
|
18105
|
+
setUpgradeSubmitting(true);
|
|
18106
|
+
setLimitUpgradeError(null);
|
|
18107
|
+
setView("limit_upgrade_submitting");
|
|
18108
|
+
const requestController = new AbortController();
|
|
18109
|
+
upgradeFlowAbortRef.current?.abort();
|
|
18110
|
+
upgradeFlowAbortRef.current = requestController;
|
|
18111
|
+
try {
|
|
18112
|
+
await requestCoinbaseApplePayLimitUpgrade(
|
|
18113
|
+
{
|
|
18114
|
+
phone: normalizedPhone,
|
|
18115
|
+
fields: { ssnLast4, dateOfBirth: dob }
|
|
18116
|
+
},
|
|
18117
|
+
publishableKey,
|
|
18118
|
+
requestController.signal
|
|
18119
|
+
);
|
|
18120
|
+
} catch (err) {
|
|
18121
|
+
if (requestController.signal.aborted) return;
|
|
18122
|
+
const raw = err instanceof Error ? err.message : "Failed to request limit upgrade";
|
|
18123
|
+
if (isLimitUpgradeTerminalBlock(raw)) {
|
|
18124
|
+
clearUpgradeFields();
|
|
18125
|
+
setLimitUpgradeError(null);
|
|
18126
|
+
setView("guest_limit_reached");
|
|
18127
|
+
return;
|
|
18128
|
+
}
|
|
18129
|
+
setLimitUpgradeError(prettifyVerificationError(raw));
|
|
18130
|
+
setView("limit_upgrade_form");
|
|
18131
|
+
return;
|
|
18132
|
+
} finally {
|
|
18133
|
+
if (upgradeFlowAbortRef.current === requestController) {
|
|
18134
|
+
upgradeFlowAbortRef.current = null;
|
|
18135
|
+
}
|
|
18136
|
+
}
|
|
18137
|
+
await startUpgradePolling();
|
|
17850
18138
|
} finally {
|
|
17851
|
-
|
|
18139
|
+
setUpgradeSubmitting(false);
|
|
17852
18140
|
}
|
|
17853
18141
|
}, [
|
|
17854
|
-
|
|
17855
|
-
|
|
17856
|
-
|
|
18142
|
+
upgradeSubmitting,
|
|
18143
|
+
dobInput,
|
|
18144
|
+
ssnLast4,
|
|
18145
|
+
normalizedPhone,
|
|
17857
18146
|
publishableKey,
|
|
17858
|
-
|
|
17859
|
-
|
|
18147
|
+
startUpgradePolling,
|
|
18148
|
+
clearUpgradeFields
|
|
17860
18149
|
]);
|
|
17861
18150
|
const submitPhoneOtp = (0, import_react17.useCallback)(async () => {
|
|
17862
18151
|
if (!verificationSession || !clientSecret || phoneCode.length !== 6) return;
|
|
@@ -17879,7 +18168,7 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17879
18168
|
publishableKey
|
|
17880
18169
|
);
|
|
17881
18170
|
setOnrampToken(tokenRes);
|
|
17882
|
-
|
|
18171
|
+
storeApplePaySession({
|
|
17883
18172
|
emailVerifiedAt: updated.email.verified_at,
|
|
17884
18173
|
phoneVerifiedAt: updated.phone.verified_at,
|
|
17885
18174
|
onrampToken: tokenRes.token,
|
|
@@ -17888,17 +18177,30 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17888
18177
|
setEmailLocked(true);
|
|
17889
18178
|
setPhoneCode("");
|
|
17890
18179
|
if (amountUsd) setAmount(amountUsd);
|
|
18180
|
+
try {
|
|
18181
|
+
const result = await refetchApplePayLimits();
|
|
18182
|
+
if (result.data) {
|
|
18183
|
+
const nextView = getViewForLimitStatus(result.data);
|
|
18184
|
+
if (nextView) {
|
|
18185
|
+
setOtpSubmitting(false);
|
|
18186
|
+
applyLimitRouting(nextView, result.data.upgrade_status);
|
|
18187
|
+
return;
|
|
18188
|
+
}
|
|
18189
|
+
}
|
|
18190
|
+
} catch {
|
|
18191
|
+
}
|
|
18192
|
+
setOtpSubmitting(false);
|
|
17891
18193
|
setView("amount");
|
|
17892
|
-
|
|
17893
|
-
setOtpError("Incorrect code. Please try again.");
|
|
17894
|
-
setPhoneCode("");
|
|
18194
|
+
return;
|
|
17895
18195
|
}
|
|
18196
|
+
setOtpError("Incorrect code. Please try again.");
|
|
18197
|
+
setPhoneCode("");
|
|
18198
|
+
setOtpSubmitting(false);
|
|
17896
18199
|
} catch (err) {
|
|
17897
18200
|
setOtpError(
|
|
17898
18201
|
prettifyVerificationError(err instanceof Error ? err.message : "Verification failed")
|
|
17899
18202
|
);
|
|
17900
18203
|
setPhoneCode("");
|
|
17901
|
-
} finally {
|
|
17902
18204
|
setOtpSubmitting(false);
|
|
17903
18205
|
}
|
|
17904
18206
|
}, [
|
|
@@ -17906,22 +18208,25 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17906
18208
|
clientSecret,
|
|
17907
18209
|
phoneCode,
|
|
17908
18210
|
publishableKey,
|
|
17909
|
-
|
|
18211
|
+
storeApplePaySession,
|
|
17910
18212
|
amountUsd,
|
|
17911
|
-
otpSubmitting
|
|
18213
|
+
otpSubmitting,
|
|
18214
|
+
refetchApplePayLimits,
|
|
18215
|
+
getViewForLimitStatus,
|
|
18216
|
+
applyLimitRouting
|
|
17912
18217
|
]);
|
|
17913
18218
|
const prepareSession = (0, import_react17.useCallback)(
|
|
17914
18219
|
async (token, amt) => {
|
|
18220
|
+
setErrorMessage("");
|
|
17915
18221
|
if (!destinationChainType || !destinationChainId) {
|
|
17916
18222
|
setErrorMessage("Deposit destination not configured. Please contact support.");
|
|
17917
18223
|
return;
|
|
17918
18224
|
}
|
|
17919
|
-
|
|
17920
|
-
|
|
17921
|
-
|
|
17922
|
-
)
|
|
17923
|
-
|
|
17924
|
-
setErrorMessage("Coinbase Apple Pay is not available for this network.");
|
|
18225
|
+
if (defaultTokenLoading) {
|
|
18226
|
+
return;
|
|
18227
|
+
}
|
|
18228
|
+
if (defaultTokenError || !defaultToken) {
|
|
18229
|
+
setErrorMessage("Unable to load token information. Please try again.");
|
|
17925
18230
|
return;
|
|
17926
18231
|
}
|
|
17927
18232
|
const settlementAddress = depositWallet?.address;
|
|
@@ -17932,19 +18237,17 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17932
18237
|
sessionAbortRef.current?.abort();
|
|
17933
18238
|
const controller = new AbortController();
|
|
17934
18239
|
sessionAbortRef.current = controller;
|
|
17935
|
-
setPreparingSession(true);
|
|
17936
|
-
setErrorMessage("");
|
|
17937
18240
|
try {
|
|
17938
18241
|
const externalId = generatePrefixedKSUID("orsext");
|
|
17939
18242
|
const session = await createCoinbaseApplePaySession(
|
|
17940
18243
|
{
|
|
17941
18244
|
source_currency: "usd",
|
|
17942
18245
|
source_amount: amt,
|
|
17943
|
-
destination_currency:
|
|
17944
|
-
destination_network:
|
|
18246
|
+
destination_currency: defaultToken.destination_currency,
|
|
18247
|
+
destination_network: defaultToken.destination_network,
|
|
17945
18248
|
wallet_address: settlementAddress,
|
|
17946
18249
|
external_id: externalId,
|
|
17947
|
-
...
|
|
18250
|
+
...userEmail ? { email: userEmail } : {}
|
|
17948
18251
|
},
|
|
17949
18252
|
token,
|
|
17950
18253
|
publishableKey,
|
|
@@ -17988,18 +18291,16 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
17988
18291
|
setPaymentSession(null);
|
|
17989
18292
|
setPaymentSessionAmount(null);
|
|
17990
18293
|
setErrorMessage("Unable to process your request. Please try again later.");
|
|
17991
|
-
} finally {
|
|
17992
|
-
if (sessionAbortRef.current === controller) {
|
|
17993
|
-
setPreparingSession(false);
|
|
17994
|
-
}
|
|
17995
18294
|
}
|
|
17996
18295
|
},
|
|
17997
18296
|
[
|
|
17998
|
-
destinationTokenSymbol,
|
|
17999
18297
|
destinationChainType,
|
|
18000
18298
|
destinationChainId,
|
|
18299
|
+
defaultToken,
|
|
18300
|
+
defaultTokenLoading,
|
|
18301
|
+
defaultTokenError,
|
|
18001
18302
|
depositWallet?.address,
|
|
18002
|
-
|
|
18303
|
+
userEmail,
|
|
18003
18304
|
publishableKey,
|
|
18004
18305
|
onEvent,
|
|
18005
18306
|
userId
|
|
@@ -18043,42 +18344,8 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18043
18344
|
if (view === "loading_config") {
|
|
18044
18345
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-16", style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LoaderCircle, { className: "uf-w-6 uf-h-6 uf-animate-spin", style: { color: colors2.primary } }) });
|
|
18045
18346
|
}
|
|
18046
|
-
if (view === "disabled") {
|
|
18047
|
-
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
18048
|
-
"div",
|
|
18049
|
-
{
|
|
18050
|
-
className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-12 uf-px-4",
|
|
18051
|
-
style: containerStyle,
|
|
18052
|
-
children: [
|
|
18053
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18054
|
-
CircleAlert,
|
|
18055
|
-
{
|
|
18056
|
-
className: "uf-w-8 uf-h-8 uf-mb-4",
|
|
18057
|
-
style: { color: colors2.foregroundMuted }
|
|
18058
|
-
}
|
|
18059
|
-
),
|
|
18060
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18061
|
-
"h3",
|
|
18062
|
-
{
|
|
18063
|
-
className: "uf-text-base uf-font-medium uf-mb-1",
|
|
18064
|
-
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
18065
|
-
children: "Apple Pay is unavailable"
|
|
18066
|
-
}
|
|
18067
|
-
),
|
|
18068
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18069
|
-
"p",
|
|
18070
|
-
{
|
|
18071
|
-
className: "uf-text-sm uf-text-center",
|
|
18072
|
-
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
18073
|
-
children: "Apple Pay is disabled for this project. Try another payment method."
|
|
18074
|
-
}
|
|
18075
|
-
)
|
|
18076
|
-
]
|
|
18077
|
-
}
|
|
18078
|
-
);
|
|
18079
|
-
}
|
|
18080
18347
|
if (view === "email_input") {
|
|
18081
|
-
const emailValid =
|
|
18348
|
+
const emailValid = EMAIL_REGEX2.test(email);
|
|
18082
18349
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "uf-flex uf-flex-col uf-pb-1 uf-pt-2", style: containerStyle, children: [
|
|
18083
18350
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18084
18351
|
"label",
|
|
@@ -18095,9 +18362,7 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18095
18362
|
value: email,
|
|
18096
18363
|
onChange: (e) => setEmail(e.target.value.trim()),
|
|
18097
18364
|
onKeyDown: (e) => {
|
|
18098
|
-
if (e.key === "Enter" && emailValid)
|
|
18099
|
-
setView("phone_input");
|
|
18100
|
-
}
|
|
18365
|
+
if (e.key === "Enter" && emailValid) setView("phone_input");
|
|
18101
18366
|
},
|
|
18102
18367
|
placeholder: "you@example.com",
|
|
18103
18368
|
autoComplete: "email",
|
|
@@ -18133,7 +18398,7 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18133
18398
|
}
|
|
18134
18399
|
if (view === "phone_input" || view === "submitting_session") {
|
|
18135
18400
|
const submitting = view === "submitting_session";
|
|
18136
|
-
const phoneValid =
|
|
18401
|
+
const phoneValid = PHONE_REGEX2.test(normalizedPhone);
|
|
18137
18402
|
const rawDigits = (() => {
|
|
18138
18403
|
const digits = phoneInput.replace(/\D/g, "");
|
|
18139
18404
|
return digits.startsWith("1") ? digits.slice(1, 11) : digits.slice(0, 10);
|
|
@@ -18214,15 +18479,7 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18214
18479
|
!phoneInput && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "uf-text-xs uf-mb-2 uf-px-1", style: { color: colors2.foregroundMuted }, children: "Re-verified every 60 days." }),
|
|
18215
18480
|
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "uf-text-xs uf-mt-2 uf-px-1", style: { color: colors2.error }, children: errorMessage }),
|
|
18216
18481
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "uf-flex-1" }),
|
|
18217
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18218
|
-
LegalDisclaimer,
|
|
18219
|
-
{
|
|
18220
|
-
legalAgreements,
|
|
18221
|
-
loading: legalAgreementsLoading,
|
|
18222
|
-
colors: colors2,
|
|
18223
|
-
fonts
|
|
18224
|
-
}
|
|
18225
|
-
),
|
|
18482
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LegalDisclaimer, { legalAgreements, loading: legalAgreementsLoading }),
|
|
18226
18483
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18227
18484
|
"button",
|
|
18228
18485
|
{
|
|
@@ -18241,12 +18498,9 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18241
18498
|
)
|
|
18242
18499
|
] });
|
|
18243
18500
|
}
|
|
18244
|
-
if (view === "
|
|
18245
|
-
const
|
|
18246
|
-
const
|
|
18247
|
-
const setCode = isEmail ? setEmailCode : setPhoneCode;
|
|
18248
|
-
const target = isEmail ? maskEmail(email) : maskPhone(normalizedPhone);
|
|
18249
|
-
const submit = isEmail ? submitEmailOtp : submitPhoneOtp;
|
|
18501
|
+
if (view === "phone_otp") {
|
|
18502
|
+
const code = phoneCode;
|
|
18503
|
+
const target = maskPhone(normalizedPhone);
|
|
18250
18504
|
const canSubmit = code.length === 6 && !otpSubmitting;
|
|
18251
18505
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "uf-flex uf-flex-col uf-pb-1 uf-items-center uf-pt-2", style: containerStyle, children: [
|
|
18252
18506
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
@@ -18269,13 +18523,12 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18269
18523
|
maxLength: 6,
|
|
18270
18524
|
value: code,
|
|
18271
18525
|
onChange: (e) => {
|
|
18272
|
-
|
|
18273
|
-
setCode(v);
|
|
18526
|
+
setPhoneCode(e.target.value.replace(/\D/g, "").slice(0, 6));
|
|
18274
18527
|
setOtpError(null);
|
|
18275
18528
|
},
|
|
18276
18529
|
onKeyDown: (e) => {
|
|
18277
18530
|
if (e.key === "Enter" && code.length === 6 && !otpSubmitting) {
|
|
18278
|
-
void
|
|
18531
|
+
void submitPhoneOtp();
|
|
18279
18532
|
}
|
|
18280
18533
|
},
|
|
18281
18534
|
autoFocus: true,
|
|
@@ -18302,7 +18555,7 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18302
18555
|
if (!verificationSession || !clientSecret) return;
|
|
18303
18556
|
void sendOnrampVerificationOtp(
|
|
18304
18557
|
verificationSession.id,
|
|
18305
|
-
|
|
18558
|
+
"phone",
|
|
18306
18559
|
clientSecret,
|
|
18307
18560
|
publishableKey
|
|
18308
18561
|
).then(() => setResendCooldown(30));
|
|
@@ -18315,7 +18568,7 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18315
18568
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18316
18569
|
"button",
|
|
18317
18570
|
{
|
|
18318
|
-
onClick:
|
|
18571
|
+
onClick: submitPhoneOtp,
|
|
18319
18572
|
disabled: !canSubmit,
|
|
18320
18573
|
className: "uf-w-full uf-py-3 uf-mt-6 uf-text-sm uf-font-medium uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed uf-flex uf-items-center uf-justify-center uf-gap-2",
|
|
18321
18574
|
style: {
|
|
@@ -18463,7 +18716,7 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18463
18716
|
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`,
|
|
18464
18717
|
opacity: 0.5
|
|
18465
18718
|
},
|
|
18466
|
-
children: !hasInput || !validAmount ? "Enter amount" : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
18719
|
+
children: !hasInput || !validAmount ? "Enter amount" : errorMessage ? "Unable to prepare Apple Pay" : defaultTokenLoading ? "Loading token information\u2026" : defaultTokenError ? "Token routing unavailable" : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
18467
18720
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
|
|
18468
18721
|
"Preparing Apple Pay"
|
|
18469
18722
|
] })
|
|
@@ -18501,7 +18754,104 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18501
18754
|
{
|
|
18502
18755
|
className: "uf-text-xl uf-mb-2 uf-text-center",
|
|
18503
18756
|
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
18504
|
-
children: "Checking for your deposit\u2026"
|
|
18757
|
+
children: "Checking for your deposit\u2026"
|
|
18758
|
+
}
|
|
18759
|
+
),
|
|
18760
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18761
|
+
"p",
|
|
18762
|
+
{
|
|
18763
|
+
className: "uf-text-sm uf-text-center uf-max-w-[280px]",
|
|
18764
|
+
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
18765
|
+
children: "Return if the payment is not made."
|
|
18766
|
+
}
|
|
18767
|
+
)
|
|
18768
|
+
]
|
|
18769
|
+
}
|
|
18770
|
+
);
|
|
18771
|
+
}
|
|
18772
|
+
if (view === "limit_upgrade_intro") {
|
|
18773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "uf-flex uf-flex-col uf-pt-8 uf-pb-2 uf-px-2", style: containerStyle, children: [
|
|
18774
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18775
|
+
"h3",
|
|
18776
|
+
{
|
|
18777
|
+
className: "uf-text-xl uf-mb-3 uf-text-center",
|
|
18778
|
+
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
18779
|
+
children: "Apple Pay limit reached"
|
|
18780
|
+
}
|
|
18781
|
+
),
|
|
18782
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18783
|
+
"p",
|
|
18784
|
+
{
|
|
18785
|
+
className: "uf-text-sm uf-text-center uf-mb-10 uf-max-w-[320px] uf-mx-auto",
|
|
18786
|
+
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
18787
|
+
children: "Submit your date of birth and SSN to increase your Apple Pay limit."
|
|
18788
|
+
}
|
|
18789
|
+
),
|
|
18790
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18791
|
+
"button",
|
|
18792
|
+
{
|
|
18793
|
+
onClick: () => {
|
|
18794
|
+
setLimitUpgradeError(null);
|
|
18795
|
+
setView("limit_upgrade_form");
|
|
18796
|
+
},
|
|
18797
|
+
className: "uf-w-full uf-py-3 uf-mb-2 uf-text-sm uf-font-medium uf-transition-colors",
|
|
18798
|
+
style: {
|
|
18799
|
+
backgroundColor: colors2.primary,
|
|
18800
|
+
color: colors2.primaryForeground,
|
|
18801
|
+
fontFamily: fonts.medium,
|
|
18802
|
+
borderRadius: components.button.borderRadius,
|
|
18803
|
+
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
|
|
18804
|
+
},
|
|
18805
|
+
children: "Continue"
|
|
18806
|
+
}
|
|
18807
|
+
),
|
|
18808
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18809
|
+
"button",
|
|
18810
|
+
{
|
|
18811
|
+
onClick: () => {
|
|
18812
|
+
setLimitUpgradeError(null);
|
|
18813
|
+
onExit?.();
|
|
18814
|
+
},
|
|
18815
|
+
className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors",
|
|
18816
|
+
style: {
|
|
18817
|
+
backgroundColor: "transparent",
|
|
18818
|
+
color: colors2.error,
|
|
18819
|
+
fontFamily: fonts.medium,
|
|
18820
|
+
borderRadius: components.button.borderRadius,
|
|
18821
|
+
border: `${components.button.borderWidth}px solid transparent`
|
|
18822
|
+
},
|
|
18823
|
+
children: "Cancel"
|
|
18824
|
+
}
|
|
18825
|
+
)
|
|
18826
|
+
] });
|
|
18827
|
+
}
|
|
18828
|
+
if (view === "limit_upgrade_submitting") {
|
|
18829
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
18830
|
+
"div",
|
|
18831
|
+
{
|
|
18832
|
+
className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16 uf-px-4",
|
|
18833
|
+
style: containerStyle,
|
|
18834
|
+
children: [
|
|
18835
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18836
|
+
"div",
|
|
18837
|
+
{
|
|
18838
|
+
className: "uf-w-20 uf-h-20 uf-rounded-full uf-flex uf-items-center uf-justify-center uf-mb-6",
|
|
18839
|
+
style: { backgroundColor: `${colors2.primary}20` },
|
|
18840
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18841
|
+
LoaderCircle,
|
|
18842
|
+
{
|
|
18843
|
+
className: "uf-w-10 uf-h-10 uf-animate-spin",
|
|
18844
|
+
style: { color: colors2.primary }
|
|
18845
|
+
}
|
|
18846
|
+
)
|
|
18847
|
+
}
|
|
18848
|
+
),
|
|
18849
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18850
|
+
"h3",
|
|
18851
|
+
{
|
|
18852
|
+
className: "uf-text-xl uf-mb-2 uf-text-center",
|
|
18853
|
+
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
18854
|
+
children: "Verifying your information"
|
|
18505
18855
|
}
|
|
18506
18856
|
),
|
|
18507
18857
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
@@ -18509,13 +18859,184 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18509
18859
|
{
|
|
18510
18860
|
className: "uf-text-sm uf-text-center uf-max-w-[280px]",
|
|
18511
18861
|
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
18512
|
-
children: "
|
|
18862
|
+
children: "Your limit increase request is under review. This usually takes just a few seconds."
|
|
18513
18863
|
}
|
|
18514
18864
|
)
|
|
18515
18865
|
]
|
|
18516
18866
|
}
|
|
18517
18867
|
);
|
|
18518
18868
|
}
|
|
18869
|
+
if (view === "limit_upgrade_form") {
|
|
18870
|
+
const dobValid = isDobInputValid(dobInput);
|
|
18871
|
+
const ssnValid = /^\d{4}$/.test(ssnLast4);
|
|
18872
|
+
const formValid = dobValid && ssnValid;
|
|
18873
|
+
const formInputStyle = {
|
|
18874
|
+
backgroundColor: components.card.backgroundColor,
|
|
18875
|
+
color: components.input.textColor,
|
|
18876
|
+
fontFamily: fonts.regular,
|
|
18877
|
+
borderRadius: components.card.borderRadius,
|
|
18878
|
+
border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
|
|
18879
|
+
};
|
|
18880
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "uf-flex uf-flex-col uf-pb-1 uf-pt-2", style: containerStyle, children: [
|
|
18881
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18882
|
+
"label",
|
|
18883
|
+
{
|
|
18884
|
+
className: "uf-text-xs uf-font-medium uf-mb-1.5 uf-px-1",
|
|
18885
|
+
style: { color: components.card.labelColor, fontFamily: fonts.medium },
|
|
18886
|
+
children: "Date of birth"
|
|
18887
|
+
}
|
|
18888
|
+
),
|
|
18889
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18890
|
+
"input",
|
|
18891
|
+
{
|
|
18892
|
+
type: "text",
|
|
18893
|
+
inputMode: "numeric",
|
|
18894
|
+
maxLength: 10,
|
|
18895
|
+
value: dobInput,
|
|
18896
|
+
onChange: (e) => {
|
|
18897
|
+
setDobInput(formatDobInput(e.target.value));
|
|
18898
|
+
if (limitUpgradeError) setLimitUpgradeError(null);
|
|
18899
|
+
},
|
|
18900
|
+
onKeyDown: (e) => {
|
|
18901
|
+
if (e.key === "Enter" && formValid) void submitLimitUpgrade();
|
|
18902
|
+
},
|
|
18903
|
+
placeholder: "MM/DD/YYYY",
|
|
18904
|
+
autoComplete: "bday",
|
|
18905
|
+
"aria-label": "Date of birth",
|
|
18906
|
+
className: "uf-w-full uf-px-3 uf-py-3 uf-mb-3 uf-text-sm uf-outline-none",
|
|
18907
|
+
style: formInputStyle
|
|
18908
|
+
}
|
|
18909
|
+
),
|
|
18910
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18911
|
+
"label",
|
|
18912
|
+
{
|
|
18913
|
+
className: "uf-text-xs uf-font-medium uf-mb-1.5 uf-px-1",
|
|
18914
|
+
style: { color: components.card.labelColor, fontFamily: fonts.medium },
|
|
18915
|
+
children: "Last 4 of SSN"
|
|
18916
|
+
}
|
|
18917
|
+
),
|
|
18918
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18919
|
+
"input",
|
|
18920
|
+
{
|
|
18921
|
+
type: "password",
|
|
18922
|
+
inputMode: "numeric",
|
|
18923
|
+
pattern: "[0-9]*",
|
|
18924
|
+
maxLength: 4,
|
|
18925
|
+
value: ssnLast4,
|
|
18926
|
+
onChange: (e) => {
|
|
18927
|
+
setSsnLast4(e.target.value.replace(/\D/g, "").slice(0, 4));
|
|
18928
|
+
if (limitUpgradeError) setLimitUpgradeError(null);
|
|
18929
|
+
},
|
|
18930
|
+
onKeyDown: (e) => {
|
|
18931
|
+
if (e.key === "Enter" && formValid) void submitLimitUpgrade();
|
|
18932
|
+
},
|
|
18933
|
+
placeholder: "\u2022\u2022\u2022\u2022",
|
|
18934
|
+
autoComplete: "off",
|
|
18935
|
+
name: "off",
|
|
18936
|
+
autoCorrect: "off",
|
|
18937
|
+
autoCapitalize: "none",
|
|
18938
|
+
spellCheck: false,
|
|
18939
|
+
"data-1p-ignore": "true",
|
|
18940
|
+
"data-lpignore": "true",
|
|
18941
|
+
"data-form-type": "other",
|
|
18942
|
+
"aria-label": "Last 4 digits of SSN",
|
|
18943
|
+
"aria-autocomplete": "none",
|
|
18944
|
+
className: "uf-w-full uf-px-3 uf-py-3 uf-mb-2 uf-text-sm uf-outline-none",
|
|
18945
|
+
style: formInputStyle
|
|
18946
|
+
}
|
|
18947
|
+
),
|
|
18948
|
+
limitUpgradeError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18949
|
+
"div",
|
|
18950
|
+
{
|
|
18951
|
+
className: "uf-text-xs uf-mt-2 uf-px-1",
|
|
18952
|
+
style: { color: colors2.error, fontFamily: fonts.regular },
|
|
18953
|
+
children: limitUpgradeError
|
|
18954
|
+
}
|
|
18955
|
+
),
|
|
18956
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "uf-flex-1" }),
|
|
18957
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18958
|
+
"button",
|
|
18959
|
+
{
|
|
18960
|
+
onClick: () => void submitLimitUpgrade(),
|
|
18961
|
+
disabled: !formValid || upgradeSubmitting,
|
|
18962
|
+
className: "uf-w-full uf-py-3 uf-mt-3 uf-text-sm uf-font-medium uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
|
|
18963
|
+
style: {
|
|
18964
|
+
backgroundColor: colors2.primary,
|
|
18965
|
+
color: colors2.primaryForeground,
|
|
18966
|
+
fontFamily: fonts.medium,
|
|
18967
|
+
borderRadius: components.button.borderRadius,
|
|
18968
|
+
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
|
|
18969
|
+
},
|
|
18970
|
+
children: upgradeSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2", children: [
|
|
18971
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
|
|
18972
|
+
"Submitting\u2026"
|
|
18973
|
+
] }) : "Submit"
|
|
18974
|
+
}
|
|
18975
|
+
)
|
|
18976
|
+
] });
|
|
18977
|
+
}
|
|
18978
|
+
if (view === "limit_upgrade_failed") {
|
|
18979
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "uf-flex uf-flex-col uf-pt-8 uf-pb-2 uf-px-2", style: containerStyle, children: [
|
|
18980
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18981
|
+
"h3",
|
|
18982
|
+
{
|
|
18983
|
+
className: "uf-text-xl uf-mb-3 uf-text-center",
|
|
18984
|
+
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
18985
|
+
children: "Apple Pay limit reached"
|
|
18986
|
+
}
|
|
18987
|
+
),
|
|
18988
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
18989
|
+
"p",
|
|
18990
|
+
{
|
|
18991
|
+
className: "uf-text-sm uf-text-center uf-mb-2 uf-max-w-[320px] uf-mx-auto",
|
|
18992
|
+
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
18993
|
+
children: [
|
|
18994
|
+
"Failed to increase. Please try again later or",
|
|
18995
|
+
" ",
|
|
18996
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
18997
|
+
"a",
|
|
18998
|
+
{
|
|
18999
|
+
href: UNIFOLD_SUPPORT_URL,
|
|
19000
|
+
target: "_blank",
|
|
19001
|
+
rel: "noreferrer noopener",
|
|
19002
|
+
className: "uf-underline",
|
|
19003
|
+
style: { color: colors2.primary },
|
|
19004
|
+
children: "contact support"
|
|
19005
|
+
}
|
|
19006
|
+
),
|
|
19007
|
+
"."
|
|
19008
|
+
]
|
|
19009
|
+
}
|
|
19010
|
+
),
|
|
19011
|
+
limitUpgradeError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
19012
|
+
"p",
|
|
19013
|
+
{
|
|
19014
|
+
className: "uf-text-xs uf-text-center uf-mb-2 uf-px-2",
|
|
19015
|
+
style: { color: colors2.error, fontFamily: fonts.regular },
|
|
19016
|
+
children: limitUpgradeError
|
|
19017
|
+
}
|
|
19018
|
+
),
|
|
19019
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "uf-mb-8" }),
|
|
19020
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
19021
|
+
"button",
|
|
19022
|
+
{
|
|
19023
|
+
onClick: () => {
|
|
19024
|
+
setLimitUpgradeError(null);
|
|
19025
|
+
onExit?.();
|
|
19026
|
+
},
|
|
19027
|
+
className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors",
|
|
19028
|
+
style: {
|
|
19029
|
+
backgroundColor: colors2.primary,
|
|
19030
|
+
color: colors2.primaryForeground,
|
|
19031
|
+
fontFamily: fonts.medium,
|
|
19032
|
+
borderRadius: components.button.borderRadius,
|
|
19033
|
+
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
|
|
19034
|
+
},
|
|
19035
|
+
children: "Return"
|
|
19036
|
+
}
|
|
19037
|
+
)
|
|
19038
|
+
] });
|
|
19039
|
+
}
|
|
18519
19040
|
if (view === "guest_limit_reached") {
|
|
18520
19041
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
18521
19042
|
"div",
|
|
@@ -18536,7 +19057,7 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18536
19057
|
{
|
|
18537
19058
|
className: "uf-text-sm uf-text-center uf-mb-12 uf-max-w-[300px]",
|
|
18538
19059
|
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
18539
|
-
children: "Your account
|
|
19060
|
+
children: "Your account is not eligible for a limit increase at this time."
|
|
18540
19061
|
}
|
|
18541
19062
|
),
|
|
18542
19063
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
@@ -18562,7 +19083,95 @@ var BuyWithApplePay = React52.forwardRef(
|
|
|
18562
19083
|
}
|
|
18563
19084
|
);
|
|
18564
19085
|
BuyWithApplePay.displayName = "BuyWithApplePay";
|
|
18565
|
-
function
|
|
19086
|
+
function formatPhoneInput(raw) {
|
|
19087
|
+
const digits = raw.replace(/\D/g, "");
|
|
19088
|
+
if (raw.startsWith("+")) {
|
|
19089
|
+
return `+${digits}`;
|
|
19090
|
+
}
|
|
19091
|
+
if (digits.length === 10) return `+1${digits}`;
|
|
19092
|
+
if (digits.length === 11 && digits.startsWith("1")) return `+${digits}`;
|
|
19093
|
+
return digits.length > 0 ? `+${digits}` : "";
|
|
19094
|
+
}
|
|
19095
|
+
function maskPhone(phone) {
|
|
19096
|
+
if (!/^\+1\d{10}$/.test(phone)) return phone;
|
|
19097
|
+
return `+1 (***) ***-${phone.slice(-4)}`;
|
|
19098
|
+
}
|
|
19099
|
+
function isGuestLimitError(err) {
|
|
19100
|
+
const message = err instanceof Error ? err.message : String(err ?? "");
|
|
19101
|
+
if (/coinbase_onramp_guest_limit_reached/i.test(message)) return true;
|
|
19102
|
+
if (/guest_(daily_)?transaction_(count|limit)/i.test(message)) return true;
|
|
19103
|
+
return false;
|
|
19104
|
+
}
|
|
19105
|
+
function isLimitUpgradeTerminalBlock(message) {
|
|
19106
|
+
if (/coinbase_onramp_guest_limit_reached/i.test(message)) return true;
|
|
19107
|
+
if (/limit upgrade is not available/i.test(message)) return true;
|
|
19108
|
+
if (/limits.?upgrade.?blocked/i.test(message)) return true;
|
|
19109
|
+
return false;
|
|
19110
|
+
}
|
|
19111
|
+
function prettifyVerificationError(message) {
|
|
19112
|
+
if (/\b429\b|too many requests|rate.?limit|throttle/i.test(message)) {
|
|
19113
|
+
return "Too many attempts. Please wait a few minutes and try again.";
|
|
19114
|
+
}
|
|
19115
|
+
if (/network|failed to fetch|abort/i.test(message)) {
|
|
19116
|
+
return "Network error. Check your connection and try again.";
|
|
19117
|
+
}
|
|
19118
|
+
if (/voip|not a valid US|not a cell/i.test(message)) {
|
|
19119
|
+
return "We can only verify real US cell phones (not VoIP). Try a different number.";
|
|
19120
|
+
}
|
|
19121
|
+
const cleaned = message.replace(/\s*\[[\w_]+\]:\s*.*$/, "").trim();
|
|
19122
|
+
return cleaned || message;
|
|
19123
|
+
}
|
|
19124
|
+
function formatDobInput(raw) {
|
|
19125
|
+
const digits = raw.replace(/\D/g, "").slice(0, 8);
|
|
19126
|
+
if (digits.length <= 2) return digits;
|
|
19127
|
+
if (digits.length <= 4) return `${digits.slice(0, 2)}/${digits.slice(2)}`;
|
|
19128
|
+
return `${digits.slice(0, 2)}/${digits.slice(2, 4)}/${digits.slice(4)}`;
|
|
19129
|
+
}
|
|
19130
|
+
function isDobInputValid(input) {
|
|
19131
|
+
return parseDobInput(input) !== null;
|
|
19132
|
+
}
|
|
19133
|
+
function parseDobInput(input) {
|
|
19134
|
+
const m = /^(\d{2})\/(\d{2})\/(\d{4})$/.exec(input);
|
|
19135
|
+
if (!m) return null;
|
|
19136
|
+
const [, month, day, year] = m;
|
|
19137
|
+
if (!/^(0[1-9]|1[0-2])$/.test(month)) return null;
|
|
19138
|
+
if (!/^(0[1-9]|[12]\d|3[01])$/.test(day)) return null;
|
|
19139
|
+
if (!/^(19|20)\d{2}$/.test(year)) return null;
|
|
19140
|
+
return { month, day, year };
|
|
19141
|
+
}
|
|
19142
|
+
var POPUP_W = 500;
|
|
19143
|
+
var POPUP_H = 700;
|
|
19144
|
+
function openCoinbasePaymentPopup(url) {
|
|
19145
|
+
if (typeof window === "undefined") return null;
|
|
19146
|
+
const screenW = window.screen.availWidth ?? window.innerWidth;
|
|
19147
|
+
const screenH = window.screen.availHeight ?? window.innerHeight;
|
|
19148
|
+
const left = Math.max(0, Math.round((screenW - POPUP_W) / 2));
|
|
19149
|
+
const top = Math.max(0, Math.round((screenH - POPUP_H) / 2));
|
|
19150
|
+
return window.open(
|
|
19151
|
+
url,
|
|
19152
|
+
"unifold_coinbase_apple_pay",
|
|
19153
|
+
`popup,width=${POPUP_W},height=${POPUP_H},left=${left},top=${top}`
|
|
19154
|
+
);
|
|
19155
|
+
}
|
|
19156
|
+
var FALLBACK_AGREEMENTS = [
|
|
19157
|
+
{
|
|
19158
|
+
key: "guest_checkout_terms",
|
|
19159
|
+
name: "Guest Checkout Terms of Service",
|
|
19160
|
+
url: "https://www.coinbase.com/legal/cb-pay/onramp-guest-checkout-terms"
|
|
19161
|
+
},
|
|
19162
|
+
{
|
|
19163
|
+
key: "user_agreement",
|
|
19164
|
+
name: "User Agreement",
|
|
19165
|
+
url: "https://www.coinbase.com/legal/user_agreement"
|
|
19166
|
+
},
|
|
19167
|
+
{
|
|
19168
|
+
key: "privacy_policy",
|
|
19169
|
+
name: "Privacy Policy",
|
|
19170
|
+
url: "https://www.coinbase.com/legal/privacy"
|
|
19171
|
+
}
|
|
19172
|
+
];
|
|
19173
|
+
function LegalDisclaimer({ legalAgreements, loading }) {
|
|
19174
|
+
const { colors: colors2, fonts } = useTheme();
|
|
18566
19175
|
if (loading) {
|
|
18567
19176
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
18568
19177
|
"div",
|
|
@@ -18606,78 +19215,6 @@ function LegalDisclaimer({ legalAgreements, loading, colors: colors2, fonts }) {
|
|
|
18606
19215
|
}
|
|
18607
19216
|
);
|
|
18608
19217
|
}
|
|
18609
|
-
function isGuestLimitError(err) {
|
|
18610
|
-
const message = err instanceof Error ? err.message : String(err ?? "");
|
|
18611
|
-
if (/coinbase_onramp_guest_limit_reached/i.test(message)) return true;
|
|
18612
|
-
if (/guest_(daily_)?transaction_(count|limit)/i.test(message)) return true;
|
|
18613
|
-
return false;
|
|
18614
|
-
}
|
|
18615
|
-
function prettifyVerificationError(message) {
|
|
18616
|
-
if (/\b429\b|too many requests|rate.?limit|throttle/i.test(message)) {
|
|
18617
|
-
return "Too many attempts. Please wait a few minutes and try again.";
|
|
18618
|
-
}
|
|
18619
|
-
if (/network|failed to fetch|abort/i.test(message)) {
|
|
18620
|
-
return "Network error. Check your connection and try again.";
|
|
18621
|
-
}
|
|
18622
|
-
if (/voip|not a valid US|not a cell/i.test(message)) {
|
|
18623
|
-
return "We can only verify real US cell phones (not VoIP). Try a different number.";
|
|
18624
|
-
}
|
|
18625
|
-
return message;
|
|
18626
|
-
}
|
|
18627
|
-
var FALLBACK_AGREEMENTS = [
|
|
18628
|
-
{
|
|
18629
|
-
key: "guest_checkout_terms",
|
|
18630
|
-
name: "Guest Checkout Terms of Service",
|
|
18631
|
-
url: "https://www.coinbase.com/legal/cb-pay/onramp-guest-checkout-terms"
|
|
18632
|
-
},
|
|
18633
|
-
{
|
|
18634
|
-
key: "user_agreement",
|
|
18635
|
-
name: "User Agreement",
|
|
18636
|
-
url: "https://www.coinbase.com/legal/user_agreement"
|
|
18637
|
-
},
|
|
18638
|
-
{
|
|
18639
|
-
key: "privacy_policy",
|
|
18640
|
-
name: "Privacy Policy",
|
|
18641
|
-
url: "https://www.coinbase.com/legal/privacy"
|
|
18642
|
-
}
|
|
18643
|
-
];
|
|
18644
|
-
var POPUP_W = 500;
|
|
18645
|
-
var POPUP_H = 700;
|
|
18646
|
-
function openCoinbasePaymentPopup(url) {
|
|
18647
|
-
if (typeof window === "undefined") return null;
|
|
18648
|
-
const screenW = window.screen.availWidth ?? window.innerWidth;
|
|
18649
|
-
const screenH = window.screen.availHeight ?? window.innerHeight;
|
|
18650
|
-
const left = Math.max(0, Math.round((screenW - POPUP_W) / 2));
|
|
18651
|
-
const top = Math.max(0, Math.round((screenH - POPUP_H) / 2));
|
|
18652
|
-
return window.open(
|
|
18653
|
-
url,
|
|
18654
|
-
"unifold_coinbase_apple_pay",
|
|
18655
|
-
`popup,width=${POPUP_W},height=${POPUP_H},left=${left},top=${top}`
|
|
18656
|
-
);
|
|
18657
|
-
}
|
|
18658
|
-
function destinationChainNameFor(chainType, chainId) {
|
|
18659
|
-
if (chainType === "solana") return "solana";
|
|
18660
|
-
if (chainType === "bitcoin") return "bitcoin";
|
|
18661
|
-
if (chainType === "ethereum") {
|
|
18662
|
-
switch (chainId) {
|
|
18663
|
-
case "1":
|
|
18664
|
-
return "ethereum";
|
|
18665
|
-
case "8453":
|
|
18666
|
-
return "base";
|
|
18667
|
-
case "137":
|
|
18668
|
-
return "polygon";
|
|
18669
|
-
case "43114":
|
|
18670
|
-
return "avalanche";
|
|
18671
|
-
case "42161":
|
|
18672
|
-
return "arbitrum";
|
|
18673
|
-
case "10":
|
|
18674
|
-
return "optimism";
|
|
18675
|
-
default:
|
|
18676
|
-
return null;
|
|
18677
|
-
}
|
|
18678
|
-
}
|
|
18679
|
-
return null;
|
|
18680
|
-
}
|
|
18681
19218
|
var t2 = i18n2.payWithExchange;
|
|
18682
19219
|
function PayWithExchange({
|
|
18683
19220
|
userId,
|
|
@@ -18692,10 +19229,10 @@ function PayWithExchange({
|
|
|
18692
19229
|
defaultToken
|
|
18693
19230
|
}) {
|
|
18694
19231
|
const { colors: colors2, fonts, components } = useTheme();
|
|
18695
|
-
const [internalView, setInternalView] = (0,
|
|
18696
|
-
const [exchangeSession, setExchangeSession] = (0,
|
|
18697
|
-
const [sessionError, setSessionError] = (0,
|
|
18698
|
-
const [hoveredIndex, setHoveredIndex] = (0,
|
|
19232
|
+
const [internalView, setInternalView] = (0, import_react19.useState)("providers");
|
|
19233
|
+
const [exchangeSession, setExchangeSession] = (0, import_react19.useState)(null);
|
|
19234
|
+
const [sessionError, setSessionError] = (0, import_react19.useState)(null);
|
|
19235
|
+
const [hoveredIndex, setHoveredIndex] = (0, import_react19.useState)(null);
|
|
18699
19236
|
const currentView = externalView ?? internalView;
|
|
18700
19237
|
const depositWalletId = wallets.find((w) => ["ethereum", "solana"].includes(w.chain_type))?.id;
|
|
18701
19238
|
const handleViewChange = (newView) => {
|
|
@@ -18975,7 +19512,7 @@ function QRCodeSkeleton({ size: size4 = 180, darkMode = false }) {
|
|
|
18975
19512
|
const spacing = size4 / gridCount;
|
|
18976
19513
|
const fillColor = darkMode ? "rgba(255,255,255,0.10)" : "rgba(0,0,0,0.08)";
|
|
18977
19514
|
const cornerColor = darkMode ? "rgba(255,255,255,0.14)" : "rgba(0,0,0,0.12)";
|
|
18978
|
-
const dots = (0,
|
|
19515
|
+
const dots = (0, import_react21.useMemo)(() => {
|
|
18979
19516
|
const result = [];
|
|
18980
19517
|
const cornerSize = 7;
|
|
18981
19518
|
const centerStart = Math.floor(gridCount / 2) - 2;
|
|
@@ -19030,10 +19567,10 @@ function StyledQRCode({
|
|
|
19030
19567
|
imageSize = 45,
|
|
19031
19568
|
darkMode = false
|
|
19032
19569
|
}) {
|
|
19033
|
-
const containerRef = (0,
|
|
19034
|
-
const qrRef = (0,
|
|
19035
|
-
const [ready, setReady] = (0,
|
|
19036
|
-
(0,
|
|
19570
|
+
const containerRef = (0, import_react21.useRef)(null);
|
|
19571
|
+
const qrRef = (0, import_react21.useRef)(null);
|
|
19572
|
+
const [ready, setReady] = (0, import_react21.useState)(false);
|
|
19573
|
+
(0, import_react21.useEffect)(() => {
|
|
19037
19574
|
if (!containerRef.current || !value) return;
|
|
19038
19575
|
const config = createQRConfig(value, size4, imageUrl, imageSize, darkMode);
|
|
19039
19576
|
if (!qrRef.current) {
|
|
@@ -19064,8 +19601,8 @@ function StyledQRCode({
|
|
|
19064
19601
|
] });
|
|
19065
19602
|
}
|
|
19066
19603
|
function useIsMobileViewport() {
|
|
19067
|
-
const [isMobile, setIsMobile] = (0,
|
|
19068
|
-
(0,
|
|
19604
|
+
const [isMobile, setIsMobile] = (0, import_react22.useState)(() => isMobileViewport());
|
|
19605
|
+
(0, import_react22.useEffect)(() => {
|
|
19069
19606
|
setIsMobile(isMobileViewport());
|
|
19070
19607
|
const mql = window.matchMedia(MOBILE_VIEWPORT_MEDIA_QUERY);
|
|
19071
19608
|
const update = () => setIsMobile(mql.matches);
|
|
@@ -19075,7 +19612,7 @@ function useIsMobileViewport() {
|
|
|
19075
19612
|
return isMobile;
|
|
19076
19613
|
}
|
|
19077
19614
|
function useCashAppLimits({ publishableKey, currency = "usd" }) {
|
|
19078
|
-
return (0,
|
|
19615
|
+
return (0, import_react_query8.useQuery)({
|
|
19079
19616
|
queryKey: ["unifold", "cashAppLimits", currency, publishableKey],
|
|
19080
19617
|
queryFn: () => getCashAppLimits(currency, publishableKey),
|
|
19081
19618
|
enabled: !!publishableKey,
|
|
@@ -19117,21 +19654,21 @@ function PayWithCashApp({
|
|
|
19117
19654
|
const { data: limits, isLoading: limitsLoading } = useCashAppLimits({ publishableKey });
|
|
19118
19655
|
const minUsd = limits?.minimum_amount ?? FALLBACK_MIN_USD;
|
|
19119
19656
|
const maxUsd = limits?.maximum_amount ?? null;
|
|
19120
|
-
const [amount, setAmount] = (0,
|
|
19121
|
-
const [loading, setLoading] = (0,
|
|
19122
|
-
const [session, setSession] = (0,
|
|
19123
|
-
const [status, setStatus] = (0,
|
|
19124
|
-
const [error, setError] = (0,
|
|
19125
|
-
const [copied, setCopied] = (0,
|
|
19126
|
-
const [view, setViewInternal] = (0,
|
|
19127
|
-
const setView = (0,
|
|
19657
|
+
const [amount, setAmount] = (0, import_react20.useState)("");
|
|
19658
|
+
const [loading, setLoading] = (0, import_react20.useState)(false);
|
|
19659
|
+
const [session, setSession] = (0, import_react20.useState)(null);
|
|
19660
|
+
const [status, setStatus] = (0, import_react20.useState)("pending");
|
|
19661
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
19662
|
+
const [copied, setCopied] = (0, import_react20.useState)(false);
|
|
19663
|
+
const [view, setViewInternal] = (0, import_react20.useState)(controlledView ?? "amount");
|
|
19664
|
+
const setView = (0, import_react20.useCallback)(
|
|
19128
19665
|
(v) => {
|
|
19129
19666
|
setViewInternal(v);
|
|
19130
19667
|
onViewChange?.(v);
|
|
19131
19668
|
},
|
|
19132
19669
|
[onViewChange]
|
|
19133
19670
|
);
|
|
19134
|
-
(0,
|
|
19671
|
+
(0, import_react20.useEffect)(() => {
|
|
19135
19672
|
if (controlledView && controlledView !== view) {
|
|
19136
19673
|
setViewInternal(controlledView);
|
|
19137
19674
|
if (controlledView === "amount") {
|
|
@@ -19143,7 +19680,7 @@ function PayWithCashApp({
|
|
|
19143
19680
|
}
|
|
19144
19681
|
}
|
|
19145
19682
|
}, [controlledView]);
|
|
19146
|
-
const [timeLeft, setTimeLeft] = (0,
|
|
19683
|
+
const [timeLeft, setTimeLeft] = (0, import_react20.useState)(null);
|
|
19147
19684
|
const depositWalletId = wallets.find((w) => w.chain_type === "ethereum")?.id;
|
|
19148
19685
|
const { executions, isPolling } = useDepositPolling({
|
|
19149
19686
|
userId,
|
|
@@ -19154,7 +19691,7 @@ function PayWithCashApp({
|
|
|
19154
19691
|
onDepositSuccess,
|
|
19155
19692
|
onDepositError
|
|
19156
19693
|
});
|
|
19157
|
-
const handleAmountChange = (0,
|
|
19694
|
+
const handleAmountChange = (0, import_react20.useCallback)(
|
|
19158
19695
|
(raw) => {
|
|
19159
19696
|
const cleaned = raw.replace(/[^0-9.]/g, "");
|
|
19160
19697
|
const parts = cleaned.split(".");
|
|
@@ -19166,7 +19703,7 @@ function PayWithCashApp({
|
|
|
19166
19703
|
},
|
|
19167
19704
|
[onAmountChange]
|
|
19168
19705
|
);
|
|
19169
|
-
const handleCreateSession = (0,
|
|
19706
|
+
const handleCreateSession = (0, import_react20.useCallback)(async () => {
|
|
19170
19707
|
if (!amount || !recipientAddress || !destinationChainType || !destinationChainId || !destinationTokenAddress) {
|
|
19171
19708
|
setError("Missing required fields");
|
|
19172
19709
|
return;
|
|
@@ -19215,7 +19752,7 @@ function PayWithCashApp({
|
|
|
19215
19752
|
onEvent,
|
|
19216
19753
|
onDepositError
|
|
19217
19754
|
]);
|
|
19218
|
-
(0,
|
|
19755
|
+
(0, import_react20.useEffect)(() => {
|
|
19219
19756
|
if (!session || view !== "payment" && view !== "confirming") return;
|
|
19220
19757
|
if (status === "completed" || status === "failed") return;
|
|
19221
19758
|
const poll = async () => {
|
|
@@ -19239,8 +19776,8 @@ function PayWithCashApp({
|
|
|
19239
19776
|
poll();
|
|
19240
19777
|
return () => clearInterval(interval);
|
|
19241
19778
|
}, [session, view, status, publishableKey, onDepositSuccess, onDepositError]);
|
|
19242
|
-
const [softExpired, setSoftExpired] = (0,
|
|
19243
|
-
(0,
|
|
19779
|
+
const [softExpired, setSoftExpired] = (0, import_react20.useState)(false);
|
|
19780
|
+
(0, import_react20.useEffect)(() => {
|
|
19244
19781
|
if (!session?.expires_at || view !== "payment") return;
|
|
19245
19782
|
const expiresMs = new Date(session.expires_at).getTime();
|
|
19246
19783
|
const tick = () => {
|
|
@@ -19254,12 +19791,12 @@ function PayWithCashApp({
|
|
|
19254
19791
|
const interval = setInterval(tick, 1e3);
|
|
19255
19792
|
return () => clearInterval(interval);
|
|
19256
19793
|
}, [session, view, status]);
|
|
19257
|
-
const handleCopy = (0,
|
|
19794
|
+
const handleCopy = (0, import_react20.useCallback)(async (text) => {
|
|
19258
19795
|
await navigator.clipboard.writeText(text);
|
|
19259
19796
|
setCopied(true);
|
|
19260
19797
|
setTimeout(() => setCopied(false), 2e3);
|
|
19261
19798
|
}, []);
|
|
19262
|
-
const handleRecreate = (0,
|
|
19799
|
+
const handleRecreate = (0, import_react20.useCallback)(() => {
|
|
19263
19800
|
setSession(null);
|
|
19264
19801
|
setStatus("pending");
|
|
19265
19802
|
setError(null);
|
|
@@ -19588,43 +20125,6 @@ function PayWithCashApp({
|
|
|
19588
20125
|
}
|
|
19589
20126
|
return null;
|
|
19590
20127
|
}
|
|
19591
|
-
function useDefaultOnrampToken({
|
|
19592
|
-
publishableKey,
|
|
19593
|
-
tokenAddress,
|
|
19594
|
-
chainId,
|
|
19595
|
-
chainType,
|
|
19596
|
-
countryCode,
|
|
19597
|
-
subdivisionCode,
|
|
19598
|
-
enabled = true
|
|
19599
|
-
}) {
|
|
19600
|
-
const { data: defaultToken, isLoading } = (0, import_react_query8.useQuery)({
|
|
19601
|
-
queryKey: [
|
|
19602
|
-
"unifold",
|
|
19603
|
-
"defaultOnrampToken",
|
|
19604
|
-
publishableKey,
|
|
19605
|
-
tokenAddress,
|
|
19606
|
-
chainId,
|
|
19607
|
-
chainType,
|
|
19608
|
-
countryCode,
|
|
19609
|
-
subdivisionCode
|
|
19610
|
-
],
|
|
19611
|
-
queryFn: () => getDefaultOnrampToken(
|
|
19612
|
-
{
|
|
19613
|
-
token_address: tokenAddress,
|
|
19614
|
-
chain_id: chainId,
|
|
19615
|
-
chain_type: chainType,
|
|
19616
|
-
country_code: countryCode,
|
|
19617
|
-
subdivision_code: subdivisionCode
|
|
19618
|
-
},
|
|
19619
|
-
publishableKey
|
|
19620
|
-
),
|
|
19621
|
-
enabled: enabled && !!tokenAddress && !!chainId && !!chainType,
|
|
19622
|
-
staleTime: 1e3 * 60 * 60,
|
|
19623
|
-
refetchOnMount: false,
|
|
19624
|
-
refetchOnWindowFocus: false
|
|
19625
|
-
});
|
|
19626
|
-
return { defaultToken, isLoading };
|
|
19627
|
-
}
|
|
19628
20128
|
function useBankTransferProviders({
|
|
19629
20129
|
publishableKey,
|
|
19630
20130
|
enabled = true,
|
|
@@ -19672,19 +20172,19 @@ function BankTransfer({
|
|
|
19672
20172
|
onDepositError
|
|
19673
20173
|
}) {
|
|
19674
20174
|
const { colors: colors2, fonts, components } = useTheme();
|
|
19675
|
-
const [internalView, setInternalView] = (0,
|
|
19676
|
-
const [sessionError, setSessionError] = (0,
|
|
19677
|
-
const [hoveredId, setHoveredId] = (0,
|
|
19678
|
-
const [activeProvider, setActiveProvider] = (0,
|
|
19679
|
-
const [requestBase, setRequestBase] = (0,
|
|
19680
|
-
const [activeRequest, setActiveRequest] = (0,
|
|
19681
|
-
const [amount, setAmount] = (0,
|
|
20175
|
+
const [internalView, setInternalView] = (0, import_react23.useState)("providers");
|
|
20176
|
+
const [sessionError, setSessionError] = (0, import_react23.useState)(null);
|
|
20177
|
+
const [hoveredId, setHoveredId] = (0, import_react23.useState)(null);
|
|
20178
|
+
const [activeProvider, setActiveProvider] = (0, import_react23.useState)(null);
|
|
20179
|
+
const [requestBase, setRequestBase] = (0, import_react23.useState)(null);
|
|
20180
|
+
const [activeRequest, setActiveRequest] = (0, import_react23.useState)(null);
|
|
20181
|
+
const [amount, setAmount] = (0, import_react23.useState)("");
|
|
19682
20182
|
const currentView = externalView ?? internalView;
|
|
19683
20183
|
const setView = (v) => {
|
|
19684
20184
|
setInternalView(v);
|
|
19685
20185
|
onViewChange?.(v);
|
|
19686
20186
|
};
|
|
19687
|
-
(0,
|
|
20187
|
+
(0, import_react23.useEffect)(() => {
|
|
19688
20188
|
if (externalView) setInternalView(externalView);
|
|
19689
20189
|
}, [externalView]);
|
|
19690
20190
|
const { userIpInfo } = useUserIp2();
|
|
@@ -19703,7 +20203,7 @@ function BankTransfer({
|
|
|
19703
20203
|
countryCode: userIpInfo?.alpha2
|
|
19704
20204
|
});
|
|
19705
20205
|
const providers = providersResponse?.data ?? [];
|
|
19706
|
-
const pollingWalletId = (0,
|
|
20206
|
+
const pollingWalletId = (0, import_react23.useMemo)(() => {
|
|
19707
20207
|
if (!defaultToken) return void 0;
|
|
19708
20208
|
return getWalletByChainType(
|
|
19709
20209
|
wallets,
|
|
@@ -19724,7 +20224,7 @@ function BankTransfer({
|
|
|
19724
20224
|
const currencySymbol = getCurrencySymbol2(sourceCurrency);
|
|
19725
20225
|
const parsedAmount = parseFloat(amount);
|
|
19726
20226
|
const amountValid = !!amount && Number.isFinite(parsedAmount) && parsedAmount >= MIN_AMOUNT;
|
|
19727
|
-
const displayTokenSymbol = (0,
|
|
20227
|
+
const displayTokenSymbol = (0, import_react23.useMemo)(
|
|
19728
20228
|
() => destinationTokenSymbol?.toUpperCase() ?? defaultToken?.destination_token_metadata?.symbol?.toUpperCase() ?? defaultToken?.destination_currency?.toUpperCase() ?? "USDC",
|
|
19729
20229
|
[destinationTokenSymbol, defaultToken]
|
|
19730
20230
|
);
|
|
@@ -23699,16 +24199,114 @@ function AmexIcon({ size: size4 = 24 }) {
|
|
|
23699
24199
|
)
|
|
23700
24200
|
] });
|
|
23701
24201
|
}
|
|
24202
|
+
function ApplePayIcon({ size: size4 = 24, color = "#000" }) {
|
|
24203
|
+
const h = size4 * 0.62;
|
|
24204
|
+
const w = h * (512 / 210.2);
|
|
24205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("svg", { width: w, height: h, viewBox: "0 0 512 210.2", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
24206
|
+
"path",
|
|
24207
|
+
{
|
|
24208
|
+
fill: color,
|
|
24209
|
+
d: "M93.6,27.1C87.6,34.2,78,39.8,68.4,39c-1.2-9.6,3.5-19.8,9-26.1c6-7.3,16.5-12.5,25-12.9 C103.4,10,99.5,19.8,93.6,27.1 M102.3,40.9c-13.9-0.8-25.8,7.9-32.4,7.9c-6.7,0-16.8-7.5-27.8-7.3c-14.3,0.2-27.6,8.3-34.9,21.2 c-15,25.8-3.9,64,10.6,85c7.1,10.4,15.6,21.8,26.8,21.4c10.6-0.4,14.8-6.9,27.6-6.9c12.9,0,16.6,6.9,27.8,6.7 c11.6-0.2,18.9-10.4,26-20.8c8.1-11.8,11.4-23.3,11.6-23.9c-0.2-0.2-22.4-8.7-22.6-34.3c-0.2-21.4,17.5-31.6,18.3-32.2 C123.3,42.9,107.7,41.3,102.3,40.9 M182.6,11.9v155.9h24.2v-53.3h33.5c30.6,0,52.1-21,52.1-51.4c0-30.4-21.1-51.2-51.3-51.2H182.6z M206.8,32.3h27.9c21,0,33,11.2,33,30.9c0,19.7-12,31-33.1,31h-27.8V32.3z M336.6,169c15.2,0,29.3-7.7,35.7-19.9h0.5v18.7h22.4V90.2 c0-22.5-18-37-45.7-37c-25.7,0-44.7,14.7-45.4,34.9h21.8c1.8-9.6,10.7-15.9,22.9-15.9c14.8,0,23.1,6.9,23.1,19.6v8.6l-30.2,1.8 c-28.1,1.7-43.3,13.2-43.3,33.2C298.4,155.6,314.1,169,336.6,169z M343.1,150.5c-12.9,0-21.1-6.2-21.1-15.7c0-9.8,7.9-15.5,23-16.4 l26.9-1.7v8.8C371.9,140.1,359.5,150.5,343.1,150.5z M425.1,210.2c23.6,0,34.7-9,44.4-36.3L512,54.7h-24.6l-28.5,92.1h-0.5 l-28.5-92.1h-25.3l41,113.5l-2.2,6.9c-3.7,11.7-9.7,16.2-20.4,16.2c-1.9,0-5.6-0.2-7.1-0.4v18.7C417.3,210,423.3,210.2,425.1,210.2z"
|
|
24210
|
+
}
|
|
24211
|
+
) });
|
|
24212
|
+
}
|
|
24213
|
+
function GooglePayIcon({ size: size4 = 24, color = "#202124" }) {
|
|
24214
|
+
const h = size4 * 0.62;
|
|
24215
|
+
const w = h * (80 / 38.1);
|
|
24216
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("svg", { width: w, height: h, viewBox: "0 0 80 38.1", fill: "none", children: [
|
|
24217
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
24218
|
+
"path",
|
|
24219
|
+
{
|
|
24220
|
+
fill: color,
|
|
24221
|
+
d: "M37.8,19.7V29h-3V6h7.8c1.9,0,3.7,0.7,5.1,2c1.4,1.2,2.1,3,2.1,4.9c0,1.9-0.7,3.6-2.1,4.9c-1.4,1.3-3.1,2-5.1,2 L37.8,19.7L37.8,19.7z M37.8,8.8v8h5c1.1,0,2.2-0.4,2.9-1.2c1.6-1.5,1.6-4,0.1-5.5c0,0-0.1-0.1-0.1-0.1c-0.8-0.8-1.8-1.3-2.9-1.2 L37.8,8.8L37.8,8.8z"
|
|
24222
|
+
}
|
|
24223
|
+
),
|
|
24224
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
24225
|
+
"path",
|
|
24226
|
+
{
|
|
24227
|
+
fill: color,
|
|
24228
|
+
d: "M56.7,12.8c2.2,0,3.9,0.6,5.2,1.8s1.9,2.8,1.9,4.8V29H61v-2.2h-0.1c-1.2,1.8-2.9,2.7-4.9,2.7 c-1.7,0-3.2-0.5-4.4-1.5c-1.1-1-1.8-2.4-1.8-3.9c0-1.6,0.6-2.9,1.8-3.9c1.2-1,2.9-1.4,4.9-1.4c1.8,0,3.2,0.3,4.3,1v-0.7 c0-1-0.4-2-1.2-2.6c-0.8-0.7-1.8-1.1-2.9-1.1c-1.7,0-3,0.7-3.9,2.1l-2.6-1.6C51.8,13.8,53.9,12.8,56.7,12.8z M52.9,24.2 c0,0.8,0.4,1.5,1,1.9c0.7,0.5,1.5,0.8,2.3,0.8c1.2,0,2.4-0.5,3.3-1.4c1-0.9,1.5-2,1.5-3.2c-0.9-0.7-2.2-1.1-3.9-1.1 c-1.2,0-2.2,0.3-3,0.9C53.3,22.6,52.9,23.3,52.9,24.2z"
|
|
24229
|
+
}
|
|
24230
|
+
),
|
|
24231
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
24232
|
+
"path",
|
|
24233
|
+
{
|
|
24234
|
+
fill: color,
|
|
24235
|
+
d: "M80,13.3l-9.9,22.7h-3l3.7-7.9l-6.5-14.7h3.2l4.7,11.3h0.1l4.6-11.3H80z"
|
|
24236
|
+
}
|
|
24237
|
+
),
|
|
24238
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
24239
|
+
"path",
|
|
24240
|
+
{
|
|
24241
|
+
fill: "#4285F4",
|
|
24242
|
+
d: "M25.9,17.7c0-0.9-0.1-1.8-0.2-2.7H13.2v5.1h7.1c-0.3,1.6-1.2,3.1-2.6,4v3.3H22C24.5,25.1,25.9,21.7,25.9,17.7z"
|
|
24243
|
+
}
|
|
24244
|
+
),
|
|
24245
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
24246
|
+
"path",
|
|
24247
|
+
{
|
|
24248
|
+
fill: "#34A853",
|
|
24249
|
+
d: "M13.2,30.6c3.6,0,6.6-1.2,8.8-3.2l-4.3-3.3c-1.2,0.8-2.7,1.3-4.5,1.3c-3.4,0-6.4-2.3-7.4-5.5H1.4v3.4 C3.7,27.8,8.2,30.6,13.2,30.6z"
|
|
24250
|
+
}
|
|
24251
|
+
),
|
|
24252
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
24253
|
+
"path",
|
|
24254
|
+
{
|
|
24255
|
+
fill: "#FBBC04",
|
|
24256
|
+
d: "M5.8,19.9c-0.6-1.6-0.6-3.4,0-5.1v-3.4H1.4c-1.9,3.7-1.9,8.1,0,11.9L5.8,19.9z"
|
|
24257
|
+
}
|
|
24258
|
+
),
|
|
24259
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
24260
|
+
"path",
|
|
24261
|
+
{
|
|
24262
|
+
fill: "#EA4335",
|
|
24263
|
+
d: "M13.2,9.4c1.9,0,3.7,0.7,5.1,2l0,0l3.8-3.8c-2.4-2.2-5.6-3.5-8.8-3.4c-5,0-9.6,2.8-11.8,7.3l4.4,3.4 C6.8,11.7,9.8,9.4,13.2,9.4z"
|
|
24264
|
+
}
|
|
24265
|
+
)
|
|
24266
|
+
] });
|
|
24267
|
+
}
|
|
23702
24268
|
function GenericCardIcon({ size: size4 = 24, color = "#888" }) {
|
|
23703
24269
|
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(CreditCard, { width: size4 * 0.8, height: size4 * 0.8, style: { color }, strokeWidth: 1.5 });
|
|
23704
24270
|
}
|
|
24271
|
+
function parseColor(input) {
|
|
24272
|
+
if (!input) return null;
|
|
24273
|
+
const s = input.trim();
|
|
24274
|
+
if (s.startsWith("#")) {
|
|
24275
|
+
let hex = s.slice(1);
|
|
24276
|
+
if (hex.length === 3)
|
|
24277
|
+
hex = hex.split("").map((c) => c + c).join("");
|
|
24278
|
+
if (hex.length !== 6) return null;
|
|
24279
|
+
const n = parseInt(hex, 16);
|
|
24280
|
+
if (Number.isNaN(n)) return null;
|
|
24281
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
24282
|
+
}
|
|
24283
|
+
const m = s.match(/rgba?\(([^)]+)\)/i);
|
|
24284
|
+
if (m) {
|
|
24285
|
+
const parts = m[1].split(",").map((p) => parseFloat(p));
|
|
24286
|
+
if (parts.length >= 3 && parts.every((p) => !Number.isNaN(p)))
|
|
24287
|
+
return [parts[0], parts[1], parts[2]];
|
|
24288
|
+
}
|
|
24289
|
+
return null;
|
|
24290
|
+
}
|
|
24291
|
+
function monochromeOn(background) {
|
|
24292
|
+
const rgb = parseColor(background);
|
|
24293
|
+
if (!rgb) return "#000000";
|
|
24294
|
+
const [r2, g, b] = rgb;
|
|
24295
|
+
const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
|
|
24296
|
+
return luminance > 0.6 ? "#000000" : "#FFFFFF";
|
|
24297
|
+
}
|
|
23705
24298
|
function CardBrandIcon({
|
|
23706
24299
|
brand,
|
|
23707
24300
|
size: size4 = 24,
|
|
23708
|
-
fallbackColor = "#888"
|
|
24301
|
+
fallbackColor = "#888",
|
|
24302
|
+
monochromeColor = "#000000"
|
|
23709
24303
|
}) {
|
|
23710
24304
|
if (!brand) return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(GenericCardIcon, { size: size4, color: fallbackColor });
|
|
23711
24305
|
const lower = brand.toLowerCase();
|
|
24306
|
+
if (lower.includes("apple_pay") || lower.includes("apple pay") || lower === "applepay")
|
|
24307
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(ApplePayIcon, { size: size4, color: monochromeColor });
|
|
24308
|
+
if (lower.includes("google_pay") || lower.includes("google pay") || lower === "googlepay")
|
|
24309
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(GooglePayIcon, { size: size4, color: monochromeColor === "#FFFFFF" ? "#FFFFFF" : "#202124" });
|
|
23712
24310
|
if (lower.includes("visa")) return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(VisaIcon, { size: size4 });
|
|
23713
24311
|
if (lower.includes("mastercard") || lower.includes("master"))
|
|
23714
24312
|
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(MastercardIcon, { size: size4 });
|
|
@@ -23717,17 +24315,28 @@ function CardBrandIcon({
|
|
|
23717
24315
|
}
|
|
23718
24316
|
function formatPaymentToken(token) {
|
|
23719
24317
|
if (token.card) {
|
|
23720
|
-
const
|
|
24318
|
+
const cardBrand = token.card.brand ?? "Card";
|
|
24319
|
+
const last4 = token.card.last4;
|
|
24320
|
+
const walletType = token.card.wallet?.type;
|
|
24321
|
+
if (walletType === "apple_pay" || walletType === "google_pay") {
|
|
24322
|
+
const funding = token.card.funding ? capitalize(token.card.funding) : null;
|
|
24323
|
+
return {
|
|
24324
|
+
label: last4 ? `${capitalize(cardBrand)} \u2022\u2022\u2022\u2022 ${last4}` : capitalize(cardBrand),
|
|
24325
|
+
sublabel: funding ?? "",
|
|
24326
|
+
brand: walletType
|
|
24327
|
+
};
|
|
24328
|
+
}
|
|
23721
24329
|
return {
|
|
23722
|
-
label: `${capitalize(
|
|
24330
|
+
label: `${capitalize(cardBrand)} \u2022\u2022\u2022\u2022 ${last4}`,
|
|
23723
24331
|
sublabel: `${capitalize(token.card.funding ?? "card")} \xB7 Expires ${token.card.exp_month}/${token.card.exp_year}`,
|
|
23724
|
-
brand
|
|
24332
|
+
brand: cardBrand
|
|
23725
24333
|
};
|
|
23726
24334
|
}
|
|
23727
24335
|
if (token.us_bank_account) {
|
|
24336
|
+
const accountType = token.us_bank_account.account_type;
|
|
23728
24337
|
return {
|
|
23729
24338
|
label: `${token.us_bank_account.bank_name ?? "Bank"} \u2022\u2022\u2022\u2022 ${token.us_bank_account.last4}`,
|
|
23730
|
-
sublabel: "Bank account"
|
|
24339
|
+
sublabel: accountType ? `${capitalize(accountType)} account` : "Bank account"
|
|
23731
24340
|
};
|
|
23732
24341
|
}
|
|
23733
24342
|
return { label: "Payment method", sublabel: token.type };
|
|
@@ -23735,59 +24344,82 @@ function formatPaymentToken(token) {
|
|
|
23735
24344
|
function capitalize(s) {
|
|
23736
24345
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
23737
24346
|
}
|
|
23738
|
-
function useStripeOnramp(stripePublishableKey) {
|
|
23739
|
-
const [coordinator, setCoordinator] = (0,
|
|
23740
|
-
const [isLoading, setIsLoading] = (0,
|
|
23741
|
-
const [error, setError] = (0,
|
|
23742
|
-
const coordinatorRef = (0,
|
|
23743
|
-
const
|
|
23744
|
-
|
|
23745
|
-
|
|
23746
|
-
|
|
23747
|
-
|
|
23748
|
-
|
|
23749
|
-
|
|
23750
|
-
|
|
23751
|
-
|
|
23752
|
-
|
|
23753
|
-
);
|
|
23754
|
-
|
|
23755
|
-
|
|
23756
|
-
|
|
23757
|
-
|
|
23758
|
-
|
|
23759
|
-
|
|
23760
|
-
|
|
23761
|
-
|
|
23762
|
-
|
|
23763
|
-
|
|
23764
|
-
|
|
23765
|
-
|
|
23766
|
-
|
|
23767
|
-
)
|
|
23768
|
-
|
|
23769
|
-
|
|
23770
|
-
|
|
23771
|
-
|
|
23772
|
-
|
|
23773
|
-
|
|
23774
|
-
|
|
23775
|
-
|
|
23776
|
-
|
|
23777
|
-
|
|
23778
|
-
|
|
23779
|
-
|
|
23780
|
-
|
|
23781
|
-
|
|
23782
|
-
|
|
23783
|
-
|
|
23784
|
-
|
|
23785
|
-
|
|
24347
|
+
function useStripeOnramp(stripePublishableKey, isDark = false) {
|
|
24348
|
+
const [coordinator, setCoordinator] = (0, import_react25.useState)(null);
|
|
24349
|
+
const [isLoading, setIsLoading] = (0, import_react25.useState)(false);
|
|
24350
|
+
const [error, setError] = (0, import_react25.useState)(null);
|
|
24351
|
+
const coordinatorRef = (0, import_react25.useRef)(null);
|
|
24352
|
+
const coordinatorThemeRef = (0, import_react25.useRef)(null);
|
|
24353
|
+
const initPromiseRef = (0, import_react25.useRef)(null);
|
|
24354
|
+
const isDarkRef = (0, import_react25.useRef)(isDark);
|
|
24355
|
+
isDarkRef.current = isDark;
|
|
24356
|
+
const initialize = (0, import_react25.useCallback)(() => {
|
|
24357
|
+
if (coordinatorRef.current) return Promise.resolve(coordinatorRef.current);
|
|
24358
|
+
if (initPromiseRef.current) return initPromiseRef.current;
|
|
24359
|
+
if (!stripePublishableKey) return Promise.resolve(null);
|
|
24360
|
+
const theme = isDarkRef.current;
|
|
24361
|
+
const promise = (async () => {
|
|
24362
|
+
setIsLoading(true);
|
|
24363
|
+
setError(null);
|
|
24364
|
+
try {
|
|
24365
|
+
console.log("[PayWithStripeLink] Importing @stripe/crypto...");
|
|
24366
|
+
const { loadCryptoOnrampAndInitialize } = await import(
|
|
24367
|
+
/* @vite-ignore */
|
|
24368
|
+
"@stripe/crypto"
|
|
24369
|
+
);
|
|
24370
|
+
console.log(
|
|
24371
|
+
"[PayWithStripeLink] @stripe/crypto imported, initializing with key:",
|
|
24372
|
+
stripePublishableKey?.slice(0, 12) + "..."
|
|
24373
|
+
);
|
|
24374
|
+
const initPromise = loadCryptoOnrampAndInitialize(stripePublishableKey, {
|
|
24375
|
+
theme: theme ? "night" : "stripe"
|
|
24376
|
+
});
|
|
24377
|
+
const timeoutPromise = new Promise(
|
|
24378
|
+
(_, reject) => setTimeout(
|
|
24379
|
+
() => reject(
|
|
24380
|
+
new Error(
|
|
24381
|
+
"Stripe SDK initialization timed out after 15 seconds. Check that your Stripe account has the Crypto Onramp feature enabled."
|
|
24382
|
+
)
|
|
24383
|
+
),
|
|
24384
|
+
15e3
|
|
24385
|
+
)
|
|
24386
|
+
);
|
|
24387
|
+
const instance = await Promise.race([initPromise, timeoutPromise]);
|
|
24388
|
+
if (!instance) {
|
|
24389
|
+
throw new Error("Stripe SDK returned null.");
|
|
24390
|
+
}
|
|
24391
|
+
console.log("[PayWithStripeLink] Stripe SDK initialized successfully");
|
|
24392
|
+
coordinatorRef.current = instance;
|
|
24393
|
+
coordinatorThemeRef.current = theme;
|
|
24394
|
+
setCoordinator(instance);
|
|
24395
|
+
return coordinatorRef.current;
|
|
24396
|
+
} catch (err) {
|
|
24397
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
24398
|
+
const msg = raw.includes("Cannot find module") || raw.includes("Module not found") || raw.includes("Failed to fetch") ? "Install @stripe/crypto to use Stripe Link: npm install @stripe/crypto" : `Failed to initialize Stripe SDK: ${raw}`;
|
|
24399
|
+
setError(msg);
|
|
24400
|
+
console.error("[PayWithStripeLink]", msg);
|
|
24401
|
+
return null;
|
|
24402
|
+
} finally {
|
|
24403
|
+
setIsLoading(false);
|
|
24404
|
+
initPromiseRef.current = null;
|
|
24405
|
+
}
|
|
24406
|
+
})();
|
|
24407
|
+
initPromiseRef.current = promise;
|
|
24408
|
+
return promise;
|
|
23786
24409
|
}, [stripePublishableKey]);
|
|
23787
|
-
(0,
|
|
24410
|
+
(0, import_react25.useEffect)(() => {
|
|
24411
|
+
if (!coordinatorRef.current) return;
|
|
24412
|
+
if (coordinatorThemeRef.current === isDark) return;
|
|
24413
|
+
coordinatorRef.current.destroy();
|
|
24414
|
+
coordinatorRef.current = null;
|
|
24415
|
+
coordinatorThemeRef.current = null;
|
|
24416
|
+
setCoordinator(null);
|
|
24417
|
+
}, [isDark, coordinator]);
|
|
24418
|
+
(0, import_react25.useEffect)(() => {
|
|
23788
24419
|
return () => {
|
|
23789
24420
|
coordinatorRef.current?.destroy();
|
|
23790
24421
|
coordinatorRef.current = null;
|
|
24422
|
+
coordinatorThemeRef.current = null;
|
|
23791
24423
|
};
|
|
23792
24424
|
}, []);
|
|
23793
24425
|
return { coordinator, isLoading, error, initialize };
|
|
@@ -23938,21 +24570,23 @@ function PayWithStripeLink({
|
|
|
23938
24570
|
onDepositSuccess,
|
|
23939
24571
|
onDepositError
|
|
23940
24572
|
}) {
|
|
23941
|
-
const { colors: colors2, fonts, components } = useTheme();
|
|
23942
|
-
const [step, setStepInternal] = (0,
|
|
23943
|
-
const setStep = (0,
|
|
24573
|
+
const { colors: colors2, fonts, components, isDark } = useTheme();
|
|
24574
|
+
const [step, setStepInternal] = (0, import_react24.useState)(controlledStep ?? "amount");
|
|
24575
|
+
const setStep = (0, import_react24.useCallback)(
|
|
23944
24576
|
(s) => {
|
|
23945
24577
|
setStepInternal(s);
|
|
23946
24578
|
onStepChange?.(s);
|
|
23947
24579
|
},
|
|
23948
24580
|
[onStepChange]
|
|
23949
24581
|
);
|
|
23950
|
-
(0,
|
|
24582
|
+
const stepRef = (0, import_react24.useRef)(step);
|
|
24583
|
+
stepRef.current = step;
|
|
24584
|
+
(0, import_react24.useEffect)(() => {
|
|
23951
24585
|
if (controlledStep && controlledStep !== step) {
|
|
23952
24586
|
setStepInternal(controlledStep);
|
|
23953
24587
|
}
|
|
23954
24588
|
}, [controlledStep]);
|
|
23955
|
-
(0,
|
|
24589
|
+
(0, import_react24.useEffect)(() => {
|
|
23956
24590
|
setLoading(false);
|
|
23957
24591
|
setError(null);
|
|
23958
24592
|
setKycPendingMessage(null);
|
|
@@ -23961,9 +24595,9 @@ function PayWithStripeLink({
|
|
|
23961
24595
|
checkoutGenRef.current++;
|
|
23962
24596
|
}
|
|
23963
24597
|
}, [step]);
|
|
23964
|
-
const [resolvedStripeKey, setResolvedStripeKey] = (0,
|
|
23965
|
-
const [configError, setConfigError] = (0,
|
|
23966
|
-
(0,
|
|
24598
|
+
const [resolvedStripeKey, setResolvedStripeKey] = (0, import_react24.useState)();
|
|
24599
|
+
const [configError, setConfigError] = (0, import_react24.useState)(null);
|
|
24600
|
+
(0, import_react24.useEffect)(() => {
|
|
23967
24601
|
let active = true;
|
|
23968
24602
|
const fetchConfig = async () => {
|
|
23969
24603
|
try {
|
|
@@ -23986,7 +24620,7 @@ function PayWithStripeLink({
|
|
|
23986
24620
|
active = false;
|
|
23987
24621
|
};
|
|
23988
24622
|
}, [publishableKey]);
|
|
23989
|
-
(0,
|
|
24623
|
+
(0, import_react24.useEffect)(() => {
|
|
23990
24624
|
if (step !== "auth" || resolvedStripeKey || configError) return;
|
|
23991
24625
|
let active = true;
|
|
23992
24626
|
const retryConfig = async () => {
|
|
@@ -24014,8 +24648,8 @@ function PayWithStripeLink({
|
|
|
24014
24648
|
isLoading: sdkLoading,
|
|
24015
24649
|
error: sdkError,
|
|
24016
24650
|
initialize
|
|
24017
|
-
} = useStripeOnramp(resolvedStripeKey);
|
|
24018
|
-
(0,
|
|
24651
|
+
} = useStripeOnramp(resolvedStripeKey, isDark);
|
|
24652
|
+
(0, import_react24.useEffect)(() => {
|
|
24019
24653
|
if (step === "auth") {
|
|
24020
24654
|
console.log("[PayWithStripeLink] Auth step state:", {
|
|
24021
24655
|
resolvedStripeKey: resolvedStripeKey ? resolvedStripeKey.slice(0, 15) + "..." : void 0,
|
|
@@ -24026,27 +24660,30 @@ function PayWithStripeLink({
|
|
|
24026
24660
|
});
|
|
24027
24661
|
}
|
|
24028
24662
|
}, [step, resolvedStripeKey, coordinator, sdkLoading, sdkError, configError]);
|
|
24029
|
-
const [email, setEmail] = (0,
|
|
24030
|
-
const [phone, setPhone] = (0,
|
|
24031
|
-
const [country, setCountry] = (0,
|
|
24032
|
-
const [loading, setLoading] = (0,
|
|
24033
|
-
const [error, setError] = (0,
|
|
24034
|
-
const [kycPendingMessage, setKycPendingMessage] = (0,
|
|
24035
|
-
const [kycRejectionReason, setKycRejectionReason] = (0,
|
|
24036
|
-
const [restoring, setRestoring] = (0,
|
|
24037
|
-
const [errorReturnStep, setErrorReturnStep] = (0,
|
|
24038
|
-
const [authIntentId, setAuthIntentId] = (0,
|
|
24039
|
-
const sdkAuthenticatedRef = (0,
|
|
24040
|
-
const
|
|
24041
|
-
const
|
|
24042
|
-
const
|
|
24043
|
-
const
|
|
24044
|
-
const
|
|
24045
|
-
const
|
|
24046
|
-
const [
|
|
24047
|
-
const
|
|
24048
|
-
const
|
|
24049
|
-
const
|
|
24663
|
+
const [email, setEmail] = (0, import_react24.useState)(emailProp ?? "");
|
|
24664
|
+
const [phone, setPhone] = (0, import_react24.useState)("");
|
|
24665
|
+
const [country, setCountry] = (0, import_react24.useState)("US");
|
|
24666
|
+
const [loading, setLoading] = (0, import_react24.useState)(false);
|
|
24667
|
+
const [error, setError] = (0, import_react24.useState)(null);
|
|
24668
|
+
const [kycPendingMessage, setKycPendingMessage] = (0, import_react24.useState)(null);
|
|
24669
|
+
const [kycRejectionReason, setKycRejectionReason] = (0, import_react24.useState)(null);
|
|
24670
|
+
const [restoring, setRestoring] = (0, import_react24.useState)(true);
|
|
24671
|
+
const [errorReturnStep, setErrorReturnStep] = (0, import_react24.useState)("email");
|
|
24672
|
+
const [authIntentId, setAuthIntentId] = (0, import_react24.useState)(null);
|
|
24673
|
+
const sdkAuthenticatedRef = (0, import_react24.useRef)(false);
|
|
24674
|
+
const everAuthenticatedRef = (0, import_react24.useRef)(false);
|
|
24675
|
+
const reauthReturnStepRef = (0, import_react24.useRef)(null);
|
|
24676
|
+
const attemptedWalletReauthRef = (0, import_react24.useRef)(false);
|
|
24677
|
+
const pendingAddPaymentRef = (0, import_react24.useRef)(false);
|
|
24678
|
+
const autoOpenedAddPaymentRef = (0, import_react24.useRef)(false);
|
|
24679
|
+
const checkoutGenRef = (0, import_react24.useRef)(0);
|
|
24680
|
+
const [stripePaymentUIReady, setStripePaymentUIReady] = (0, import_react24.useState)(false);
|
|
24681
|
+
const [oauthToken, setOauthToken] = (0, import_react24.useState)(null);
|
|
24682
|
+
const [refreshTokenValue, setRefreshTokenValue] = (0, import_react24.useState)(null);
|
|
24683
|
+
const [customerId, setCustomerId] = (0, import_react24.useState)(null);
|
|
24684
|
+
const accessTokenRef = (0, import_react24.useRef)("");
|
|
24685
|
+
const refreshTokenRef = (0, import_react24.useRef)("");
|
|
24686
|
+
const persistSession = (0, import_react24.useCallback)(
|
|
24050
24687
|
(cid, token, refresh, expiresIn, loginEmail) => {
|
|
24051
24688
|
accessTokenRef.current = token;
|
|
24052
24689
|
refreshTokenRef.current = refresh;
|
|
@@ -24060,8 +24697,8 @@ function PayWithStripeLink({
|
|
|
24060
24697
|
},
|
|
24061
24698
|
[userId, email]
|
|
24062
24699
|
);
|
|
24063
|
-
const refreshInFlightRef = (0,
|
|
24064
|
-
const tryRefreshToken = (0,
|
|
24700
|
+
const refreshInFlightRef = (0, import_react24.useRef)(null);
|
|
24701
|
+
const tryRefreshToken = (0, import_react24.useCallback)(async () => {
|
|
24065
24702
|
if (refreshInFlightRef.current) return refreshInFlightRef.current;
|
|
24066
24703
|
const rt = refreshTokenRef.current;
|
|
24067
24704
|
if (!rt) return null;
|
|
@@ -24091,7 +24728,7 @@ function PayWithStripeLink({
|
|
|
24091
24728
|
refreshInFlightRef.current = doRefresh();
|
|
24092
24729
|
return refreshInFlightRef.current;
|
|
24093
24730
|
}, [publishableKey, customerId, persistSession, userId]);
|
|
24094
|
-
const withTokenRefresh = (0,
|
|
24731
|
+
const withTokenRefresh = (0, import_react24.useCallback)(
|
|
24095
24732
|
async (fn) => {
|
|
24096
24733
|
const token = accessTokenRef.current;
|
|
24097
24734
|
if (!token) {
|
|
@@ -24119,7 +24756,7 @@ function PayWithStripeLink({
|
|
|
24119
24756
|
},
|
|
24120
24757
|
[tryRefreshToken, setStep]
|
|
24121
24758
|
);
|
|
24122
|
-
(0,
|
|
24759
|
+
(0, import_react24.useEffect)(() => {
|
|
24123
24760
|
const stored = getStoredStripeSession(userId);
|
|
24124
24761
|
console.log("[PayWithStripeLink] Restore check:", {
|
|
24125
24762
|
hasStored: !!stored,
|
|
@@ -24210,9 +24847,9 @@ function PayWithStripeLink({
|
|
|
24210
24847
|
cancelled = true;
|
|
24211
24848
|
};
|
|
24212
24849
|
}, [userId, publishableKey]);
|
|
24213
|
-
const [customer, setCustomer] = (0,
|
|
24214
|
-
const [kycFormMode, setKycFormMode] = (0,
|
|
24215
|
-
const [kycForm, setKycForm] = (0,
|
|
24850
|
+
const [customer, setCustomer] = (0, import_react24.useState)(null);
|
|
24851
|
+
const [kycFormMode, setKycFormMode] = (0, import_react24.useState)("name");
|
|
24852
|
+
const [kycForm, setKycForm] = (0, import_react24.useState)({
|
|
24216
24853
|
givenName: "",
|
|
24217
24854
|
surname: "",
|
|
24218
24855
|
dob: { day: "", month: "", year: "" },
|
|
@@ -24224,7 +24861,7 @@ function PayWithStripeLink({
|
|
|
24224
24861
|
addressPostalCode: "",
|
|
24225
24862
|
addressCountry: "US"
|
|
24226
24863
|
});
|
|
24227
|
-
(0,
|
|
24864
|
+
(0, import_react24.useEffect)(() => {
|
|
24228
24865
|
if (!backHandlerRef) return;
|
|
24229
24866
|
backHandlerRef.current = () => {
|
|
24230
24867
|
if (step === "kyc_form" && kycFormMode === "address") {
|
|
@@ -24235,6 +24872,7 @@ function PayWithStripeLink({
|
|
|
24235
24872
|
if (step === "auth" && (pendingAddPaymentRef.current || !!accessTokenRef.current)) {
|
|
24236
24873
|
pendingAddPaymentRef.current = false;
|
|
24237
24874
|
autoOpenedAddPaymentRef.current = false;
|
|
24875
|
+
reauthReturnStepRef.current = null;
|
|
24238
24876
|
setError(null);
|
|
24239
24877
|
setStep("amount");
|
|
24240
24878
|
return true;
|
|
@@ -24245,24 +24883,41 @@ function PayWithStripeLink({
|
|
|
24245
24883
|
backHandlerRef.current = null;
|
|
24246
24884
|
};
|
|
24247
24885
|
}, [backHandlerRef, step, kycFormMode]);
|
|
24248
|
-
const [wallets, setWallets] = (0,
|
|
24249
|
-
const [paymentTokens, setPaymentTokens] = (0,
|
|
24250
|
-
const [storedSelectedToken, setStoredSelectedTokenState] = (0,
|
|
24886
|
+
const [wallets, setWallets] = (0, import_react24.useState)([]);
|
|
24887
|
+
const [paymentTokens, setPaymentTokens] = (0, import_react24.useState)([]);
|
|
24888
|
+
const [storedSelectedToken, setStoredSelectedTokenState] = (0, import_react24.useState)(
|
|
24251
24889
|
null
|
|
24252
24890
|
);
|
|
24253
|
-
const [selectedPaymentToken, setSelectedPaymentToken] = (0,
|
|
24254
|
-
const [paymentDisplay, setPaymentDisplay] = (0,
|
|
24255
|
-
const
|
|
24891
|
+
const [selectedPaymentToken, setSelectedPaymentToken] = (0, import_react24.useState)(null);
|
|
24892
|
+
const [paymentDisplay, setPaymentDisplay] = (0, import_react24.useState)(null);
|
|
24893
|
+
const selectedTokenSingleUseRef = (0, import_react24.useRef)(false);
|
|
24894
|
+
const selectPaymentToken = (0, import_react24.useCallback)(
|
|
24256
24895
|
(token) => {
|
|
24896
|
+
selectedTokenSingleUseRef.current = !!token.singleUse;
|
|
24257
24897
|
setSelectedPaymentToken(token.id);
|
|
24258
24898
|
setPaymentDisplay(
|
|
24259
24899
|
token.label ? { label: token.label, sublabel: token.sublabel, brand: token.brand } : null
|
|
24260
24900
|
);
|
|
24261
24901
|
setStoredSelectedTokenState(token);
|
|
24262
|
-
if (customerId) setStoredSelectedToken(customerId, token);
|
|
24902
|
+
if (customerId && !token.singleUse) setStoredSelectedToken(customerId, token);
|
|
24263
24903
|
},
|
|
24264
24904
|
[customerId]
|
|
24265
24905
|
);
|
|
24906
|
+
const clearSelectedPaymentToken = (0, import_react24.useCallback)(() => {
|
|
24907
|
+
selectedTokenSingleUseRef.current = false;
|
|
24908
|
+
const persisted = customerId ? getStoredSelectedToken(customerId) : null;
|
|
24909
|
+
if (persisted && !persisted.singleUse) {
|
|
24910
|
+
setSelectedPaymentToken(persisted.id);
|
|
24911
|
+
setPaymentDisplay(
|
|
24912
|
+
persisted.label ? { label: persisted.label, sublabel: persisted.sublabel, brand: persisted.brand } : null
|
|
24913
|
+
);
|
|
24914
|
+
setStoredSelectedTokenState(persisted);
|
|
24915
|
+
} else {
|
|
24916
|
+
setSelectedPaymentToken(null);
|
|
24917
|
+
setPaymentDisplay(null);
|
|
24918
|
+
setStoredSelectedTokenState(null);
|
|
24919
|
+
}
|
|
24920
|
+
}, [customerId]);
|
|
24266
24921
|
const displayPaymentTokens = (() => {
|
|
24267
24922
|
const apiDisplay = paymentTokens.map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) }));
|
|
24268
24923
|
if (storedSelectedToken && !paymentTokens.some((t13) => t13.id === storedSelectedToken.id)) {
|
|
@@ -24270,7 +24925,7 @@ function PayWithStripeLink({
|
|
|
24270
24925
|
}
|
|
24271
24926
|
return apiDisplay;
|
|
24272
24927
|
})();
|
|
24273
|
-
(0,
|
|
24928
|
+
(0, import_react24.useEffect)(() => {
|
|
24274
24929
|
if (!customerId) return;
|
|
24275
24930
|
const stored = getStoredSelectedToken(customerId);
|
|
24276
24931
|
if (stored) {
|
|
@@ -24281,19 +24936,19 @@ function PayWithStripeLink({
|
|
|
24281
24936
|
);
|
|
24282
24937
|
}
|
|
24283
24938
|
}, [customerId]);
|
|
24284
|
-
const [amount, setAmount] = (0,
|
|
24285
|
-
(0,
|
|
24939
|
+
const [amount, setAmount] = (0, import_react24.useState)("");
|
|
24940
|
+
(0, import_react24.useEffect)(() => {
|
|
24286
24941
|
console.log("[PayWithStripeLink] Component mounted/remounted. Amount:", amount, "Step:", step);
|
|
24287
24942
|
}, []);
|
|
24288
24943
|
const sourceCurrency = "usd";
|
|
24289
24944
|
const extractRefreshToken = (res) => res.refresh_token ?? res.refresh?.refresh_token ?? "";
|
|
24290
|
-
const [stripeDestCurrency, setStripeDestCurrency] = (0,
|
|
24291
|
-
const [stripeDestNetwork, setStripeDestNetwork] = (0,
|
|
24292
|
-
const [stripeDestChainType, setStripeDestChainType] = (0,
|
|
24293
|
-
const [stripeTokenSymbol, setStripeTokenSymbol] = (0,
|
|
24294
|
-
const [stripeTokenIconUrl, setStripeTokenIconUrl] = (0,
|
|
24295
|
-
const [stripeNetworkName, setStripeNetworkName] = (0,
|
|
24296
|
-
(0,
|
|
24945
|
+
const [stripeDestCurrency, setStripeDestCurrency] = (0, import_react24.useState)("usdc");
|
|
24946
|
+
const [stripeDestNetwork, setStripeDestNetwork] = (0, import_react24.useState)("base");
|
|
24947
|
+
const [stripeDestChainType, setStripeDestChainType] = (0, import_react24.useState)("ethereum");
|
|
24948
|
+
const [stripeTokenSymbol, setStripeTokenSymbol] = (0, import_react24.useState)("USDC");
|
|
24949
|
+
const [stripeTokenIconUrl, setStripeTokenIconUrl] = (0, import_react24.useState)(null);
|
|
24950
|
+
const [stripeNetworkName, setStripeNetworkName] = (0, import_react24.useState)("Base");
|
|
24951
|
+
(0, import_react24.useEffect)(() => {
|
|
24297
24952
|
if (!destinationTokenAddress || !destinationChainId || !destinationChainType) return;
|
|
24298
24953
|
let cancelled = false;
|
|
24299
24954
|
stripeGetDefaultToken(
|
|
@@ -24321,26 +24976,26 @@ function PayWithStripeLink({
|
|
|
24321
24976
|
};
|
|
24322
24977
|
}, [publishableKey, destinationTokenAddress, destinationChainId, destinationChainType]);
|
|
24323
24978
|
const destinationCurrency = stripeDestCurrency;
|
|
24324
|
-
const authInnerRef = (0,
|
|
24325
|
-
const paymentInnerRef = (0,
|
|
24326
|
-
const [authReady, setAuthReady] = (0,
|
|
24979
|
+
const authInnerRef = (0, import_react24.useRef)(null);
|
|
24980
|
+
const paymentInnerRef = (0, import_react24.useRef)(null);
|
|
24981
|
+
const [authReady, setAuthReady] = (0, import_react24.useState)(false);
|
|
24327
24982
|
if (typeof document !== "undefined" && !authInnerRef.current) {
|
|
24328
24983
|
authInnerRef.current = document.createElement("div");
|
|
24329
24984
|
}
|
|
24330
24985
|
if (typeof document !== "undefined" && !paymentInnerRef.current) {
|
|
24331
24986
|
paymentInnerRef.current = document.createElement("div");
|
|
24332
24987
|
}
|
|
24333
|
-
const authMountRef = (0,
|
|
24988
|
+
const authMountRef = (0, import_react24.useCallback)((node) => {
|
|
24334
24989
|
if (node && !node.contains(authInnerRef.current)) {
|
|
24335
24990
|
node.appendChild(authInnerRef.current);
|
|
24336
24991
|
}
|
|
24337
24992
|
}, []);
|
|
24338
|
-
const paymentMountRef = (0,
|
|
24993
|
+
const paymentMountRef = (0, import_react24.useCallback)((node) => {
|
|
24339
24994
|
if (node && !node.contains(paymentInnerRef.current)) {
|
|
24340
24995
|
node.appendChild(paymentInnerRef.current);
|
|
24341
24996
|
}
|
|
24342
24997
|
}, []);
|
|
24343
|
-
(0,
|
|
24998
|
+
(0, import_react24.useEffect)(() => {
|
|
24344
24999
|
return () => {
|
|
24345
25000
|
authInnerRef.current?.remove();
|
|
24346
25001
|
paymentInnerRef.current?.remove();
|
|
@@ -24358,10 +25013,10 @@ function PayWithStripeLink({
|
|
|
24358
25013
|
});
|
|
24359
25014
|
const depositWallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
24360
25015
|
const onrampWalletAddress = getWalletByChainType(depositWallets, stripeDestChainType)?.address;
|
|
24361
|
-
const [registeredWalletKey, setRegisteredWalletKey] = (0,
|
|
25016
|
+
const [registeredWalletKey, setRegisteredWalletKey] = (0, import_react24.useState)(null);
|
|
24362
25017
|
const walletKeyFor = (address) => `${stripeDestNetwork}:${stripeDestChainType === "ethereum" ? address.toLowerCase() : address}`;
|
|
24363
25018
|
const isOnrampWalletRegistered = !!onrampWalletAddress && registeredWalletKey === walletKeyFor(onrampWalletAddress);
|
|
24364
|
-
(0,
|
|
25019
|
+
(0, import_react24.useEffect)(() => {
|
|
24365
25020
|
if (depositWallets.length > 0 && !onrampWalletAddress) {
|
|
24366
25021
|
console.warn(
|
|
24367
25022
|
"[PayWithStripeLink] No deposit-intent wallet matches Stripe chain type",
|
|
@@ -24384,14 +25039,14 @@ function PayWithStripeLink({
|
|
|
24384
25039
|
onDepositSuccess,
|
|
24385
25040
|
onDepositError
|
|
24386
25041
|
});
|
|
24387
|
-
const [confirmedSessionId, setConfirmedSessionId] = (0,
|
|
24388
|
-
const [sessionStatus, setSessionStatus] = (0,
|
|
24389
|
-
const handledTerminalSessionRef = (0,
|
|
24390
|
-
const executionReconciledSessionRef = (0,
|
|
25042
|
+
const [confirmedSessionId, setConfirmedSessionId] = (0, import_react24.useState)(null);
|
|
25043
|
+
const [sessionStatus, setSessionStatus] = (0, import_react24.useState)(null);
|
|
25044
|
+
const handledTerminalSessionRef = (0, import_react24.useRef)(null);
|
|
25045
|
+
const executionReconciledSessionRef = (0, import_react24.useRef)(null);
|
|
24391
25046
|
const hasExecution = executions.length > 0;
|
|
24392
25047
|
const isSessionFulfilled = sessionStatus === STRIPE_SESSION_STATUS.FULFILLMENT_COMPLETE || hasExecution;
|
|
24393
25048
|
const isSessionFailed = !hasExecution && (sessionStatus === STRIPE_SESSION_STATUS.REJECTED || sessionStatus === STRIPE_SESSION_STATUS.EXPIRED);
|
|
24394
|
-
(0,
|
|
25049
|
+
(0, import_react24.useEffect)(() => {
|
|
24395
25050
|
if (step !== "success" || !hasExecution || !confirmedSessionId) return;
|
|
24396
25051
|
if (executionReconciledSessionRef.current === confirmedSessionId) return;
|
|
24397
25052
|
executionReconciledSessionRef.current = confirmedSessionId;
|
|
@@ -24409,7 +25064,7 @@ function PayWithStripeLink({
|
|
|
24409
25064
|
cancelled = true;
|
|
24410
25065
|
};
|
|
24411
25066
|
}, [step, hasExecution, confirmedSessionId, withTokenRefresh, publishableKey]);
|
|
24412
|
-
(0,
|
|
25067
|
+
(0, import_react24.useEffect)(() => {
|
|
24413
25068
|
if (step !== "success" || !confirmedSessionId) return;
|
|
24414
25069
|
if (hasExecution) return;
|
|
24415
25070
|
if (handledTerminalSessionRef.current === confirmedSessionId) return;
|
|
@@ -24496,12 +25151,16 @@ function PayWithStripeLink({
|
|
|
24496
25151
|
setLoading(false);
|
|
24497
25152
|
}
|
|
24498
25153
|
};
|
|
24499
|
-
(0,
|
|
25154
|
+
(0, import_react24.useEffect)(() => {
|
|
24500
25155
|
if (coordinator || sdkLoading || sdkError) return;
|
|
24501
25156
|
if (!resolvedStripeKey) return;
|
|
24502
25157
|
initialize();
|
|
24503
25158
|
}, [coordinator, sdkLoading, sdkError, resolvedStripeKey, initialize]);
|
|
24504
|
-
|
|
25159
|
+
(0, import_react24.useEffect)(() => {
|
|
25160
|
+
sdkAuthenticatedRef.current = false;
|
|
25161
|
+
attemptedWalletReauthRef.current = false;
|
|
25162
|
+
}, [coordinator]);
|
|
25163
|
+
const handleAuthInterrupted = (0, import_react24.useCallback)(
|
|
24505
25164
|
(message) => {
|
|
24506
25165
|
const alreadySignedIn = !!accessTokenRef.current;
|
|
24507
25166
|
if (alreadySignedIn || emailProp) {
|
|
@@ -24514,7 +25173,27 @@ function PayWithStripeLink({
|
|
|
24514
25173
|
},
|
|
24515
25174
|
[emailProp, setStep]
|
|
24516
25175
|
);
|
|
24517
|
-
(0,
|
|
25176
|
+
const reauthenticateSdk = (0, import_react24.useCallback)(async () => {
|
|
25177
|
+
const current = stepRef.current;
|
|
25178
|
+
const preAuthSteps = ["email", "register", "auth"];
|
|
25179
|
+
reauthReturnStepRef.current = preAuthSteps.includes(current) ? null : current;
|
|
25180
|
+
const knownEmail = (email || emailProp || "").trim();
|
|
25181
|
+
if (!knownEmail) {
|
|
25182
|
+
reauthReturnStepRef.current = null;
|
|
25183
|
+
setStep("email");
|
|
25184
|
+
return;
|
|
25185
|
+
}
|
|
25186
|
+
try {
|
|
25187
|
+
const authResult = await stripeCreateAuthIntent(knownEmail, publishableKey);
|
|
25188
|
+
setAuthIntentId(authResult.auth_intent_id);
|
|
25189
|
+
setStep("auth");
|
|
25190
|
+
} catch (err) {
|
|
25191
|
+
reauthReturnStepRef.current = null;
|
|
25192
|
+
setError(err instanceof Error ? err.message : "Failed to re-verify. Please try again.");
|
|
25193
|
+
setStep("email");
|
|
25194
|
+
}
|
|
25195
|
+
}, [email, emailProp, publishableKey]);
|
|
25196
|
+
(0, import_react24.useEffect)(() => {
|
|
24518
25197
|
if (step !== "auth" || !coordinator || !authIntentId) return;
|
|
24519
25198
|
let mounted = true;
|
|
24520
25199
|
const runAuth = async () => {
|
|
@@ -24524,6 +25203,7 @@ function PayWithStripeLink({
|
|
|
24524
25203
|
if (result.result === "success" && result.crypto_customer_id) {
|
|
24525
25204
|
setCustomerId(result.crypto_customer_id);
|
|
24526
25205
|
sdkAuthenticatedRef.current = true;
|
|
25206
|
+
everAuthenticatedRef.current = true;
|
|
24527
25207
|
const tokens = await stripeExchangeTokens(authIntentId, publishableKey);
|
|
24528
25208
|
setOauthToken(tokens.access_token);
|
|
24529
25209
|
const refresh = extractRefreshToken(tokens);
|
|
@@ -24537,16 +25217,22 @@ function PayWithStripeLink({
|
|
|
24537
25217
|
tokens.expires_in ?? 3600,
|
|
24538
25218
|
email.trim()
|
|
24539
25219
|
);
|
|
25220
|
+
const resumeStep = reauthReturnStepRef.current;
|
|
25221
|
+
reauthReturnStepRef.current = null;
|
|
24540
25222
|
if (pendingAddPaymentRef.current) {
|
|
24541
25223
|
setStep("payment");
|
|
25224
|
+
} else if (resumeStep) {
|
|
25225
|
+
setStep(resumeStep);
|
|
24542
25226
|
} else {
|
|
24543
25227
|
setStep("kyc");
|
|
24544
25228
|
}
|
|
24545
25229
|
} else if (result.result === "abandoned") {
|
|
24546
25230
|
pendingAddPaymentRef.current = false;
|
|
25231
|
+
reauthReturnStepRef.current = null;
|
|
24547
25232
|
handleAuthInterrupted("Verification was cancelled.");
|
|
24548
25233
|
} else if (result.result === "declined") {
|
|
24549
25234
|
pendingAddPaymentRef.current = false;
|
|
25235
|
+
reauthReturnStepRef.current = null;
|
|
24550
25236
|
handleAuthInterrupted("You must consent to continue.");
|
|
24551
25237
|
}
|
|
24552
25238
|
});
|
|
@@ -24558,6 +25244,7 @@ function PayWithStripeLink({
|
|
|
24558
25244
|
}
|
|
24559
25245
|
} catch (err) {
|
|
24560
25246
|
if (!mounted) return;
|
|
25247
|
+
reauthReturnStepRef.current = null;
|
|
24561
25248
|
const msg = err instanceof Error ? err.message : "Verification was cancelled.";
|
|
24562
25249
|
handleAuthInterrupted(msg);
|
|
24563
25250
|
}
|
|
@@ -24569,7 +25256,7 @@ function PayWithStripeLink({
|
|
|
24569
25256
|
authInnerRef.current.replaceChildren();
|
|
24570
25257
|
};
|
|
24571
25258
|
}, [step, coordinator, authIntentId, publishableKey]);
|
|
24572
|
-
(0,
|
|
25259
|
+
(0, import_react24.useEffect)(() => {
|
|
24573
25260
|
if (step !== "kyc" || !oauthToken || !customerId) return;
|
|
24574
25261
|
let mounted = true;
|
|
24575
25262
|
let pollTimer = null;
|
|
@@ -24659,6 +25346,10 @@ function PayWithStripeLink({
|
|
|
24659
25346
|
};
|
|
24660
25347
|
const handleKycSubmit = async () => {
|
|
24661
25348
|
if (!coordinator) return;
|
|
25349
|
+
if (!sdkAuthenticatedRef.current) {
|
|
25350
|
+
await reauthenticateSdk();
|
|
25351
|
+
return;
|
|
25352
|
+
}
|
|
24662
25353
|
let kycInfo;
|
|
24663
25354
|
if (kycFormMode === "address") {
|
|
24664
25355
|
if (!kycForm.givenName.trim() || !kycForm.surname.trim()) {
|
|
@@ -24713,11 +25404,15 @@ function PayWithStripeLink({
|
|
|
24713
25404
|
setLoading(false);
|
|
24714
25405
|
}
|
|
24715
25406
|
};
|
|
24716
|
-
(0,
|
|
25407
|
+
(0, import_react24.useEffect)(() => {
|
|
24717
25408
|
if (step !== "kyc_document" || !coordinator) return;
|
|
24718
25409
|
let mounted = true;
|
|
24719
25410
|
const verify = async () => {
|
|
24720
25411
|
try {
|
|
25412
|
+
if (!sdkAuthenticatedRef.current) {
|
|
25413
|
+
await reauthenticateSdk();
|
|
25414
|
+
return;
|
|
25415
|
+
}
|
|
24721
25416
|
const result = await coordinator.verifyDocuments();
|
|
24722
25417
|
if (!mounted) return;
|
|
24723
25418
|
const outcome = typeof result === "string" ? result : result?.result;
|
|
@@ -24737,8 +25432,8 @@ function PayWithStripeLink({
|
|
|
24737
25432
|
return () => {
|
|
24738
25433
|
mounted = false;
|
|
24739
25434
|
};
|
|
24740
|
-
}, [step, coordinator]);
|
|
24741
|
-
(0,
|
|
25435
|
+
}, [step, coordinator, reauthenticateSdk]);
|
|
25436
|
+
(0, import_react24.useEffect)(() => {
|
|
24742
25437
|
if (step !== "wallet" || !oauthToken || !customerId) return;
|
|
24743
25438
|
let mounted = true;
|
|
24744
25439
|
const setupWallet = async () => {
|
|
@@ -24763,6 +25458,10 @@ function PayWithStripeLink({
|
|
|
24763
25458
|
if (!coordinator) {
|
|
24764
25459
|
return;
|
|
24765
25460
|
}
|
|
25461
|
+
if (!sdkAuthenticatedRef.current) {
|
|
25462
|
+
await reauthenticateSdk();
|
|
25463
|
+
return;
|
|
25464
|
+
}
|
|
24766
25465
|
await coordinator.registerWalletAddress(onrampWalletAddress, network);
|
|
24767
25466
|
}
|
|
24768
25467
|
if (mounted) setRegisteredWalletKey(walletKeyFor(onrampWalletAddress));
|
|
@@ -24779,8 +25478,16 @@ function PayWithStripeLink({
|
|
|
24779
25478
|
return () => {
|
|
24780
25479
|
mounted = false;
|
|
24781
25480
|
};
|
|
24782
|
-
}, [
|
|
24783
|
-
|
|
25481
|
+
}, [
|
|
25482
|
+
step,
|
|
25483
|
+
oauthToken,
|
|
25484
|
+
customerId,
|
|
25485
|
+
publishableKey,
|
|
25486
|
+
onrampWalletAddress,
|
|
25487
|
+
coordinator,
|
|
25488
|
+
reauthenticateSdk
|
|
25489
|
+
]);
|
|
25490
|
+
(0, import_react24.useEffect)(() => {
|
|
24784
25491
|
if (step !== "amount" && step !== "review") return;
|
|
24785
25492
|
if (!customerId || !oauthToken || !onrampWalletAddress) return;
|
|
24786
25493
|
if (isOnrampWalletRegistered) return;
|
|
@@ -24808,6 +25515,10 @@ function PayWithStripeLink({
|
|
|
24808
25515
|
if (coordinator && sdkAuthenticatedRef.current) {
|
|
24809
25516
|
await coordinator.registerWalletAddress(onrampWalletAddress, network);
|
|
24810
25517
|
if (!cancelled) setRegisteredWalletKey(walletKeyFor(onrampWalletAddress));
|
|
25518
|
+
} else if (coordinator && everAuthenticatedRef.current && !attemptedWalletReauthRef.current) {
|
|
25519
|
+
attemptedWalletReauthRef.current = true;
|
|
25520
|
+
await reauthenticateSdk();
|
|
25521
|
+
return;
|
|
24811
25522
|
}
|
|
24812
25523
|
} catch {
|
|
24813
25524
|
}
|
|
@@ -24825,9 +25536,10 @@ function PayWithStripeLink({
|
|
|
24825
25536
|
coordinator,
|
|
24826
25537
|
stripeDestNetwork,
|
|
24827
25538
|
stripeDestChainType,
|
|
24828
|
-
publishableKey
|
|
25539
|
+
publishableKey,
|
|
25540
|
+
reauthenticateSdk
|
|
24829
25541
|
]);
|
|
24830
|
-
(0,
|
|
25542
|
+
(0, import_react24.useEffect)(() => {
|
|
24831
25543
|
if (step !== "payment" || !oauthToken || !customerId) return;
|
|
24832
25544
|
if (pendingAddPaymentRef.current) {
|
|
24833
25545
|
pendingAddPaymentRef.current = false;
|
|
@@ -24890,7 +25602,7 @@ function PayWithStripeLink({
|
|
|
24890
25602
|
paymentInnerRef.current.replaceChildren();
|
|
24891
25603
|
};
|
|
24892
25604
|
}, [step, oauthToken, customerId, publishableKey, coordinator]);
|
|
24893
|
-
(0,
|
|
25605
|
+
(0, import_react24.useEffect)(() => {
|
|
24894
25606
|
if (step !== "add_payment") return;
|
|
24895
25607
|
if (!isCustomerVerified(customer)) {
|
|
24896
25608
|
setStep("kyc");
|
|
@@ -24922,6 +25634,32 @@ function PayWithStripeLink({
|
|
|
24922
25634
|
if (!mounted) return;
|
|
24923
25635
|
const tokenId = result.cryptoPaymentToken;
|
|
24924
25636
|
let display = null;
|
|
25637
|
+
const pmd = result.paymentMethodDetails;
|
|
25638
|
+
if (pmd) {
|
|
25639
|
+
display = formatPaymentToken(pmd);
|
|
25640
|
+
}
|
|
25641
|
+
const singleUse = pmd?.type === "card" && !!pmd.card.wallet;
|
|
25642
|
+
const applyAndAdvance = () => {
|
|
25643
|
+
selectPaymentToken({
|
|
25644
|
+
id: tokenId,
|
|
25645
|
+
label: display?.label ?? "",
|
|
25646
|
+
sublabel: display?.sublabel ?? "",
|
|
25647
|
+
brand: display?.brand,
|
|
25648
|
+
singleUse
|
|
25649
|
+
});
|
|
25650
|
+
autoOpenedAddPaymentRef.current = false;
|
|
25651
|
+
setStep("amount");
|
|
25652
|
+
};
|
|
25653
|
+
if (display) {
|
|
25654
|
+
applyAndAdvance();
|
|
25655
|
+
if (customerId && accessTokenRef.current) {
|
|
25656
|
+
stripeListPaymentTokens(customerId, accessTokenRef.current, publishableKey).then((tokens) => {
|
|
25657
|
+
if (mounted) setPaymentTokens(tokens.data);
|
|
25658
|
+
}).catch(() => {
|
|
25659
|
+
});
|
|
25660
|
+
}
|
|
25661
|
+
return;
|
|
25662
|
+
}
|
|
24925
25663
|
try {
|
|
24926
25664
|
if (customerId && accessTokenRef.current) {
|
|
24927
25665
|
const tokens = await stripeListPaymentTokens(
|
|
@@ -24929,28 +25667,15 @@ function PayWithStripeLink({
|
|
|
24929
25667
|
accessTokenRef.current,
|
|
24930
25668
|
publishableKey
|
|
24931
25669
|
);
|
|
25670
|
+
if (!mounted) return;
|
|
25671
|
+
setPaymentTokens(tokens.data);
|
|
24932
25672
|
const match = tokens.data.find((t13) => t13.id === tokenId);
|
|
24933
|
-
if (match)
|
|
24934
|
-
display = formatPaymentToken(match);
|
|
24935
|
-
setPaymentTokens(tokens.data);
|
|
24936
|
-
}
|
|
25673
|
+
if (match) display = formatPaymentToken(match);
|
|
24937
25674
|
}
|
|
24938
25675
|
} catch {
|
|
24939
25676
|
}
|
|
24940
|
-
if (!
|
|
24941
|
-
|
|
24942
|
-
if (dd?.label) {
|
|
24943
|
-
display = { label: dd.label, sublabel: dd.sublabel ?? "", brand: dd.type };
|
|
24944
|
-
}
|
|
24945
|
-
}
|
|
24946
|
-
selectPaymentToken({
|
|
24947
|
-
id: tokenId,
|
|
24948
|
-
label: display?.label ?? "",
|
|
24949
|
-
sublabel: display?.sublabel ?? "",
|
|
24950
|
-
brand: display?.brand
|
|
24951
|
-
});
|
|
24952
|
-
autoOpenedAddPaymentRef.current = false;
|
|
24953
|
-
setStep("amount");
|
|
25677
|
+
if (!mounted) return;
|
|
25678
|
+
applyAndAdvance();
|
|
24954
25679
|
}
|
|
24955
25680
|
);
|
|
24956
25681
|
if (mounted && el) {
|
|
@@ -24987,6 +25712,10 @@ function PayWithStripeLink({
|
|
|
24987
25712
|
const handleCheckout = async () => {
|
|
24988
25713
|
if (!amount || !oauthToken || !customerId || !selectedPaymentToken || !onrampWalletAddress || !isOnrampWalletRegistered || !coordinator)
|
|
24989
25714
|
return;
|
|
25715
|
+
if (!sdkAuthenticatedRef.current) {
|
|
25716
|
+
await reauthenticateSdk();
|
|
25717
|
+
return;
|
|
25718
|
+
}
|
|
24990
25719
|
const gen = ++checkoutGenRef.current;
|
|
24991
25720
|
const isStale = () => checkoutGenRef.current !== gen;
|
|
24992
25721
|
const surfaceStepUpOnAmount = (err, message, tier) => {
|
|
@@ -25098,6 +25827,7 @@ function PayWithStripeLink({
|
|
|
25098
25827
|
executionReconciledSessionRef.current = null;
|
|
25099
25828
|
setConfirmedSessionId(activeSessionId);
|
|
25100
25829
|
setSessionStatus(STRIPE_SESSION_STATUS.FULFILLMENT_PROCESSING);
|
|
25830
|
+
if (selectedTokenSingleUseRef.current) clearSelectedPaymentToken();
|
|
25101
25831
|
setStep("success");
|
|
25102
25832
|
} else if (lastError === "quote_rate_drifted" || lastError === "charged_with_expired_quote") {
|
|
25103
25833
|
setSessionForCheckout(null);
|
|
@@ -25140,15 +25870,34 @@ function PayWithStripeLink({
|
|
|
25140
25870
|
setLoading(false);
|
|
25141
25871
|
}
|
|
25142
25872
|
};
|
|
25143
|
-
const [quote, setQuote] = (0,
|
|
25144
|
-
const [quoteLoading, setQuoteLoading] = (0,
|
|
25145
|
-
const quoteTimerRef = (0,
|
|
25146
|
-
const [sessionForCheckout, setSessionForCheckoutState] = (0,
|
|
25147
|
-
const sessionForCheckoutRef = (0,
|
|
25873
|
+
const [quote, setQuote] = (0, import_react24.useState)(null);
|
|
25874
|
+
const [quoteLoading, setQuoteLoading] = (0, import_react24.useState)(false);
|
|
25875
|
+
const quoteTimerRef = (0, import_react24.useRef)(null);
|
|
25876
|
+
const [sessionForCheckout, setSessionForCheckoutState] = (0, import_react24.useState)(null);
|
|
25877
|
+
const sessionForCheckoutRef = (0, import_react24.useRef)(sessionForCheckout);
|
|
25148
25878
|
const setSessionForCheckout = (s) => {
|
|
25149
25879
|
sessionForCheckoutRef.current = s;
|
|
25150
25880
|
setSessionForCheckoutState(s);
|
|
25151
25881
|
};
|
|
25882
|
+
const loadAndSelectPreferredToken = (0, import_react24.useCallback)(async () => {
|
|
25883
|
+
if (!customerId) return;
|
|
25884
|
+
try {
|
|
25885
|
+
const existing = await withTokenRefresh(
|
|
25886
|
+
(tok) => stripeListPaymentTokens(customerId, tok, publishableKey)
|
|
25887
|
+
);
|
|
25888
|
+
setPaymentTokens(existing.data);
|
|
25889
|
+
const stored = getStoredSelectedToken(customerId);
|
|
25890
|
+
const merged = [
|
|
25891
|
+
...existing.data.map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) })),
|
|
25892
|
+
...stored && !existing.data.some((t13) => t13.id === stored.id) ? [stored] : []
|
|
25893
|
+
];
|
|
25894
|
+
if (merged.length > 0) {
|
|
25895
|
+
const preferred = stored && merged.find((m) => m.id === stored.id) || merged[0];
|
|
25896
|
+
selectPaymentToken(preferred);
|
|
25897
|
+
}
|
|
25898
|
+
} catch {
|
|
25899
|
+
}
|
|
25900
|
+
}, [customerId, publishableKey, selectPaymentToken, withTokenRefresh]);
|
|
25152
25901
|
const handleDone = () => {
|
|
25153
25902
|
handledTerminalSessionRef.current = null;
|
|
25154
25903
|
executionReconciledSessionRef.current = null;
|
|
@@ -25156,14 +25905,15 @@ function PayWithStripeLink({
|
|
|
25156
25905
|
setSessionStatus(null);
|
|
25157
25906
|
setSessionForCheckout(null);
|
|
25158
25907
|
setStep("amount");
|
|
25908
|
+
if (!selectedPaymentToken) void loadAndSelectPreferredToken();
|
|
25159
25909
|
};
|
|
25160
|
-
const [quoteError, setQuoteError] = (0,
|
|
25161
|
-
const [quoteNonce, setQuoteNonce] = (0,
|
|
25162
|
-
const quoteNonceAtReviewRef = (0,
|
|
25163
|
-
const [purchaseLimit, setPurchaseLimit] = (0,
|
|
25164
|
-
const [limitReachedAmount, setLimitReachedAmount] = (0,
|
|
25165
|
-
const [requiredStepUp, setRequiredStepUp] = (0,
|
|
25166
|
-
(0,
|
|
25910
|
+
const [quoteError, setQuoteError] = (0, import_react24.useState)(null);
|
|
25911
|
+
const [quoteNonce, setQuoteNonce] = (0, import_react24.useState)(0);
|
|
25912
|
+
const quoteNonceAtReviewRef = (0, import_react24.useRef)(quoteNonce);
|
|
25913
|
+
const [purchaseLimit, setPurchaseLimit] = (0, import_react24.useState)(null);
|
|
25914
|
+
const [limitReachedAmount, setLimitReachedAmount] = (0, import_react24.useState)(null);
|
|
25915
|
+
const [requiredStepUp, setRequiredStepUp] = (0, import_react24.useState)(null);
|
|
25916
|
+
(0, import_react24.useEffect)(() => {
|
|
25167
25917
|
if (step !== "amount" || !customerId || !onrampWalletAddress) return;
|
|
25168
25918
|
if (!accessTokenRef.current) return;
|
|
25169
25919
|
let cancelled = false;
|
|
@@ -25216,7 +25966,7 @@ function PayWithStripeLink({
|
|
|
25216
25966
|
setQuoteError(null);
|
|
25217
25967
|
setRequiredStepUp(null);
|
|
25218
25968
|
};
|
|
25219
|
-
(0,
|
|
25969
|
+
(0, import_react24.useEffect)(() => {
|
|
25220
25970
|
if (step === "review") {
|
|
25221
25971
|
const existing = sessionForCheckoutRef.current;
|
|
25222
25972
|
const hasFreshSession = !!(existing && existing.amount === amount && existing.paymentToken === selectedPaymentToken);
|
|
@@ -25348,9 +26098,9 @@ function PayWithStripeLink({
|
|
|
25348
26098
|
quoteNonce
|
|
25349
26099
|
]);
|
|
25350
26100
|
const QUOTE_TTL = 30;
|
|
25351
|
-
const [quoteCountdown, setQuoteCountdown] = (0,
|
|
26101
|
+
const [quoteCountdown, setQuoteCountdown] = (0, import_react24.useState)(QUOTE_TTL);
|
|
25352
26102
|
const hasReviewSession = !!(customerId && selectedPaymentToken && onrampWalletAddress);
|
|
25353
|
-
(0,
|
|
26103
|
+
(0, import_react24.useEffect)(() => {
|
|
25354
26104
|
if (step !== "review" || !hasReviewSession) return;
|
|
25355
26105
|
quoteNonceAtReviewRef.current = quoteNonce;
|
|
25356
26106
|
setQuoteCountdown(QUOTE_TTL);
|
|
@@ -25995,7 +26745,8 @@ function PayWithStripeLink({
|
|
|
25995
26745
|
{
|
|
25996
26746
|
brand: display.brand,
|
|
25997
26747
|
size: 28,
|
|
25998
|
-
fallbackColor: colors2.foregroundMuted
|
|
26748
|
+
fallbackColor: colors2.foregroundMuted,
|
|
26749
|
+
monochromeColor: monochromeOn(components.card.backgroundColor)
|
|
25999
26750
|
}
|
|
26000
26751
|
)
|
|
26001
26752
|
}
|
|
@@ -26580,7 +27331,8 @@ function PayWithStripeLink({
|
|
|
26580
27331
|
{
|
|
26581
27332
|
brand: paymentDisplay.brand,
|
|
26582
27333
|
size: 20,
|
|
26583
|
-
fallbackColor: colors2.foregroundMuted
|
|
27334
|
+
fallbackColor: colors2.foregroundMuted,
|
|
27335
|
+
monochromeColor: monochromeOn(components.card.backgroundColor)
|
|
26584
27336
|
}
|
|
26585
27337
|
),
|
|
26586
27338
|
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
@@ -27064,6 +27816,20 @@ function PayWithStripeLink({
|
|
|
27064
27816
|
}
|
|
27065
27817
|
return null;
|
|
27066
27818
|
}
|
|
27819
|
+
function useProjectConfig({
|
|
27820
|
+
publishableKey,
|
|
27821
|
+
enabled = true
|
|
27822
|
+
}) {
|
|
27823
|
+
const { data: projectConfig, isLoading } = (0, import_react_query10.useQuery)({
|
|
27824
|
+
queryKey: ["unifold", "projectConfig", publishableKey],
|
|
27825
|
+
queryFn: () => getProjectConfig(publishableKey),
|
|
27826
|
+
enabled,
|
|
27827
|
+
staleTime: 1e3 * 60 * 30,
|
|
27828
|
+
refetchOnMount: true,
|
|
27829
|
+
refetchOnWindowFocus: true
|
|
27830
|
+
});
|
|
27831
|
+
return { projectConfig, isLoading };
|
|
27832
|
+
}
|
|
27067
27833
|
function useSupportedDepositTokens(publishableKey, options) {
|
|
27068
27834
|
const hasDestination = options?.destination_token_address && options?.destination_chain_id && options?.destination_chain_type;
|
|
27069
27835
|
const filteredOptions = {
|
|
@@ -27075,7 +27841,7 @@ function useSupportedDepositTokens(publishableKey, options) {
|
|
|
27075
27841
|
...options?.product_type ? { product_type: options.product_type } : {}
|
|
27076
27842
|
};
|
|
27077
27843
|
const hasFilteredOptions = Object.keys(filteredOptions).length > 0;
|
|
27078
|
-
return (0,
|
|
27844
|
+
return (0, import_react_query11.useQuery)({
|
|
27079
27845
|
queryKey: [
|
|
27080
27846
|
"unifold",
|
|
27081
27847
|
"supportedDepositTokens",
|
|
@@ -27099,7 +27865,7 @@ function useIntegrationTransferDefaultToken({
|
|
|
27099
27865
|
publishableKey,
|
|
27100
27866
|
enabled = true
|
|
27101
27867
|
}) {
|
|
27102
|
-
return (0,
|
|
27868
|
+
return (0, import_react_query12.useQuery)({
|
|
27103
27869
|
queryKey: [
|
|
27104
27870
|
"unifold",
|
|
27105
27871
|
"integrationTransferDefaultToken",
|
|
@@ -27175,12 +27941,12 @@ function CoinbaseConnect({
|
|
|
27175
27941
|
destination_chain_id: destinationChainId,
|
|
27176
27942
|
destination_chain_type: destinationChainType
|
|
27177
27943
|
});
|
|
27178
|
-
const supportedSymbols = (0,
|
|
27944
|
+
const supportedSymbols = (0, import_react26.useMemo)(() => {
|
|
27179
27945
|
const set = /* @__PURE__ */ new Set();
|
|
27180
27946
|
supportedTokensData?.data.forEach((token) => set.add(token.symbol.toLowerCase()));
|
|
27181
27947
|
return set;
|
|
27182
27948
|
}, [supportedTokensData]);
|
|
27183
|
-
const stablecoinSymbols = (0,
|
|
27949
|
+
const stablecoinSymbols = (0, import_react26.useMemo)(() => {
|
|
27184
27950
|
const set = /* @__PURE__ */ new Set();
|
|
27185
27951
|
supportedTokensData?.data.forEach((token) => {
|
|
27186
27952
|
if (token.is_stablecoin) set.add(token.symbol.toLowerCase());
|
|
@@ -27190,35 +27956,35 @@ function CoinbaseConnect({
|
|
|
27190
27956
|
const appName = projectConfig?.project_name ?? "Unifold";
|
|
27191
27957
|
const t13 = i18n2.connectExchange;
|
|
27192
27958
|
const initialView = skipToHoldings && getStoredIntegrationToken(IntegrationProvider.COINBASE) ? "holdings" : "select_exchange";
|
|
27193
|
-
const [view, setView] = (0,
|
|
27194
|
-
const [prevView, setPrevView] = (0,
|
|
27195
|
-
const [isTransitioning, setIsTransitioning] = (0,
|
|
27196
|
-
const [exchanges, setExchanges] = (0,
|
|
27197
|
-
const [exchangesLoading, setExchangesLoading] = (0,
|
|
27198
|
-
const [selectedExchange, setSelectedExchange] = (0,
|
|
27199
|
-
const [accessToken, setAccessToken] = (0,
|
|
27200
|
-
const [holdings, setHoldings] = (0,
|
|
27201
|
-
const [selectedHolding, setSelectedHolding] = (0,
|
|
27202
|
-
const [selectedAsset, setSelectedAsset] = (0,
|
|
27203
|
-
const [sendAmount, setSendAmount] = (0,
|
|
27204
|
-
const [transferIntent, setTransferIntent] = (0,
|
|
27959
|
+
const [view, setView] = (0, import_react26.useState)(initialView);
|
|
27960
|
+
const [prevView, setPrevView] = (0, import_react26.useState)(initialView);
|
|
27961
|
+
const [isTransitioning, setIsTransitioning] = (0, import_react26.useState)(false);
|
|
27962
|
+
const [exchanges, setExchanges] = (0, import_react26.useState)([]);
|
|
27963
|
+
const [exchangesLoading, setExchangesLoading] = (0, import_react26.useState)(true);
|
|
27964
|
+
const [selectedExchange, setSelectedExchange] = (0, import_react26.useState)(null);
|
|
27965
|
+
const [accessToken, setAccessToken] = (0, import_react26.useState)(null);
|
|
27966
|
+
const [holdings, setHoldings] = (0, import_react26.useState)([]);
|
|
27967
|
+
const [selectedHolding, setSelectedHolding] = (0, import_react26.useState)(null);
|
|
27968
|
+
const [selectedAsset, setSelectedAsset] = (0, import_react26.useState)(null);
|
|
27969
|
+
const [sendAmount, setSendAmount] = (0, import_react26.useState)("");
|
|
27970
|
+
const [transferIntent, setTransferIntent] = (0, import_react26.useState)(
|
|
27205
27971
|
null
|
|
27206
27972
|
);
|
|
27207
|
-
const [mfaCode, setMfaCode] = (0,
|
|
27208
|
-
const [mfaError, setMfaError] = (0,
|
|
27209
|
-
const [errorMessage, setErrorMessage] = (0,
|
|
27210
|
-
const [isLoading, setIsLoading] = (0,
|
|
27211
|
-
const [confirmResult, setConfirmResult] = (0,
|
|
27212
|
-
const [showTransferDetails, setShowTransferDetails] = (0,
|
|
27213
|
-
const [transferDepositWalletId, setTransferDepositWalletId] = (0,
|
|
27973
|
+
const [mfaCode, setMfaCode] = (0, import_react26.useState)("");
|
|
27974
|
+
const [mfaError, setMfaError] = (0, import_react26.useState)(false);
|
|
27975
|
+
const [errorMessage, setErrorMessage] = (0, import_react26.useState)("");
|
|
27976
|
+
const [isLoading, setIsLoading] = (0, import_react26.useState)(initialView === "holdings");
|
|
27977
|
+
const [confirmResult, setConfirmResult] = (0, import_react26.useState)(null);
|
|
27978
|
+
const [showTransferDetails, setShowTransferDetails] = (0, import_react26.useState)(false);
|
|
27979
|
+
const [transferDepositWalletId, setTransferDepositWalletId] = (0, import_react26.useState)(
|
|
27214
27980
|
void 0
|
|
27215
27981
|
);
|
|
27216
|
-
const exchangeSupportedCurrencies = (0,
|
|
27982
|
+
const exchangeSupportedCurrencies = (0, import_react26.useMemo)(() => {
|
|
27217
27983
|
const set = /* @__PURE__ */ new Set();
|
|
27218
27984
|
selectedExchange?.supported_currencies.forEach((c) => set.add(c.toLowerCase()));
|
|
27219
27985
|
return set;
|
|
27220
27986
|
}, [selectedExchange]);
|
|
27221
|
-
const defaultTokenParams = (0,
|
|
27987
|
+
const defaultTokenParams = (0, import_react26.useMemo)(
|
|
27222
27988
|
() => selectedAsset ? {
|
|
27223
27989
|
integration_provider: IntegrationProvider.COINBASE,
|
|
27224
27990
|
source_currency: selectedAsset.currency.toLowerCase(),
|
|
@@ -27241,7 +28007,7 @@ function CoinbaseConnect({
|
|
|
27241
28007
|
params: defaultTokenParams,
|
|
27242
28008
|
publishableKey
|
|
27243
28009
|
});
|
|
27244
|
-
const defaultSourceCurrency = (0,
|
|
28010
|
+
const defaultSourceCurrency = (0, import_react26.useMemo)(
|
|
27245
28011
|
() => resolveDefaultSourceSymbol(supportedTokensData?.data, {
|
|
27246
28012
|
defaultSourceChainType,
|
|
27247
28013
|
defaultSourceChainId,
|
|
@@ -27256,7 +28022,7 @@ function CoinbaseConnect({
|
|
|
27256
28022
|
defaultSourceSymbol
|
|
27257
28023
|
]
|
|
27258
28024
|
);
|
|
27259
|
-
const sortedHoldings = (0,
|
|
28025
|
+
const sortedHoldings = (0, import_react26.useMemo)(() => {
|
|
27260
28026
|
const supported = [];
|
|
27261
28027
|
const unsupported = [];
|
|
27262
28028
|
holdings.forEach((account) => {
|
|
@@ -27276,12 +28042,12 @@ function CoinbaseConnect({
|
|
|
27276
28042
|
}
|
|
27277
28043
|
return [...supported, ...unsupported];
|
|
27278
28044
|
}, [holdings, supportedSymbols, exchangeSupportedCurrencies, defaultSourceCurrency]);
|
|
27279
|
-
const selectedHoldingIsSupported = (0,
|
|
28045
|
+
const selectedHoldingIsSupported = (0, import_react26.useMemo)(() => {
|
|
27280
28046
|
if (!selectedHolding) return false;
|
|
27281
28047
|
const currencyLower = selectedHolding.currency.toLowerCase();
|
|
27282
28048
|
return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
|
|
27283
28049
|
}, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
|
|
27284
|
-
(0,
|
|
28050
|
+
(0, import_react26.useEffect)(() => {
|
|
27285
28051
|
if (!defaultSourceCurrency || selectedHolding) return;
|
|
27286
28052
|
const defaultHolding = sortedHoldings.find((account) => {
|
|
27287
28053
|
const currencyLower = account.currency.toLowerCase();
|
|
@@ -27317,13 +28083,13 @@ function CoinbaseConnect({
|
|
|
27317
28083
|
onTransferError?.({ message: error.message });
|
|
27318
28084
|
} : void 0
|
|
27319
28085
|
});
|
|
27320
|
-
(0,
|
|
28086
|
+
(0, import_react26.useEffect)(() => {
|
|
27321
28087
|
onExecutionsChange?.(depositExecutions);
|
|
27322
28088
|
}, [depositExecutions, onExecutionsChange]);
|
|
27323
|
-
const pollRef = (0,
|
|
27324
|
-
const popupRef = (0,
|
|
27325
|
-
const viewRef = (0,
|
|
27326
|
-
const transitionTo = (0,
|
|
28089
|
+
const pollRef = (0, import_react26.useRef)(null);
|
|
28090
|
+
const popupRef = (0, import_react26.useRef)(null);
|
|
28091
|
+
const viewRef = (0, import_react26.useRef)(initialView);
|
|
28092
|
+
const transitionTo = (0, import_react26.useCallback)((nextView) => {
|
|
27327
28093
|
if (nextView === viewRef.current) return;
|
|
27328
28094
|
setIsTransitioning(true);
|
|
27329
28095
|
setTimeout(() => {
|
|
@@ -27333,7 +28099,7 @@ function CoinbaseConnect({
|
|
|
27333
28099
|
setIsTransitioning(false);
|
|
27334
28100
|
}, 150);
|
|
27335
28101
|
}, []);
|
|
27336
|
-
const tryRefreshToken = (0,
|
|
28102
|
+
const tryRefreshToken = (0, import_react26.useCallback)(
|
|
27337
28103
|
async (currentToken) => {
|
|
27338
28104
|
try {
|
|
27339
28105
|
const result = await refreshIntegrationToken(currentToken, publishableKey);
|
|
@@ -27352,7 +28118,7 @@ function CoinbaseConnect({
|
|
|
27352
28118
|
},
|
|
27353
28119
|
[publishableKey]
|
|
27354
28120
|
);
|
|
27355
|
-
(0,
|
|
28121
|
+
(0, import_react26.useEffect)(() => {
|
|
27356
28122
|
getIntegrationExchanges(publishableKey).then((res) => {
|
|
27357
28123
|
setExchanges(res.data);
|
|
27358
28124
|
if (!selectedExchange) {
|
|
@@ -27371,7 +28137,7 @@ function CoinbaseConnect({
|
|
|
27371
28137
|
}
|
|
27372
28138
|
}
|
|
27373
28139
|
}, []);
|
|
27374
|
-
const loadHoldings = (0,
|
|
28140
|
+
const loadHoldings = (0, import_react26.useCallback)(
|
|
27375
28141
|
async (token) => {
|
|
27376
28142
|
setIsLoading(true);
|
|
27377
28143
|
try {
|
|
@@ -27418,12 +28184,12 @@ function CoinbaseConnect({
|
|
|
27418
28184
|
},
|
|
27419
28185
|
[publishableKey, transitionTo, tryRefreshToken]
|
|
27420
28186
|
);
|
|
27421
|
-
(0,
|
|
28187
|
+
(0, import_react26.useEffect)(() => {
|
|
27422
28188
|
return () => {
|
|
27423
28189
|
if (pollRef.current) clearInterval(pollRef.current);
|
|
27424
28190
|
};
|
|
27425
28191
|
}, []);
|
|
27426
|
-
const minDepositUsd = (0,
|
|
28192
|
+
const minDepositUsd = (0, import_react26.useMemo)(() => {
|
|
27427
28193
|
if (!selectedAsset || !defaultTokenData) return 0;
|
|
27428
28194
|
const supportedToken = supportedTokensData?.data.find(
|
|
27429
28195
|
(t14) => t14.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
|
|
@@ -27434,7 +28200,7 @@ function CoinbaseConnect({
|
|
|
27434
28200
|
);
|
|
27435
28201
|
return matchingChain?.minimum_deposit_amount_usd ?? Math.min(...supportedToken.chains.map((c) => c.minimum_deposit_amount_usd));
|
|
27436
28202
|
}, [selectedAsset, supportedTokensData, defaultTokenData]);
|
|
27437
|
-
const estimatedProcessingTime = (0,
|
|
28203
|
+
const estimatedProcessingTime = (0, import_react26.useMemo)(() => {
|
|
27438
28204
|
if (!selectedAsset || !defaultTokenData) return null;
|
|
27439
28205
|
const supportedToken = supportedTokensData?.data.find(
|
|
27440
28206
|
(t14) => t14.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
|
|
@@ -29076,7 +29842,7 @@ function useExchanges({
|
|
|
29076
29842
|
publishableKey,
|
|
29077
29843
|
enabled = true
|
|
29078
29844
|
}) {
|
|
29079
|
-
const { data: exchanges = [], isLoading } = (0,
|
|
29845
|
+
const { data: exchanges = [], isLoading } = (0, import_react_query13.useQuery)({
|
|
29080
29846
|
queryKey: ["unifold", "exchanges", publishableKey],
|
|
29081
29847
|
queryFn: () => getExchanges(void 0, publishableKey).then((res) => res.data),
|
|
29082
29848
|
enabled,
|
|
@@ -29090,7 +29856,7 @@ function useApplePayProviders({
|
|
|
29090
29856
|
publishableKey,
|
|
29091
29857
|
enabled = true
|
|
29092
29858
|
}) {
|
|
29093
|
-
const { data: providers, isLoading } = (0,
|
|
29859
|
+
const { data: providers, isLoading } = (0, import_react_query14.useQuery)({
|
|
29094
29860
|
queryKey: ["unifold", "applePayProviders", publishableKey],
|
|
29095
29861
|
queryFn: () => getApplePayProviders(publishableKey),
|
|
29096
29862
|
enabled,
|
|
@@ -29105,7 +29871,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
29105
29871
|
data: ipData,
|
|
29106
29872
|
isLoading: isIpLoading,
|
|
29107
29873
|
error: ipError
|
|
29108
|
-
} = (0,
|
|
29874
|
+
} = (0, import_react_query15.useQuery)({
|
|
29109
29875
|
queryKey: ["unifold", "ipAddress"],
|
|
29110
29876
|
queryFn: () => getIpAddress(),
|
|
29111
29877
|
refetchOnMount: false,
|
|
@@ -29120,7 +29886,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
29120
29886
|
data: configData,
|
|
29121
29887
|
isLoading: isConfigLoading,
|
|
29122
29888
|
error: configError
|
|
29123
|
-
} = (0,
|
|
29889
|
+
} = (0, import_react_query15.useQuery)({
|
|
29124
29890
|
queryKey: ["unifold", "projectConfig", publishableKey],
|
|
29125
29891
|
queryFn: () => getProjectConfig(publishableKey),
|
|
29126
29892
|
refetchOnMount: false,
|
|
@@ -29167,7 +29933,7 @@ function useAddressValidation({
|
|
|
29167
29933
|
refetchOnMount = false
|
|
29168
29934
|
}) {
|
|
29169
29935
|
const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
29170
|
-
const { data, isLoading, error } = (0,
|
|
29936
|
+
const { data, isLoading, error } = (0, import_react_query16.useQuery)({
|
|
29171
29937
|
queryKey: [
|
|
29172
29938
|
"unifold",
|
|
29173
29939
|
"addressValidation",
|
|
@@ -29451,9 +30217,9 @@ function DepositsModal({
|
|
|
29451
30217
|
themeClass = ""
|
|
29452
30218
|
}) {
|
|
29453
30219
|
const { colors: colors2, fonts, components } = useTheme();
|
|
29454
|
-
const [allExecutions, setAllExecutions] = (0,
|
|
29455
|
-
const [selectedExecution, setSelectedExecution] = (0,
|
|
29456
|
-
(0,
|
|
30220
|
+
const [allExecutions, setAllExecutions] = (0, import_react28.useState)(sessionExecutions);
|
|
30221
|
+
const [selectedExecution, setSelectedExecution] = (0, import_react28.useState)(null);
|
|
30222
|
+
(0, import_react28.useEffect)(() => {
|
|
29457
30223
|
if (!open || !userId) return;
|
|
29458
30224
|
const fetchExecutions = async () => {
|
|
29459
30225
|
try {
|
|
@@ -29475,7 +30241,7 @@ function DepositsModal({
|
|
|
29475
30241
|
clearInterval(pollInterval);
|
|
29476
30242
|
};
|
|
29477
30243
|
}, [open, userId, publishableKey, sessionExecutions]);
|
|
29478
|
-
(0,
|
|
30244
|
+
(0, import_react28.useEffect)(() => {
|
|
29479
30245
|
if (!open) {
|
|
29480
30246
|
setSelectedExecution(null);
|
|
29481
30247
|
}
|
|
@@ -29598,13 +30364,13 @@ function TokenSelectorSheet({
|
|
|
29598
30364
|
}) {
|
|
29599
30365
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
29600
30366
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
29601
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
29602
|
-
const [recentTokens, setRecentTokens] = (0,
|
|
29603
|
-
const [hoveredTokenKey, setHoveredTokenKey] = (0,
|
|
29604
|
-
(0,
|
|
30367
|
+
const [searchQuery, setSearchQuery] = (0, import_react29.useState)("");
|
|
30368
|
+
const [recentTokens, setRecentTokens] = (0, import_react29.useState)([]);
|
|
30369
|
+
const [hoveredTokenKey, setHoveredTokenKey] = (0, import_react29.useState)(null);
|
|
30370
|
+
(0, import_react29.useEffect)(() => {
|
|
29605
30371
|
setRecentTokens(getRecentTokens());
|
|
29606
30372
|
}, []);
|
|
29607
|
-
const allOptions = (0,
|
|
30373
|
+
const allOptions = (0, import_react29.useMemo)(() => {
|
|
29608
30374
|
const options = [];
|
|
29609
30375
|
tokens.forEach((token) => {
|
|
29610
30376
|
token.chains.forEach((chain) => {
|
|
@@ -29613,7 +30379,7 @@ function TokenSelectorSheet({
|
|
|
29613
30379
|
});
|
|
29614
30380
|
return options;
|
|
29615
30381
|
}, [tokens]);
|
|
29616
|
-
const quickSelectOptions = (0,
|
|
30382
|
+
const quickSelectOptions = (0, import_react29.useMemo)(() => {
|
|
29617
30383
|
const result = [];
|
|
29618
30384
|
const seen = /* @__PURE__ */ new Set();
|
|
29619
30385
|
const addOption = (symbol, chainType, chainId, isRecent) => {
|
|
@@ -29645,7 +30411,7 @@ function TokenSelectorSheet({
|
|
|
29645
30411
|
});
|
|
29646
30412
|
setRecentTokens(updated);
|
|
29647
30413
|
};
|
|
29648
|
-
const fuse = (0,
|
|
30414
|
+
const fuse = (0, import_react29.useMemo)(
|
|
29649
30415
|
() => new Fuse(allOptions, {
|
|
29650
30416
|
keys: [
|
|
29651
30417
|
{ name: "token.symbol", weight: 2 },
|
|
@@ -29658,7 +30424,7 @@ function TokenSelectorSheet({
|
|
|
29658
30424
|
}),
|
|
29659
30425
|
[allOptions]
|
|
29660
30426
|
);
|
|
29661
|
-
const filteredOptions = (0,
|
|
30427
|
+
const filteredOptions = (0, import_react29.useMemo)(() => {
|
|
29662
30428
|
if (!searchQuery.trim()) return allOptions;
|
|
29663
30429
|
const query = searchQuery.trim();
|
|
29664
30430
|
const results = fuse.search(query);
|
|
@@ -30082,11 +30848,11 @@ function useDefaultToken({
|
|
|
30082
30848
|
defaultTokenAddress,
|
|
30083
30849
|
defaultSymbol
|
|
30084
30850
|
}) {
|
|
30085
|
-
const [token, setToken] = (0,
|
|
30086
|
-
const [chain, setChain] = (0,
|
|
30087
|
-
const [initialSelectionDone, setInitialSelectionDone] = (0,
|
|
30088
|
-
const appliedDefaultsRef = (0,
|
|
30089
|
-
(0,
|
|
30851
|
+
const [token, setToken] = (0, import_react30.useState)(null);
|
|
30852
|
+
const [chain, setChain] = (0, import_react30.useState)(null);
|
|
30853
|
+
const [initialSelectionDone, setInitialSelectionDone] = (0, import_react30.useState)(false);
|
|
30854
|
+
const appliedDefaultsRef = (0, import_react30.useRef)("");
|
|
30855
|
+
(0, import_react30.useEffect)(() => {
|
|
30090
30856
|
if (!tokens.length) return;
|
|
30091
30857
|
const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
|
|
30092
30858
|
const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
|
|
@@ -30112,7 +30878,7 @@ function useDefaultToken({
|
|
|
30112
30878
|
defaultChainId,
|
|
30113
30879
|
initialSelectionDone
|
|
30114
30880
|
]);
|
|
30115
|
-
(0,
|
|
30881
|
+
(0, import_react30.useEffect)(() => {
|
|
30116
30882
|
if (!tokens.length || !token) return;
|
|
30117
30883
|
const currentToken = tokens.find((t13) => t13.symbol === token);
|
|
30118
30884
|
if (!currentToken || currentToken.chains.length === 0) return;
|
|
@@ -30411,7 +31177,7 @@ function GlossaryModal({
|
|
|
30411
31177
|
) });
|
|
30412
31178
|
}
|
|
30413
31179
|
function useCopyAddress() {
|
|
30414
|
-
const [copied, setCopied] = (0,
|
|
31180
|
+
const [copied, setCopied] = (0, import_react31.useState)(false);
|
|
30415
31181
|
const handleCopy = (address) => {
|
|
30416
31182
|
if (!address) return;
|
|
30417
31183
|
navigator.clipboard.writeText(address);
|
|
@@ -30469,7 +31235,7 @@ function useHypercoreActivation(params) {
|
|
|
30469
31235
|
const recipient = recipientAddress?.trim() ?? "";
|
|
30470
31236
|
const source = sourceAddress?.trim() ?? "";
|
|
30471
31237
|
const hasAddresses = !!recipient && !!source;
|
|
30472
|
-
const { data, isLoading } = (0,
|
|
31238
|
+
const { data, isLoading } = (0, import_react_query17.useQuery)({
|
|
30473
31239
|
queryKey: ["unifold", "hypercoreActivation", source, recipient, publishableKey],
|
|
30474
31240
|
queryFn: () => checkHypercoreActivation(
|
|
30475
31241
|
{
|
|
@@ -30555,12 +31321,12 @@ function TransferCryptoSingleInput({
|
|
|
30555
31321
|
}) {
|
|
30556
31322
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
30557
31323
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
30558
|
-
const [copied, setCopied] = (0,
|
|
31324
|
+
const [copied, setCopied] = (0, import_react27.useState)(false);
|
|
30559
31325
|
const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
|
|
30560
|
-
const [glossaryOpen, setGlossaryOpen] = (0,
|
|
30561
|
-
const [detailsExpanded, setDetailsExpanded] = (0,
|
|
30562
|
-
const [depositsModalOpen, setDepositsModalOpen] = (0,
|
|
30563
|
-
const [tokenSelectorOpen, setTokenSelectorOpen] = (0,
|
|
31326
|
+
const [glossaryOpen, setGlossaryOpen] = (0, import_react27.useState)(false);
|
|
31327
|
+
const [detailsExpanded, setDetailsExpanded] = (0, import_react27.useState)(false);
|
|
31328
|
+
const [depositsModalOpen, setDepositsModalOpen] = (0, import_react27.useState)(false);
|
|
31329
|
+
const [tokenSelectorOpen, setTokenSelectorOpen] = (0, import_react27.useState)(false);
|
|
30564
31330
|
const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(
|
|
30565
31331
|
publishableKey,
|
|
30566
31332
|
{
|
|
@@ -30595,7 +31361,7 @@ function TransferCryptoSingleInput({
|
|
|
30595
31361
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
30596
31362
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
30597
31363
|
const error = walletsError?.message ?? null;
|
|
30598
|
-
const allAvailableChains = (0,
|
|
31364
|
+
const allAvailableChains = (0, import_react27.useMemo)(() => {
|
|
30599
31365
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
30600
31366
|
supportedTokens.forEach((t13) => {
|
|
30601
31367
|
t13.chains.forEach((c) => {
|
|
@@ -30640,7 +31406,7 @@ function TransferCryptoSingleInput({
|
|
|
30640
31406
|
publishableKey,
|
|
30641
31407
|
enabled: !!depositAddress && !!recipientAddress
|
|
30642
31408
|
});
|
|
30643
|
-
(0,
|
|
31409
|
+
(0, import_react27.useEffect)(() => {
|
|
30644
31410
|
if (!onSourceTokenChange || !token || !chain || !initialSelectionDone) return;
|
|
30645
31411
|
const { chainType, chainId } = parseChainKey(chain);
|
|
30646
31412
|
const matchedToken = supportedTokens.find((t13) => t13.symbol === token);
|
|
@@ -30657,7 +31423,7 @@ function TransferCryptoSingleInput({
|
|
|
30657
31423
|
isStablecoin: matchedToken?.is_stablecoin ?? false
|
|
30658
31424
|
});
|
|
30659
31425
|
}, [token, chain, initialSelectionDone, onSourceTokenChange, supportedTokens]);
|
|
30660
|
-
(0,
|
|
31426
|
+
(0, import_react27.useEffect)(() => {
|
|
30661
31427
|
if (onExecutionsChange) {
|
|
30662
31428
|
onExecutionsChange(depositExecutions);
|
|
30663
31429
|
}
|
|
@@ -31333,11 +32099,11 @@ function TransferCryptoDoubleInput({
|
|
|
31333
32099
|
}) {
|
|
31334
32100
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
31335
32101
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
31336
|
-
const [copied, setCopied] = (0,
|
|
32102
|
+
const [copied, setCopied] = (0, import_react32.useState)(false);
|
|
31337
32103
|
const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
|
|
31338
|
-
const [glossaryOpen, setGlossaryOpen] = (0,
|
|
31339
|
-
const [detailsExpanded, setDetailsExpanded] = (0,
|
|
31340
|
-
const [depositsModalOpen, setDepositsModalOpen] = (0,
|
|
32104
|
+
const [glossaryOpen, setGlossaryOpen] = (0, import_react32.useState)(false);
|
|
32105
|
+
const [detailsExpanded, setDetailsExpanded] = (0, import_react32.useState)(false);
|
|
32106
|
+
const [depositsModalOpen, setDepositsModalOpen] = (0, import_react32.useState)(false);
|
|
31341
32107
|
const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(
|
|
31342
32108
|
publishableKey,
|
|
31343
32109
|
{
|
|
@@ -31371,7 +32137,7 @@ function TransferCryptoDoubleInput({
|
|
|
31371
32137
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
31372
32138
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
31373
32139
|
const error = walletsError?.message ?? null;
|
|
31374
|
-
const allAvailableChains = (0,
|
|
32140
|
+
const allAvailableChains = (0, import_react32.useMemo)(() => {
|
|
31375
32141
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
31376
32142
|
supportedTokens.forEach((t13) => {
|
|
31377
32143
|
t13.chains.forEach((c) => {
|
|
@@ -31415,7 +32181,7 @@ function TransferCryptoDoubleInput({
|
|
|
31415
32181
|
publishableKey,
|
|
31416
32182
|
enabled: !!depositAddress && !!recipientAddress
|
|
31417
32183
|
});
|
|
31418
|
-
(0,
|
|
32184
|
+
(0, import_react32.useEffect)(() => {
|
|
31419
32185
|
if (onExecutionsChange) {
|
|
31420
32186
|
onExecutionsChange(depositExecutions);
|
|
31421
32187
|
}
|
|
@@ -31967,7 +32733,7 @@ function useDepositQuote(params) {
|
|
|
31967
32733
|
...adjustForSlippage ? { adjust_for_slippage: true } : {},
|
|
31968
32734
|
...stablecoinParity ? { stablecoin_parity: true } : {}
|
|
31969
32735
|
};
|
|
31970
|
-
return (0,
|
|
32736
|
+
return (0, import_react_query18.useQuery)({
|
|
31971
32737
|
queryKey: [
|
|
31972
32738
|
"unifold",
|
|
31973
32739
|
"depositQuote",
|
|
@@ -31997,7 +32763,7 @@ function useExternalWallets({
|
|
|
31997
32763
|
publishableKey,
|
|
31998
32764
|
enabled = true
|
|
31999
32765
|
}) {
|
|
32000
|
-
const { data: wallets = [], isLoading } = (0,
|
|
32766
|
+
const { data: wallets = [], isLoading } = (0, import_react_query19.useQuery)({
|
|
32001
32767
|
queryKey: ["unifold", "external-wallets", publishableKey],
|
|
32002
32768
|
queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
|
|
32003
32769
|
enabled: enabled && !!publishableKey,
|
|
@@ -32861,13 +33627,13 @@ function ConfirmingView({
|
|
|
32861
33627
|
amountReceivedUsdAtSubmission
|
|
32862
33628
|
}) {
|
|
32863
33629
|
const { colors: colors2, fonts, components } = useTheme();
|
|
32864
|
-
const [fallbackSettled, setFallbackSettled] = (0,
|
|
33630
|
+
const [fallbackSettled, setFallbackSettled] = (0, import_react33.useState)(false);
|
|
32865
33631
|
const hasExecution = executions.length > 0;
|
|
32866
33632
|
const isCheckoutMode = paymentIntentStatus != null;
|
|
32867
33633
|
const isPaymentComplete = paymentIntentStatus === "succeeded";
|
|
32868
33634
|
const amountChanged = amountReceivedUsdAtSubmission != null && amountReceivedUsd != null && amountReceivedUsd !== amountReceivedUsdAtSubmission;
|
|
32869
33635
|
const piSettled = !isCheckoutMode || isPaymentComplete || amountChanged || fallbackSettled;
|
|
32870
|
-
(0,
|
|
33636
|
+
(0, import_react33.useEffect)(() => {
|
|
32871
33637
|
if (!hasExecution || piSettled) return;
|
|
32872
33638
|
const timeout = setTimeout(() => setFallbackSettled(true), SETTLE_FALLBACK_MS);
|
|
32873
33639
|
return () => clearTimeout(timeout);
|
|
@@ -34601,10 +35367,9 @@ function DepositModal({
|
|
|
34601
35367
|
applePaySubTitle = "Instant",
|
|
34602
35368
|
enableBankTransfer,
|
|
34603
35369
|
enableStripeLink = false,
|
|
34604
|
-
|
|
35370
|
+
userEmail,
|
|
34605
35371
|
hideDepositFlowInfo = false,
|
|
34606
35372
|
hideDisplayDescription = false,
|
|
34607
|
-
externalUserEmail,
|
|
34608
35373
|
onDepositSuccess,
|
|
34609
35374
|
onDepositError,
|
|
34610
35375
|
onEvent,
|
|
@@ -35035,11 +35800,18 @@ function DepositModal({
|
|
|
35035
35800
|
return "Success";
|
|
35036
35801
|
case "guest_limit_reached":
|
|
35037
35802
|
return "Limit reached";
|
|
35803
|
+
case "limit_upgrade_intro":
|
|
35804
|
+
case "limit_upgrade_failed":
|
|
35805
|
+
return "Limit reached";
|
|
35806
|
+
case "limit_upgrade_form":
|
|
35807
|
+
return "Verify identity";
|
|
35808
|
+
case "limit_upgrade_submitting":
|
|
35809
|
+
return "Verifying";
|
|
35038
35810
|
default:
|
|
35039
35811
|
return "Pay with Apple Pay";
|
|
35040
35812
|
}
|
|
35041
35813
|
})();
|
|
35042
|
-
const applePayShowBack = sessionOpenedFromMenu || applePayView === "phone_input" || applePayView === "email_otp" || applePayView === "phone_otp" || applePayView === "submitting_session" || applePayView === "checking_deposit";
|
|
35814
|
+
const applePayShowBack = sessionOpenedFromMenu || applePayView === "phone_input" || applePayView === "email_otp" || applePayView === "phone_otp" || applePayView === "submitting_session" || applePayView === "checking_deposit" || applePayView === "limit_upgrade_intro" || applePayView === "limit_upgrade_form" || applePayView === "limit_upgrade_failed";
|
|
35043
35815
|
const handleBack = () => {
|
|
35044
35816
|
if (view === "card" && cardView === "quotes") {
|
|
35045
35817
|
setCardView("amount");
|
|
@@ -35718,7 +36490,7 @@ function DepositModal({
|
|
|
35718
36490
|
destinationChainId,
|
|
35719
36491
|
destinationTokenAddress,
|
|
35720
36492
|
wallets,
|
|
35721
|
-
email:
|
|
36493
|
+
email: userEmail,
|
|
35722
36494
|
iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/link.svg` : void 0,
|
|
35723
36495
|
step: stripeLinkStep,
|
|
35724
36496
|
onStepChange: setStripeLinkStep,
|
|
@@ -35781,13 +36553,10 @@ function DepositModal({
|
|
|
35781
36553
|
ref: applePayHandleRef,
|
|
35782
36554
|
userId,
|
|
35783
36555
|
publishableKey,
|
|
35784
|
-
recipientAddress,
|
|
35785
36556
|
destinationChainType,
|
|
35786
36557
|
destinationChainId,
|
|
35787
36558
|
destinationTokenAddress,
|
|
35788
|
-
|
|
35789
|
-
externalUserEmail,
|
|
35790
|
-
enableApplePay,
|
|
36559
|
+
userEmail,
|
|
35791
36560
|
wallets,
|
|
35792
36561
|
onViewChange: setApplePayView,
|
|
35793
36562
|
onEvent,
|
|
@@ -35815,7 +36584,7 @@ function DepositModal({
|
|
|
35815
36584
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["succeeded", "expired", "refunded", "canceled"]);
|
|
35816
36585
|
function usePaymentIntent(params) {
|
|
35817
36586
|
const { clientSecret, publishableKey, enabled = true, pollingInterval = 3e3 } = params;
|
|
35818
|
-
return (0,
|
|
36587
|
+
return (0, import_react_query20.useQuery)({
|
|
35819
36588
|
queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
|
|
35820
36589
|
queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
|
|
35821
36590
|
enabled: enabled && !!clientSecret && !!publishableKey,
|
|
@@ -35897,12 +36666,12 @@ function CheckoutModal({
|
|
|
35897
36666
|
onEvent
|
|
35898
36667
|
}) {
|
|
35899
36668
|
const { colors: colors2, fonts, components } = useTheme();
|
|
35900
|
-
const [view, setView] = (0,
|
|
35901
|
-
const resetViewTimeoutRef = (0,
|
|
35902
|
-
const [browserWalletInfo, setBrowserWalletInfo] = (0,
|
|
35903
|
-
const [browserWalletChainType, setBrowserWalletChainType] = (0,
|
|
35904
|
-
const lastCheckoutMethodRef = (0,
|
|
35905
|
-
const emitCheckoutSuccess = (0,
|
|
36669
|
+
const [view, setView] = (0, import_react34.useState)("main");
|
|
36670
|
+
const resetViewTimeoutRef = (0, import_react34.useRef)(null);
|
|
36671
|
+
const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react34.useState)(null);
|
|
36672
|
+
const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react34.useState)(() => getStoredWalletState()?.chainType);
|
|
36673
|
+
const lastCheckoutMethodRef = (0, import_react34.useRef)(void 0);
|
|
36674
|
+
const emitCheckoutSuccess = (0, import_react34.useCallback)(
|
|
35906
36675
|
(data, method) => {
|
|
35907
36676
|
const isSucceeded = data.status === "succeeded";
|
|
35908
36677
|
const richIntent = isSucceeded && data.paymentIntent ? mapToCheckoutPaymentIntent(data.paymentIntent) : void 0;
|
|
@@ -35925,10 +36694,10 @@ function CheckoutModal({
|
|
|
35925
36694
|
},
|
|
35926
36695
|
[onCheckoutSuccess, onEvent]
|
|
35927
36696
|
);
|
|
35928
|
-
const [resolvedTheme, setResolvedTheme] = (0,
|
|
36697
|
+
const [resolvedTheme, setResolvedTheme] = (0, import_react34.useState)(
|
|
35929
36698
|
theme === "auto" ? "dark" : theme
|
|
35930
36699
|
);
|
|
35931
|
-
(0,
|
|
36700
|
+
(0, import_react34.useEffect)(() => {
|
|
35932
36701
|
if (theme === "auto") {
|
|
35933
36702
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
35934
36703
|
setResolvedTheme(mediaQuery.matches ? "dark" : "light");
|
|
@@ -35958,15 +36727,15 @@ function CheckoutModal({
|
|
|
35958
36727
|
});
|
|
35959
36728
|
const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
|
|
35960
36729
|
const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
|
|
35961
|
-
(0,
|
|
36730
|
+
(0, import_react34.useEffect)(() => {
|
|
35962
36731
|
if (view === "transfer" && !showTransferCrypto) {
|
|
35963
36732
|
setView("main");
|
|
35964
36733
|
} else if (view === "wallet_connect" && !showConnectWallet) {
|
|
35965
36734
|
setView("main");
|
|
35966
36735
|
}
|
|
35967
36736
|
}, [showConnectWallet, showTransferCrypto, view]);
|
|
35968
|
-
const prevStatusRef = (0,
|
|
35969
|
-
(0,
|
|
36737
|
+
const prevStatusRef = (0, import_react34.useRef)(null);
|
|
36738
|
+
(0, import_react34.useEffect)(() => {
|
|
35970
36739
|
if (!paymentIntent) return;
|
|
35971
36740
|
const prev = prevStatusRef.current;
|
|
35972
36741
|
prevStatusRef.current = paymentIntent.status;
|
|
@@ -35984,11 +36753,11 @@ function CheckoutModal({
|
|
|
35984
36753
|
);
|
|
35985
36754
|
}
|
|
35986
36755
|
}, [emitCheckoutSuccess, paymentIntent, view]);
|
|
35987
|
-
const wallets = (0,
|
|
36756
|
+
const wallets = (0, import_react34.useMemo)(() => {
|
|
35988
36757
|
if (!paymentIntent) return [];
|
|
35989
36758
|
return mapDepositAddressesToWallets(paymentIntent.deposit_addresses, paymentIntent);
|
|
35990
36759
|
}, [paymentIntent]);
|
|
35991
|
-
const formatCryptoAmount = (0,
|
|
36760
|
+
const formatCryptoAmount = (0, import_react34.useMemo)(() => {
|
|
35992
36761
|
if (!paymentIntent) return (_) => "";
|
|
35993
36762
|
const decimals = paymentIntent.destination_token_decimals ?? 6;
|
|
35994
36763
|
const symbol = paymentIntent.currency.toUpperCase();
|
|
@@ -35998,7 +36767,7 @@ function CheckoutModal({
|
|
|
35998
36767
|
return `${formatted} ${symbol}`;
|
|
35999
36768
|
};
|
|
36000
36769
|
}, [paymentIntent]);
|
|
36001
|
-
const remainingAmountUsd = (0,
|
|
36770
|
+
const remainingAmountUsd = (0, import_react34.useMemo)(() => {
|
|
36002
36771
|
if (!paymentIntent) return void 0;
|
|
36003
36772
|
const total = parseFloat(paymentIntent.destination_amount_usd || paymentIntent.amount_usd);
|
|
36004
36773
|
const received = parseFloat(
|
|
@@ -36009,8 +36778,8 @@ function CheckoutModal({
|
|
|
36009
36778
|
const remaining = total - received;
|
|
36010
36779
|
return remaining > 0 ? remaining.toFixed(2) : "0.00";
|
|
36011
36780
|
}, [paymentIntent]);
|
|
36012
|
-
const [selectedSource, setSelectedSource] = (0,
|
|
36013
|
-
const remainingDestinationAmount = (0,
|
|
36781
|
+
const [selectedSource, setSelectedSource] = (0, import_react34.useState)(null);
|
|
36782
|
+
const remainingDestinationAmount = (0, import_react34.useMemo)(() => {
|
|
36014
36783
|
if (!paymentIntent) return "0";
|
|
36015
36784
|
const remaining = BigInt(paymentIntent.destination_amount) - BigInt(paymentIntent.destination_amount_received);
|
|
36016
36785
|
return remaining > 0n ? remaining.toString() : "0";
|
|
@@ -36032,7 +36801,7 @@ function CheckoutModal({
|
|
|
36032
36801
|
stablecoinParity: paymentIntent?.stablecoin_parity ?? false,
|
|
36033
36802
|
enabled: open && view === "transfer" && !!paymentIntent && !!selectedSource && remainingDestinationAmount !== "0"
|
|
36034
36803
|
});
|
|
36035
|
-
const effectiveCheckoutQuote = (0,
|
|
36804
|
+
const effectiveCheckoutQuote = (0, import_react34.useMemo)(() => {
|
|
36036
36805
|
if (!sourceQuote || !selectedSource) return null;
|
|
36037
36806
|
const baseQuote = {
|
|
36038
36807
|
sourceAmount: sourceQuote.source_amount,
|
|
@@ -36053,7 +36822,7 @@ function CheckoutModal({
|
|
|
36053
36822
|
sourceAmountUsd: minUsd.toFixed(2)
|
|
36054
36823
|
};
|
|
36055
36824
|
}, [sourceQuote, selectedSource]);
|
|
36056
|
-
const handleBrowserWalletClick = (0,
|
|
36825
|
+
const handleBrowserWalletClick = (0, import_react34.useCallback)(
|
|
36057
36826
|
(walletInfo) => {
|
|
36058
36827
|
const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
|
|
36059
36828
|
setStoredWalletState(walletInfo.type);
|
|
@@ -36076,19 +36845,19 @@ function CheckoutModal({
|
|
|
36076
36845
|
},
|
|
36077
36846
|
[wallets, onCheckoutError]
|
|
36078
36847
|
);
|
|
36079
|
-
const handleWalletConnectClick = (0,
|
|
36848
|
+
const handleWalletConnectClick = (0, import_react34.useCallback)(() => {
|
|
36080
36849
|
setBrowserWalletInfo(null);
|
|
36081
36850
|
lastCheckoutMethodRef.current = "wallet_connect";
|
|
36082
36851
|
setView("wallet_connect");
|
|
36083
36852
|
}, []);
|
|
36084
|
-
const handleWalletDisconnect = (0,
|
|
36853
|
+
const handleWalletDisconnect = (0, import_react34.useCallback)(() => {
|
|
36085
36854
|
setUserDisconnectedWallet(true);
|
|
36086
36855
|
clearStoredWalletState();
|
|
36087
36856
|
setBrowserWalletChainType(void 0);
|
|
36088
36857
|
setBrowserWalletInfo(null);
|
|
36089
36858
|
setView("main");
|
|
36090
36859
|
}, []);
|
|
36091
|
-
const handleClose = (0,
|
|
36860
|
+
const handleClose = (0, import_react34.useCallback)(() => {
|
|
36092
36861
|
onOpenChange(false);
|
|
36093
36862
|
if (resetViewTimeoutRef.current) {
|
|
36094
36863
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -36100,7 +36869,7 @@ function CheckoutModal({
|
|
|
36100
36869
|
resetViewTimeoutRef.current = null;
|
|
36101
36870
|
}, 200);
|
|
36102
36871
|
}, [onOpenChange]);
|
|
36103
|
-
(0,
|
|
36872
|
+
(0, import_react34.useLayoutEffect)(() => {
|
|
36104
36873
|
if (!open) return;
|
|
36105
36874
|
if (resetViewTimeoutRef.current) {
|
|
36106
36875
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -36110,7 +36879,7 @@ function CheckoutModal({
|
|
|
36110
36879
|
setBrowserWalletInfo(null);
|
|
36111
36880
|
lastCheckoutMethodRef.current = void 0;
|
|
36112
36881
|
}, [open]);
|
|
36113
|
-
(0,
|
|
36882
|
+
(0, import_react34.useEffect)(
|
|
36114
36883
|
() => () => {
|
|
36115
36884
|
if (resetViewTimeoutRef.current) {
|
|
36116
36885
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -36118,7 +36887,7 @@ function CheckoutModal({
|
|
|
36118
36887
|
},
|
|
36119
36888
|
[]
|
|
36120
36889
|
);
|
|
36121
|
-
const handleBack = (0,
|
|
36890
|
+
const handleBack = (0, import_react34.useCallback)(() => {
|
|
36122
36891
|
setView("main");
|
|
36123
36892
|
}, []);
|
|
36124
36893
|
const poweredByFooter = /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "uf-pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
@@ -36495,7 +37264,7 @@ function CheckoutModal({
|
|
|
36495
37264
|
) }) });
|
|
36496
37265
|
}
|
|
36497
37266
|
function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
36498
|
-
return (0,
|
|
37267
|
+
return (0, import_react_query21.useQuery)({
|
|
36499
37268
|
queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
|
|
36500
37269
|
queryFn: () => getSupportedDestinationTokens(publishableKey),
|
|
36501
37270
|
staleTime: 1e3 * 60 * 5,
|
|
@@ -36530,7 +37299,7 @@ function useSourceTokenValidation(params) {
|
|
|
36530
37299
|
enabled = true
|
|
36531
37300
|
} = params;
|
|
36532
37301
|
const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
|
|
36533
|
-
return (0,
|
|
37302
|
+
return (0, import_react_query22.useQuery)({
|
|
36534
37303
|
queryKey: [
|
|
36535
37304
|
"unifold",
|
|
36536
37305
|
"sourceTokenValidation",
|
|
@@ -36579,7 +37348,7 @@ function useSourceTokenValidation(params) {
|
|
|
36579
37348
|
function useAddressBalance(params) {
|
|
36580
37349
|
const { address, chainType, chainId, tokenAddress, publishableKey, enabled = true } = params;
|
|
36581
37350
|
const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
|
|
36582
|
-
return (0,
|
|
37351
|
+
return (0, import_react_query23.useQuery)({
|
|
36583
37352
|
queryKey: [
|
|
36584
37353
|
"unifold",
|
|
36585
37354
|
"addressBalance",
|
|
@@ -36635,7 +37404,7 @@ function useAddressBalance(params) {
|
|
|
36635
37404
|
}
|
|
36636
37405
|
function useExecutions(userId, publishableKey, options) {
|
|
36637
37406
|
const actionType = options?.actionType ?? ActionType.Deposit;
|
|
36638
|
-
return (0,
|
|
37407
|
+
return (0, import_react_query24.useQuery)({
|
|
36639
37408
|
queryKey: ["unifold", "executions", actionType, userId, publishableKey],
|
|
36640
37409
|
queryFn: () => queryExecutions(userId, publishableKey, actionType),
|
|
36641
37410
|
enabled: (options?.enabled ?? true) && !!userId,
|
|
@@ -36681,20 +37450,20 @@ function useWithdrawPolling({
|
|
|
36681
37450
|
status: execution.status,
|
|
36682
37451
|
failureReason: execution.failure_reason
|
|
36683
37452
|
});
|
|
36684
|
-
const [executions, setExecutions] = (0,
|
|
36685
|
-
const [isPolling, setIsPolling] = (0,
|
|
36686
|
-
const enabledAtRef = (0,
|
|
36687
|
-
const trackedRef = (0,
|
|
36688
|
-
const prevEnabledRef = (0,
|
|
36689
|
-
const onSuccessRef = (0,
|
|
36690
|
-
const onErrorRef = (0,
|
|
36691
|
-
(0,
|
|
37453
|
+
const [executions, setExecutions] = (0, import_react36.useState)([]);
|
|
37454
|
+
const [isPolling, setIsPolling] = (0, import_react36.useState)(false);
|
|
37455
|
+
const enabledAtRef = (0, import_react36.useRef)(/* @__PURE__ */ new Date());
|
|
37456
|
+
const trackedRef = (0, import_react36.useRef)(/* @__PURE__ */ new Map());
|
|
37457
|
+
const prevEnabledRef = (0, import_react36.useRef)(false);
|
|
37458
|
+
const onSuccessRef = (0, import_react36.useRef)(onWithdrawSuccess);
|
|
37459
|
+
const onErrorRef = (0, import_react36.useRef)(onWithdrawError);
|
|
37460
|
+
(0, import_react36.useEffect)(() => {
|
|
36692
37461
|
onSuccessRef.current = onWithdrawSuccess;
|
|
36693
37462
|
}, [onWithdrawSuccess]);
|
|
36694
|
-
(0,
|
|
37463
|
+
(0, import_react36.useEffect)(() => {
|
|
36695
37464
|
onErrorRef.current = onWithdrawError;
|
|
36696
37465
|
}, [onWithdrawError]);
|
|
36697
|
-
(0,
|
|
37466
|
+
(0, import_react36.useEffect)(() => {
|
|
36698
37467
|
if (enabled && !prevEnabledRef.current) {
|
|
36699
37468
|
enabledAtRef.current = /* @__PURE__ */ new Date();
|
|
36700
37469
|
trackedRef.current.clear();
|
|
@@ -36704,7 +37473,7 @@ function useWithdrawPolling({
|
|
|
36704
37473
|
}
|
|
36705
37474
|
prevEnabledRef.current = enabled;
|
|
36706
37475
|
}, [enabled]);
|
|
36707
|
-
(0,
|
|
37476
|
+
(0, import_react36.useEffect)(() => {
|
|
36708
37477
|
if (!userId || !enabled) return;
|
|
36709
37478
|
const enabledAt = enabledAtRef.current;
|
|
36710
37479
|
const poll = async () => {
|
|
@@ -36784,7 +37553,7 @@ function useWithdrawPolling({
|
|
|
36784
37553
|
setIsPolling(false);
|
|
36785
37554
|
};
|
|
36786
37555
|
}, [userId, publishableKey, enabled]);
|
|
36787
|
-
(0,
|
|
37556
|
+
(0, import_react36.useEffect)(() => {
|
|
36788
37557
|
if (!enabled || !depositWalletId) return;
|
|
36789
37558
|
const trigger = async () => {
|
|
36790
37559
|
try {
|
|
@@ -36961,7 +37730,7 @@ function useVerifyRecipientAddress(params) {
|
|
|
36961
37730
|
} = params;
|
|
36962
37731
|
const trimmedAddress = recipientAddress?.trim() || "";
|
|
36963
37732
|
const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
|
|
36964
|
-
return (0,
|
|
37733
|
+
return (0, import_react_query25.useQuery)({
|
|
36965
37734
|
queryKey: [
|
|
36966
37735
|
"unifold",
|
|
36967
37736
|
"verifyRecipientAddress",
|
|
@@ -37000,7 +37769,7 @@ function useGetDepositAddress(params) {
|
|
|
37000
37769
|
enabled = true
|
|
37001
37770
|
} = params;
|
|
37002
37771
|
const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
37003
|
-
return (0,
|
|
37772
|
+
return (0, import_react_query26.useQuery)({
|
|
37004
37773
|
queryKey: [
|
|
37005
37774
|
"unifold",
|
|
37006
37775
|
"getDepositAddress",
|
|
@@ -37067,7 +37836,7 @@ function useHypercoreWithdrawActivation(params) {
|
|
|
37067
37836
|
actionType: ActionType.Withdraw,
|
|
37068
37837
|
enabled: enabled && isHypercore(sourceChainId)
|
|
37069
37838
|
});
|
|
37070
|
-
const depositWalletAddress = (0,
|
|
37839
|
+
const depositWalletAddress = (0, import_react38.useMemo)(() => {
|
|
37071
37840
|
const wallets = depositWalletLookup.data?.data ?? [];
|
|
37072
37841
|
return wallets.find((w) => w.chain_type === sourceChainType)?.address;
|
|
37073
37842
|
}, [depositWalletLookup.data, sourceChainType]);
|
|
@@ -37153,22 +37922,22 @@ function WithdrawForm({
|
|
|
37153
37922
|
footerLeft
|
|
37154
37923
|
}) {
|
|
37155
37924
|
const { colors: colors2, fonts, components } = useTheme();
|
|
37156
|
-
const [recipientAddress, setRecipientAddress] = (0,
|
|
37157
|
-
const [amount, setAmount] = (0,
|
|
37158
|
-
const [inputUnit, setInputUnit] = (0,
|
|
37159
|
-
const [isSubmitting, setIsSubmitting] = (0,
|
|
37160
|
-
const [submitError, setSubmitError] = (0,
|
|
37161
|
-
const [detailsExpanded, setDetailsExpanded] = (0,
|
|
37162
|
-
const [glossaryOpen, setGlossaryOpen] = (0,
|
|
37163
|
-
const [isMaxed, setIsMaxed] = (0,
|
|
37164
|
-
(0,
|
|
37925
|
+
const [recipientAddress, setRecipientAddress] = (0, import_react37.useState)(recipientAddressProp || "");
|
|
37926
|
+
const [amount, setAmount] = (0, import_react37.useState)("");
|
|
37927
|
+
const [inputUnit, setInputUnit] = (0, import_react37.useState)("fiat");
|
|
37928
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react37.useState)(false);
|
|
37929
|
+
const [submitError, setSubmitError] = (0, import_react37.useState)(null);
|
|
37930
|
+
const [detailsExpanded, setDetailsExpanded] = (0, import_react37.useState)(false);
|
|
37931
|
+
const [glossaryOpen, setGlossaryOpen] = (0, import_react37.useState)(false);
|
|
37932
|
+
const [isMaxed, setIsMaxed] = (0, import_react37.useState)(false);
|
|
37933
|
+
(0, import_react37.useEffect)(() => {
|
|
37165
37934
|
setRecipientAddress(recipientAddressProp || "");
|
|
37166
37935
|
setAmount("");
|
|
37167
37936
|
setInputUnit("fiat");
|
|
37168
37937
|
setSubmitError(null);
|
|
37169
37938
|
setIsMaxed(false);
|
|
37170
37939
|
}, [recipientAddressProp]);
|
|
37171
|
-
(0,
|
|
37940
|
+
(0, import_react37.useEffect)(() => {
|
|
37172
37941
|
setIsMaxed(false);
|
|
37173
37942
|
}, [balanceData?.balanceBaseUnit]);
|
|
37174
37943
|
const trimmedAddress = recipientAddress.trim();
|
|
@@ -37186,7 +37955,7 @@ function WithdrawForm({
|
|
|
37186
37955
|
enabled: debouncedAddress.length > 5 && !!selectedChain
|
|
37187
37956
|
});
|
|
37188
37957
|
const isDebouncing = trimmedAddress !== debouncedAddress;
|
|
37189
|
-
const addressError = (0,
|
|
37958
|
+
const addressError = (0, import_react37.useMemo)(() => {
|
|
37190
37959
|
if (!trimmedAddress || trimmedAddress.length <= 5) return null;
|
|
37191
37960
|
if (isDebouncing || isVerifyingAddress) return null;
|
|
37192
37961
|
if (verifyError) return t10.invalidAddress;
|
|
@@ -37220,33 +37989,33 @@ function WithdrawForm({
|
|
|
37220
37989
|
destinationTokenAddress: selectedChain?.token_address,
|
|
37221
37990
|
enabled: isAddressValid
|
|
37222
37991
|
});
|
|
37223
|
-
const exchangeRate = (0,
|
|
37992
|
+
const exchangeRate = (0, import_react37.useMemo)(() => {
|
|
37224
37993
|
if (!balanceData?.exchangeRate) return 0;
|
|
37225
37994
|
return parseFloat(balanceData.exchangeRate);
|
|
37226
37995
|
}, [balanceData]);
|
|
37227
|
-
const balanceCrypto = (0,
|
|
37996
|
+
const balanceCrypto = (0, import_react37.useMemo)(() => {
|
|
37228
37997
|
if (!balanceData?.balanceHuman) return 0;
|
|
37229
37998
|
return parseFloat(balanceData.balanceHuman);
|
|
37230
37999
|
}, [balanceData]);
|
|
37231
|
-
const balanceUsdNum = (0,
|
|
38000
|
+
const balanceUsdNum = (0, import_react37.useMemo)(() => {
|
|
37232
38001
|
if (!balanceData?.balanceUsd) return 0;
|
|
37233
38002
|
return parseFloat(balanceData.balanceUsd);
|
|
37234
38003
|
}, [balanceData]);
|
|
37235
38004
|
const tokenSymbol = sourceTokenSymbol || balanceData?.symbol || "TOKEN";
|
|
37236
38005
|
const sourceDecimals = balanceData?.decimals ?? 6;
|
|
37237
|
-
const cryptoAmountFromInput = (0,
|
|
38006
|
+
const cryptoAmountFromInput = (0, import_react37.useMemo)(() => {
|
|
37238
38007
|
const val = parseFloat(amount);
|
|
37239
38008
|
if (!val || val <= 0) return 0;
|
|
37240
38009
|
if (inputUnit === "crypto") return val;
|
|
37241
38010
|
return exchangeRate > 0 ? val / exchangeRate : 0;
|
|
37242
38011
|
}, [amount, inputUnit, exchangeRate]);
|
|
37243
|
-
const fiatAmountFromInput = (0,
|
|
38012
|
+
const fiatAmountFromInput = (0, import_react37.useMemo)(() => {
|
|
37244
38013
|
const val = parseFloat(amount);
|
|
37245
38014
|
if (!val || val <= 0) return 0;
|
|
37246
38015
|
if (inputUnit === "fiat") return val;
|
|
37247
38016
|
return val * exchangeRate;
|
|
37248
38017
|
}, [amount, inputUnit, exchangeRate]);
|
|
37249
|
-
const convertedDisplay = (0,
|
|
38018
|
+
const convertedDisplay = (0, import_react37.useMemo)(() => {
|
|
37250
38019
|
if (!amount || parseFloat(amount) <= 0) return null;
|
|
37251
38020
|
if (inputUnit === "crypto") {
|
|
37252
38021
|
return `$${fiatAmountFromInput.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
@@ -37265,7 +38034,7 @@ function WithdrawForm({
|
|
|
37265
38034
|
isMaxed,
|
|
37266
38035
|
isStablecoin
|
|
37267
38036
|
]);
|
|
37268
|
-
const balanceDisplay = (0,
|
|
38037
|
+
const balanceDisplay = (0, import_react37.useMemo)(() => {
|
|
37269
38038
|
if (isLoadingBalance || !balanceData) return null;
|
|
37270
38039
|
if (inputUnit === "crypto") {
|
|
37271
38040
|
const displayDecimals = isStablecoin ? 2 : 6;
|
|
@@ -37288,7 +38057,7 @@ function WithdrawForm({
|
|
|
37288
38057
|
tokenSymbol,
|
|
37289
38058
|
isStablecoin
|
|
37290
38059
|
]);
|
|
37291
|
-
const handleSwitchUnit = (0,
|
|
38060
|
+
const handleSwitchUnit = (0, import_react37.useCallback)(() => {
|
|
37292
38061
|
if (isMaxed && balanceData) {
|
|
37293
38062
|
if (inputUnit === "crypto") {
|
|
37294
38063
|
setAmount((Math.round(balanceUsdNum * 100) / 100).toFixed(2));
|
|
@@ -37315,7 +38084,7 @@ function WithdrawForm({
|
|
|
37315
38084
|
setInputUnit("crypto");
|
|
37316
38085
|
}
|
|
37317
38086
|
}, [amount, inputUnit, exchangeRate, sourceDecimals, isMaxed, balanceData, balanceUsdNum]);
|
|
37318
|
-
const handleMaxClick = (0,
|
|
38087
|
+
const handleMaxClick = (0, import_react37.useCallback)(() => {
|
|
37319
38088
|
if (inputUnit === "crypto") {
|
|
37320
38089
|
if (balanceCrypto <= 0) return;
|
|
37321
38090
|
setAmount(balanceData?.balanceHuman ?? "0");
|
|
@@ -37329,7 +38098,7 @@ function WithdrawForm({
|
|
|
37329
38098
|
const isBelowMinimum = minimumWithdrawAmountUsd !== null && fiatAmountFromInput > 0 && Math.round(fiatAmountFromInput * 100) / 100 < minimumWithdrawAmountUsd;
|
|
37330
38099
|
const isOverBalance = inputUnit === "crypto" ? cryptoAmountFromInput > 0 && balanceCrypto > 0 && cryptoAmountFromInput > balanceCrypto : fiatAmountFromInput > 0 && balanceUsdNum > 0 && Math.round(fiatAmountFromInput * 100) / 100 > Math.round(balanceUsdNum * 100) / 100;
|
|
37331
38100
|
const isFormValid = trimmedAddress.length > 0 && amount.trim().length > 0 && cryptoAmountFromInput > 0 && isAddressValid && !isBelowMinimum && !isOverBalance && !isBalanceBelowMinimum && !!balanceData;
|
|
37332
|
-
const handleWithdraw = (0,
|
|
38101
|
+
const handleWithdraw = (0, import_react37.useCallback)(async () => {
|
|
37333
38102
|
if (!selectedToken || !selectedChain) return;
|
|
37334
38103
|
if (!isFormValid) return;
|
|
37335
38104
|
setIsSubmitting(true);
|
|
@@ -37956,9 +38725,9 @@ function WithdrawConfirmingView({
|
|
|
37956
38725
|
onViewTracker
|
|
37957
38726
|
}) {
|
|
37958
38727
|
const { colors: colors2, fonts, components } = useTheme();
|
|
37959
|
-
const [showButton, setShowButton] = (0,
|
|
38728
|
+
const [showButton, setShowButton] = (0, import_react39.useState)(false);
|
|
37960
38729
|
const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
|
|
37961
|
-
(0,
|
|
38730
|
+
(0, import_react39.useEffect)(() => {
|
|
37962
38731
|
if (latestExecution) return;
|
|
37963
38732
|
const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
|
|
37964
38733
|
return () => clearTimeout(timer);
|
|
@@ -38102,7 +38871,7 @@ function WithdrawModal({
|
|
|
38102
38871
|
theme = "dark",
|
|
38103
38872
|
hideOverlay = false
|
|
38104
38873
|
}) {
|
|
38105
|
-
const onWithdrawSuccessFor = (0,
|
|
38874
|
+
const onWithdrawSuccessFor = (0, import_react35.useCallback)(
|
|
38106
38875
|
(data) => {
|
|
38107
38876
|
onWithdrawSuccess?.(data);
|
|
38108
38877
|
if (data.execution) {
|
|
@@ -38112,14 +38881,14 @@ function WithdrawModal({
|
|
|
38112
38881
|
[onWithdrawSuccess, onEvent]
|
|
38113
38882
|
);
|
|
38114
38883
|
const { colors: colors2, fonts, components } = useTheme();
|
|
38115
|
-
const [containerEl, setContainerEl] = (0,
|
|
38116
|
-
const containerCallbackRef = (0,
|
|
38884
|
+
const [containerEl, setContainerEl] = (0, import_react35.useState)(null);
|
|
38885
|
+
const containerCallbackRef = (0, import_react35.useCallback)((el) => {
|
|
38117
38886
|
setContainerEl(el);
|
|
38118
38887
|
}, []);
|
|
38119
|
-
const [resolvedTheme, setResolvedTheme] = (0,
|
|
38888
|
+
const [resolvedTheme, setResolvedTheme] = (0, import_react35.useState)(
|
|
38120
38889
|
theme === "auto" ? "dark" : theme
|
|
38121
38890
|
);
|
|
38122
|
-
(0,
|
|
38891
|
+
(0, import_react35.useEffect)(() => {
|
|
38123
38892
|
if (theme === "auto") {
|
|
38124
38893
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
38125
38894
|
setResolvedTheme(mq.matches ? "dark" : "light");
|
|
@@ -38168,10 +38937,10 @@ function WithdrawModal({
|
|
|
38168
38937
|
const selectedChain = selectedToken && selectedChainKey ? selectedToken.chains.find(
|
|
38169
38938
|
(c) => getChainKey5(c.chain_id, c.chain_type) === selectedChainKey
|
|
38170
38939
|
) ?? null : null;
|
|
38171
|
-
const [view, setView] = (0,
|
|
38172
|
-
const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0,
|
|
38173
|
-
const [selectedExecution, setSelectedExecution] = (0,
|
|
38174
|
-
const [submittedTxInfo, setSubmittedTxInfo] = (0,
|
|
38940
|
+
const [view, setView] = (0, import_react35.useState)("form");
|
|
38941
|
+
const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react35.useState)();
|
|
38942
|
+
const [selectedExecution, setSelectedExecution] = (0, import_react35.useState)(null);
|
|
38943
|
+
const [submittedTxInfo, setSubmittedTxInfo] = (0, import_react35.useState)(null);
|
|
38175
38944
|
const { executions: realtimeExecutions } = useWithdrawPolling({
|
|
38176
38945
|
userId: externalUserId,
|
|
38177
38946
|
publishableKey,
|
|
@@ -38186,7 +38955,7 @@ function WithdrawModal({
|
|
|
38186
38955
|
refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
|
|
38187
38956
|
});
|
|
38188
38957
|
const allWithdrawals = allWithdrawalsData?.data ?? [];
|
|
38189
|
-
const handleDepositWalletCreation = (0,
|
|
38958
|
+
const handleDepositWalletCreation = (0, import_react35.useCallback)(
|
|
38190
38959
|
async (params) => {
|
|
38191
38960
|
const { data: wallets } = await createDepositAddress(
|
|
38192
38961
|
{
|
|
@@ -38209,12 +38978,12 @@ function WithdrawModal({
|
|
|
38209
38978
|
},
|
|
38210
38979
|
[externalUserId, publishableKey, sourceChainType]
|
|
38211
38980
|
);
|
|
38212
|
-
const handleWithdrawSubmitted = (0,
|
|
38981
|
+
const handleWithdrawSubmitted = (0, import_react35.useCallback)((txInfo) => {
|
|
38213
38982
|
setSubmittedTxInfo(txInfo);
|
|
38214
38983
|
setView("confirming");
|
|
38215
38984
|
}, []);
|
|
38216
|
-
const resetViewTimeoutRef = (0,
|
|
38217
|
-
const handleClose = (0,
|
|
38985
|
+
const resetViewTimeoutRef = (0, import_react35.useRef)(null);
|
|
38986
|
+
const handleClose = (0, import_react35.useCallback)(() => {
|
|
38218
38987
|
onOpenChange(false);
|
|
38219
38988
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
38220
38989
|
resetViewTimeoutRef.current = setTimeout(() => {
|
|
@@ -38225,7 +38994,7 @@ function WithdrawModal({
|
|
|
38225
38994
|
resetViewTimeoutRef.current = null;
|
|
38226
38995
|
}, 200);
|
|
38227
38996
|
}, [onOpenChange]);
|
|
38228
|
-
(0,
|
|
38997
|
+
(0, import_react35.useLayoutEffect)(() => {
|
|
38229
38998
|
if (!open) return;
|
|
38230
38999
|
if (resetViewTimeoutRef.current) {
|
|
38231
39000
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -38236,19 +39005,19 @@ function WithdrawModal({
|
|
|
38236
39005
|
setSubmittedTxInfo(null);
|
|
38237
39006
|
setWithdrawDepositWalletId(void 0);
|
|
38238
39007
|
}, [open]);
|
|
38239
|
-
(0,
|
|
39008
|
+
(0, import_react35.useEffect)(
|
|
38240
39009
|
() => () => {
|
|
38241
39010
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
38242
39011
|
},
|
|
38243
39012
|
[]
|
|
38244
39013
|
);
|
|
38245
|
-
const handleTokenSymbolChange = (0,
|
|
39014
|
+
const handleTokenSymbolChange = (0, import_react35.useCallback)(
|
|
38246
39015
|
(symbol) => {
|
|
38247
39016
|
setSelectedTokenSymbol(symbol);
|
|
38248
39017
|
},
|
|
38249
39018
|
[setSelectedTokenSymbol]
|
|
38250
39019
|
);
|
|
38251
|
-
const handleChainKeyChange = (0,
|
|
39020
|
+
const handleChainKeyChange = (0, import_react35.useCallback)(
|
|
38252
39021
|
(chainKey) => {
|
|
38253
39022
|
setSelectedChainKey(chainKey);
|
|
38254
39023
|
},
|
|
@@ -38443,19 +39212,19 @@ function UnifoldProvider2({
|
|
|
38443
39212
|
queryClient,
|
|
38444
39213
|
config
|
|
38445
39214
|
}) {
|
|
38446
|
-
const [isOpen, setIsOpen] = (0,
|
|
38447
|
-
const [depositConfig, setDepositConfig] = (0,
|
|
38448
|
-
const [isCheckoutOpen, setIsCheckoutOpen] = (0,
|
|
38449
|
-
const [checkoutConfig, setCheckoutConfig] = (0,
|
|
38450
|
-
const [isWithdrawOpen, setIsWithdrawOpen] = (0,
|
|
38451
|
-
const [withdrawConfig, setWithdrawConfig] = (0,
|
|
38452
|
-
const [resolvedTheme, setResolvedTheme] =
|
|
38453
|
-
(0,
|
|
39215
|
+
const [isOpen, setIsOpen] = (0, import_react41.useState)(false);
|
|
39216
|
+
const [depositConfig, setDepositConfig] = (0, import_react41.useState)(null);
|
|
39217
|
+
const [isCheckoutOpen, setIsCheckoutOpen] = (0, import_react41.useState)(false);
|
|
39218
|
+
const [checkoutConfig, setCheckoutConfig] = (0, import_react41.useState)(null);
|
|
39219
|
+
const [isWithdrawOpen, setIsWithdrawOpen] = (0, import_react41.useState)(false);
|
|
39220
|
+
const [withdrawConfig, setWithdrawConfig] = (0, import_react41.useState)(null);
|
|
39221
|
+
const [resolvedTheme, setResolvedTheme] = import_react41.default.useState("dark");
|
|
39222
|
+
(0, import_react41.useEffect)(() => {
|
|
38454
39223
|
if (publishableKey) {
|
|
38455
39224
|
setApiConfig({ publishableKey });
|
|
38456
39225
|
}
|
|
38457
39226
|
}, [publishableKey]);
|
|
38458
|
-
|
|
39227
|
+
import_react41.default.useEffect(() => {
|
|
38459
39228
|
const appearance = config?.appearance || "dark";
|
|
38460
39229
|
if (appearance === "auto") {
|
|
38461
39230
|
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
@@ -38470,17 +39239,17 @@ function UnifoldProvider2({
|
|
|
38470
39239
|
setResolvedTheme(appearance);
|
|
38471
39240
|
}
|
|
38472
39241
|
}, [config?.appearance]);
|
|
38473
|
-
const depositPromiseRef =
|
|
38474
|
-
const depositConfigRef =
|
|
39242
|
+
const depositPromiseRef = import_react41.default.useRef(null);
|
|
39243
|
+
const depositConfigRef = import_react41.default.useRef(null);
|
|
38475
39244
|
depositConfigRef.current = depositConfig;
|
|
38476
|
-
const closeTimeoutRef =
|
|
38477
|
-
const closeGuardRef =
|
|
38478
|
-
const withdrawPromiseRef =
|
|
38479
|
-
const withdrawConfigRef =
|
|
39245
|
+
const closeTimeoutRef = import_react41.default.useRef(null);
|
|
39246
|
+
const closeGuardRef = import_react41.default.useRef(false);
|
|
39247
|
+
const withdrawPromiseRef = import_react41.default.useRef(null);
|
|
39248
|
+
const withdrawConfigRef = import_react41.default.useRef(null);
|
|
38480
39249
|
withdrawConfigRef.current = withdrawConfig;
|
|
38481
|
-
const withdrawCloseTimeoutRef =
|
|
38482
|
-
const withdrawCloseGuardRef =
|
|
38483
|
-
const beginDeposit = (0,
|
|
39250
|
+
const withdrawCloseTimeoutRef = import_react41.default.useRef(null);
|
|
39251
|
+
const withdrawCloseGuardRef = import_react41.default.useRef(false);
|
|
39252
|
+
const beginDeposit = (0, import_react41.useCallback)((config2) => {
|
|
38484
39253
|
if (closeTimeoutRef.current) {
|
|
38485
39254
|
clearTimeout(closeTimeoutRef.current);
|
|
38486
39255
|
closeTimeoutRef.current = null;
|
|
@@ -38515,7 +39284,7 @@ function UnifoldProvider2({
|
|
|
38515
39284
|
setIsOpen(true);
|
|
38516
39285
|
return promise;
|
|
38517
39286
|
}, []);
|
|
38518
|
-
const closeDeposit = (0,
|
|
39287
|
+
const closeDeposit = (0, import_react41.useCallback)(() => {
|
|
38519
39288
|
if (closeGuardRef.current) {
|
|
38520
39289
|
return;
|
|
38521
39290
|
}
|
|
@@ -38537,7 +39306,7 @@ function UnifoldProvider2({
|
|
|
38537
39306
|
closeTimeoutRef.current = null;
|
|
38538
39307
|
}, 200);
|
|
38539
39308
|
}, []);
|
|
38540
|
-
const handleDepositSuccess = (0,
|
|
39309
|
+
const handleDepositSuccess = (0, import_react41.useCallback)(
|
|
38541
39310
|
(data) => {
|
|
38542
39311
|
if (depositConfig?.onSuccess) {
|
|
38543
39312
|
depositConfig.onSuccess(data);
|
|
@@ -38549,7 +39318,7 @@ function UnifoldProvider2({
|
|
|
38549
39318
|
},
|
|
38550
39319
|
[depositConfig]
|
|
38551
39320
|
);
|
|
38552
|
-
const handleDepositError = (0,
|
|
39321
|
+
const handleDepositError = (0, import_react41.useCallback)(
|
|
38553
39322
|
(error) => {
|
|
38554
39323
|
console.error("[UnifoldProvider] Deposit error:", error);
|
|
38555
39324
|
if (depositConfig?.onError) {
|
|
@@ -38562,12 +39331,12 @@ function UnifoldProvider2({
|
|
|
38562
39331
|
},
|
|
38563
39332
|
[depositConfig]
|
|
38564
39333
|
);
|
|
38565
|
-
const checkoutPromiseRef =
|
|
38566
|
-
const checkoutConfigRef =
|
|
39334
|
+
const checkoutPromiseRef = import_react41.default.useRef(null);
|
|
39335
|
+
const checkoutConfigRef = import_react41.default.useRef(null);
|
|
38567
39336
|
checkoutConfigRef.current = checkoutConfig;
|
|
38568
|
-
const checkoutCloseTimeoutRef =
|
|
38569
|
-
const checkoutCloseGuardRef =
|
|
38570
|
-
const beginCheckout = (0,
|
|
39337
|
+
const checkoutCloseTimeoutRef = import_react41.default.useRef(null);
|
|
39338
|
+
const checkoutCloseGuardRef = import_react41.default.useRef(false);
|
|
39339
|
+
const beginCheckout = (0, import_react41.useCallback)((config2) => {
|
|
38571
39340
|
if (checkoutCloseTimeoutRef.current) {
|
|
38572
39341
|
clearTimeout(checkoutCloseTimeoutRef.current);
|
|
38573
39342
|
checkoutCloseTimeoutRef.current = null;
|
|
@@ -38592,7 +39361,7 @@ function UnifoldProvider2({
|
|
|
38592
39361
|
setIsCheckoutOpen(true);
|
|
38593
39362
|
return promise;
|
|
38594
39363
|
}, []);
|
|
38595
|
-
const closeCheckout = (0,
|
|
39364
|
+
const closeCheckout = (0, import_react41.useCallback)(() => {
|
|
38596
39365
|
if (checkoutCloseGuardRef.current) {
|
|
38597
39366
|
return;
|
|
38598
39367
|
}
|
|
@@ -38614,7 +39383,7 @@ function UnifoldProvider2({
|
|
|
38614
39383
|
checkoutCloseTimeoutRef.current = null;
|
|
38615
39384
|
}, 200);
|
|
38616
39385
|
}, []);
|
|
38617
|
-
const handleCheckoutSuccess = (0,
|
|
39386
|
+
const handleCheckoutSuccess = (0, import_react41.useCallback)(
|
|
38618
39387
|
(data) => {
|
|
38619
39388
|
if (checkoutConfig?.onSuccess) {
|
|
38620
39389
|
checkoutConfig.onSuccess(data);
|
|
@@ -38626,7 +39395,7 @@ function UnifoldProvider2({
|
|
|
38626
39395
|
},
|
|
38627
39396
|
[checkoutConfig]
|
|
38628
39397
|
);
|
|
38629
|
-
const handleCheckoutError = (0,
|
|
39398
|
+
const handleCheckoutError = (0, import_react41.useCallback)(
|
|
38630
39399
|
(error) => {
|
|
38631
39400
|
console.error("[UnifoldProvider] Checkout error:", error);
|
|
38632
39401
|
if (checkoutConfig?.onError) {
|
|
@@ -38639,7 +39408,7 @@ function UnifoldProvider2({
|
|
|
38639
39408
|
},
|
|
38640
39409
|
[checkoutConfig]
|
|
38641
39410
|
);
|
|
38642
|
-
const beginWithdraw = (0,
|
|
39411
|
+
const beginWithdraw = (0, import_react41.useCallback)((config2) => {
|
|
38643
39412
|
if (withdrawCloseTimeoutRef.current) {
|
|
38644
39413
|
clearTimeout(withdrawCloseTimeoutRef.current);
|
|
38645
39414
|
withdrawCloseTimeoutRef.current = null;
|
|
@@ -38664,7 +39433,7 @@ function UnifoldProvider2({
|
|
|
38664
39433
|
setIsWithdrawOpen(true);
|
|
38665
39434
|
return promise;
|
|
38666
39435
|
}, []);
|
|
38667
|
-
const closeWithdraw = (0,
|
|
39436
|
+
const closeWithdraw = (0, import_react41.useCallback)(() => {
|
|
38668
39437
|
if (withdrawCloseGuardRef.current) {
|
|
38669
39438
|
return;
|
|
38670
39439
|
}
|
|
@@ -38686,7 +39455,7 @@ function UnifoldProvider2({
|
|
|
38686
39455
|
withdrawCloseTimeoutRef.current = null;
|
|
38687
39456
|
}, 200);
|
|
38688
39457
|
}, []);
|
|
38689
|
-
const handleWithdrawSuccess = (0,
|
|
39458
|
+
const handleWithdrawSuccess = (0, import_react41.useCallback)((data) => {
|
|
38690
39459
|
if (withdrawConfigRef.current?.onSuccess) {
|
|
38691
39460
|
withdrawConfigRef.current.onSuccess(data);
|
|
38692
39461
|
}
|
|
@@ -38695,7 +39464,7 @@ function UnifoldProvider2({
|
|
|
38695
39464
|
withdrawPromiseRef.current = null;
|
|
38696
39465
|
}
|
|
38697
39466
|
}, []);
|
|
38698
|
-
const handleWithdrawError = (0,
|
|
39467
|
+
const handleWithdrawError = (0, import_react41.useCallback)((error) => {
|
|
38699
39468
|
console.error("[UnifoldProvider] Withdraw error:", error);
|
|
38700
39469
|
if (withdrawConfigRef.current?.onError) {
|
|
38701
39470
|
withdrawConfigRef.current.onError(error);
|
|
@@ -38705,7 +39474,7 @@ function UnifoldProvider2({
|
|
|
38705
39474
|
withdrawPromiseRef.current = null;
|
|
38706
39475
|
}
|
|
38707
39476
|
}, []);
|
|
38708
|
-
const contextValue = (0,
|
|
39477
|
+
const contextValue = (0, import_react41.useMemo)(
|
|
38709
39478
|
() => ({
|
|
38710
39479
|
beginDeposit,
|
|
38711
39480
|
closeDeposit,
|
|
@@ -38800,7 +39569,7 @@ function UnifoldProvider2({
|
|
|
38800
39569
|
defaultSourceChainId: depositConfig.defaultSourceChainId,
|
|
38801
39570
|
defaultSourceTokenAddress: depositConfig.defaultSourceTokenAddress,
|
|
38802
39571
|
defaultSourceSymbol: depositConfig.defaultSourceSymbol,
|
|
38803
|
-
|
|
39572
|
+
userEmail: depositConfig.user?.email,
|
|
38804
39573
|
depositConfirmationMode: depositConfig.depositConfirmationMode ?? "auto_ui",
|
|
38805
39574
|
hideDepositTracker: config?.hideDepositTracker,
|
|
38806
39575
|
showBalanceHeader: config?.showBalanceHeader,
|
|
@@ -38813,7 +39582,6 @@ function UnifoldProvider2({
|
|
|
38813
39582
|
enableConnectExchange: config?.enableConnectExchange,
|
|
38814
39583
|
enableCashApp: config?.enableCashApp,
|
|
38815
39584
|
enableStripeLink: config?.enableStripeLink,
|
|
38816
|
-
email: depositConfig?.email,
|
|
38817
39585
|
enableApplePay: config?.enableApplePay,
|
|
38818
39586
|
applePayTitle: config?.applePayTitle,
|
|
38819
39587
|
applePaySubTitle: config?.applePaySubTitle,
|
|
@@ -38836,10 +39604,10 @@ function UnifoldProvider2({
|
|
|
38836
39604
|
}
|
|
38837
39605
|
) }) });
|
|
38838
39606
|
}
|
|
38839
|
-
var ConnectContext =
|
|
39607
|
+
var ConnectContext = import_react41.default.createContext(null);
|
|
38840
39608
|
function useUnifold2() {
|
|
38841
39609
|
const baseContext = useUnifold();
|
|
38842
|
-
const connectContext =
|
|
39610
|
+
const connectContext = import_react41.default.useContext(ConnectContext);
|
|
38843
39611
|
if (typeof window === "undefined") {
|
|
38844
39612
|
return {
|
|
38845
39613
|
publishableKey: "",
|