@unifold/ui-web 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.js +1554 -787
- package/dist/index.mjs +1554 -787
- package/dist/styles-base.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -34394,7 +34394,7 @@ var require_jsx_runtime = __commonJS({
|
|
|
34394
34394
|
});
|
|
34395
34395
|
|
|
34396
34396
|
// src/unifold.tsx
|
|
34397
|
-
var
|
|
34397
|
+
var import_react42 = __toESM(require_react());
|
|
34398
34398
|
var import_client = __toESM(require_client());
|
|
34399
34399
|
|
|
34400
34400
|
// ../connect-react/dist/index.mjs
|
|
@@ -37120,15 +37120,16 @@ var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
|
|
|
37120
37120
|
var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
|
|
37121
37121
|
var React522 = __toESM(require_react(), 1);
|
|
37122
37122
|
var import_react15 = __toESM(require_react(), 1);
|
|
37123
|
-
var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
|
|
37124
37123
|
var import_react16 = __toESM(require_react(), 1);
|
|
37125
|
-
var
|
|
37124
|
+
var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
|
|
37126
37125
|
var import_react17 = __toESM(require_react(), 1);
|
|
37126
|
+
var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
|
|
37127
37127
|
var import_react18 = __toESM(require_react(), 1);
|
|
37128
|
-
var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
|
|
37129
37128
|
var import_react19 = __toESM(require_react(), 1);
|
|
37130
|
-
var
|
|
37129
|
+
var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
|
|
37131
37130
|
var import_react20 = __toESM(require_react(), 1);
|
|
37131
|
+
var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
|
|
37132
|
+
var import_react21 = __toESM(require_react(), 1);
|
|
37132
37133
|
var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
|
|
37133
37134
|
var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
|
|
37134
37135
|
var React622 = __toESM(require_react(), 1);
|
|
@@ -37181,29 +37182,29 @@ var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
|
|
|
37181
37182
|
var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
|
|
37182
37183
|
var React292 = __toESM(require_react(), 1);
|
|
37183
37184
|
var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
|
|
37184
|
-
var import_react21 = __toESM(require_react(), 1);
|
|
37185
|
-
var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
|
|
37186
37185
|
var import_react22 = __toESM(require_react(), 1);
|
|
37187
|
-
var
|
|
37186
|
+
var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
|
|
37188
37187
|
var import_react23 = __toESM(require_react(), 1);
|
|
37189
|
-
var
|
|
37188
|
+
var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
|
|
37190
37189
|
var import_react24 = __toESM(require_react(), 1);
|
|
37190
|
+
var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
|
|
37191
37191
|
var import_react25 = __toESM(require_react(), 1);
|
|
37192
|
+
var import_react26 = __toESM(require_react(), 1);
|
|
37192
37193
|
var React312 = __toESM(require_react(), 1);
|
|
37193
37194
|
var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
|
|
37194
37195
|
var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
|
|
37195
37196
|
var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
|
|
37196
|
-
var import_react26 = __toESM(require_react(), 1);
|
|
37197
|
-
var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
|
|
37198
37197
|
var import_react27 = __toESM(require_react(), 1);
|
|
37198
|
+
var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
|
|
37199
|
+
var import_react28 = __toESM(require_react(), 1);
|
|
37199
37200
|
var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
|
|
37200
37201
|
var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
|
|
37201
|
-
var
|
|
37202
|
+
var import_react29 = __toESM(require_react(), 1);
|
|
37202
37203
|
var React322 = __toESM(require_react(), 1);
|
|
37203
37204
|
var React31 = __toESM(require_react(), 1);
|
|
37204
37205
|
var React29 = __toESM(require_react(), 1);
|
|
37205
37206
|
var React26 = __toESM(require_react(), 1);
|
|
37206
|
-
var
|
|
37207
|
+
var import_react30 = __toESM(require_react(), 1);
|
|
37207
37208
|
var ReactDOM3 = __toESM(require_react_dom(), 1);
|
|
37208
37209
|
var React27 = __toESM(require_react(), 1);
|
|
37209
37210
|
var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -37215,13 +37216,13 @@ var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
|
|
|
37215
37216
|
var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
|
|
37216
37217
|
var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
|
|
37217
37218
|
var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
|
|
37218
|
-
var
|
|
37219
|
+
var import_react31 = __toESM(require_react(), 1);
|
|
37219
37220
|
var React332 = __toESM(require_react(), 1);
|
|
37220
37221
|
var React35 = __toESM(require_react(), 1);
|
|
37221
37222
|
var ReactDOM4 = __toESM(require_react_dom(), 1);
|
|
37222
|
-
var import_react31 = __toESM(require_react(), 1);
|
|
37223
|
-
var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
|
|
37224
37223
|
var import_react32 = __toESM(require_react(), 1);
|
|
37224
|
+
var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
|
|
37225
|
+
var import_react33 = __toESM(require_react(), 1);
|
|
37225
37226
|
var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
|
|
37226
37227
|
var React33 = __toESM(require_react(), 1);
|
|
37227
37228
|
var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -37234,23 +37235,23 @@ var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1);
|
|
|
37234
37235
|
var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
|
|
37235
37236
|
var import_jsx_runtime78 = __toESM(require_jsx_runtime(), 1);
|
|
37236
37237
|
var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1);
|
|
37237
|
-
var
|
|
37238
|
+
var import_react34 = __toESM(require_react(), 1);
|
|
37238
37239
|
var import_jsx_runtime80 = __toESM(require_jsx_runtime(), 1);
|
|
37239
37240
|
var import_jsx_runtime81 = __toESM(require_jsx_runtime(), 1);
|
|
37240
37241
|
var import_jsx_runtime82 = __toESM(require_jsx_runtime(), 1);
|
|
37241
|
-
var import_react34 = __toESM(require_react(), 1);
|
|
37242
|
-
var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1);
|
|
37243
37242
|
var import_react35 = __toESM(require_react(), 1);
|
|
37243
|
+
var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1);
|
|
37244
37244
|
var import_react36 = __toESM(require_react(), 1);
|
|
37245
|
-
var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1);
|
|
37246
37245
|
var import_react37 = __toESM(require_react(), 1);
|
|
37246
|
+
var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1);
|
|
37247
37247
|
var import_react38 = __toESM(require_react(), 1);
|
|
37248
|
+
var import_react39 = __toESM(require_react(), 1);
|
|
37248
37249
|
var import_jsx_runtime85 = __toESM(require_jsx_runtime(), 1);
|
|
37249
37250
|
var import_jsx_runtime86 = __toESM(require_jsx_runtime(), 1);
|
|
37250
|
-
var
|
|
37251
|
+
var import_react40 = __toESM(require_react(), 1);
|
|
37251
37252
|
var import_jsx_runtime87 = __toESM(require_jsx_runtime(), 1);
|
|
37252
37253
|
var import_jsx_runtime88 = __toESM(require_jsx_runtime(), 1);
|
|
37253
|
-
var
|
|
37254
|
+
var import_react41 = __toESM(require_react(), 1);
|
|
37254
37255
|
var import_jsx_runtime89 = __toESM(require_jsx_runtime(), 1);
|
|
37255
37256
|
var import_jsx_runtime90 = __toESM(require_jsx_runtime(), 1);
|
|
37256
37257
|
var __create2 = Object.create;
|
|
@@ -44528,6 +44529,59 @@ async function exchangeOnrampVerificationToken(id, clientSecret, publishableKey)
|
|
|
44528
44529
|
"Failed to exchange verification token"
|
|
44529
44530
|
);
|
|
44530
44531
|
}
|
|
44532
|
+
function isApplePayLimitReached(response) {
|
|
44533
|
+
return response.limits.some((l) => l.remaining === "0");
|
|
44534
|
+
}
|
|
44535
|
+
function getApplePayLimitUpgradeStatus(response) {
|
|
44536
|
+
const opt = response.limit_upgrade_options?.[0];
|
|
44537
|
+
if (!opt || typeof opt.status !== "string") return null;
|
|
44538
|
+
return opt.status;
|
|
44539
|
+
}
|
|
44540
|
+
async function getCoinbaseApplePayLimits(phone, publishableKey, signal) {
|
|
44541
|
+
const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
|
|
44542
|
+
validatePublishableKey(pk);
|
|
44543
|
+
const response = await fetch(
|
|
44544
|
+
`${API_BASE_URL}/v1/public/onramps/headless/coinbase/apple_pay/limits`,
|
|
44545
|
+
{
|
|
44546
|
+
method: "POST",
|
|
44547
|
+
headers: {
|
|
44548
|
+
accept: "application/json",
|
|
44549
|
+
"x-publishable-key": pk,
|
|
44550
|
+
"Content-Type": "application/json"
|
|
44551
|
+
},
|
|
44552
|
+
body: JSON.stringify({ phone }),
|
|
44553
|
+
signal
|
|
44554
|
+
}
|
|
44555
|
+
);
|
|
44556
|
+
const raw = await jsonOrThrow(response, "Failed to fetch Apple Pay limits");
|
|
44557
|
+
return {
|
|
44558
|
+
limits: raw.limits,
|
|
44559
|
+
limit_upgrade_options: raw.limit_upgrade_options,
|
|
44560
|
+
limit_reached: isApplePayLimitReached(raw),
|
|
44561
|
+
upgrade_status: getApplePayLimitUpgradeStatus(raw)
|
|
44562
|
+
};
|
|
44563
|
+
}
|
|
44564
|
+
async function requestCoinbaseApplePayLimitUpgrade(request, publishableKey, signal) {
|
|
44565
|
+
const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
|
|
44566
|
+
validatePublishableKey(pk);
|
|
44567
|
+
const response = await fetch(
|
|
44568
|
+
`${API_BASE_URL}/v1/public/onramps/headless/coinbase/apple_pay/limits/upgrade`,
|
|
44569
|
+
{
|
|
44570
|
+
method: "POST",
|
|
44571
|
+
headers: {
|
|
44572
|
+
accept: "application/json",
|
|
44573
|
+
"x-publishable-key": pk,
|
|
44574
|
+
"Content-Type": "application/json"
|
|
44575
|
+
},
|
|
44576
|
+
body: JSON.stringify(request),
|
|
44577
|
+
signal
|
|
44578
|
+
}
|
|
44579
|
+
);
|
|
44580
|
+
return jsonOrThrow(
|
|
44581
|
+
response,
|
|
44582
|
+
"Failed to request Apple Pay limit upgrade"
|
|
44583
|
+
);
|
|
44584
|
+
}
|
|
44531
44585
|
async function createCoinbaseApplePaySession(request, onrampToken, publishableKey, signal) {
|
|
44532
44586
|
const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
|
|
44533
44587
|
validatePublishableKey(pk);
|
|
@@ -48348,7 +48402,7 @@ var computePosition2 = (reference, floating, options2) => {
|
|
|
48348
48402
|
var isClient = typeof document !== "undefined";
|
|
48349
48403
|
var noop2 = function noop22() {
|
|
48350
48404
|
};
|
|
48351
|
-
var index = isClient ?
|
|
48405
|
+
var index = isClient ? import_react30.useLayoutEffect : noop2;
|
|
48352
48406
|
function deepEqual(a, b) {
|
|
48353
48407
|
if (a === b) {
|
|
48354
48408
|
return true;
|
|
@@ -49457,14 +49511,14 @@ function createCollection(name) {
|
|
|
49457
49511
|
);
|
|
49458
49512
|
const CollectionProvider = (props) => {
|
|
49459
49513
|
const { scope, children } = props;
|
|
49460
|
-
const ref =
|
|
49461
|
-
const itemMap =
|
|
49514
|
+
const ref = import_react32.default.useRef(null);
|
|
49515
|
+
const itemMap = import_react32.default.useRef(/* @__PURE__ */ new Map()).current;
|
|
49462
49516
|
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
|
|
49463
49517
|
};
|
|
49464
49518
|
CollectionProvider.displayName = PROVIDER_NAME2;
|
|
49465
49519
|
const COLLECTION_SLOT_NAME = name + "CollectionSlot";
|
|
49466
49520
|
const CollectionSlotImpl = /* @__PURE__ */ createSlot(COLLECTION_SLOT_NAME);
|
|
49467
|
-
const CollectionSlot =
|
|
49521
|
+
const CollectionSlot = import_react32.default.forwardRef(
|
|
49468
49522
|
(props, forwardedRef) => {
|
|
49469
49523
|
const { scope, children } = props;
|
|
49470
49524
|
const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
|
|
@@ -49476,13 +49530,13 @@ function createCollection(name) {
|
|
|
49476
49530
|
const ITEM_SLOT_NAME = name + "CollectionItemSlot";
|
|
49477
49531
|
const ITEM_DATA_ATTR = "data-radix-collection-item";
|
|
49478
49532
|
const CollectionItemSlotImpl = /* @__PURE__ */ createSlot(ITEM_SLOT_NAME);
|
|
49479
|
-
const CollectionItemSlot =
|
|
49533
|
+
const CollectionItemSlot = import_react32.default.forwardRef(
|
|
49480
49534
|
(props, forwardedRef) => {
|
|
49481
49535
|
const { scope, children, ...itemData } = props;
|
|
49482
|
-
const ref =
|
|
49536
|
+
const ref = import_react32.default.useRef(null);
|
|
49483
49537
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
49484
49538
|
const context = useCollectionContext(ITEM_SLOT_NAME, scope);
|
|
49485
|
-
|
|
49539
|
+
import_react32.default.useEffect(() => {
|
|
49486
49540
|
context.itemMap.set(ref, { ref, ...itemData });
|
|
49487
49541
|
return () => void context.itemMap.delete(ref);
|
|
49488
49542
|
});
|
|
@@ -49492,7 +49546,7 @@ function createCollection(name) {
|
|
|
49492
49546
|
CollectionItemSlot.displayName = ITEM_SLOT_NAME;
|
|
49493
49547
|
function useCollection2(scope) {
|
|
49494
49548
|
const context = useCollectionContext(name + "CollectionConsumer", scope);
|
|
49495
|
-
const getItems =
|
|
49549
|
+
const getItems = import_react32.default.useCallback(() => {
|
|
49496
49550
|
const collectionNode = context.collectionRef.current;
|
|
49497
49551
|
if (!collectionNode) return [];
|
|
49498
49552
|
const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
|
|
@@ -52043,7 +52097,7 @@ var en_default2 = {
|
|
|
52043
52097
|
payWithStripeLink: {
|
|
52044
52098
|
success: {
|
|
52045
52099
|
processingTitle: "Payment confirmed",
|
|
52046
|
-
processingSubtitle: "We\u2019ve received your payment and are
|
|
52100
|
+
processingSubtitle: "We\u2019ve received your payment and are sending your purchase to your wallet. This usually takes just a few minutes.",
|
|
52047
52101
|
completeTitle: "Your purchase is on the way",
|
|
52048
52102
|
completeSubtitle: "Your purchase is complete and is being sent to your wallet.",
|
|
52049
52103
|
failedTitle: "Purchase didn\u2019t go through",
|
|
@@ -54027,20 +54081,6 @@ function BuyWithCard({
|
|
|
54027
54081
|
}
|
|
54028
54082
|
);
|
|
54029
54083
|
}
|
|
54030
|
-
function useProjectConfig({
|
|
54031
|
-
publishableKey,
|
|
54032
|
-
enabled = true
|
|
54033
|
-
}) {
|
|
54034
|
-
const { data: projectConfig, isLoading } = useQuery({
|
|
54035
|
-
queryKey: ["unifold", "projectConfig", publishableKey],
|
|
54036
|
-
queryFn: () => getProjectConfig(publishableKey),
|
|
54037
|
-
enabled,
|
|
54038
|
-
staleTime: 1e3 * 60 * 30,
|
|
54039
|
-
refetchOnMount: true,
|
|
54040
|
-
refetchOnWindowFocus: true
|
|
54041
|
-
});
|
|
54042
|
-
return { projectConfig, isLoading };
|
|
54043
|
-
}
|
|
54044
54084
|
var STORAGE_KEY_PREFIX = "unifold:apple-pay:session";
|
|
54045
54085
|
var PHONE_FRESH_MS = 55 * 24 * 60 * 60 * 1e3;
|
|
54046
54086
|
function isBrowser() {
|
|
@@ -54088,47 +54128,200 @@ function useCoinbaseLegalAgreements({
|
|
|
54088
54128
|
retry: 1
|
|
54089
54129
|
});
|
|
54090
54130
|
}
|
|
54091
|
-
var
|
|
54092
|
-
|
|
54093
|
-
|
|
54094
|
-
|
|
54131
|
+
var US_E164_REGEX = /^\+1\d{10}$/;
|
|
54132
|
+
function useApplePayLimits({
|
|
54133
|
+
phone,
|
|
54134
|
+
publishableKey,
|
|
54135
|
+
enabled = true
|
|
54136
|
+
}) {
|
|
54137
|
+
const phoneValid = US_E164_REGEX.test(phone);
|
|
54138
|
+
return useQuery({
|
|
54139
|
+
queryKey: ["unifold", "applePayLimits", phone, publishableKey],
|
|
54140
|
+
queryFn: ({ signal }) => getCoinbaseApplePayLimits(phone, publishableKey, signal),
|
|
54141
|
+
enabled: enabled && phoneValid && !!publishableKey,
|
|
54142
|
+
// Coinbase's caps don't change second-to-second; 30s is plenty fresh
|
|
54143
|
+
// for the "user opened the modal, edited their phone, opened it
|
|
54144
|
+
// again" usage pattern, while keeping us off their API on rapid
|
|
54145
|
+
// tap-throughs.
|
|
54146
|
+
staleTime: 3e4,
|
|
54147
|
+
gcTime: 5 * 6e4,
|
|
54148
|
+
refetchOnWindowFocus: false,
|
|
54149
|
+
retry: false
|
|
54150
|
+
});
|
|
54151
|
+
}
|
|
54095
54152
|
var PHONE_REGEX = /^\+1\d{10}$/;
|
|
54096
54153
|
var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
54097
|
-
function
|
|
54098
|
-
|
|
54099
|
-
|
|
54100
|
-
|
|
54154
|
+
function getViewForLimitStatus(limits) {
|
|
54155
|
+
if (!limits.limit_reached) return void 0;
|
|
54156
|
+
switch (limits.upgrade_status) {
|
|
54157
|
+
case "unrequested":
|
|
54158
|
+
return "limit_upgrade_intro";
|
|
54159
|
+
case "resubmit":
|
|
54160
|
+
return "limit_upgrade_form";
|
|
54161
|
+
case "pending":
|
|
54162
|
+
return "limit_upgrade_submitting";
|
|
54163
|
+
case "active":
|
|
54164
|
+
return void 0;
|
|
54165
|
+
default:
|
|
54166
|
+
return "guest_limit_reached";
|
|
54101
54167
|
}
|
|
54102
|
-
if (digits.length === 10) return `+1${digits}`;
|
|
54103
|
-
if (digits.length === 11 && digits.startsWith("1")) return `+${digits}`;
|
|
54104
|
-
return digits.length > 0 ? `+${digits}` : "";
|
|
54105
54168
|
}
|
|
54106
|
-
function
|
|
54107
|
-
|
|
54108
|
-
|
|
54109
|
-
|
|
54110
|
-
|
|
54169
|
+
function useApplePayInitialScreen({
|
|
54170
|
+
userId,
|
|
54171
|
+
publishableKey,
|
|
54172
|
+
normalizedPhone,
|
|
54173
|
+
userEmail,
|
|
54174
|
+
sessionPhoneVerified,
|
|
54175
|
+
isWaiting
|
|
54176
|
+
}) {
|
|
54177
|
+
const initialStoredSession = (0, import_react16.useMemo)(() => getStoredApplePaySession(userId), [userId]);
|
|
54178
|
+
const phoneVerified = PHONE_REGEX.test(normalizedPhone) && (sessionPhoneVerified || initialStoredSession?.phone === normalizedPhone && !!initialStoredSession?.phoneVerifiedAt);
|
|
54179
|
+
const {
|
|
54180
|
+
data: applePayLimits,
|
|
54181
|
+
isLoading: applePayLimitsLoading,
|
|
54182
|
+
refetch: refetchApplePayLimits
|
|
54183
|
+
} = useApplePayLimits({
|
|
54184
|
+
phone: normalizedPhone,
|
|
54185
|
+
publishableKey,
|
|
54186
|
+
enabled: phoneVerified
|
|
54187
|
+
});
|
|
54188
|
+
const action = (0, import_react16.useMemo)(() => {
|
|
54189
|
+
if (isWaiting || applePayLimitsLoading) return { kind: "pending" };
|
|
54190
|
+
const stored = initialStoredSession;
|
|
54191
|
+
const hasUserEmail = !!userEmail && EMAIL_REGEX.test(userEmail);
|
|
54192
|
+
if (!stored) {
|
|
54193
|
+
return { kind: "navigate", view: hasUserEmail ? "phone_input" : "email_input" };
|
|
54194
|
+
}
|
|
54195
|
+
if (hasUserEmail && stored.email.toLowerCase() !== userEmail.toLowerCase()) {
|
|
54196
|
+
return { kind: "navigate", view: "phone_input" };
|
|
54197
|
+
}
|
|
54198
|
+
if (applePayLimits) {
|
|
54199
|
+
const limitView = getViewForLimitStatus(applePayLimits);
|
|
54200
|
+
if (limitView) {
|
|
54201
|
+
return { kind: "limit_upgrade", view: limitView, status: applePayLimits.upgrade_status };
|
|
54202
|
+
}
|
|
54203
|
+
}
|
|
54204
|
+
if (isOnrampTokenFresh(stored) && stored.onrampToken && stored.onrampTokenExpiresAtMs) {
|
|
54205
|
+
return {
|
|
54206
|
+
kind: "resume_with_token",
|
|
54207
|
+
token: {
|
|
54208
|
+
token: stored.onrampToken,
|
|
54209
|
+
token_type: "Bearer",
|
|
54210
|
+
expires_in: Math.max(0, Math.floor((stored.onrampTokenExpiresAtMs - Date.now()) / 1e3))
|
|
54211
|
+
}
|
|
54212
|
+
};
|
|
54213
|
+
}
|
|
54214
|
+
return { kind: "resume_send_sms" };
|
|
54215
|
+
}, [isWaiting, applePayLimitsLoading, initialStoredSession, userEmail, applePayLimits]);
|
|
54216
|
+
return {
|
|
54217
|
+
action,
|
|
54218
|
+
applePayLimits,
|
|
54219
|
+
applePayLimitsLoading,
|
|
54220
|
+
refetchApplePayLimits,
|
|
54221
|
+
phoneVerified
|
|
54222
|
+
};
|
|
54111
54223
|
}
|
|
54112
|
-
function
|
|
54113
|
-
|
|
54114
|
-
|
|
54224
|
+
function useDefaultOnrampToken({
|
|
54225
|
+
publishableKey,
|
|
54226
|
+
tokenAddress,
|
|
54227
|
+
chainId,
|
|
54228
|
+
chainType,
|
|
54229
|
+
countryCode,
|
|
54230
|
+
subdivisionCode,
|
|
54231
|
+
enabled = true
|
|
54232
|
+
}) {
|
|
54233
|
+
const {
|
|
54234
|
+
data: defaultToken,
|
|
54235
|
+
isLoading,
|
|
54236
|
+
isError,
|
|
54237
|
+
error
|
|
54238
|
+
} = useQuery({
|
|
54239
|
+
queryKey: [
|
|
54240
|
+
"unifold",
|
|
54241
|
+
"defaultOnrampToken",
|
|
54242
|
+
publishableKey,
|
|
54243
|
+
tokenAddress,
|
|
54244
|
+
chainId,
|
|
54245
|
+
chainType,
|
|
54246
|
+
countryCode,
|
|
54247
|
+
subdivisionCode
|
|
54248
|
+
],
|
|
54249
|
+
queryFn: () => getDefaultOnrampToken(
|
|
54250
|
+
{
|
|
54251
|
+
token_address: tokenAddress,
|
|
54252
|
+
chain_id: chainId,
|
|
54253
|
+
chain_type: chainType,
|
|
54254
|
+
country_code: countryCode,
|
|
54255
|
+
subdivision_code: subdivisionCode
|
|
54256
|
+
},
|
|
54257
|
+
publishableKey
|
|
54258
|
+
),
|
|
54259
|
+
enabled: enabled && !!tokenAddress && !!chainId && !!chainType,
|
|
54260
|
+
staleTime: 1e3 * 60 * 60,
|
|
54261
|
+
refetchOnMount: false,
|
|
54262
|
+
refetchOnWindowFocus: false
|
|
54263
|
+
});
|
|
54264
|
+
return { defaultToken, isLoading, isError, error: error ?? null };
|
|
54265
|
+
}
|
|
54266
|
+
var COINBASE_PAY_ORIGIN = "https://pay.coinbase.com";
|
|
54267
|
+
var COINBASE_ALLOWED_POSTMESSAGE_ORIGINS = /* @__PURE__ */ new Set([
|
|
54268
|
+
COINBASE_PAY_ORIGIN,
|
|
54269
|
+
"https://www.coinbase.com"
|
|
54270
|
+
]);
|
|
54271
|
+
var UNIFOLD_SUPPORT_URL = "https://unifold.io/support";
|
|
54272
|
+
var DEFAULT_MIN_USD = 5;
|
|
54273
|
+
var DEFAULT_MAX_USD = 500;
|
|
54274
|
+
var DEFAULT_SUGGESTED = [25, 50, 100];
|
|
54275
|
+
var PHONE_REGEX2 = /^\+1\d{10}$/;
|
|
54276
|
+
var EMAIL_REGEX2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
54277
|
+
function parseCoinbasePostMessage(raw) {
|
|
54278
|
+
const parseString = (s) => {
|
|
54279
|
+
try {
|
|
54280
|
+
return JSON.parse(s);
|
|
54281
|
+
} catch {
|
|
54282
|
+
return null;
|
|
54283
|
+
}
|
|
54284
|
+
};
|
|
54285
|
+
const asObject = (value) => value && typeof value === "object" ? value : null;
|
|
54286
|
+
let candidate = raw;
|
|
54287
|
+
if (typeof candidate === "string") {
|
|
54288
|
+
candidate = parseString(candidate);
|
|
54289
|
+
}
|
|
54290
|
+
const obj = asObject(candidate);
|
|
54291
|
+
if (!obj) return null;
|
|
54292
|
+
const nestedData = obj.data;
|
|
54293
|
+
let eventName = typeof obj.eventName === "string" && obj.eventName || typeof obj.event_name === "string" && obj.event_name || typeof obj.type === "string" && obj.type || null;
|
|
54294
|
+
let dataObj = asObject(nestedData);
|
|
54295
|
+
if (!eventName && typeof nestedData === "string") {
|
|
54296
|
+
const nestedParsed = parseString(nestedData);
|
|
54297
|
+
const nestedObj = asObject(nestedParsed);
|
|
54298
|
+
if (nestedObj) {
|
|
54299
|
+
eventName = typeof nestedObj.eventName === "string" && nestedObj.eventName || typeof nestedObj.event_name === "string" && nestedObj.event_name || typeof nestedObj.type === "string" && nestedObj.type || null;
|
|
54300
|
+
dataObj = asObject(nestedObj.data);
|
|
54301
|
+
}
|
|
54302
|
+
}
|
|
54303
|
+
if (!eventName || !/^onramp_api\./i.test(eventName)) return null;
|
|
54304
|
+
return {
|
|
54305
|
+
eventName,
|
|
54306
|
+
data: dataObj ? {
|
|
54307
|
+
errorCode: typeof dataObj.errorCode === "string" ? dataObj.errorCode : typeof dataObj.error_code === "string" ? dataObj.error_code : void 0,
|
|
54308
|
+
errorMessage: typeof dataObj.errorMessage === "string" ? dataObj.errorMessage : typeof dataObj.error_message === "string" ? dataObj.error_message : void 0
|
|
54309
|
+
} : void 0
|
|
54310
|
+
};
|
|
54115
54311
|
}
|
|
54116
54312
|
var BuyWithApplePay = React522.forwardRef(
|
|
54117
54313
|
function BuyWithApplePay2({
|
|
54118
54314
|
userId,
|
|
54119
54315
|
publishableKey,
|
|
54120
|
-
recipientAddress,
|
|
54121
54316
|
destinationChainType,
|
|
54122
54317
|
destinationChainId,
|
|
54123
54318
|
destinationTokenAddress,
|
|
54124
|
-
|
|
54125
|
-
externalUserEmail,
|
|
54126
|
-
enableApplePay,
|
|
54319
|
+
userEmail,
|
|
54127
54320
|
amountUsd,
|
|
54128
54321
|
minAmountUsd = DEFAULT_MIN_USD,
|
|
54129
54322
|
maxAmountUsd = DEFAULT_MAX_USD,
|
|
54130
54323
|
suggestedAmountsUsd = DEFAULT_SUGGESTED,
|
|
54131
|
-
wallets:
|
|
54324
|
+
wallets: depositWallets,
|
|
54132
54325
|
onDepositSuccess,
|
|
54133
54326
|
onDepositError,
|
|
54134
54327
|
onEvent,
|
|
@@ -54137,48 +54330,61 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54137
54330
|
onExit
|
|
54138
54331
|
}, ref) {
|
|
54139
54332
|
const { colors: colors2, fonts, components } = useTheme();
|
|
54140
|
-
const { projectConfig, isLoading: configLoading } = useProjectConfig({ publishableKey });
|
|
54141
|
-
const applePayEnabled = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
|
|
54142
54333
|
const [view, setView] = (0, import_react15.useState)("loading_config");
|
|
54143
54334
|
const [errorMessage, setErrorMessage] = (0, import_react15.useState)("");
|
|
54144
|
-
const [email, setEmail] = (0, import_react15.useState)(
|
|
54145
|
-
|
|
54146
|
-
|
|
54335
|
+
const [email, setEmail] = (0, import_react15.useState)(() => {
|
|
54336
|
+
if (userEmail && EMAIL_REGEX2.test(userEmail)) return userEmail;
|
|
54337
|
+
return getStoredApplePaySession(userId)?.email ?? "";
|
|
54338
|
+
});
|
|
54339
|
+
const [phoneInput, setPhoneInput] = (0, import_react15.useState)(() => {
|
|
54340
|
+
const stored = getStoredApplePaySession(userId);
|
|
54341
|
+
if (!stored) return "";
|
|
54342
|
+
if (userEmail && EMAIL_REGEX2.test(userEmail) && stored.email.toLowerCase() !== userEmail.toLowerCase()) {
|
|
54343
|
+
return "";
|
|
54344
|
+
}
|
|
54345
|
+
return stored.phone;
|
|
54346
|
+
});
|
|
54147
54347
|
const { data: legalAgreementsData, isLoading: legalAgreementsLoading } = useCoinbaseLegalAgreements({
|
|
54148
|
-
publishableKey
|
|
54149
|
-
enabled: applePayEnabled
|
|
54348
|
+
publishableKey
|
|
54150
54349
|
});
|
|
54151
54350
|
const legalAgreements = legalAgreementsData ?? null;
|
|
54152
54351
|
const [verificationSession, setVerificationSession] = (0, import_react15.useState)(null);
|
|
54153
54352
|
const [clientSecret, setClientSecret] = (0, import_react15.useState)(null);
|
|
54154
|
-
const [emailCode, setEmailCode] = (0, import_react15.useState)("");
|
|
54155
54353
|
const [phoneCode, setPhoneCode] = (0, import_react15.useState)("");
|
|
54156
54354
|
const [otpError, setOtpError] = (0, import_react15.useState)(null);
|
|
54157
54355
|
const [otpSubmitting, setOtpSubmitting] = (0, import_react15.useState)(false);
|
|
54158
54356
|
const [resendCooldown, setResendCooldown] = (0, import_react15.useState)(0);
|
|
54357
|
+
const [dobInput, setDobInput] = (0, import_react15.useState)("");
|
|
54358
|
+
const [ssnLast4, setSsnLast4] = (0, import_react15.useState)("");
|
|
54359
|
+
const [limitUpgradeError, setLimitUpgradeError] = (0, import_react15.useState)(null);
|
|
54360
|
+
const [upgradeSubmitting, setUpgradeSubmitting] = (0, import_react15.useState)(false);
|
|
54361
|
+
const upgradeFlowAbortRef = (0, import_react15.useRef)(null);
|
|
54159
54362
|
const [amount, setAmount] = (0, import_react15.useState)(amountUsd ?? "");
|
|
54160
54363
|
const [paymentSession, setPaymentSession] = (0, import_react15.useState)(
|
|
54161
54364
|
null
|
|
54162
54365
|
);
|
|
54163
54366
|
const [paymentSessionAmount, setPaymentSessionAmount] = (0, import_react15.useState)(null);
|
|
54164
|
-
const [preparingSession, setPreparingSession] = (0, import_react15.useState)(false);
|
|
54165
54367
|
const popupRef = (0, import_react15.useRef)(null);
|
|
54166
54368
|
const sessionAbortRef = (0, import_react15.useRef)(null);
|
|
54167
54369
|
const [onrampToken, setOnrampToken] = (0, import_react15.useState)(null);
|
|
54168
|
-
const {
|
|
54169
|
-
|
|
54370
|
+
const { userIpInfo, isLoading: userIpInfoLoading } = useUserIp2();
|
|
54371
|
+
const {
|
|
54372
|
+
defaultToken,
|
|
54373
|
+
isLoading: defaultTokenLoading,
|
|
54374
|
+
isError: defaultTokenError
|
|
54375
|
+
} = useDefaultOnrampToken({
|
|
54170
54376
|
publishableKey,
|
|
54171
|
-
|
|
54172
|
-
|
|
54173
|
-
|
|
54174
|
-
|
|
54175
|
-
|
|
54377
|
+
tokenAddress: destinationTokenAddress,
|
|
54378
|
+
chainId: destinationChainId,
|
|
54379
|
+
chainType: destinationChainType,
|
|
54380
|
+
countryCode: userIpInfo?.alpha2,
|
|
54381
|
+
subdivisionCode: userIpInfo?.subdivisionCode ?? void 0
|
|
54176
54382
|
});
|
|
54177
|
-
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
54178
54383
|
const depositWallet = (0, import_react15.useMemo)(() => {
|
|
54179
|
-
|
|
54180
|
-
|
|
54181
|
-
|
|
54384
|
+
const routingChainType = defaultToken?.destination_token_metadata?.chain_type;
|
|
54385
|
+
if (!routingChainType) return void 0;
|
|
54386
|
+
return getWalletByChainType(depositWallets ?? [], routingChainType);
|
|
54387
|
+
}, [depositWallets, defaultToken]);
|
|
54182
54388
|
const depositWalletId = depositWallet?.id;
|
|
54183
54389
|
const { executions } = useDepositPolling({
|
|
54184
54390
|
userId,
|
|
@@ -54202,49 +54408,10 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54202
54408
|
onDepositError(error);
|
|
54203
54409
|
} : void 0
|
|
54204
54410
|
});
|
|
54205
|
-
const [emailLocked, setEmailLocked] = (0, import_react15.useState)(
|
|
54206
|
-
|
|
54207
|
-
|
|
54208
|
-
|
|
54209
|
-
setView("disabled");
|
|
54210
|
-
return;
|
|
54211
|
-
}
|
|
54212
|
-
setTosAccepted(true);
|
|
54213
|
-
const applyStoredOnrampToken = (stored2) => {
|
|
54214
|
-
if (!isOnrampTokenFresh(stored2) || !stored2.onrampToken || !stored2.onrampTokenExpiresAtMs) {
|
|
54215
|
-
return false;
|
|
54216
|
-
}
|
|
54217
|
-
setOnrampToken({
|
|
54218
|
-
token: stored2.onrampToken,
|
|
54219
|
-
token_type: "Bearer",
|
|
54220
|
-
expires_in: Math.max(0, Math.floor((stored2.onrampTokenExpiresAtMs - Date.now()) / 1e3))
|
|
54221
|
-
});
|
|
54222
|
-
setView("amount");
|
|
54223
|
-
return true;
|
|
54224
|
-
};
|
|
54225
|
-
if (externalUserEmail && EMAIL_REGEX.test(externalUserEmail)) {
|
|
54226
|
-
setEmail(externalUserEmail);
|
|
54227
|
-
setEmailLocked(true);
|
|
54228
|
-
const stored2 = getStoredApplePaySession(userId);
|
|
54229
|
-
if (stored2?.email?.toLowerCase() === externalUserEmail.toLowerCase()) {
|
|
54230
|
-
setPhoneInput(stored2.phone);
|
|
54231
|
-
if (applyStoredOnrampToken(stored2)) return;
|
|
54232
|
-
}
|
|
54233
|
-
setView("phone_input");
|
|
54234
|
-
return;
|
|
54235
|
-
}
|
|
54236
|
-
const stored = getStoredApplePaySession(userId);
|
|
54237
|
-
if (stored) {
|
|
54238
|
-
setEmail(stored.email);
|
|
54239
|
-
setPhoneInput(stored.phone);
|
|
54240
|
-
setEmailLocked(true);
|
|
54241
|
-
if (applyStoredOnrampToken(stored)) return;
|
|
54242
|
-
setView("phone_input");
|
|
54243
|
-
return;
|
|
54244
|
-
}
|
|
54245
|
-
setEmailLocked(false);
|
|
54246
|
-
setView("email_input");
|
|
54247
|
-
}, [configLoading, applePayEnabled, externalUserEmail, userId]);
|
|
54411
|
+
const [emailLocked, setEmailLocked] = (0, import_react15.useState)(() => {
|
|
54412
|
+
if (userEmail && EMAIL_REGEX2.test(userEmail)) return true;
|
|
54413
|
+
return !!getStoredApplePaySession(userId);
|
|
54414
|
+
});
|
|
54248
54415
|
(0, import_react15.useEffect)(() => {
|
|
54249
54416
|
if (resendCooldown <= 0) return;
|
|
54250
54417
|
const t13 = setInterval(() => setResendCooldown((c) => Math.max(0, c - 1)), 1e3);
|
|
@@ -54253,19 +54420,10 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54253
54420
|
(0, import_react15.useEffect)(() => {
|
|
54254
54421
|
if (view !== "checking_deposit") return;
|
|
54255
54422
|
const onMessage = (event) => {
|
|
54256
|
-
if (event.origin
|
|
54257
|
-
|
|
54258
|
-
const data = event.data;
|
|
54259
|
-
if (typeof data === "string") {
|
|
54260
|
-
try {
|
|
54261
|
-
parsed = JSON.parse(data);
|
|
54262
|
-
} catch {
|
|
54263
|
-
return;
|
|
54264
|
-
}
|
|
54265
|
-
} else if (data && typeof data === "object" && "eventName" in data) {
|
|
54266
|
-
parsed = data;
|
|
54267
|
-
}
|
|
54423
|
+
if (!COINBASE_ALLOWED_POSTMESSAGE_ORIGINS.has(event.origin)) return;
|
|
54424
|
+
const parsed = parseCoinbasePostMessage(event.data);
|
|
54268
54425
|
if (!parsed) return;
|
|
54426
|
+
const eventName = parsed.eventName.toLowerCase();
|
|
54269
54427
|
const code = parsed.data?.errorCode;
|
|
54270
54428
|
const closePopup = () => {
|
|
54271
54429
|
try {
|
|
@@ -54274,16 +54432,20 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54274
54432
|
}
|
|
54275
54433
|
popupRef.current = null;
|
|
54276
54434
|
};
|
|
54277
|
-
switch (
|
|
54435
|
+
switch (eventName) {
|
|
54278
54436
|
case "onramp_api.commit_success":
|
|
54279
54437
|
case "onramp_api.polling_success":
|
|
54438
|
+
case "onramp_api.cancel":
|
|
54280
54439
|
closePopup();
|
|
54281
54440
|
break;
|
|
54282
54441
|
case "onramp_api.commit_error":
|
|
54442
|
+
case "onramp_api.polling_failed":
|
|
54283
54443
|
if (code === "ERROR_CODE_GUEST_TRANSACTION_COUNT" || code === "ERROR_CODE_GUEST_DAILY_TRANSACTION_COUNT" || code === "ERROR_CODE_GUEST_TRANSACTION_LIMIT") {
|
|
54284
54444
|
closePopup();
|
|
54285
54445
|
setView("guest_limit_reached");
|
|
54446
|
+
return;
|
|
54286
54447
|
}
|
|
54448
|
+
closePopup();
|
|
54287
54449
|
break;
|
|
54288
54450
|
default:
|
|
54289
54451
|
break;
|
|
@@ -54295,17 +54457,17 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54295
54457
|
(0, import_react15.useEffect)(() => {
|
|
54296
54458
|
onViewChange?.(view);
|
|
54297
54459
|
}, [view, onViewChange]);
|
|
54298
|
-
(0, import_react15.useEffect)(
|
|
54299
|
-
|
|
54460
|
+
(0, import_react15.useEffect)(() => {
|
|
54461
|
+
return () => {
|
|
54300
54462
|
sessionAbortRef.current?.abort();
|
|
54463
|
+
upgradeFlowAbortRef.current?.abort();
|
|
54301
54464
|
try {
|
|
54302
54465
|
popupRef.current?.close();
|
|
54303
54466
|
} catch {
|
|
54304
54467
|
}
|
|
54305
54468
|
popupRef.current = null;
|
|
54306
|
-
}
|
|
54307
|
-
|
|
54308
|
-
);
|
|
54469
|
+
};
|
|
54470
|
+
}, []);
|
|
54309
54471
|
React522.useImperativeHandle(
|
|
54310
54472
|
ref,
|
|
54311
54473
|
() => ({
|
|
@@ -54315,14 +54477,20 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54315
54477
|
setView("email_input");
|
|
54316
54478
|
return true;
|
|
54317
54479
|
}
|
|
54318
|
-
if (view === "email_otp") {
|
|
54319
|
-
setView("phone_input");
|
|
54320
|
-
setEmailCode("");
|
|
54321
|
-
return true;
|
|
54322
|
-
}
|
|
54323
54480
|
if (view === "phone_otp") {
|
|
54324
54481
|
setView("phone_input");
|
|
54325
54482
|
setPhoneCode("");
|
|
54483
|
+
setOtpSubmitting(false);
|
|
54484
|
+
return true;
|
|
54485
|
+
}
|
|
54486
|
+
if (view === "limit_upgrade_intro" || view === "limit_upgrade_failed") {
|
|
54487
|
+
return false;
|
|
54488
|
+
}
|
|
54489
|
+
if (view === "limit_upgrade_form") {
|
|
54490
|
+
setView("limit_upgrade_intro");
|
|
54491
|
+
return true;
|
|
54492
|
+
}
|
|
54493
|
+
if (view === "limit_upgrade_submitting") {
|
|
54326
54494
|
return true;
|
|
54327
54495
|
}
|
|
54328
54496
|
if (view === "checking_deposit") {
|
|
@@ -54343,21 +54511,20 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54343
54511
|
[view, emailLocked]
|
|
54344
54512
|
);
|
|
54345
54513
|
const normalizedPhone = (0, import_react15.useMemo)(() => formatPhoneInput(phoneInput), [phoneInput]);
|
|
54346
|
-
const isContactValid =
|
|
54347
|
-
const
|
|
54514
|
+
const isContactValid = EMAIL_REGEX2.test(email) && PHONE_REGEX2.test(normalizedPhone);
|
|
54515
|
+
const storeApplePaySession = (0, import_react15.useCallback)(
|
|
54348
54516
|
(patch = {}) => {
|
|
54349
|
-
const
|
|
54517
|
+
const session = {
|
|
54350
54518
|
email,
|
|
54351
54519
|
phone: normalizedPhone,
|
|
54352
54520
|
termsAcceptedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
54353
54521
|
...patch
|
|
54354
54522
|
};
|
|
54355
|
-
setStoredApplePaySession(userId,
|
|
54523
|
+
setStoredApplePaySession(userId, session);
|
|
54356
54524
|
},
|
|
54357
54525
|
[email, normalizedPhone, userId]
|
|
54358
54526
|
);
|
|
54359
|
-
const
|
|
54360
|
-
if (!isContactValid) return;
|
|
54527
|
+
const createSessionAndSendOtp = (0, import_react15.useCallback)(async () => {
|
|
54361
54528
|
setView("submitting_session");
|
|
54362
54529
|
setErrorMessage("");
|
|
54363
54530
|
try {
|
|
@@ -54375,71 +54542,192 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54375
54542
|
throw new Error("Server did not return a client_secret");
|
|
54376
54543
|
}
|
|
54377
54544
|
setClientSecret(session.client_secret);
|
|
54378
|
-
|
|
54379
|
-
|
|
54380
|
-
|
|
54381
|
-
|
|
54382
|
-
"phone",
|
|
54383
|
-
session.client_secret,
|
|
54384
|
-
publishableKey
|
|
54385
|
-
);
|
|
54386
|
-
setResendCooldown(30);
|
|
54387
|
-
setView("phone_otp");
|
|
54388
|
-
} else {
|
|
54389
|
-
await sendOnrampVerificationOtp(
|
|
54390
|
-
session.id,
|
|
54391
|
-
"email",
|
|
54392
|
-
session.client_secret,
|
|
54393
|
-
publishableKey
|
|
54394
|
-
);
|
|
54395
|
-
setResendCooldown(30);
|
|
54396
|
-
setView("email_otp");
|
|
54397
|
-
}
|
|
54545
|
+
storeApplePaySession();
|
|
54546
|
+
await sendOnrampVerificationOtp(session.id, "phone", session.client_secret, publishableKey);
|
|
54547
|
+
setResendCooldown(30);
|
|
54548
|
+
setView("phone_otp");
|
|
54398
54549
|
} catch (err) {
|
|
54399
54550
|
const raw = err instanceof Error ? err.message : "Failed to start verification";
|
|
54400
54551
|
setErrorMessage(prettifyVerificationError(raw));
|
|
54401
54552
|
setView("phone_input");
|
|
54402
54553
|
}
|
|
54403
|
-
}, [
|
|
54404
|
-
const
|
|
54405
|
-
|
|
54406
|
-
|
|
54407
|
-
|
|
54408
|
-
|
|
54554
|
+
}, [email, normalizedPhone, publishableKey, storeApplePaySession]);
|
|
54555
|
+
const clearUpgradeFields = (0, import_react15.useCallback)(() => {
|
|
54556
|
+
setSsnLast4("");
|
|
54557
|
+
setDobInput("");
|
|
54558
|
+
}, []);
|
|
54559
|
+
const { action: initialAction, refetchApplePayLimits } = useApplePayInitialScreen({
|
|
54560
|
+
userId,
|
|
54561
|
+
publishableKey,
|
|
54562
|
+
normalizedPhone,
|
|
54563
|
+
userEmail,
|
|
54564
|
+
sessionPhoneVerified: verificationSession?.phone?.status === "verified",
|
|
54565
|
+
isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
|
|
54566
|
+
});
|
|
54567
|
+
const pollLimitUpgradeStatus = (0, import_react15.useCallback)(
|
|
54568
|
+
async (signal) => {
|
|
54569
|
+
const POLL_INTERVAL_MS4 = 1500;
|
|
54570
|
+
const POLL_TIMEOUT_MS = 3e4;
|
|
54571
|
+
const startedAt = Date.now();
|
|
54572
|
+
let firstIteration = true;
|
|
54573
|
+
while (Date.now() - startedAt < POLL_TIMEOUT_MS) {
|
|
54574
|
+
if (signal.aborted) return;
|
|
54575
|
+
if (!firstIteration) {
|
|
54576
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS4));
|
|
54577
|
+
}
|
|
54578
|
+
firstIteration = false;
|
|
54579
|
+
if (signal.aborted) return;
|
|
54580
|
+
let fresh;
|
|
54581
|
+
try {
|
|
54582
|
+
fresh = await getCoinbaseApplePayLimits(normalizedPhone, publishableKey, signal);
|
|
54583
|
+
} catch {
|
|
54584
|
+
if (signal.aborted) return;
|
|
54585
|
+
continue;
|
|
54586
|
+
}
|
|
54587
|
+
const { upgrade_status: status, limit_reached: stillCapped } = fresh;
|
|
54588
|
+
if (status === "active" || !stillCapped) {
|
|
54589
|
+
await refetchApplePayLimits();
|
|
54590
|
+
clearUpgradeFields();
|
|
54591
|
+
setLimitUpgradeError(null);
|
|
54592
|
+
if (onrampToken) {
|
|
54593
|
+
setView("amount");
|
|
54594
|
+
} else {
|
|
54595
|
+
if (signal.aborted) return;
|
|
54596
|
+
await createSessionAndSendOtp();
|
|
54597
|
+
}
|
|
54598
|
+
return;
|
|
54599
|
+
}
|
|
54600
|
+
if (status === "inactive") {
|
|
54601
|
+
await refetchApplePayLimits();
|
|
54602
|
+
clearUpgradeFields();
|
|
54603
|
+
setLimitUpgradeError(null);
|
|
54604
|
+
setView("guest_limit_reached");
|
|
54605
|
+
return;
|
|
54606
|
+
}
|
|
54607
|
+
if (status === "resubmit") {
|
|
54608
|
+
await refetchApplePayLimits();
|
|
54609
|
+
setSsnLast4("");
|
|
54610
|
+
setLimitUpgradeError(
|
|
54611
|
+
"We couldn't verify your information. Please check your SSN and date of birth and try again."
|
|
54612
|
+
);
|
|
54613
|
+
setView("limit_upgrade_form");
|
|
54614
|
+
return;
|
|
54615
|
+
}
|
|
54616
|
+
}
|
|
54617
|
+
setLimitUpgradeError(null);
|
|
54618
|
+
setView("limit_upgrade_failed");
|
|
54619
|
+
},
|
|
54620
|
+
[
|
|
54621
|
+
normalizedPhone,
|
|
54622
|
+
publishableKey,
|
|
54623
|
+
refetchApplePayLimits,
|
|
54624
|
+
onrampToken,
|
|
54625
|
+
createSessionAndSendOtp,
|
|
54626
|
+
clearUpgradeFields
|
|
54627
|
+
]
|
|
54628
|
+
);
|
|
54629
|
+
const startUpgradePolling = (0, import_react15.useCallback)(async () => {
|
|
54630
|
+
upgradeFlowAbortRef.current?.abort();
|
|
54631
|
+
const controller = new AbortController();
|
|
54632
|
+
upgradeFlowAbortRef.current = controller;
|
|
54409
54633
|
try {
|
|
54410
|
-
|
|
54411
|
-
|
|
54412
|
-
|
|
54413
|
-
|
|
54414
|
-
|
|
54415
|
-
|
|
54416
|
-
|
|
54417
|
-
|
|
54418
|
-
|
|
54419
|
-
|
|
54420
|
-
|
|
54421
|
-
|
|
54422
|
-
|
|
54423
|
-
setView("phone_otp");
|
|
54634
|
+
await pollLimitUpgradeStatus(controller.signal);
|
|
54635
|
+
} finally {
|
|
54636
|
+
if (upgradeFlowAbortRef.current === controller) {
|
|
54637
|
+
upgradeFlowAbortRef.current = null;
|
|
54638
|
+
}
|
|
54639
|
+
}
|
|
54640
|
+
}, [pollLimitUpgradeStatus]);
|
|
54641
|
+
const applyLimitRouting = (0, import_react15.useCallback)(
|
|
54642
|
+
(nextView, status) => {
|
|
54643
|
+
if (nextView === "limit_upgrade_form" && status === "resubmit") {
|
|
54644
|
+
setLimitUpgradeError(
|
|
54645
|
+
"We couldn't verify your information. Please check your SSN and date of birth and try again."
|
|
54646
|
+
);
|
|
54424
54647
|
} else {
|
|
54425
|
-
|
|
54426
|
-
setEmailCode("");
|
|
54648
|
+
setLimitUpgradeError(null);
|
|
54427
54649
|
}
|
|
54428
|
-
|
|
54429
|
-
|
|
54430
|
-
|
|
54431
|
-
|
|
54432
|
-
|
|
54650
|
+
setView(nextView);
|
|
54651
|
+
if (nextView === "limit_upgrade_submitting") {
|
|
54652
|
+
void startUpgradePolling();
|
|
54653
|
+
}
|
|
54654
|
+
},
|
|
54655
|
+
[startUpgradePolling]
|
|
54656
|
+
);
|
|
54657
|
+
const hasInitializedRef = (0, import_react15.useRef)(false);
|
|
54658
|
+
(0, import_react15.useEffect)(() => {
|
|
54659
|
+
if (hasInitializedRef.current) return;
|
|
54660
|
+
if (initialAction.kind === "pending") return;
|
|
54661
|
+
hasInitializedRef.current = true;
|
|
54662
|
+
switch (initialAction.kind) {
|
|
54663
|
+
case "navigate":
|
|
54664
|
+
setView(initialAction.view);
|
|
54665
|
+
break;
|
|
54666
|
+
case "limit_upgrade":
|
|
54667
|
+
applyLimitRouting(initialAction.view, initialAction.status);
|
|
54668
|
+
break;
|
|
54669
|
+
case "resume_with_token":
|
|
54670
|
+
setOnrampToken(initialAction.token);
|
|
54671
|
+
setView("amount");
|
|
54672
|
+
break;
|
|
54673
|
+
case "resume_send_sms":
|
|
54674
|
+
void createSessionAndSendOtp();
|
|
54675
|
+
break;
|
|
54676
|
+
}
|
|
54677
|
+
}, [initialAction, applyLimitRouting, createSessionAndSendOtp]);
|
|
54678
|
+
const startVerification = (0, import_react15.useCallback)(async () => {
|
|
54679
|
+
if (!isContactValid) return;
|
|
54680
|
+
await createSessionAndSendOtp();
|
|
54681
|
+
}, [isContactValid, createSessionAndSendOtp]);
|
|
54682
|
+
const submitLimitUpgrade = (0, import_react15.useCallback)(async () => {
|
|
54683
|
+
if (upgradeSubmitting) return;
|
|
54684
|
+
try {
|
|
54685
|
+
const dob = parseDobInput(dobInput);
|
|
54686
|
+
if (!dob || !/^\d{4}$/.test(ssnLast4)) return;
|
|
54687
|
+
setUpgradeSubmitting(true);
|
|
54688
|
+
setLimitUpgradeError(null);
|
|
54689
|
+
setView("limit_upgrade_submitting");
|
|
54690
|
+
const requestController = new AbortController();
|
|
54691
|
+
upgradeFlowAbortRef.current?.abort();
|
|
54692
|
+
upgradeFlowAbortRef.current = requestController;
|
|
54693
|
+
try {
|
|
54694
|
+
await requestCoinbaseApplePayLimitUpgrade(
|
|
54695
|
+
{
|
|
54696
|
+
phone: normalizedPhone,
|
|
54697
|
+
fields: { ssnLast4, dateOfBirth: dob }
|
|
54698
|
+
},
|
|
54699
|
+
publishableKey,
|
|
54700
|
+
requestController.signal
|
|
54701
|
+
);
|
|
54702
|
+
} catch (err) {
|
|
54703
|
+
if (requestController.signal.aborted) return;
|
|
54704
|
+
const raw = err instanceof Error ? err.message : "Failed to request limit upgrade";
|
|
54705
|
+
if (isLimitUpgradeTerminalBlock(raw)) {
|
|
54706
|
+
clearUpgradeFields();
|
|
54707
|
+
setLimitUpgradeError(null);
|
|
54708
|
+
setView("guest_limit_reached");
|
|
54709
|
+
return;
|
|
54710
|
+
}
|
|
54711
|
+
setLimitUpgradeError(prettifyVerificationError(raw));
|
|
54712
|
+
setView("limit_upgrade_form");
|
|
54713
|
+
return;
|
|
54714
|
+
} finally {
|
|
54715
|
+
if (upgradeFlowAbortRef.current === requestController) {
|
|
54716
|
+
upgradeFlowAbortRef.current = null;
|
|
54717
|
+
}
|
|
54718
|
+
}
|
|
54719
|
+
await startUpgradePolling();
|
|
54433
54720
|
} finally {
|
|
54434
|
-
|
|
54721
|
+
setUpgradeSubmitting(false);
|
|
54435
54722
|
}
|
|
54436
54723
|
}, [
|
|
54437
|
-
|
|
54438
|
-
|
|
54439
|
-
|
|
54724
|
+
upgradeSubmitting,
|
|
54725
|
+
dobInput,
|
|
54726
|
+
ssnLast4,
|
|
54727
|
+
normalizedPhone,
|
|
54440
54728
|
publishableKey,
|
|
54441
|
-
|
|
54442
|
-
|
|
54729
|
+
startUpgradePolling,
|
|
54730
|
+
clearUpgradeFields
|
|
54443
54731
|
]);
|
|
54444
54732
|
const submitPhoneOtp = (0, import_react15.useCallback)(async () => {
|
|
54445
54733
|
if (!verificationSession || !clientSecret || phoneCode.length !== 6) return;
|
|
@@ -54462,7 +54750,7 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54462
54750
|
publishableKey
|
|
54463
54751
|
);
|
|
54464
54752
|
setOnrampToken(tokenRes);
|
|
54465
|
-
|
|
54753
|
+
storeApplePaySession({
|
|
54466
54754
|
emailVerifiedAt: updated.email.verified_at,
|
|
54467
54755
|
phoneVerifiedAt: updated.phone.verified_at,
|
|
54468
54756
|
onrampToken: tokenRes.token,
|
|
@@ -54471,17 +54759,30 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54471
54759
|
setEmailLocked(true);
|
|
54472
54760
|
setPhoneCode("");
|
|
54473
54761
|
if (amountUsd) setAmount(amountUsd);
|
|
54762
|
+
try {
|
|
54763
|
+
const result = await refetchApplePayLimits();
|
|
54764
|
+
if (result.data) {
|
|
54765
|
+
const nextView = getViewForLimitStatus(result.data);
|
|
54766
|
+
if (nextView) {
|
|
54767
|
+
setOtpSubmitting(false);
|
|
54768
|
+
applyLimitRouting(nextView, result.data.upgrade_status);
|
|
54769
|
+
return;
|
|
54770
|
+
}
|
|
54771
|
+
}
|
|
54772
|
+
} catch {
|
|
54773
|
+
}
|
|
54774
|
+
setOtpSubmitting(false);
|
|
54474
54775
|
setView("amount");
|
|
54475
|
-
|
|
54476
|
-
setOtpError("Incorrect code. Please try again.");
|
|
54477
|
-
setPhoneCode("");
|
|
54776
|
+
return;
|
|
54478
54777
|
}
|
|
54778
|
+
setOtpError("Incorrect code. Please try again.");
|
|
54779
|
+
setPhoneCode("");
|
|
54780
|
+
setOtpSubmitting(false);
|
|
54479
54781
|
} catch (err) {
|
|
54480
54782
|
setOtpError(
|
|
54481
54783
|
prettifyVerificationError(err instanceof Error ? err.message : "Verification failed")
|
|
54482
54784
|
);
|
|
54483
54785
|
setPhoneCode("");
|
|
54484
|
-
} finally {
|
|
54485
54786
|
setOtpSubmitting(false);
|
|
54486
54787
|
}
|
|
54487
54788
|
}, [
|
|
@@ -54489,22 +54790,25 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54489
54790
|
clientSecret,
|
|
54490
54791
|
phoneCode,
|
|
54491
54792
|
publishableKey,
|
|
54492
|
-
|
|
54793
|
+
storeApplePaySession,
|
|
54493
54794
|
amountUsd,
|
|
54494
|
-
otpSubmitting
|
|
54795
|
+
otpSubmitting,
|
|
54796
|
+
refetchApplePayLimits,
|
|
54797
|
+
getViewForLimitStatus,
|
|
54798
|
+
applyLimitRouting
|
|
54495
54799
|
]);
|
|
54496
54800
|
const prepareSession = (0, import_react15.useCallback)(
|
|
54497
54801
|
async (token, amt) => {
|
|
54802
|
+
setErrorMessage("");
|
|
54498
54803
|
if (!destinationChainType || !destinationChainId) {
|
|
54499
54804
|
setErrorMessage("Deposit destination not configured. Please contact support.");
|
|
54500
54805
|
return;
|
|
54501
54806
|
}
|
|
54502
|
-
|
|
54503
|
-
|
|
54504
|
-
|
|
54505
|
-
)
|
|
54506
|
-
|
|
54507
|
-
setErrorMessage("Coinbase Apple Pay is not available for this network.");
|
|
54807
|
+
if (defaultTokenLoading) {
|
|
54808
|
+
return;
|
|
54809
|
+
}
|
|
54810
|
+
if (defaultTokenError || !defaultToken) {
|
|
54811
|
+
setErrorMessage("Unable to load token information. Please try again.");
|
|
54508
54812
|
return;
|
|
54509
54813
|
}
|
|
54510
54814
|
const settlementAddress = depositWallet?.address;
|
|
@@ -54515,19 +54819,17 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54515
54819
|
sessionAbortRef.current?.abort();
|
|
54516
54820
|
const controller = new AbortController();
|
|
54517
54821
|
sessionAbortRef.current = controller;
|
|
54518
|
-
setPreparingSession(true);
|
|
54519
|
-
setErrorMessage("");
|
|
54520
54822
|
try {
|
|
54521
54823
|
const externalId = generatePrefixedKSUID("orsext");
|
|
54522
54824
|
const session = await createCoinbaseApplePaySession(
|
|
54523
54825
|
{
|
|
54524
54826
|
source_currency: "usd",
|
|
54525
54827
|
source_amount: amt,
|
|
54526
|
-
destination_currency:
|
|
54527
|
-
destination_network:
|
|
54828
|
+
destination_currency: defaultToken.destination_currency,
|
|
54829
|
+
destination_network: defaultToken.destination_network,
|
|
54528
54830
|
wallet_address: settlementAddress,
|
|
54529
54831
|
external_id: externalId,
|
|
54530
|
-
...
|
|
54832
|
+
...userEmail ? { email: userEmail } : {}
|
|
54531
54833
|
},
|
|
54532
54834
|
token,
|
|
54533
54835
|
publishableKey,
|
|
@@ -54571,18 +54873,16 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54571
54873
|
setPaymentSession(null);
|
|
54572
54874
|
setPaymentSessionAmount(null);
|
|
54573
54875
|
setErrorMessage("Unable to process your request. Please try again later.");
|
|
54574
|
-
} finally {
|
|
54575
|
-
if (sessionAbortRef.current === controller) {
|
|
54576
|
-
setPreparingSession(false);
|
|
54577
|
-
}
|
|
54578
54876
|
}
|
|
54579
54877
|
},
|
|
54580
54878
|
[
|
|
54581
|
-
destinationTokenSymbol,
|
|
54582
54879
|
destinationChainType,
|
|
54583
54880
|
destinationChainId,
|
|
54881
|
+
defaultToken,
|
|
54882
|
+
defaultTokenLoading,
|
|
54883
|
+
defaultTokenError,
|
|
54584
54884
|
depositWallet?.address,
|
|
54585
|
-
|
|
54885
|
+
userEmail,
|
|
54586
54886
|
publishableKey,
|
|
54587
54887
|
onEvent,
|
|
54588
54888
|
userId
|
|
@@ -54626,42 +54926,8 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54626
54926
|
if (view === "loading_config") {
|
|
54627
54927
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-16", style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LoaderCircle, { className: "uf-w-6 uf-h-6 uf-animate-spin", style: { color: colors2.primary } }) });
|
|
54628
54928
|
}
|
|
54629
|
-
if (view === "disabled") {
|
|
54630
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
54631
|
-
"div",
|
|
54632
|
-
{
|
|
54633
|
-
className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-12 uf-px-4",
|
|
54634
|
-
style: containerStyle,
|
|
54635
|
-
children: [
|
|
54636
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
54637
|
-
CircleAlert,
|
|
54638
|
-
{
|
|
54639
|
-
className: "uf-w-8 uf-h-8 uf-mb-4",
|
|
54640
|
-
style: { color: colors2.foregroundMuted }
|
|
54641
|
-
}
|
|
54642
|
-
),
|
|
54643
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
54644
|
-
"h3",
|
|
54645
|
-
{
|
|
54646
|
-
className: "uf-text-base uf-font-medium uf-mb-1",
|
|
54647
|
-
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
54648
|
-
children: "Apple Pay is unavailable"
|
|
54649
|
-
}
|
|
54650
|
-
),
|
|
54651
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
54652
|
-
"p",
|
|
54653
|
-
{
|
|
54654
|
-
className: "uf-text-sm uf-text-center",
|
|
54655
|
-
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
54656
|
-
children: "Apple Pay is disabled for this project. Try another payment method."
|
|
54657
|
-
}
|
|
54658
|
-
)
|
|
54659
|
-
]
|
|
54660
|
-
}
|
|
54661
|
-
);
|
|
54662
|
-
}
|
|
54663
54929
|
if (view === "email_input") {
|
|
54664
|
-
const emailValid =
|
|
54930
|
+
const emailValid = EMAIL_REGEX2.test(email);
|
|
54665
54931
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "uf-flex uf-flex-col uf-pb-1 uf-pt-2", style: containerStyle, children: [
|
|
54666
54932
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
54667
54933
|
"label",
|
|
@@ -54678,9 +54944,7 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54678
54944
|
value: email,
|
|
54679
54945
|
onChange: (e) => setEmail(e.target.value.trim()),
|
|
54680
54946
|
onKeyDown: (e) => {
|
|
54681
|
-
if (e.key === "Enter" && emailValid)
|
|
54682
|
-
setView("phone_input");
|
|
54683
|
-
}
|
|
54947
|
+
if (e.key === "Enter" && emailValid) setView("phone_input");
|
|
54684
54948
|
},
|
|
54685
54949
|
placeholder: "you@example.com",
|
|
54686
54950
|
autoComplete: "email",
|
|
@@ -54716,7 +54980,7 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54716
54980
|
}
|
|
54717
54981
|
if (view === "phone_input" || view === "submitting_session") {
|
|
54718
54982
|
const submitting = view === "submitting_session";
|
|
54719
|
-
const phoneValid =
|
|
54983
|
+
const phoneValid = PHONE_REGEX2.test(normalizedPhone);
|
|
54720
54984
|
const rawDigits = (() => {
|
|
54721
54985
|
const digits = phoneInput.replace(/\D/g, "");
|
|
54722
54986
|
return digits.startsWith("1") ? digits.slice(1, 11) : digits.slice(0, 10);
|
|
@@ -54797,15 +55061,7 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54797
55061
|
!phoneInput && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-text-xs uf-mb-2 uf-px-1", style: { color: colors2.foregroundMuted }, children: "Re-verified every 60 days." }),
|
|
54798
55062
|
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-text-xs uf-mt-2 uf-px-1", style: { color: colors2.error }, children: errorMessage }),
|
|
54799
55063
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-flex-1" }),
|
|
54800
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
54801
|
-
LegalDisclaimer,
|
|
54802
|
-
{
|
|
54803
|
-
legalAgreements,
|
|
54804
|
-
loading: legalAgreementsLoading,
|
|
54805
|
-
colors: colors2,
|
|
54806
|
-
fonts
|
|
54807
|
-
}
|
|
54808
|
-
),
|
|
55064
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LegalDisclaimer, { legalAgreements, loading: legalAgreementsLoading }),
|
|
54809
55065
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
54810
55066
|
"button",
|
|
54811
55067
|
{
|
|
@@ -54824,12 +55080,9 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54824
55080
|
)
|
|
54825
55081
|
] });
|
|
54826
55082
|
}
|
|
54827
|
-
if (view === "
|
|
54828
|
-
const
|
|
54829
|
-
const
|
|
54830
|
-
const setCode = isEmail ? setEmailCode : setPhoneCode;
|
|
54831
|
-
const target = isEmail ? maskEmail(email) : maskPhone(normalizedPhone);
|
|
54832
|
-
const submit = isEmail ? submitEmailOtp : submitPhoneOtp;
|
|
55083
|
+
if (view === "phone_otp") {
|
|
55084
|
+
const code = phoneCode;
|
|
55085
|
+
const target = maskPhone(normalizedPhone);
|
|
54833
55086
|
const canSubmit = code.length === 6 && !otpSubmitting;
|
|
54834
55087
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "uf-flex uf-flex-col uf-pb-1 uf-items-center uf-pt-2", style: containerStyle, children: [
|
|
54835
55088
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
@@ -54852,13 +55105,12 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54852
55105
|
maxLength: 6,
|
|
54853
55106
|
value: code,
|
|
54854
55107
|
onChange: (e) => {
|
|
54855
|
-
|
|
54856
|
-
setCode(v);
|
|
55108
|
+
setPhoneCode(e.target.value.replace(/\D/g, "").slice(0, 6));
|
|
54857
55109
|
setOtpError(null);
|
|
54858
55110
|
},
|
|
54859
55111
|
onKeyDown: (e) => {
|
|
54860
55112
|
if (e.key === "Enter" && code.length === 6 && !otpSubmitting) {
|
|
54861
|
-
void
|
|
55113
|
+
void submitPhoneOtp();
|
|
54862
55114
|
}
|
|
54863
55115
|
},
|
|
54864
55116
|
autoFocus: true,
|
|
@@ -54885,7 +55137,7 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54885
55137
|
if (!verificationSession || !clientSecret) return;
|
|
54886
55138
|
void sendOnrampVerificationOtp(
|
|
54887
55139
|
verificationSession.id,
|
|
54888
|
-
|
|
55140
|
+
"phone",
|
|
54889
55141
|
clientSecret,
|
|
54890
55142
|
publishableKey
|
|
54891
55143
|
).then(() => setResendCooldown(30));
|
|
@@ -54898,7 +55150,7 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
54898
55150
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
54899
55151
|
"button",
|
|
54900
55152
|
{
|
|
54901
|
-
onClick:
|
|
55153
|
+
onClick: submitPhoneOtp,
|
|
54902
55154
|
disabled: !canSubmit,
|
|
54903
55155
|
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",
|
|
54904
55156
|
style: {
|
|
@@ -55046,7 +55298,7 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
55046
55298
|
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`,
|
|
55047
55299
|
opacity: 0.5
|
|
55048
55300
|
},
|
|
55049
|
-
children: !hasInput || !validAmount ? "Enter amount" : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
55301
|
+
children: !hasInput || !validAmount ? "Enter amount" : errorMessage ? "Unable to prepare Apple Pay" : defaultTokenLoading ? "Loading token information\u2026" : defaultTokenError ? "Token routing unavailable" : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
55050
55302
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
|
|
55051
55303
|
"Preparing Apple Pay"
|
|
55052
55304
|
] })
|
|
@@ -55084,7 +55336,104 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
55084
55336
|
{
|
|
55085
55337
|
className: "uf-text-xl uf-mb-2 uf-text-center",
|
|
55086
55338
|
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
55087
|
-
children: "Checking for your deposit\u2026"
|
|
55339
|
+
children: "Checking for your deposit\u2026"
|
|
55340
|
+
}
|
|
55341
|
+
),
|
|
55342
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55343
|
+
"p",
|
|
55344
|
+
{
|
|
55345
|
+
className: "uf-text-sm uf-text-center uf-max-w-[280px]",
|
|
55346
|
+
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
55347
|
+
children: "Return if the payment is not made."
|
|
55348
|
+
}
|
|
55349
|
+
)
|
|
55350
|
+
]
|
|
55351
|
+
}
|
|
55352
|
+
);
|
|
55353
|
+
}
|
|
55354
|
+
if (view === "limit_upgrade_intro") {
|
|
55355
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "uf-flex uf-flex-col uf-pt-8 uf-pb-2 uf-px-2", style: containerStyle, children: [
|
|
55356
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55357
|
+
"h3",
|
|
55358
|
+
{
|
|
55359
|
+
className: "uf-text-xl uf-mb-3 uf-text-center",
|
|
55360
|
+
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
55361
|
+
children: "Apple Pay limit reached"
|
|
55362
|
+
}
|
|
55363
|
+
),
|
|
55364
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55365
|
+
"p",
|
|
55366
|
+
{
|
|
55367
|
+
className: "uf-text-sm uf-text-center uf-mb-10 uf-max-w-[320px] uf-mx-auto",
|
|
55368
|
+
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
55369
|
+
children: "Submit your date of birth and SSN to increase your Apple Pay limit."
|
|
55370
|
+
}
|
|
55371
|
+
),
|
|
55372
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55373
|
+
"button",
|
|
55374
|
+
{
|
|
55375
|
+
onClick: () => {
|
|
55376
|
+
setLimitUpgradeError(null);
|
|
55377
|
+
setView("limit_upgrade_form");
|
|
55378
|
+
},
|
|
55379
|
+
className: "uf-w-full uf-py-3 uf-mb-2 uf-text-sm uf-font-medium uf-transition-colors",
|
|
55380
|
+
style: {
|
|
55381
|
+
backgroundColor: colors2.primary,
|
|
55382
|
+
color: colors2.primaryForeground,
|
|
55383
|
+
fontFamily: fonts.medium,
|
|
55384
|
+
borderRadius: components.button.borderRadius,
|
|
55385
|
+
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
|
|
55386
|
+
},
|
|
55387
|
+
children: "Continue"
|
|
55388
|
+
}
|
|
55389
|
+
),
|
|
55390
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55391
|
+
"button",
|
|
55392
|
+
{
|
|
55393
|
+
onClick: () => {
|
|
55394
|
+
setLimitUpgradeError(null);
|
|
55395
|
+
onExit?.();
|
|
55396
|
+
},
|
|
55397
|
+
className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors",
|
|
55398
|
+
style: {
|
|
55399
|
+
backgroundColor: "transparent",
|
|
55400
|
+
color: colors2.error,
|
|
55401
|
+
fontFamily: fonts.medium,
|
|
55402
|
+
borderRadius: components.button.borderRadius,
|
|
55403
|
+
border: `${components.button.borderWidth}px solid transparent`
|
|
55404
|
+
},
|
|
55405
|
+
children: "Cancel"
|
|
55406
|
+
}
|
|
55407
|
+
)
|
|
55408
|
+
] });
|
|
55409
|
+
}
|
|
55410
|
+
if (view === "limit_upgrade_submitting") {
|
|
55411
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
55412
|
+
"div",
|
|
55413
|
+
{
|
|
55414
|
+
className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16 uf-px-4",
|
|
55415
|
+
style: containerStyle,
|
|
55416
|
+
children: [
|
|
55417
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55418
|
+
"div",
|
|
55419
|
+
{
|
|
55420
|
+
className: "uf-w-20 uf-h-20 uf-rounded-full uf-flex uf-items-center uf-justify-center uf-mb-6",
|
|
55421
|
+
style: { backgroundColor: `${colors2.primary}20` },
|
|
55422
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55423
|
+
LoaderCircle,
|
|
55424
|
+
{
|
|
55425
|
+
className: "uf-w-10 uf-h-10 uf-animate-spin",
|
|
55426
|
+
style: { color: colors2.primary }
|
|
55427
|
+
}
|
|
55428
|
+
)
|
|
55429
|
+
}
|
|
55430
|
+
),
|
|
55431
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55432
|
+
"h3",
|
|
55433
|
+
{
|
|
55434
|
+
className: "uf-text-xl uf-mb-2 uf-text-center",
|
|
55435
|
+
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
55436
|
+
children: "Verifying your information"
|
|
55088
55437
|
}
|
|
55089
55438
|
),
|
|
55090
55439
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
@@ -55092,13 +55441,184 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
55092
55441
|
{
|
|
55093
55442
|
className: "uf-text-sm uf-text-center uf-max-w-[280px]",
|
|
55094
55443
|
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
55095
|
-
children: "
|
|
55444
|
+
children: "Your limit increase request is under review. This usually takes just a few seconds."
|
|
55096
55445
|
}
|
|
55097
55446
|
)
|
|
55098
55447
|
]
|
|
55099
55448
|
}
|
|
55100
55449
|
);
|
|
55101
55450
|
}
|
|
55451
|
+
if (view === "limit_upgrade_form") {
|
|
55452
|
+
const dobValid = isDobInputValid(dobInput);
|
|
55453
|
+
const ssnValid = /^\d{4}$/.test(ssnLast4);
|
|
55454
|
+
const formValid = dobValid && ssnValid;
|
|
55455
|
+
const formInputStyle = {
|
|
55456
|
+
backgroundColor: components.card.backgroundColor,
|
|
55457
|
+
color: components.input.textColor,
|
|
55458
|
+
fontFamily: fonts.regular,
|
|
55459
|
+
borderRadius: components.card.borderRadius,
|
|
55460
|
+
border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
|
|
55461
|
+
};
|
|
55462
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "uf-flex uf-flex-col uf-pb-1 uf-pt-2", style: containerStyle, children: [
|
|
55463
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55464
|
+
"label",
|
|
55465
|
+
{
|
|
55466
|
+
className: "uf-text-xs uf-font-medium uf-mb-1.5 uf-px-1",
|
|
55467
|
+
style: { color: components.card.labelColor, fontFamily: fonts.medium },
|
|
55468
|
+
children: "Date of birth"
|
|
55469
|
+
}
|
|
55470
|
+
),
|
|
55471
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55472
|
+
"input",
|
|
55473
|
+
{
|
|
55474
|
+
type: "text",
|
|
55475
|
+
inputMode: "numeric",
|
|
55476
|
+
maxLength: 10,
|
|
55477
|
+
value: dobInput,
|
|
55478
|
+
onChange: (e) => {
|
|
55479
|
+
setDobInput(formatDobInput(e.target.value));
|
|
55480
|
+
if (limitUpgradeError) setLimitUpgradeError(null);
|
|
55481
|
+
},
|
|
55482
|
+
onKeyDown: (e) => {
|
|
55483
|
+
if (e.key === "Enter" && formValid) void submitLimitUpgrade();
|
|
55484
|
+
},
|
|
55485
|
+
placeholder: "MM/DD/YYYY",
|
|
55486
|
+
autoComplete: "bday",
|
|
55487
|
+
"aria-label": "Date of birth",
|
|
55488
|
+
className: "uf-w-full uf-px-3 uf-py-3 uf-mb-3 uf-text-sm uf-outline-none",
|
|
55489
|
+
style: formInputStyle
|
|
55490
|
+
}
|
|
55491
|
+
),
|
|
55492
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55493
|
+
"label",
|
|
55494
|
+
{
|
|
55495
|
+
className: "uf-text-xs uf-font-medium uf-mb-1.5 uf-px-1",
|
|
55496
|
+
style: { color: components.card.labelColor, fontFamily: fonts.medium },
|
|
55497
|
+
children: "Last 4 of SSN"
|
|
55498
|
+
}
|
|
55499
|
+
),
|
|
55500
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55501
|
+
"input",
|
|
55502
|
+
{
|
|
55503
|
+
type: "password",
|
|
55504
|
+
inputMode: "numeric",
|
|
55505
|
+
pattern: "[0-9]*",
|
|
55506
|
+
maxLength: 4,
|
|
55507
|
+
value: ssnLast4,
|
|
55508
|
+
onChange: (e) => {
|
|
55509
|
+
setSsnLast4(e.target.value.replace(/\D/g, "").slice(0, 4));
|
|
55510
|
+
if (limitUpgradeError) setLimitUpgradeError(null);
|
|
55511
|
+
},
|
|
55512
|
+
onKeyDown: (e) => {
|
|
55513
|
+
if (e.key === "Enter" && formValid) void submitLimitUpgrade();
|
|
55514
|
+
},
|
|
55515
|
+
placeholder: "\u2022\u2022\u2022\u2022",
|
|
55516
|
+
autoComplete: "off",
|
|
55517
|
+
name: "off",
|
|
55518
|
+
autoCorrect: "off",
|
|
55519
|
+
autoCapitalize: "none",
|
|
55520
|
+
spellCheck: false,
|
|
55521
|
+
"data-1p-ignore": "true",
|
|
55522
|
+
"data-lpignore": "true",
|
|
55523
|
+
"data-form-type": "other",
|
|
55524
|
+
"aria-label": "Last 4 digits of SSN",
|
|
55525
|
+
"aria-autocomplete": "none",
|
|
55526
|
+
className: "uf-w-full uf-px-3 uf-py-3 uf-mb-2 uf-text-sm uf-outline-none",
|
|
55527
|
+
style: formInputStyle
|
|
55528
|
+
}
|
|
55529
|
+
),
|
|
55530
|
+
limitUpgradeError && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55531
|
+
"div",
|
|
55532
|
+
{
|
|
55533
|
+
className: "uf-text-xs uf-mt-2 uf-px-1",
|
|
55534
|
+
style: { color: colors2.error, fontFamily: fonts.regular },
|
|
55535
|
+
children: limitUpgradeError
|
|
55536
|
+
}
|
|
55537
|
+
),
|
|
55538
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-flex-1" }),
|
|
55539
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55540
|
+
"button",
|
|
55541
|
+
{
|
|
55542
|
+
onClick: () => void submitLimitUpgrade(),
|
|
55543
|
+
disabled: !formValid || upgradeSubmitting,
|
|
55544
|
+
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",
|
|
55545
|
+
style: {
|
|
55546
|
+
backgroundColor: colors2.primary,
|
|
55547
|
+
color: colors2.primaryForeground,
|
|
55548
|
+
fontFamily: fonts.medium,
|
|
55549
|
+
borderRadius: components.button.borderRadius,
|
|
55550
|
+
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
|
|
55551
|
+
},
|
|
55552
|
+
children: upgradeSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2", children: [
|
|
55553
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
|
|
55554
|
+
"Submitting\u2026"
|
|
55555
|
+
] }) : "Submit"
|
|
55556
|
+
}
|
|
55557
|
+
)
|
|
55558
|
+
] });
|
|
55559
|
+
}
|
|
55560
|
+
if (view === "limit_upgrade_failed") {
|
|
55561
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "uf-flex uf-flex-col uf-pt-8 uf-pb-2 uf-px-2", style: containerStyle, children: [
|
|
55562
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55563
|
+
"h3",
|
|
55564
|
+
{
|
|
55565
|
+
className: "uf-text-xl uf-mb-3 uf-text-center",
|
|
55566
|
+
style: { color: colors2.foreground, fontFamily: fonts.medium },
|
|
55567
|
+
children: "Apple Pay limit reached"
|
|
55568
|
+
}
|
|
55569
|
+
),
|
|
55570
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
55571
|
+
"p",
|
|
55572
|
+
{
|
|
55573
|
+
className: "uf-text-sm uf-text-center uf-mb-2 uf-max-w-[320px] uf-mx-auto",
|
|
55574
|
+
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
55575
|
+
children: [
|
|
55576
|
+
"Failed to increase. Please try again later or",
|
|
55577
|
+
" ",
|
|
55578
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55579
|
+
"a",
|
|
55580
|
+
{
|
|
55581
|
+
href: UNIFOLD_SUPPORT_URL,
|
|
55582
|
+
target: "_blank",
|
|
55583
|
+
rel: "noreferrer noopener",
|
|
55584
|
+
className: "uf-underline",
|
|
55585
|
+
style: { color: colors2.primary },
|
|
55586
|
+
children: "contact support"
|
|
55587
|
+
}
|
|
55588
|
+
),
|
|
55589
|
+
"."
|
|
55590
|
+
]
|
|
55591
|
+
}
|
|
55592
|
+
),
|
|
55593
|
+
limitUpgradeError && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55594
|
+
"p",
|
|
55595
|
+
{
|
|
55596
|
+
className: "uf-text-xs uf-text-center uf-mb-2 uf-px-2",
|
|
55597
|
+
style: { color: colors2.error, fontFamily: fonts.regular },
|
|
55598
|
+
children: limitUpgradeError
|
|
55599
|
+
}
|
|
55600
|
+
),
|
|
55601
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-mb-8" }),
|
|
55602
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
55603
|
+
"button",
|
|
55604
|
+
{
|
|
55605
|
+
onClick: () => {
|
|
55606
|
+
setLimitUpgradeError(null);
|
|
55607
|
+
onExit?.();
|
|
55608
|
+
},
|
|
55609
|
+
className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors",
|
|
55610
|
+
style: {
|
|
55611
|
+
backgroundColor: colors2.primary,
|
|
55612
|
+
color: colors2.primaryForeground,
|
|
55613
|
+
fontFamily: fonts.medium,
|
|
55614
|
+
borderRadius: components.button.borderRadius,
|
|
55615
|
+
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
|
|
55616
|
+
},
|
|
55617
|
+
children: "Return"
|
|
55618
|
+
}
|
|
55619
|
+
)
|
|
55620
|
+
] });
|
|
55621
|
+
}
|
|
55102
55622
|
if (view === "guest_limit_reached") {
|
|
55103
55623
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
55104
55624
|
"div",
|
|
@@ -55119,7 +55639,7 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
55119
55639
|
{
|
|
55120
55640
|
className: "uf-text-sm uf-text-center uf-mb-12 uf-max-w-[300px]",
|
|
55121
55641
|
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
55122
|
-
children: "Your account
|
|
55642
|
+
children: "Your account is not eligible for a limit increase at this time."
|
|
55123
55643
|
}
|
|
55124
55644
|
),
|
|
55125
55645
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
@@ -55145,7 +55665,95 @@ var BuyWithApplePay = React522.forwardRef(
|
|
|
55145
55665
|
}
|
|
55146
55666
|
);
|
|
55147
55667
|
BuyWithApplePay.displayName = "BuyWithApplePay";
|
|
55148
|
-
function
|
|
55668
|
+
function formatPhoneInput(raw) {
|
|
55669
|
+
const digits = raw.replace(/\D/g, "");
|
|
55670
|
+
if (raw.startsWith("+")) {
|
|
55671
|
+
return `+${digits}`;
|
|
55672
|
+
}
|
|
55673
|
+
if (digits.length === 10) return `+1${digits}`;
|
|
55674
|
+
if (digits.length === 11 && digits.startsWith("1")) return `+${digits}`;
|
|
55675
|
+
return digits.length > 0 ? `+${digits}` : "";
|
|
55676
|
+
}
|
|
55677
|
+
function maskPhone(phone) {
|
|
55678
|
+
if (!/^\+1\d{10}$/.test(phone)) return phone;
|
|
55679
|
+
return `+1 (***) ***-${phone.slice(-4)}`;
|
|
55680
|
+
}
|
|
55681
|
+
function isGuestLimitError(err) {
|
|
55682
|
+
const message = err instanceof Error ? err.message : String(err ?? "");
|
|
55683
|
+
if (/coinbase_onramp_guest_limit_reached/i.test(message)) return true;
|
|
55684
|
+
if (/guest_(daily_)?transaction_(count|limit)/i.test(message)) return true;
|
|
55685
|
+
return false;
|
|
55686
|
+
}
|
|
55687
|
+
function isLimitUpgradeTerminalBlock(message) {
|
|
55688
|
+
if (/coinbase_onramp_guest_limit_reached/i.test(message)) return true;
|
|
55689
|
+
if (/limit upgrade is not available/i.test(message)) return true;
|
|
55690
|
+
if (/limits.?upgrade.?blocked/i.test(message)) return true;
|
|
55691
|
+
return false;
|
|
55692
|
+
}
|
|
55693
|
+
function prettifyVerificationError(message) {
|
|
55694
|
+
if (/\b429\b|too many requests|rate.?limit|throttle/i.test(message)) {
|
|
55695
|
+
return "Too many attempts. Please wait a few minutes and try again.";
|
|
55696
|
+
}
|
|
55697
|
+
if (/network|failed to fetch|abort/i.test(message)) {
|
|
55698
|
+
return "Network error. Check your connection and try again.";
|
|
55699
|
+
}
|
|
55700
|
+
if (/voip|not a valid US|not a cell/i.test(message)) {
|
|
55701
|
+
return "We can only verify real US cell phones (not VoIP). Try a different number.";
|
|
55702
|
+
}
|
|
55703
|
+
const cleaned = message.replace(/\s*\[[\w_]+\]:\s*.*$/, "").trim();
|
|
55704
|
+
return cleaned || message;
|
|
55705
|
+
}
|
|
55706
|
+
function formatDobInput(raw) {
|
|
55707
|
+
const digits = raw.replace(/\D/g, "").slice(0, 8);
|
|
55708
|
+
if (digits.length <= 2) return digits;
|
|
55709
|
+
if (digits.length <= 4) return `${digits.slice(0, 2)}/${digits.slice(2)}`;
|
|
55710
|
+
return `${digits.slice(0, 2)}/${digits.slice(2, 4)}/${digits.slice(4)}`;
|
|
55711
|
+
}
|
|
55712
|
+
function isDobInputValid(input) {
|
|
55713
|
+
return parseDobInput(input) !== null;
|
|
55714
|
+
}
|
|
55715
|
+
function parseDobInput(input) {
|
|
55716
|
+
const m = /^(\d{2})\/(\d{2})\/(\d{4})$/.exec(input);
|
|
55717
|
+
if (!m) return null;
|
|
55718
|
+
const [, month, day, year] = m;
|
|
55719
|
+
if (!/^(0[1-9]|1[0-2])$/.test(month)) return null;
|
|
55720
|
+
if (!/^(0[1-9]|[12]\d|3[01])$/.test(day)) return null;
|
|
55721
|
+
if (!/^(19|20)\d{2}$/.test(year)) return null;
|
|
55722
|
+
return { month, day, year };
|
|
55723
|
+
}
|
|
55724
|
+
var POPUP_W = 500;
|
|
55725
|
+
var POPUP_H = 700;
|
|
55726
|
+
function openCoinbasePaymentPopup(url) {
|
|
55727
|
+
if (typeof window === "undefined") return null;
|
|
55728
|
+
const screenW = window.screen.availWidth ?? window.innerWidth;
|
|
55729
|
+
const screenH = window.screen.availHeight ?? window.innerHeight;
|
|
55730
|
+
const left = Math.max(0, Math.round((screenW - POPUP_W) / 2));
|
|
55731
|
+
const top = Math.max(0, Math.round((screenH - POPUP_H) / 2));
|
|
55732
|
+
return window.open(
|
|
55733
|
+
url,
|
|
55734
|
+
"unifold_coinbase_apple_pay",
|
|
55735
|
+
`popup,width=${POPUP_W},height=${POPUP_H},left=${left},top=${top}`
|
|
55736
|
+
);
|
|
55737
|
+
}
|
|
55738
|
+
var FALLBACK_AGREEMENTS = [
|
|
55739
|
+
{
|
|
55740
|
+
key: "guest_checkout_terms",
|
|
55741
|
+
name: "Guest Checkout Terms of Service",
|
|
55742
|
+
url: "https://www.coinbase.com/legal/cb-pay/onramp-guest-checkout-terms"
|
|
55743
|
+
},
|
|
55744
|
+
{
|
|
55745
|
+
key: "user_agreement",
|
|
55746
|
+
name: "User Agreement",
|
|
55747
|
+
url: "https://www.coinbase.com/legal/user_agreement"
|
|
55748
|
+
},
|
|
55749
|
+
{
|
|
55750
|
+
key: "privacy_policy",
|
|
55751
|
+
name: "Privacy Policy",
|
|
55752
|
+
url: "https://www.coinbase.com/legal/privacy"
|
|
55753
|
+
}
|
|
55754
|
+
];
|
|
55755
|
+
function LegalDisclaimer({ legalAgreements, loading }) {
|
|
55756
|
+
const { colors: colors2, fonts } = useTheme();
|
|
55149
55757
|
if (loading) {
|
|
55150
55758
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
55151
55759
|
"div",
|
|
@@ -55189,78 +55797,6 @@ function LegalDisclaimer({ legalAgreements, loading, colors: colors2, fonts }) {
|
|
|
55189
55797
|
}
|
|
55190
55798
|
);
|
|
55191
55799
|
}
|
|
55192
|
-
function isGuestLimitError(err) {
|
|
55193
|
-
const message = err instanceof Error ? err.message : String(err ?? "");
|
|
55194
|
-
if (/coinbase_onramp_guest_limit_reached/i.test(message)) return true;
|
|
55195
|
-
if (/guest_(daily_)?transaction_(count|limit)/i.test(message)) return true;
|
|
55196
|
-
return false;
|
|
55197
|
-
}
|
|
55198
|
-
function prettifyVerificationError(message) {
|
|
55199
|
-
if (/\b429\b|too many requests|rate.?limit|throttle/i.test(message)) {
|
|
55200
|
-
return "Too many attempts. Please wait a few minutes and try again.";
|
|
55201
|
-
}
|
|
55202
|
-
if (/network|failed to fetch|abort/i.test(message)) {
|
|
55203
|
-
return "Network error. Check your connection and try again.";
|
|
55204
|
-
}
|
|
55205
|
-
if (/voip|not a valid US|not a cell/i.test(message)) {
|
|
55206
|
-
return "We can only verify real US cell phones (not VoIP). Try a different number.";
|
|
55207
|
-
}
|
|
55208
|
-
return message;
|
|
55209
|
-
}
|
|
55210
|
-
var FALLBACK_AGREEMENTS = [
|
|
55211
|
-
{
|
|
55212
|
-
key: "guest_checkout_terms",
|
|
55213
|
-
name: "Guest Checkout Terms of Service",
|
|
55214
|
-
url: "https://www.coinbase.com/legal/cb-pay/onramp-guest-checkout-terms"
|
|
55215
|
-
},
|
|
55216
|
-
{
|
|
55217
|
-
key: "user_agreement",
|
|
55218
|
-
name: "User Agreement",
|
|
55219
|
-
url: "https://www.coinbase.com/legal/user_agreement"
|
|
55220
|
-
},
|
|
55221
|
-
{
|
|
55222
|
-
key: "privacy_policy",
|
|
55223
|
-
name: "Privacy Policy",
|
|
55224
|
-
url: "https://www.coinbase.com/legal/privacy"
|
|
55225
|
-
}
|
|
55226
|
-
];
|
|
55227
|
-
var POPUP_W = 500;
|
|
55228
|
-
var POPUP_H = 700;
|
|
55229
|
-
function openCoinbasePaymentPopup(url) {
|
|
55230
|
-
if (typeof window === "undefined") return null;
|
|
55231
|
-
const screenW = window.screen.availWidth ?? window.innerWidth;
|
|
55232
|
-
const screenH = window.screen.availHeight ?? window.innerHeight;
|
|
55233
|
-
const left = Math.max(0, Math.round((screenW - POPUP_W) / 2));
|
|
55234
|
-
const top = Math.max(0, Math.round((screenH - POPUP_H) / 2));
|
|
55235
|
-
return window.open(
|
|
55236
|
-
url,
|
|
55237
|
-
"unifold_coinbase_apple_pay",
|
|
55238
|
-
`popup,width=${POPUP_W},height=${POPUP_H},left=${left},top=${top}`
|
|
55239
|
-
);
|
|
55240
|
-
}
|
|
55241
|
-
function destinationChainNameFor(chainType, chainId) {
|
|
55242
|
-
if (chainType === "solana") return "solana";
|
|
55243
|
-
if (chainType === "bitcoin") return "bitcoin";
|
|
55244
|
-
if (chainType === "ethereum") {
|
|
55245
|
-
switch (chainId) {
|
|
55246
|
-
case "1":
|
|
55247
|
-
return "ethereum";
|
|
55248
|
-
case "8453":
|
|
55249
|
-
return "base";
|
|
55250
|
-
case "137":
|
|
55251
|
-
return "polygon";
|
|
55252
|
-
case "43114":
|
|
55253
|
-
return "avalanche";
|
|
55254
|
-
case "42161":
|
|
55255
|
-
return "arbitrum";
|
|
55256
|
-
case "10":
|
|
55257
|
-
return "optimism";
|
|
55258
|
-
default:
|
|
55259
|
-
return null;
|
|
55260
|
-
}
|
|
55261
|
-
}
|
|
55262
|
-
return null;
|
|
55263
|
-
}
|
|
55264
55800
|
var t2 = i18n2.payWithExchange;
|
|
55265
55801
|
function PayWithExchange({
|
|
55266
55802
|
userId,
|
|
@@ -55275,10 +55811,10 @@ function PayWithExchange({
|
|
|
55275
55811
|
defaultToken
|
|
55276
55812
|
}) {
|
|
55277
55813
|
const { colors: colors2, fonts, components } = useTheme();
|
|
55278
|
-
const [internalView, setInternalView] = (0,
|
|
55279
|
-
const [exchangeSession, setExchangeSession] = (0,
|
|
55280
|
-
const [sessionError, setSessionError] = (0,
|
|
55281
|
-
const [hoveredIndex, setHoveredIndex] = (0,
|
|
55814
|
+
const [internalView, setInternalView] = (0, import_react17.useState)("providers");
|
|
55815
|
+
const [exchangeSession, setExchangeSession] = (0, import_react17.useState)(null);
|
|
55816
|
+
const [sessionError, setSessionError] = (0, import_react17.useState)(null);
|
|
55817
|
+
const [hoveredIndex, setHoveredIndex] = (0, import_react17.useState)(null);
|
|
55282
55818
|
const currentView = externalView ?? internalView;
|
|
55283
55819
|
const depositWalletId = wallets.find((w) => ["ethereum", "solana"].includes(w.chain_type))?.id;
|
|
55284
55820
|
const handleViewChange = (newView) => {
|
|
@@ -55558,7 +56094,7 @@ function QRCodeSkeleton({ size: size4 = 180, darkMode = false }) {
|
|
|
55558
56094
|
const spacing = size4 / gridCount;
|
|
55559
56095
|
const fillColor = darkMode ? "rgba(255,255,255,0.10)" : "rgba(0,0,0,0.08)";
|
|
55560
56096
|
const cornerColor = darkMode ? "rgba(255,255,255,0.14)" : "rgba(0,0,0,0.12)";
|
|
55561
|
-
const dots = (0,
|
|
56097
|
+
const dots = (0, import_react19.useMemo)(() => {
|
|
55562
56098
|
const result = [];
|
|
55563
56099
|
const cornerSize = 7;
|
|
55564
56100
|
const centerStart = Math.floor(gridCount / 2) - 2;
|
|
@@ -55613,10 +56149,10 @@ function StyledQRCode({
|
|
|
55613
56149
|
imageSize = 45,
|
|
55614
56150
|
darkMode = false
|
|
55615
56151
|
}) {
|
|
55616
|
-
const containerRef = (0,
|
|
55617
|
-
const qrRef = (0,
|
|
55618
|
-
const [ready, setReady] = (0,
|
|
55619
|
-
(0,
|
|
56152
|
+
const containerRef = (0, import_react19.useRef)(null);
|
|
56153
|
+
const qrRef = (0, import_react19.useRef)(null);
|
|
56154
|
+
const [ready, setReady] = (0, import_react19.useState)(false);
|
|
56155
|
+
(0, import_react19.useEffect)(() => {
|
|
55620
56156
|
if (!containerRef.current || !value) return;
|
|
55621
56157
|
const config = createQRConfig(value, size4, imageUrl, imageSize, darkMode);
|
|
55622
56158
|
if (!qrRef.current) {
|
|
@@ -55647,8 +56183,8 @@ function StyledQRCode({
|
|
|
55647
56183
|
] });
|
|
55648
56184
|
}
|
|
55649
56185
|
function useIsMobileViewport() {
|
|
55650
|
-
const [isMobile, setIsMobile] = (0,
|
|
55651
|
-
(0,
|
|
56186
|
+
const [isMobile, setIsMobile] = (0, import_react20.useState)(() => isMobileViewport());
|
|
56187
|
+
(0, import_react20.useEffect)(() => {
|
|
55652
56188
|
setIsMobile(isMobileViewport());
|
|
55653
56189
|
const mql = window.matchMedia(MOBILE_VIEWPORT_MEDIA_QUERY);
|
|
55654
56190
|
const update = () => setIsMobile(mql.matches);
|
|
@@ -55700,21 +56236,21 @@ function PayWithCashApp({
|
|
|
55700
56236
|
const { data: limits, isLoading: limitsLoading } = useCashAppLimits({ publishableKey });
|
|
55701
56237
|
const minUsd = limits?.minimum_amount ?? FALLBACK_MIN_USD;
|
|
55702
56238
|
const maxUsd = limits?.maximum_amount ?? null;
|
|
55703
|
-
const [amount, setAmount] = (0,
|
|
55704
|
-
const [loading, setLoading] = (0,
|
|
55705
|
-
const [session, setSession] = (0,
|
|
55706
|
-
const [status, setStatus] = (0,
|
|
55707
|
-
const [error, setError] = (0,
|
|
55708
|
-
const [copied, setCopied] = (0,
|
|
55709
|
-
const [view, setViewInternal] = (0,
|
|
55710
|
-
const setView = (0,
|
|
56239
|
+
const [amount, setAmount] = (0, import_react18.useState)("");
|
|
56240
|
+
const [loading, setLoading] = (0, import_react18.useState)(false);
|
|
56241
|
+
const [session, setSession] = (0, import_react18.useState)(null);
|
|
56242
|
+
const [status, setStatus] = (0, import_react18.useState)("pending");
|
|
56243
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
56244
|
+
const [copied, setCopied] = (0, import_react18.useState)(false);
|
|
56245
|
+
const [view, setViewInternal] = (0, import_react18.useState)(controlledView ?? "amount");
|
|
56246
|
+
const setView = (0, import_react18.useCallback)(
|
|
55711
56247
|
(v) => {
|
|
55712
56248
|
setViewInternal(v);
|
|
55713
56249
|
onViewChange?.(v);
|
|
55714
56250
|
},
|
|
55715
56251
|
[onViewChange]
|
|
55716
56252
|
);
|
|
55717
|
-
(0,
|
|
56253
|
+
(0, import_react18.useEffect)(() => {
|
|
55718
56254
|
if (controlledView && controlledView !== view) {
|
|
55719
56255
|
setViewInternal(controlledView);
|
|
55720
56256
|
if (controlledView === "amount") {
|
|
@@ -55726,7 +56262,7 @@ function PayWithCashApp({
|
|
|
55726
56262
|
}
|
|
55727
56263
|
}
|
|
55728
56264
|
}, [controlledView]);
|
|
55729
|
-
const [timeLeft, setTimeLeft] = (0,
|
|
56265
|
+
const [timeLeft, setTimeLeft] = (0, import_react18.useState)(null);
|
|
55730
56266
|
const depositWalletId = wallets.find((w) => w.chain_type === "ethereum")?.id;
|
|
55731
56267
|
const { executions, isPolling } = useDepositPolling({
|
|
55732
56268
|
userId,
|
|
@@ -55737,7 +56273,7 @@ function PayWithCashApp({
|
|
|
55737
56273
|
onDepositSuccess,
|
|
55738
56274
|
onDepositError
|
|
55739
56275
|
});
|
|
55740
|
-
const handleAmountChange = (0,
|
|
56276
|
+
const handleAmountChange = (0, import_react18.useCallback)(
|
|
55741
56277
|
(raw) => {
|
|
55742
56278
|
const cleaned = raw.replace(/[^0-9.]/g, "");
|
|
55743
56279
|
const parts = cleaned.split(".");
|
|
@@ -55749,7 +56285,7 @@ function PayWithCashApp({
|
|
|
55749
56285
|
},
|
|
55750
56286
|
[onAmountChange]
|
|
55751
56287
|
);
|
|
55752
|
-
const handleCreateSession = (0,
|
|
56288
|
+
const handleCreateSession = (0, import_react18.useCallback)(async () => {
|
|
55753
56289
|
if (!amount || !recipientAddress || !destinationChainType || !destinationChainId || !destinationTokenAddress) {
|
|
55754
56290
|
setError("Missing required fields");
|
|
55755
56291
|
return;
|
|
@@ -55798,7 +56334,7 @@ function PayWithCashApp({
|
|
|
55798
56334
|
onEvent,
|
|
55799
56335
|
onDepositError
|
|
55800
56336
|
]);
|
|
55801
|
-
(0,
|
|
56337
|
+
(0, import_react18.useEffect)(() => {
|
|
55802
56338
|
if (!session || view !== "payment" && view !== "confirming") return;
|
|
55803
56339
|
if (status === "completed" || status === "failed") return;
|
|
55804
56340
|
const poll = async () => {
|
|
@@ -55822,8 +56358,8 @@ function PayWithCashApp({
|
|
|
55822
56358
|
poll();
|
|
55823
56359
|
return () => clearInterval(interval);
|
|
55824
56360
|
}, [session, view, status, publishableKey, onDepositSuccess, onDepositError]);
|
|
55825
|
-
const [softExpired, setSoftExpired] = (0,
|
|
55826
|
-
(0,
|
|
56361
|
+
const [softExpired, setSoftExpired] = (0, import_react18.useState)(false);
|
|
56362
|
+
(0, import_react18.useEffect)(() => {
|
|
55827
56363
|
if (!session?.expires_at || view !== "payment") return;
|
|
55828
56364
|
const expiresMs = new Date(session.expires_at).getTime();
|
|
55829
56365
|
const tick = () => {
|
|
@@ -55837,12 +56373,12 @@ function PayWithCashApp({
|
|
|
55837
56373
|
const interval = setInterval(tick, 1e3);
|
|
55838
56374
|
return () => clearInterval(interval);
|
|
55839
56375
|
}, [session, view, status]);
|
|
55840
|
-
const handleCopy = (0,
|
|
56376
|
+
const handleCopy = (0, import_react18.useCallback)(async (text) => {
|
|
55841
56377
|
await navigator.clipboard.writeText(text);
|
|
55842
56378
|
setCopied(true);
|
|
55843
56379
|
setTimeout(() => setCopied(false), 2e3);
|
|
55844
56380
|
}, []);
|
|
55845
|
-
const handleRecreate = (0,
|
|
56381
|
+
const handleRecreate = (0, import_react18.useCallback)(() => {
|
|
55846
56382
|
setSession(null);
|
|
55847
56383
|
setStatus("pending");
|
|
55848
56384
|
setError(null);
|
|
@@ -56171,43 +56707,6 @@ function PayWithCashApp({
|
|
|
56171
56707
|
}
|
|
56172
56708
|
return null;
|
|
56173
56709
|
}
|
|
56174
|
-
function useDefaultOnrampToken({
|
|
56175
|
-
publishableKey,
|
|
56176
|
-
tokenAddress,
|
|
56177
|
-
chainId,
|
|
56178
|
-
chainType,
|
|
56179
|
-
countryCode,
|
|
56180
|
-
subdivisionCode,
|
|
56181
|
-
enabled = true
|
|
56182
|
-
}) {
|
|
56183
|
-
const { data: defaultToken, isLoading } = useQuery({
|
|
56184
|
-
queryKey: [
|
|
56185
|
-
"unifold",
|
|
56186
|
-
"defaultOnrampToken",
|
|
56187
|
-
publishableKey,
|
|
56188
|
-
tokenAddress,
|
|
56189
|
-
chainId,
|
|
56190
|
-
chainType,
|
|
56191
|
-
countryCode,
|
|
56192
|
-
subdivisionCode
|
|
56193
|
-
],
|
|
56194
|
-
queryFn: () => getDefaultOnrampToken(
|
|
56195
|
-
{
|
|
56196
|
-
token_address: tokenAddress,
|
|
56197
|
-
chain_id: chainId,
|
|
56198
|
-
chain_type: chainType,
|
|
56199
|
-
country_code: countryCode,
|
|
56200
|
-
subdivision_code: subdivisionCode
|
|
56201
|
-
},
|
|
56202
|
-
publishableKey
|
|
56203
|
-
),
|
|
56204
|
-
enabled: enabled && !!tokenAddress && !!chainId && !!chainType,
|
|
56205
|
-
staleTime: 1e3 * 60 * 60,
|
|
56206
|
-
refetchOnMount: false,
|
|
56207
|
-
refetchOnWindowFocus: false
|
|
56208
|
-
});
|
|
56209
|
-
return { defaultToken, isLoading };
|
|
56210
|
-
}
|
|
56211
56710
|
function useBankTransferProviders({
|
|
56212
56711
|
publishableKey,
|
|
56213
56712
|
enabled = true,
|
|
@@ -56255,19 +56754,19 @@ function BankTransfer({
|
|
|
56255
56754
|
onDepositError
|
|
56256
56755
|
}) {
|
|
56257
56756
|
const { colors: colors2, fonts, components } = useTheme();
|
|
56258
|
-
const [internalView, setInternalView] = (0,
|
|
56259
|
-
const [sessionError, setSessionError] = (0,
|
|
56260
|
-
const [hoveredId, setHoveredId] = (0,
|
|
56261
|
-
const [activeProvider, setActiveProvider] = (0,
|
|
56262
|
-
const [requestBase, setRequestBase] = (0,
|
|
56263
|
-
const [activeRequest, setActiveRequest] = (0,
|
|
56264
|
-
const [amount, setAmount] = (0,
|
|
56757
|
+
const [internalView, setInternalView] = (0, import_react21.useState)("providers");
|
|
56758
|
+
const [sessionError, setSessionError] = (0, import_react21.useState)(null);
|
|
56759
|
+
const [hoveredId, setHoveredId] = (0, import_react21.useState)(null);
|
|
56760
|
+
const [activeProvider, setActiveProvider] = (0, import_react21.useState)(null);
|
|
56761
|
+
const [requestBase, setRequestBase] = (0, import_react21.useState)(null);
|
|
56762
|
+
const [activeRequest, setActiveRequest] = (0, import_react21.useState)(null);
|
|
56763
|
+
const [amount, setAmount] = (0, import_react21.useState)("");
|
|
56265
56764
|
const currentView = externalView ?? internalView;
|
|
56266
56765
|
const setView = (v) => {
|
|
56267
56766
|
setInternalView(v);
|
|
56268
56767
|
onViewChange?.(v);
|
|
56269
56768
|
};
|
|
56270
|
-
(0,
|
|
56769
|
+
(0, import_react21.useEffect)(() => {
|
|
56271
56770
|
if (externalView) setInternalView(externalView);
|
|
56272
56771
|
}, [externalView]);
|
|
56273
56772
|
const { userIpInfo } = useUserIp2();
|
|
@@ -56286,7 +56785,7 @@ function BankTransfer({
|
|
|
56286
56785
|
countryCode: userIpInfo?.alpha2
|
|
56287
56786
|
});
|
|
56288
56787
|
const providers = providersResponse?.data ?? [];
|
|
56289
|
-
const pollingWalletId = (0,
|
|
56788
|
+
const pollingWalletId = (0, import_react21.useMemo)(() => {
|
|
56290
56789
|
if (!defaultToken) return void 0;
|
|
56291
56790
|
return getWalletByChainType(
|
|
56292
56791
|
wallets,
|
|
@@ -56307,7 +56806,7 @@ function BankTransfer({
|
|
|
56307
56806
|
const currencySymbol = getCurrencySymbol2(sourceCurrency);
|
|
56308
56807
|
const parsedAmount = parseFloat(amount);
|
|
56309
56808
|
const amountValid = !!amount && Number.isFinite(parsedAmount) && parsedAmount >= MIN_AMOUNT;
|
|
56310
|
-
const displayTokenSymbol = (0,
|
|
56809
|
+
const displayTokenSymbol = (0, import_react21.useMemo)(
|
|
56311
56810
|
() => destinationTokenSymbol?.toUpperCase() ?? defaultToken?.destination_token_metadata?.symbol?.toUpperCase() ?? defaultToken?.destination_currency?.toUpperCase() ?? "USDC",
|
|
56312
56811
|
[destinationTokenSymbol, defaultToken]
|
|
56313
56812
|
);
|
|
@@ -60282,16 +60781,114 @@ function AmexIcon({ size: size4 = 24 }) {
|
|
|
60282
60781
|
)
|
|
60283
60782
|
] });
|
|
60284
60783
|
}
|
|
60784
|
+
function ApplePayIcon({ size: size4 = 24, color = "#000" }) {
|
|
60785
|
+
const h = size4 * 0.62;
|
|
60786
|
+
const w = h * (512 / 210.2);
|
|
60787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("svg", { width: w, height: h, viewBox: "0 0 512 210.2", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
60788
|
+
"path",
|
|
60789
|
+
{
|
|
60790
|
+
fill: color,
|
|
60791
|
+
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"
|
|
60792
|
+
}
|
|
60793
|
+
) });
|
|
60794
|
+
}
|
|
60795
|
+
function GooglePayIcon({ size: size4 = 24, color = "#202124" }) {
|
|
60796
|
+
const h = size4 * 0.62;
|
|
60797
|
+
const w = h * (80 / 38.1);
|
|
60798
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("svg", { width: w, height: h, viewBox: "0 0 80 38.1", fill: "none", children: [
|
|
60799
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
60800
|
+
"path",
|
|
60801
|
+
{
|
|
60802
|
+
fill: color,
|
|
60803
|
+
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"
|
|
60804
|
+
}
|
|
60805
|
+
),
|
|
60806
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
60807
|
+
"path",
|
|
60808
|
+
{
|
|
60809
|
+
fill: color,
|
|
60810
|
+
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"
|
|
60811
|
+
}
|
|
60812
|
+
),
|
|
60813
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
60814
|
+
"path",
|
|
60815
|
+
{
|
|
60816
|
+
fill: color,
|
|
60817
|
+
d: "M80,13.3l-9.9,22.7h-3l3.7-7.9l-6.5-14.7h3.2l4.7,11.3h0.1l4.6-11.3H80z"
|
|
60818
|
+
}
|
|
60819
|
+
),
|
|
60820
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
60821
|
+
"path",
|
|
60822
|
+
{
|
|
60823
|
+
fill: "#4285F4",
|
|
60824
|
+
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"
|
|
60825
|
+
}
|
|
60826
|
+
),
|
|
60827
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
60828
|
+
"path",
|
|
60829
|
+
{
|
|
60830
|
+
fill: "#34A853",
|
|
60831
|
+
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"
|
|
60832
|
+
}
|
|
60833
|
+
),
|
|
60834
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
60835
|
+
"path",
|
|
60836
|
+
{
|
|
60837
|
+
fill: "#FBBC04",
|
|
60838
|
+
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"
|
|
60839
|
+
}
|
|
60840
|
+
),
|
|
60841
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
60842
|
+
"path",
|
|
60843
|
+
{
|
|
60844
|
+
fill: "#EA4335",
|
|
60845
|
+
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"
|
|
60846
|
+
}
|
|
60847
|
+
)
|
|
60848
|
+
] });
|
|
60849
|
+
}
|
|
60285
60850
|
function GenericCardIcon({ size: size4 = 24, color = "#888" }) {
|
|
60286
60851
|
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(CreditCard, { width: size4 * 0.8, height: size4 * 0.8, style: { color }, strokeWidth: 1.5 });
|
|
60287
60852
|
}
|
|
60853
|
+
function parseColor(input) {
|
|
60854
|
+
if (!input) return null;
|
|
60855
|
+
const s = input.trim();
|
|
60856
|
+
if (s.startsWith("#")) {
|
|
60857
|
+
let hex = s.slice(1);
|
|
60858
|
+
if (hex.length === 3)
|
|
60859
|
+
hex = hex.split("").map((c) => c + c).join("");
|
|
60860
|
+
if (hex.length !== 6) return null;
|
|
60861
|
+
const n = parseInt(hex, 16);
|
|
60862
|
+
if (Number.isNaN(n)) return null;
|
|
60863
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
60864
|
+
}
|
|
60865
|
+
const m = s.match(/rgba?\(([^)]+)\)/i);
|
|
60866
|
+
if (m) {
|
|
60867
|
+
const parts = m[1].split(",").map((p) => parseFloat(p));
|
|
60868
|
+
if (parts.length >= 3 && parts.every((p) => !Number.isNaN(p)))
|
|
60869
|
+
return [parts[0], parts[1], parts[2]];
|
|
60870
|
+
}
|
|
60871
|
+
return null;
|
|
60872
|
+
}
|
|
60873
|
+
function monochromeOn(background) {
|
|
60874
|
+
const rgb = parseColor(background);
|
|
60875
|
+
if (!rgb) return "#000000";
|
|
60876
|
+
const [r2, g, b] = rgb;
|
|
60877
|
+
const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
|
|
60878
|
+
return luminance > 0.6 ? "#000000" : "#FFFFFF";
|
|
60879
|
+
}
|
|
60288
60880
|
function CardBrandIcon({
|
|
60289
60881
|
brand,
|
|
60290
60882
|
size: size4 = 24,
|
|
60291
|
-
fallbackColor = "#888"
|
|
60883
|
+
fallbackColor = "#888",
|
|
60884
|
+
monochromeColor = "#000000"
|
|
60292
60885
|
}) {
|
|
60293
60886
|
if (!brand) return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(GenericCardIcon, { size: size4, color: fallbackColor });
|
|
60294
60887
|
const lower = brand.toLowerCase();
|
|
60888
|
+
if (lower.includes("apple_pay") || lower.includes("apple pay") || lower === "applepay")
|
|
60889
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ApplePayIcon, { size: size4, color: monochromeColor });
|
|
60890
|
+
if (lower.includes("google_pay") || lower.includes("google pay") || lower === "googlepay")
|
|
60891
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(GooglePayIcon, { size: size4, color: monochromeColor === "#FFFFFF" ? "#FFFFFF" : "#202124" });
|
|
60295
60892
|
if (lower.includes("visa")) return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(VisaIcon, { size: size4 });
|
|
60296
60893
|
if (lower.includes("mastercard") || lower.includes("master"))
|
|
60297
60894
|
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(MastercardIcon, { size: size4 });
|
|
@@ -60300,17 +60897,28 @@ function CardBrandIcon({
|
|
|
60300
60897
|
}
|
|
60301
60898
|
function formatPaymentToken(token) {
|
|
60302
60899
|
if (token.card) {
|
|
60303
|
-
const
|
|
60900
|
+
const cardBrand = token.card.brand ?? "Card";
|
|
60901
|
+
const last4 = token.card.last4;
|
|
60902
|
+
const walletType = token.card.wallet?.type;
|
|
60903
|
+
if (walletType === "apple_pay" || walletType === "google_pay") {
|
|
60904
|
+
const funding = token.card.funding ? capitalize(token.card.funding) : null;
|
|
60905
|
+
return {
|
|
60906
|
+
label: last4 ? `${capitalize(cardBrand)} \u2022\u2022\u2022\u2022 ${last4}` : capitalize(cardBrand),
|
|
60907
|
+
sublabel: funding ?? "",
|
|
60908
|
+
brand: walletType
|
|
60909
|
+
};
|
|
60910
|
+
}
|
|
60304
60911
|
return {
|
|
60305
|
-
label: `${capitalize(
|
|
60912
|
+
label: `${capitalize(cardBrand)} \u2022\u2022\u2022\u2022 ${last4}`,
|
|
60306
60913
|
sublabel: `${capitalize(token.card.funding ?? "card")} \xB7 Expires ${token.card.exp_month}/${token.card.exp_year}`,
|
|
60307
|
-
brand
|
|
60914
|
+
brand: cardBrand
|
|
60308
60915
|
};
|
|
60309
60916
|
}
|
|
60310
60917
|
if (token.us_bank_account) {
|
|
60918
|
+
const accountType = token.us_bank_account.account_type;
|
|
60311
60919
|
return {
|
|
60312
60920
|
label: `${token.us_bank_account.bank_name ?? "Bank"} \u2022\u2022\u2022\u2022 ${token.us_bank_account.last4}`,
|
|
60313
|
-
sublabel: "Bank account"
|
|
60921
|
+
sublabel: accountType ? `${capitalize(accountType)} account` : "Bank account"
|
|
60314
60922
|
};
|
|
60315
60923
|
}
|
|
60316
60924
|
return { label: "Payment method", sublabel: token.type };
|
|
@@ -60318,59 +60926,82 @@ function formatPaymentToken(token) {
|
|
|
60318
60926
|
function capitalize(s) {
|
|
60319
60927
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
60320
60928
|
}
|
|
60321
|
-
function useStripeOnramp(stripePublishableKey) {
|
|
60322
|
-
const [coordinator, setCoordinator] = (0,
|
|
60323
|
-
const [isLoading, setIsLoading] = (0,
|
|
60324
|
-
const [error, setError] = (0,
|
|
60325
|
-
const coordinatorRef = (0,
|
|
60326
|
-
const
|
|
60327
|
-
|
|
60328
|
-
|
|
60329
|
-
|
|
60330
|
-
|
|
60331
|
-
|
|
60332
|
-
|
|
60333
|
-
|
|
60334
|
-
|
|
60335
|
-
|
|
60336
|
-
);
|
|
60337
|
-
|
|
60338
|
-
|
|
60339
|
-
|
|
60340
|
-
|
|
60341
|
-
|
|
60342
|
-
|
|
60343
|
-
|
|
60344
|
-
|
|
60345
|
-
|
|
60346
|
-
|
|
60347
|
-
|
|
60348
|
-
|
|
60349
|
-
|
|
60350
|
-
)
|
|
60351
|
-
|
|
60352
|
-
|
|
60353
|
-
|
|
60354
|
-
|
|
60355
|
-
|
|
60356
|
-
|
|
60357
|
-
|
|
60358
|
-
|
|
60359
|
-
|
|
60360
|
-
|
|
60361
|
-
|
|
60362
|
-
|
|
60363
|
-
|
|
60364
|
-
|
|
60365
|
-
|
|
60366
|
-
|
|
60367
|
-
|
|
60368
|
-
|
|
60929
|
+
function useStripeOnramp(stripePublishableKey, isDark = false) {
|
|
60930
|
+
const [coordinator, setCoordinator] = (0, import_react23.useState)(null);
|
|
60931
|
+
const [isLoading, setIsLoading] = (0, import_react23.useState)(false);
|
|
60932
|
+
const [error, setError] = (0, import_react23.useState)(null);
|
|
60933
|
+
const coordinatorRef = (0, import_react23.useRef)(null);
|
|
60934
|
+
const coordinatorThemeRef = (0, import_react23.useRef)(null);
|
|
60935
|
+
const initPromiseRef = (0, import_react23.useRef)(null);
|
|
60936
|
+
const isDarkRef = (0, import_react23.useRef)(isDark);
|
|
60937
|
+
isDarkRef.current = isDark;
|
|
60938
|
+
const initialize = (0, import_react23.useCallback)(() => {
|
|
60939
|
+
if (coordinatorRef.current) return Promise.resolve(coordinatorRef.current);
|
|
60940
|
+
if (initPromiseRef.current) return initPromiseRef.current;
|
|
60941
|
+
if (!stripePublishableKey) return Promise.resolve(null);
|
|
60942
|
+
const theme = isDarkRef.current;
|
|
60943
|
+
const promise = (async () => {
|
|
60944
|
+
setIsLoading(true);
|
|
60945
|
+
setError(null);
|
|
60946
|
+
try {
|
|
60947
|
+
console.log("[PayWithStripeLink] Importing @stripe/crypto...");
|
|
60948
|
+
const { loadCryptoOnrampAndInitialize } = await import(
|
|
60949
|
+
/* @vite-ignore */
|
|
60950
|
+
"@stripe/crypto"
|
|
60951
|
+
);
|
|
60952
|
+
console.log(
|
|
60953
|
+
"[PayWithStripeLink] @stripe/crypto imported, initializing with key:",
|
|
60954
|
+
stripePublishableKey?.slice(0, 12) + "..."
|
|
60955
|
+
);
|
|
60956
|
+
const initPromise = loadCryptoOnrampAndInitialize(stripePublishableKey, {
|
|
60957
|
+
theme: theme ? "night" : "stripe"
|
|
60958
|
+
});
|
|
60959
|
+
const timeoutPromise = new Promise(
|
|
60960
|
+
(_, reject) => setTimeout(
|
|
60961
|
+
() => reject(
|
|
60962
|
+
new Error(
|
|
60963
|
+
"Stripe SDK initialization timed out after 15 seconds. Check that your Stripe account has the Crypto Onramp feature enabled."
|
|
60964
|
+
)
|
|
60965
|
+
),
|
|
60966
|
+
15e3
|
|
60967
|
+
)
|
|
60968
|
+
);
|
|
60969
|
+
const instance = await Promise.race([initPromise, timeoutPromise]);
|
|
60970
|
+
if (!instance) {
|
|
60971
|
+
throw new Error("Stripe SDK returned null.");
|
|
60972
|
+
}
|
|
60973
|
+
console.log("[PayWithStripeLink] Stripe SDK initialized successfully");
|
|
60974
|
+
coordinatorRef.current = instance;
|
|
60975
|
+
coordinatorThemeRef.current = theme;
|
|
60976
|
+
setCoordinator(instance);
|
|
60977
|
+
return coordinatorRef.current;
|
|
60978
|
+
} catch (err) {
|
|
60979
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
60980
|
+
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}`;
|
|
60981
|
+
setError(msg);
|
|
60982
|
+
console.error("[PayWithStripeLink]", msg);
|
|
60983
|
+
return null;
|
|
60984
|
+
} finally {
|
|
60985
|
+
setIsLoading(false);
|
|
60986
|
+
initPromiseRef.current = null;
|
|
60987
|
+
}
|
|
60988
|
+
})();
|
|
60989
|
+
initPromiseRef.current = promise;
|
|
60990
|
+
return promise;
|
|
60369
60991
|
}, [stripePublishableKey]);
|
|
60370
|
-
(0,
|
|
60992
|
+
(0, import_react23.useEffect)(() => {
|
|
60993
|
+
if (!coordinatorRef.current) return;
|
|
60994
|
+
if (coordinatorThemeRef.current === isDark) return;
|
|
60995
|
+
coordinatorRef.current.destroy();
|
|
60996
|
+
coordinatorRef.current = null;
|
|
60997
|
+
coordinatorThemeRef.current = null;
|
|
60998
|
+
setCoordinator(null);
|
|
60999
|
+
}, [isDark, coordinator]);
|
|
61000
|
+
(0, import_react23.useEffect)(() => {
|
|
60371
61001
|
return () => {
|
|
60372
61002
|
coordinatorRef.current?.destroy();
|
|
60373
61003
|
coordinatorRef.current = null;
|
|
61004
|
+
coordinatorThemeRef.current = null;
|
|
60374
61005
|
};
|
|
60375
61006
|
}, []);
|
|
60376
61007
|
return { coordinator, isLoading, error, initialize };
|
|
@@ -60521,21 +61152,23 @@ function PayWithStripeLink({
|
|
|
60521
61152
|
onDepositSuccess,
|
|
60522
61153
|
onDepositError
|
|
60523
61154
|
}) {
|
|
60524
|
-
const { colors: colors2, fonts, components } = useTheme();
|
|
60525
|
-
const [step, setStepInternal] = (0,
|
|
60526
|
-
const setStep = (0,
|
|
61155
|
+
const { colors: colors2, fonts, components, isDark } = useTheme();
|
|
61156
|
+
const [step, setStepInternal] = (0, import_react22.useState)(controlledStep ?? "amount");
|
|
61157
|
+
const setStep = (0, import_react22.useCallback)(
|
|
60527
61158
|
(s) => {
|
|
60528
61159
|
setStepInternal(s);
|
|
60529
61160
|
onStepChange?.(s);
|
|
60530
61161
|
},
|
|
60531
61162
|
[onStepChange]
|
|
60532
61163
|
);
|
|
60533
|
-
(0,
|
|
61164
|
+
const stepRef = (0, import_react22.useRef)(step);
|
|
61165
|
+
stepRef.current = step;
|
|
61166
|
+
(0, import_react22.useEffect)(() => {
|
|
60534
61167
|
if (controlledStep && controlledStep !== step) {
|
|
60535
61168
|
setStepInternal(controlledStep);
|
|
60536
61169
|
}
|
|
60537
61170
|
}, [controlledStep]);
|
|
60538
|
-
(0,
|
|
61171
|
+
(0, import_react22.useEffect)(() => {
|
|
60539
61172
|
setLoading(false);
|
|
60540
61173
|
setError(null);
|
|
60541
61174
|
setKycPendingMessage(null);
|
|
@@ -60544,9 +61177,9 @@ function PayWithStripeLink({
|
|
|
60544
61177
|
checkoutGenRef.current++;
|
|
60545
61178
|
}
|
|
60546
61179
|
}, [step]);
|
|
60547
|
-
const [resolvedStripeKey, setResolvedStripeKey] = (0,
|
|
60548
|
-
const [configError, setConfigError] = (0,
|
|
60549
|
-
(0,
|
|
61180
|
+
const [resolvedStripeKey, setResolvedStripeKey] = (0, import_react22.useState)();
|
|
61181
|
+
const [configError, setConfigError] = (0, import_react22.useState)(null);
|
|
61182
|
+
(0, import_react22.useEffect)(() => {
|
|
60550
61183
|
let active = true;
|
|
60551
61184
|
const fetchConfig = async () => {
|
|
60552
61185
|
try {
|
|
@@ -60569,7 +61202,7 @@ function PayWithStripeLink({
|
|
|
60569
61202
|
active = false;
|
|
60570
61203
|
};
|
|
60571
61204
|
}, [publishableKey]);
|
|
60572
|
-
(0,
|
|
61205
|
+
(0, import_react22.useEffect)(() => {
|
|
60573
61206
|
if (step !== "auth" || resolvedStripeKey || configError) return;
|
|
60574
61207
|
let active = true;
|
|
60575
61208
|
const retryConfig = async () => {
|
|
@@ -60597,8 +61230,8 @@ function PayWithStripeLink({
|
|
|
60597
61230
|
isLoading: sdkLoading,
|
|
60598
61231
|
error: sdkError,
|
|
60599
61232
|
initialize
|
|
60600
|
-
} = useStripeOnramp(resolvedStripeKey);
|
|
60601
|
-
(0,
|
|
61233
|
+
} = useStripeOnramp(resolvedStripeKey, isDark);
|
|
61234
|
+
(0, import_react22.useEffect)(() => {
|
|
60602
61235
|
if (step === "auth") {
|
|
60603
61236
|
console.log("[PayWithStripeLink] Auth step state:", {
|
|
60604
61237
|
resolvedStripeKey: resolvedStripeKey ? resolvedStripeKey.slice(0, 15) + "..." : void 0,
|
|
@@ -60609,27 +61242,30 @@ function PayWithStripeLink({
|
|
|
60609
61242
|
});
|
|
60610
61243
|
}
|
|
60611
61244
|
}, [step, resolvedStripeKey, coordinator, sdkLoading, sdkError, configError]);
|
|
60612
|
-
const [email, setEmail] = (0,
|
|
60613
|
-
const [phone, setPhone] = (0,
|
|
60614
|
-
const [country, setCountry] = (0,
|
|
60615
|
-
const [loading, setLoading] = (0,
|
|
60616
|
-
const [error, setError] = (0,
|
|
60617
|
-
const [kycPendingMessage, setKycPendingMessage] = (0,
|
|
60618
|
-
const [kycRejectionReason, setKycRejectionReason] = (0,
|
|
60619
|
-
const [restoring, setRestoring] = (0,
|
|
60620
|
-
const [errorReturnStep, setErrorReturnStep] = (0,
|
|
60621
|
-
const [authIntentId, setAuthIntentId] = (0,
|
|
60622
|
-
const sdkAuthenticatedRef = (0,
|
|
60623
|
-
const
|
|
60624
|
-
const
|
|
60625
|
-
const
|
|
60626
|
-
const
|
|
60627
|
-
const
|
|
60628
|
-
const
|
|
60629
|
-
const [
|
|
60630
|
-
const
|
|
60631
|
-
const
|
|
60632
|
-
const
|
|
61245
|
+
const [email, setEmail] = (0, import_react22.useState)(emailProp ?? "");
|
|
61246
|
+
const [phone, setPhone] = (0, import_react22.useState)("");
|
|
61247
|
+
const [country, setCountry] = (0, import_react22.useState)("US");
|
|
61248
|
+
const [loading, setLoading] = (0, import_react22.useState)(false);
|
|
61249
|
+
const [error, setError] = (0, import_react22.useState)(null);
|
|
61250
|
+
const [kycPendingMessage, setKycPendingMessage] = (0, import_react22.useState)(null);
|
|
61251
|
+
const [kycRejectionReason, setKycRejectionReason] = (0, import_react22.useState)(null);
|
|
61252
|
+
const [restoring, setRestoring] = (0, import_react22.useState)(true);
|
|
61253
|
+
const [errorReturnStep, setErrorReturnStep] = (0, import_react22.useState)("email");
|
|
61254
|
+
const [authIntentId, setAuthIntentId] = (0, import_react22.useState)(null);
|
|
61255
|
+
const sdkAuthenticatedRef = (0, import_react22.useRef)(false);
|
|
61256
|
+
const everAuthenticatedRef = (0, import_react22.useRef)(false);
|
|
61257
|
+
const reauthReturnStepRef = (0, import_react22.useRef)(null);
|
|
61258
|
+
const attemptedWalletReauthRef = (0, import_react22.useRef)(false);
|
|
61259
|
+
const pendingAddPaymentRef = (0, import_react22.useRef)(false);
|
|
61260
|
+
const autoOpenedAddPaymentRef = (0, import_react22.useRef)(false);
|
|
61261
|
+
const checkoutGenRef = (0, import_react22.useRef)(0);
|
|
61262
|
+
const [stripePaymentUIReady, setStripePaymentUIReady] = (0, import_react22.useState)(false);
|
|
61263
|
+
const [oauthToken, setOauthToken] = (0, import_react22.useState)(null);
|
|
61264
|
+
const [refreshTokenValue, setRefreshTokenValue] = (0, import_react22.useState)(null);
|
|
61265
|
+
const [customerId, setCustomerId] = (0, import_react22.useState)(null);
|
|
61266
|
+
const accessTokenRef = (0, import_react22.useRef)("");
|
|
61267
|
+
const refreshTokenRef = (0, import_react22.useRef)("");
|
|
61268
|
+
const persistSession = (0, import_react22.useCallback)(
|
|
60633
61269
|
(cid, token, refresh, expiresIn, loginEmail) => {
|
|
60634
61270
|
accessTokenRef.current = token;
|
|
60635
61271
|
refreshTokenRef.current = refresh;
|
|
@@ -60643,8 +61279,8 @@ function PayWithStripeLink({
|
|
|
60643
61279
|
},
|
|
60644
61280
|
[userId, email]
|
|
60645
61281
|
);
|
|
60646
|
-
const refreshInFlightRef = (0,
|
|
60647
|
-
const tryRefreshToken = (0,
|
|
61282
|
+
const refreshInFlightRef = (0, import_react22.useRef)(null);
|
|
61283
|
+
const tryRefreshToken = (0, import_react22.useCallback)(async () => {
|
|
60648
61284
|
if (refreshInFlightRef.current) return refreshInFlightRef.current;
|
|
60649
61285
|
const rt = refreshTokenRef.current;
|
|
60650
61286
|
if (!rt) return null;
|
|
@@ -60674,7 +61310,7 @@ function PayWithStripeLink({
|
|
|
60674
61310
|
refreshInFlightRef.current = doRefresh();
|
|
60675
61311
|
return refreshInFlightRef.current;
|
|
60676
61312
|
}, [publishableKey, customerId, persistSession, userId]);
|
|
60677
|
-
const withTokenRefresh = (0,
|
|
61313
|
+
const withTokenRefresh = (0, import_react22.useCallback)(
|
|
60678
61314
|
async (fn) => {
|
|
60679
61315
|
const token = accessTokenRef.current;
|
|
60680
61316
|
if (!token) {
|
|
@@ -60702,7 +61338,7 @@ function PayWithStripeLink({
|
|
|
60702
61338
|
},
|
|
60703
61339
|
[tryRefreshToken, setStep]
|
|
60704
61340
|
);
|
|
60705
|
-
(0,
|
|
61341
|
+
(0, import_react22.useEffect)(() => {
|
|
60706
61342
|
const stored = getStoredStripeSession(userId);
|
|
60707
61343
|
console.log("[PayWithStripeLink] Restore check:", {
|
|
60708
61344
|
hasStored: !!stored,
|
|
@@ -60793,9 +61429,9 @@ function PayWithStripeLink({
|
|
|
60793
61429
|
cancelled = true;
|
|
60794
61430
|
};
|
|
60795
61431
|
}, [userId, publishableKey]);
|
|
60796
|
-
const [customer, setCustomer] = (0,
|
|
60797
|
-
const [kycFormMode, setKycFormMode] = (0,
|
|
60798
|
-
const [kycForm, setKycForm] = (0,
|
|
61432
|
+
const [customer, setCustomer] = (0, import_react22.useState)(null);
|
|
61433
|
+
const [kycFormMode, setKycFormMode] = (0, import_react22.useState)("name");
|
|
61434
|
+
const [kycForm, setKycForm] = (0, import_react22.useState)({
|
|
60799
61435
|
givenName: "",
|
|
60800
61436
|
surname: "",
|
|
60801
61437
|
dob: { day: "", month: "", year: "" },
|
|
@@ -60807,7 +61443,7 @@ function PayWithStripeLink({
|
|
|
60807
61443
|
addressPostalCode: "",
|
|
60808
61444
|
addressCountry: "US"
|
|
60809
61445
|
});
|
|
60810
|
-
(0,
|
|
61446
|
+
(0, import_react22.useEffect)(() => {
|
|
60811
61447
|
if (!backHandlerRef) return;
|
|
60812
61448
|
backHandlerRef.current = () => {
|
|
60813
61449
|
if (step === "kyc_form" && kycFormMode === "address") {
|
|
@@ -60818,6 +61454,7 @@ function PayWithStripeLink({
|
|
|
60818
61454
|
if (step === "auth" && (pendingAddPaymentRef.current || !!accessTokenRef.current)) {
|
|
60819
61455
|
pendingAddPaymentRef.current = false;
|
|
60820
61456
|
autoOpenedAddPaymentRef.current = false;
|
|
61457
|
+
reauthReturnStepRef.current = null;
|
|
60821
61458
|
setError(null);
|
|
60822
61459
|
setStep("amount");
|
|
60823
61460
|
return true;
|
|
@@ -60828,24 +61465,41 @@ function PayWithStripeLink({
|
|
|
60828
61465
|
backHandlerRef.current = null;
|
|
60829
61466
|
};
|
|
60830
61467
|
}, [backHandlerRef, step, kycFormMode]);
|
|
60831
|
-
const [wallets, setWallets] = (0,
|
|
60832
|
-
const [paymentTokens, setPaymentTokens] = (0,
|
|
60833
|
-
const [storedSelectedToken, setStoredSelectedTokenState] = (0,
|
|
61468
|
+
const [wallets, setWallets] = (0, import_react22.useState)([]);
|
|
61469
|
+
const [paymentTokens, setPaymentTokens] = (0, import_react22.useState)([]);
|
|
61470
|
+
const [storedSelectedToken, setStoredSelectedTokenState] = (0, import_react22.useState)(
|
|
60834
61471
|
null
|
|
60835
61472
|
);
|
|
60836
|
-
const [selectedPaymentToken, setSelectedPaymentToken] = (0,
|
|
60837
|
-
const [paymentDisplay, setPaymentDisplay] = (0,
|
|
60838
|
-
const
|
|
61473
|
+
const [selectedPaymentToken, setSelectedPaymentToken] = (0, import_react22.useState)(null);
|
|
61474
|
+
const [paymentDisplay, setPaymentDisplay] = (0, import_react22.useState)(null);
|
|
61475
|
+
const selectedTokenSingleUseRef = (0, import_react22.useRef)(false);
|
|
61476
|
+
const selectPaymentToken = (0, import_react22.useCallback)(
|
|
60839
61477
|
(token) => {
|
|
61478
|
+
selectedTokenSingleUseRef.current = !!token.singleUse;
|
|
60840
61479
|
setSelectedPaymentToken(token.id);
|
|
60841
61480
|
setPaymentDisplay(
|
|
60842
61481
|
token.label ? { label: token.label, sublabel: token.sublabel, brand: token.brand } : null
|
|
60843
61482
|
);
|
|
60844
61483
|
setStoredSelectedTokenState(token);
|
|
60845
|
-
if (customerId) setStoredSelectedToken(customerId, token);
|
|
61484
|
+
if (customerId && !token.singleUse) setStoredSelectedToken(customerId, token);
|
|
60846
61485
|
},
|
|
60847
61486
|
[customerId]
|
|
60848
61487
|
);
|
|
61488
|
+
const clearSelectedPaymentToken = (0, import_react22.useCallback)(() => {
|
|
61489
|
+
selectedTokenSingleUseRef.current = false;
|
|
61490
|
+
const persisted = customerId ? getStoredSelectedToken(customerId) : null;
|
|
61491
|
+
if (persisted && !persisted.singleUse) {
|
|
61492
|
+
setSelectedPaymentToken(persisted.id);
|
|
61493
|
+
setPaymentDisplay(
|
|
61494
|
+
persisted.label ? { label: persisted.label, sublabel: persisted.sublabel, brand: persisted.brand } : null
|
|
61495
|
+
);
|
|
61496
|
+
setStoredSelectedTokenState(persisted);
|
|
61497
|
+
} else {
|
|
61498
|
+
setSelectedPaymentToken(null);
|
|
61499
|
+
setPaymentDisplay(null);
|
|
61500
|
+
setStoredSelectedTokenState(null);
|
|
61501
|
+
}
|
|
61502
|
+
}, [customerId]);
|
|
60849
61503
|
const displayPaymentTokens = (() => {
|
|
60850
61504
|
const apiDisplay = paymentTokens.map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) }));
|
|
60851
61505
|
if (storedSelectedToken && !paymentTokens.some((t13) => t13.id === storedSelectedToken.id)) {
|
|
@@ -60853,7 +61507,7 @@ function PayWithStripeLink({
|
|
|
60853
61507
|
}
|
|
60854
61508
|
return apiDisplay;
|
|
60855
61509
|
})();
|
|
60856
|
-
(0,
|
|
61510
|
+
(0, import_react22.useEffect)(() => {
|
|
60857
61511
|
if (!customerId) return;
|
|
60858
61512
|
const stored = getStoredSelectedToken(customerId);
|
|
60859
61513
|
if (stored) {
|
|
@@ -60864,19 +61518,19 @@ function PayWithStripeLink({
|
|
|
60864
61518
|
);
|
|
60865
61519
|
}
|
|
60866
61520
|
}, [customerId]);
|
|
60867
|
-
const [amount, setAmount] = (0,
|
|
60868
|
-
(0,
|
|
61521
|
+
const [amount, setAmount] = (0, import_react22.useState)("");
|
|
61522
|
+
(0, import_react22.useEffect)(() => {
|
|
60869
61523
|
console.log("[PayWithStripeLink] Component mounted/remounted. Amount:", amount, "Step:", step);
|
|
60870
61524
|
}, []);
|
|
60871
61525
|
const sourceCurrency = "usd";
|
|
60872
61526
|
const extractRefreshToken = (res) => res.refresh_token ?? res.refresh?.refresh_token ?? "";
|
|
60873
|
-
const [stripeDestCurrency, setStripeDestCurrency] = (0,
|
|
60874
|
-
const [stripeDestNetwork, setStripeDestNetwork] = (0,
|
|
60875
|
-
const [stripeDestChainType, setStripeDestChainType] = (0,
|
|
60876
|
-
const [stripeTokenSymbol, setStripeTokenSymbol] = (0,
|
|
60877
|
-
const [stripeTokenIconUrl, setStripeTokenIconUrl] = (0,
|
|
60878
|
-
const [stripeNetworkName, setStripeNetworkName] = (0,
|
|
60879
|
-
(0,
|
|
61527
|
+
const [stripeDestCurrency, setStripeDestCurrency] = (0, import_react22.useState)("usdc");
|
|
61528
|
+
const [stripeDestNetwork, setStripeDestNetwork] = (0, import_react22.useState)("base");
|
|
61529
|
+
const [stripeDestChainType, setStripeDestChainType] = (0, import_react22.useState)("ethereum");
|
|
61530
|
+
const [stripeTokenSymbol, setStripeTokenSymbol] = (0, import_react22.useState)("USDC");
|
|
61531
|
+
const [stripeTokenIconUrl, setStripeTokenIconUrl] = (0, import_react22.useState)(null);
|
|
61532
|
+
const [stripeNetworkName, setStripeNetworkName] = (0, import_react22.useState)("Base");
|
|
61533
|
+
(0, import_react22.useEffect)(() => {
|
|
60880
61534
|
if (!destinationTokenAddress || !destinationChainId || !destinationChainType) return;
|
|
60881
61535
|
let cancelled = false;
|
|
60882
61536
|
stripeGetDefaultToken(
|
|
@@ -60904,26 +61558,26 @@ function PayWithStripeLink({
|
|
|
60904
61558
|
};
|
|
60905
61559
|
}, [publishableKey, destinationTokenAddress, destinationChainId, destinationChainType]);
|
|
60906
61560
|
const destinationCurrency = stripeDestCurrency;
|
|
60907
|
-
const authInnerRef = (0,
|
|
60908
|
-
const paymentInnerRef = (0,
|
|
60909
|
-
const [authReady, setAuthReady] = (0,
|
|
61561
|
+
const authInnerRef = (0, import_react22.useRef)(null);
|
|
61562
|
+
const paymentInnerRef = (0, import_react22.useRef)(null);
|
|
61563
|
+
const [authReady, setAuthReady] = (0, import_react22.useState)(false);
|
|
60910
61564
|
if (typeof document !== "undefined" && !authInnerRef.current) {
|
|
60911
61565
|
authInnerRef.current = document.createElement("div");
|
|
60912
61566
|
}
|
|
60913
61567
|
if (typeof document !== "undefined" && !paymentInnerRef.current) {
|
|
60914
61568
|
paymentInnerRef.current = document.createElement("div");
|
|
60915
61569
|
}
|
|
60916
|
-
const authMountRef = (0,
|
|
61570
|
+
const authMountRef = (0, import_react22.useCallback)((node) => {
|
|
60917
61571
|
if (node && !node.contains(authInnerRef.current)) {
|
|
60918
61572
|
node.appendChild(authInnerRef.current);
|
|
60919
61573
|
}
|
|
60920
61574
|
}, []);
|
|
60921
|
-
const paymentMountRef = (0,
|
|
61575
|
+
const paymentMountRef = (0, import_react22.useCallback)((node) => {
|
|
60922
61576
|
if (node && !node.contains(paymentInnerRef.current)) {
|
|
60923
61577
|
node.appendChild(paymentInnerRef.current);
|
|
60924
61578
|
}
|
|
60925
61579
|
}, []);
|
|
60926
|
-
(0,
|
|
61580
|
+
(0, import_react22.useEffect)(() => {
|
|
60927
61581
|
return () => {
|
|
60928
61582
|
authInnerRef.current?.remove();
|
|
60929
61583
|
paymentInnerRef.current?.remove();
|
|
@@ -60941,10 +61595,10 @@ function PayWithStripeLink({
|
|
|
60941
61595
|
});
|
|
60942
61596
|
const depositWallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
60943
61597
|
const onrampWalletAddress = getWalletByChainType(depositWallets, stripeDestChainType)?.address;
|
|
60944
|
-
const [registeredWalletKey, setRegisteredWalletKey] = (0,
|
|
61598
|
+
const [registeredWalletKey, setRegisteredWalletKey] = (0, import_react22.useState)(null);
|
|
60945
61599
|
const walletKeyFor = (address) => `${stripeDestNetwork}:${stripeDestChainType === "ethereum" ? address.toLowerCase() : address}`;
|
|
60946
61600
|
const isOnrampWalletRegistered = !!onrampWalletAddress && registeredWalletKey === walletKeyFor(onrampWalletAddress);
|
|
60947
|
-
(0,
|
|
61601
|
+
(0, import_react22.useEffect)(() => {
|
|
60948
61602
|
if (depositWallets.length > 0 && !onrampWalletAddress) {
|
|
60949
61603
|
console.warn(
|
|
60950
61604
|
"[PayWithStripeLink] No deposit-intent wallet matches Stripe chain type",
|
|
@@ -60967,14 +61621,14 @@ function PayWithStripeLink({
|
|
|
60967
61621
|
onDepositSuccess,
|
|
60968
61622
|
onDepositError
|
|
60969
61623
|
});
|
|
60970
|
-
const [confirmedSessionId, setConfirmedSessionId] = (0,
|
|
60971
|
-
const [sessionStatus, setSessionStatus] = (0,
|
|
60972
|
-
const handledTerminalSessionRef = (0,
|
|
60973
|
-
const executionReconciledSessionRef = (0,
|
|
61624
|
+
const [confirmedSessionId, setConfirmedSessionId] = (0, import_react22.useState)(null);
|
|
61625
|
+
const [sessionStatus, setSessionStatus] = (0, import_react22.useState)(null);
|
|
61626
|
+
const handledTerminalSessionRef = (0, import_react22.useRef)(null);
|
|
61627
|
+
const executionReconciledSessionRef = (0, import_react22.useRef)(null);
|
|
60974
61628
|
const hasExecution = executions.length > 0;
|
|
60975
61629
|
const isSessionFulfilled = sessionStatus === STRIPE_SESSION_STATUS.FULFILLMENT_COMPLETE || hasExecution;
|
|
60976
61630
|
const isSessionFailed = !hasExecution && (sessionStatus === STRIPE_SESSION_STATUS.REJECTED || sessionStatus === STRIPE_SESSION_STATUS.EXPIRED);
|
|
60977
|
-
(0,
|
|
61631
|
+
(0, import_react22.useEffect)(() => {
|
|
60978
61632
|
if (step !== "success" || !hasExecution || !confirmedSessionId) return;
|
|
60979
61633
|
if (executionReconciledSessionRef.current === confirmedSessionId) return;
|
|
60980
61634
|
executionReconciledSessionRef.current = confirmedSessionId;
|
|
@@ -60992,7 +61646,7 @@ function PayWithStripeLink({
|
|
|
60992
61646
|
cancelled = true;
|
|
60993
61647
|
};
|
|
60994
61648
|
}, [step, hasExecution, confirmedSessionId, withTokenRefresh, publishableKey]);
|
|
60995
|
-
(0,
|
|
61649
|
+
(0, import_react22.useEffect)(() => {
|
|
60996
61650
|
if (step !== "success" || !confirmedSessionId) return;
|
|
60997
61651
|
if (hasExecution) return;
|
|
60998
61652
|
if (handledTerminalSessionRef.current === confirmedSessionId) return;
|
|
@@ -61079,12 +61733,16 @@ function PayWithStripeLink({
|
|
|
61079
61733
|
setLoading(false);
|
|
61080
61734
|
}
|
|
61081
61735
|
};
|
|
61082
|
-
(0,
|
|
61736
|
+
(0, import_react22.useEffect)(() => {
|
|
61083
61737
|
if (coordinator || sdkLoading || sdkError) return;
|
|
61084
61738
|
if (!resolvedStripeKey) return;
|
|
61085
61739
|
initialize();
|
|
61086
61740
|
}, [coordinator, sdkLoading, sdkError, resolvedStripeKey, initialize]);
|
|
61087
|
-
|
|
61741
|
+
(0, import_react22.useEffect)(() => {
|
|
61742
|
+
sdkAuthenticatedRef.current = false;
|
|
61743
|
+
attemptedWalletReauthRef.current = false;
|
|
61744
|
+
}, [coordinator]);
|
|
61745
|
+
const handleAuthInterrupted = (0, import_react22.useCallback)(
|
|
61088
61746
|
(message) => {
|
|
61089
61747
|
const alreadySignedIn = !!accessTokenRef.current;
|
|
61090
61748
|
if (alreadySignedIn || emailProp) {
|
|
@@ -61097,7 +61755,27 @@ function PayWithStripeLink({
|
|
|
61097
61755
|
},
|
|
61098
61756
|
[emailProp, setStep]
|
|
61099
61757
|
);
|
|
61100
|
-
(0,
|
|
61758
|
+
const reauthenticateSdk = (0, import_react22.useCallback)(async () => {
|
|
61759
|
+
const current = stepRef.current;
|
|
61760
|
+
const preAuthSteps = ["email", "register", "auth"];
|
|
61761
|
+
reauthReturnStepRef.current = preAuthSteps.includes(current) ? null : current;
|
|
61762
|
+
const knownEmail = (email || emailProp || "").trim();
|
|
61763
|
+
if (!knownEmail) {
|
|
61764
|
+
reauthReturnStepRef.current = null;
|
|
61765
|
+
setStep("email");
|
|
61766
|
+
return;
|
|
61767
|
+
}
|
|
61768
|
+
try {
|
|
61769
|
+
const authResult = await stripeCreateAuthIntent(knownEmail, publishableKey);
|
|
61770
|
+
setAuthIntentId(authResult.auth_intent_id);
|
|
61771
|
+
setStep("auth");
|
|
61772
|
+
} catch (err) {
|
|
61773
|
+
reauthReturnStepRef.current = null;
|
|
61774
|
+
setError(err instanceof Error ? err.message : "Failed to re-verify. Please try again.");
|
|
61775
|
+
setStep("email");
|
|
61776
|
+
}
|
|
61777
|
+
}, [email, emailProp, publishableKey]);
|
|
61778
|
+
(0, import_react22.useEffect)(() => {
|
|
61101
61779
|
if (step !== "auth" || !coordinator || !authIntentId) return;
|
|
61102
61780
|
let mounted = true;
|
|
61103
61781
|
const runAuth = async () => {
|
|
@@ -61107,6 +61785,7 @@ function PayWithStripeLink({
|
|
|
61107
61785
|
if (result.result === "success" && result.crypto_customer_id) {
|
|
61108
61786
|
setCustomerId(result.crypto_customer_id);
|
|
61109
61787
|
sdkAuthenticatedRef.current = true;
|
|
61788
|
+
everAuthenticatedRef.current = true;
|
|
61110
61789
|
const tokens = await stripeExchangeTokens(authIntentId, publishableKey);
|
|
61111
61790
|
setOauthToken(tokens.access_token);
|
|
61112
61791
|
const refresh = extractRefreshToken(tokens);
|
|
@@ -61120,16 +61799,22 @@ function PayWithStripeLink({
|
|
|
61120
61799
|
tokens.expires_in ?? 3600,
|
|
61121
61800
|
email.trim()
|
|
61122
61801
|
);
|
|
61802
|
+
const resumeStep = reauthReturnStepRef.current;
|
|
61803
|
+
reauthReturnStepRef.current = null;
|
|
61123
61804
|
if (pendingAddPaymentRef.current) {
|
|
61124
61805
|
setStep("payment");
|
|
61806
|
+
} else if (resumeStep) {
|
|
61807
|
+
setStep(resumeStep);
|
|
61125
61808
|
} else {
|
|
61126
61809
|
setStep("kyc");
|
|
61127
61810
|
}
|
|
61128
61811
|
} else if (result.result === "abandoned") {
|
|
61129
61812
|
pendingAddPaymentRef.current = false;
|
|
61813
|
+
reauthReturnStepRef.current = null;
|
|
61130
61814
|
handleAuthInterrupted("Verification was cancelled.");
|
|
61131
61815
|
} else if (result.result === "declined") {
|
|
61132
61816
|
pendingAddPaymentRef.current = false;
|
|
61817
|
+
reauthReturnStepRef.current = null;
|
|
61133
61818
|
handleAuthInterrupted("You must consent to continue.");
|
|
61134
61819
|
}
|
|
61135
61820
|
});
|
|
@@ -61141,6 +61826,7 @@ function PayWithStripeLink({
|
|
|
61141
61826
|
}
|
|
61142
61827
|
} catch (err) {
|
|
61143
61828
|
if (!mounted) return;
|
|
61829
|
+
reauthReturnStepRef.current = null;
|
|
61144
61830
|
const msg = err instanceof Error ? err.message : "Verification was cancelled.";
|
|
61145
61831
|
handleAuthInterrupted(msg);
|
|
61146
61832
|
}
|
|
@@ -61152,7 +61838,7 @@ function PayWithStripeLink({
|
|
|
61152
61838
|
authInnerRef.current.replaceChildren();
|
|
61153
61839
|
};
|
|
61154
61840
|
}, [step, coordinator, authIntentId, publishableKey]);
|
|
61155
|
-
(0,
|
|
61841
|
+
(0, import_react22.useEffect)(() => {
|
|
61156
61842
|
if (step !== "kyc" || !oauthToken || !customerId) return;
|
|
61157
61843
|
let mounted = true;
|
|
61158
61844
|
let pollTimer = null;
|
|
@@ -61242,6 +61928,10 @@ function PayWithStripeLink({
|
|
|
61242
61928
|
};
|
|
61243
61929
|
const handleKycSubmit = async () => {
|
|
61244
61930
|
if (!coordinator) return;
|
|
61931
|
+
if (!sdkAuthenticatedRef.current) {
|
|
61932
|
+
await reauthenticateSdk();
|
|
61933
|
+
return;
|
|
61934
|
+
}
|
|
61245
61935
|
let kycInfo;
|
|
61246
61936
|
if (kycFormMode === "address") {
|
|
61247
61937
|
if (!kycForm.givenName.trim() || !kycForm.surname.trim()) {
|
|
@@ -61296,11 +61986,15 @@ function PayWithStripeLink({
|
|
|
61296
61986
|
setLoading(false);
|
|
61297
61987
|
}
|
|
61298
61988
|
};
|
|
61299
|
-
(0,
|
|
61989
|
+
(0, import_react22.useEffect)(() => {
|
|
61300
61990
|
if (step !== "kyc_document" || !coordinator) return;
|
|
61301
61991
|
let mounted = true;
|
|
61302
61992
|
const verify = async () => {
|
|
61303
61993
|
try {
|
|
61994
|
+
if (!sdkAuthenticatedRef.current) {
|
|
61995
|
+
await reauthenticateSdk();
|
|
61996
|
+
return;
|
|
61997
|
+
}
|
|
61304
61998
|
const result = await coordinator.verifyDocuments();
|
|
61305
61999
|
if (!mounted) return;
|
|
61306
62000
|
const outcome = typeof result === "string" ? result : result?.result;
|
|
@@ -61320,8 +62014,8 @@ function PayWithStripeLink({
|
|
|
61320
62014
|
return () => {
|
|
61321
62015
|
mounted = false;
|
|
61322
62016
|
};
|
|
61323
|
-
}, [step, coordinator]);
|
|
61324
|
-
(0,
|
|
62017
|
+
}, [step, coordinator, reauthenticateSdk]);
|
|
62018
|
+
(0, import_react22.useEffect)(() => {
|
|
61325
62019
|
if (step !== "wallet" || !oauthToken || !customerId) return;
|
|
61326
62020
|
let mounted = true;
|
|
61327
62021
|
const setupWallet = async () => {
|
|
@@ -61346,6 +62040,10 @@ function PayWithStripeLink({
|
|
|
61346
62040
|
if (!coordinator) {
|
|
61347
62041
|
return;
|
|
61348
62042
|
}
|
|
62043
|
+
if (!sdkAuthenticatedRef.current) {
|
|
62044
|
+
await reauthenticateSdk();
|
|
62045
|
+
return;
|
|
62046
|
+
}
|
|
61349
62047
|
await coordinator.registerWalletAddress(onrampWalletAddress, network);
|
|
61350
62048
|
}
|
|
61351
62049
|
if (mounted) setRegisteredWalletKey(walletKeyFor(onrampWalletAddress));
|
|
@@ -61362,8 +62060,16 @@ function PayWithStripeLink({
|
|
|
61362
62060
|
return () => {
|
|
61363
62061
|
mounted = false;
|
|
61364
62062
|
};
|
|
61365
|
-
}, [
|
|
61366
|
-
|
|
62063
|
+
}, [
|
|
62064
|
+
step,
|
|
62065
|
+
oauthToken,
|
|
62066
|
+
customerId,
|
|
62067
|
+
publishableKey,
|
|
62068
|
+
onrampWalletAddress,
|
|
62069
|
+
coordinator,
|
|
62070
|
+
reauthenticateSdk
|
|
62071
|
+
]);
|
|
62072
|
+
(0, import_react22.useEffect)(() => {
|
|
61367
62073
|
if (step !== "amount" && step !== "review") return;
|
|
61368
62074
|
if (!customerId || !oauthToken || !onrampWalletAddress) return;
|
|
61369
62075
|
if (isOnrampWalletRegistered) return;
|
|
@@ -61391,6 +62097,10 @@ function PayWithStripeLink({
|
|
|
61391
62097
|
if (coordinator && sdkAuthenticatedRef.current) {
|
|
61392
62098
|
await coordinator.registerWalletAddress(onrampWalletAddress, network);
|
|
61393
62099
|
if (!cancelled) setRegisteredWalletKey(walletKeyFor(onrampWalletAddress));
|
|
62100
|
+
} else if (coordinator && everAuthenticatedRef.current && !attemptedWalletReauthRef.current) {
|
|
62101
|
+
attemptedWalletReauthRef.current = true;
|
|
62102
|
+
await reauthenticateSdk();
|
|
62103
|
+
return;
|
|
61394
62104
|
}
|
|
61395
62105
|
} catch {
|
|
61396
62106
|
}
|
|
@@ -61408,9 +62118,10 @@ function PayWithStripeLink({
|
|
|
61408
62118
|
coordinator,
|
|
61409
62119
|
stripeDestNetwork,
|
|
61410
62120
|
stripeDestChainType,
|
|
61411
|
-
publishableKey
|
|
62121
|
+
publishableKey,
|
|
62122
|
+
reauthenticateSdk
|
|
61412
62123
|
]);
|
|
61413
|
-
(0,
|
|
62124
|
+
(0, import_react22.useEffect)(() => {
|
|
61414
62125
|
if (step !== "payment" || !oauthToken || !customerId) return;
|
|
61415
62126
|
if (pendingAddPaymentRef.current) {
|
|
61416
62127
|
pendingAddPaymentRef.current = false;
|
|
@@ -61473,7 +62184,7 @@ function PayWithStripeLink({
|
|
|
61473
62184
|
paymentInnerRef.current.replaceChildren();
|
|
61474
62185
|
};
|
|
61475
62186
|
}, [step, oauthToken, customerId, publishableKey, coordinator]);
|
|
61476
|
-
(0,
|
|
62187
|
+
(0, import_react22.useEffect)(() => {
|
|
61477
62188
|
if (step !== "add_payment") return;
|
|
61478
62189
|
if (!isCustomerVerified(customer)) {
|
|
61479
62190
|
setStep("kyc");
|
|
@@ -61505,6 +62216,32 @@ function PayWithStripeLink({
|
|
|
61505
62216
|
if (!mounted) return;
|
|
61506
62217
|
const tokenId = result.cryptoPaymentToken;
|
|
61507
62218
|
let display = null;
|
|
62219
|
+
const pmd = result.paymentMethodDetails;
|
|
62220
|
+
if (pmd) {
|
|
62221
|
+
display = formatPaymentToken(pmd);
|
|
62222
|
+
}
|
|
62223
|
+
const singleUse = pmd?.type === "card" && !!pmd.card.wallet;
|
|
62224
|
+
const applyAndAdvance = () => {
|
|
62225
|
+
selectPaymentToken({
|
|
62226
|
+
id: tokenId,
|
|
62227
|
+
label: display?.label ?? "",
|
|
62228
|
+
sublabel: display?.sublabel ?? "",
|
|
62229
|
+
brand: display?.brand,
|
|
62230
|
+
singleUse
|
|
62231
|
+
});
|
|
62232
|
+
autoOpenedAddPaymentRef.current = false;
|
|
62233
|
+
setStep("amount");
|
|
62234
|
+
};
|
|
62235
|
+
if (display) {
|
|
62236
|
+
applyAndAdvance();
|
|
62237
|
+
if (customerId && accessTokenRef.current) {
|
|
62238
|
+
stripeListPaymentTokens(customerId, accessTokenRef.current, publishableKey).then((tokens) => {
|
|
62239
|
+
if (mounted) setPaymentTokens(tokens.data);
|
|
62240
|
+
}).catch(() => {
|
|
62241
|
+
});
|
|
62242
|
+
}
|
|
62243
|
+
return;
|
|
62244
|
+
}
|
|
61508
62245
|
try {
|
|
61509
62246
|
if (customerId && accessTokenRef.current) {
|
|
61510
62247
|
const tokens = await stripeListPaymentTokens(
|
|
@@ -61512,28 +62249,15 @@ function PayWithStripeLink({
|
|
|
61512
62249
|
accessTokenRef.current,
|
|
61513
62250
|
publishableKey
|
|
61514
62251
|
);
|
|
62252
|
+
if (!mounted) return;
|
|
62253
|
+
setPaymentTokens(tokens.data);
|
|
61515
62254
|
const match = tokens.data.find((t13) => t13.id === tokenId);
|
|
61516
|
-
if (match)
|
|
61517
|
-
display = formatPaymentToken(match);
|
|
61518
|
-
setPaymentTokens(tokens.data);
|
|
61519
|
-
}
|
|
62255
|
+
if (match) display = formatPaymentToken(match);
|
|
61520
62256
|
}
|
|
61521
62257
|
} catch {
|
|
61522
62258
|
}
|
|
61523
|
-
if (!
|
|
61524
|
-
|
|
61525
|
-
if (dd?.label) {
|
|
61526
|
-
display = { label: dd.label, sublabel: dd.sublabel ?? "", brand: dd.type };
|
|
61527
|
-
}
|
|
61528
|
-
}
|
|
61529
|
-
selectPaymentToken({
|
|
61530
|
-
id: tokenId,
|
|
61531
|
-
label: display?.label ?? "",
|
|
61532
|
-
sublabel: display?.sublabel ?? "",
|
|
61533
|
-
brand: display?.brand
|
|
61534
|
-
});
|
|
61535
|
-
autoOpenedAddPaymentRef.current = false;
|
|
61536
|
-
setStep("amount");
|
|
62259
|
+
if (!mounted) return;
|
|
62260
|
+
applyAndAdvance();
|
|
61537
62261
|
}
|
|
61538
62262
|
);
|
|
61539
62263
|
if (mounted && el) {
|
|
@@ -61570,6 +62294,10 @@ function PayWithStripeLink({
|
|
|
61570
62294
|
const handleCheckout = async () => {
|
|
61571
62295
|
if (!amount || !oauthToken || !customerId || !selectedPaymentToken || !onrampWalletAddress || !isOnrampWalletRegistered || !coordinator)
|
|
61572
62296
|
return;
|
|
62297
|
+
if (!sdkAuthenticatedRef.current) {
|
|
62298
|
+
await reauthenticateSdk();
|
|
62299
|
+
return;
|
|
62300
|
+
}
|
|
61573
62301
|
const gen = ++checkoutGenRef.current;
|
|
61574
62302
|
const isStale2 = () => checkoutGenRef.current !== gen;
|
|
61575
62303
|
const surfaceStepUpOnAmount = (err, message, tier) => {
|
|
@@ -61681,6 +62409,7 @@ function PayWithStripeLink({
|
|
|
61681
62409
|
executionReconciledSessionRef.current = null;
|
|
61682
62410
|
setConfirmedSessionId(activeSessionId);
|
|
61683
62411
|
setSessionStatus(STRIPE_SESSION_STATUS.FULFILLMENT_PROCESSING);
|
|
62412
|
+
if (selectedTokenSingleUseRef.current) clearSelectedPaymentToken();
|
|
61684
62413
|
setStep("success");
|
|
61685
62414
|
} else if (lastError === "quote_rate_drifted" || lastError === "charged_with_expired_quote") {
|
|
61686
62415
|
setSessionForCheckout(null);
|
|
@@ -61723,15 +62452,34 @@ function PayWithStripeLink({
|
|
|
61723
62452
|
setLoading(false);
|
|
61724
62453
|
}
|
|
61725
62454
|
};
|
|
61726
|
-
const [quote, setQuote] = (0,
|
|
61727
|
-
const [quoteLoading, setQuoteLoading] = (0,
|
|
61728
|
-
const quoteTimerRef = (0,
|
|
61729
|
-
const [sessionForCheckout, setSessionForCheckoutState] = (0,
|
|
61730
|
-
const sessionForCheckoutRef = (0,
|
|
62455
|
+
const [quote, setQuote] = (0, import_react22.useState)(null);
|
|
62456
|
+
const [quoteLoading, setQuoteLoading] = (0, import_react22.useState)(false);
|
|
62457
|
+
const quoteTimerRef = (0, import_react22.useRef)(null);
|
|
62458
|
+
const [sessionForCheckout, setSessionForCheckoutState] = (0, import_react22.useState)(null);
|
|
62459
|
+
const sessionForCheckoutRef = (0, import_react22.useRef)(sessionForCheckout);
|
|
61731
62460
|
const setSessionForCheckout = (s) => {
|
|
61732
62461
|
sessionForCheckoutRef.current = s;
|
|
61733
62462
|
setSessionForCheckoutState(s);
|
|
61734
62463
|
};
|
|
62464
|
+
const loadAndSelectPreferredToken = (0, import_react22.useCallback)(async () => {
|
|
62465
|
+
if (!customerId) return;
|
|
62466
|
+
try {
|
|
62467
|
+
const existing = await withTokenRefresh(
|
|
62468
|
+
(tok) => stripeListPaymentTokens(customerId, tok, publishableKey)
|
|
62469
|
+
);
|
|
62470
|
+
setPaymentTokens(existing.data);
|
|
62471
|
+
const stored = getStoredSelectedToken(customerId);
|
|
62472
|
+
const merged = [
|
|
62473
|
+
...existing.data.map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) })),
|
|
62474
|
+
...stored && !existing.data.some((t13) => t13.id === stored.id) ? [stored] : []
|
|
62475
|
+
];
|
|
62476
|
+
if (merged.length > 0) {
|
|
62477
|
+
const preferred = stored && merged.find((m) => m.id === stored.id) || merged[0];
|
|
62478
|
+
selectPaymentToken(preferred);
|
|
62479
|
+
}
|
|
62480
|
+
} catch {
|
|
62481
|
+
}
|
|
62482
|
+
}, [customerId, publishableKey, selectPaymentToken, withTokenRefresh]);
|
|
61735
62483
|
const handleDone = () => {
|
|
61736
62484
|
handledTerminalSessionRef.current = null;
|
|
61737
62485
|
executionReconciledSessionRef.current = null;
|
|
@@ -61739,14 +62487,15 @@ function PayWithStripeLink({
|
|
|
61739
62487
|
setSessionStatus(null);
|
|
61740
62488
|
setSessionForCheckout(null);
|
|
61741
62489
|
setStep("amount");
|
|
62490
|
+
if (!selectedPaymentToken) void loadAndSelectPreferredToken();
|
|
61742
62491
|
};
|
|
61743
|
-
const [quoteError, setQuoteError] = (0,
|
|
61744
|
-
const [quoteNonce, setQuoteNonce] = (0,
|
|
61745
|
-
const quoteNonceAtReviewRef = (0,
|
|
61746
|
-
const [purchaseLimit, setPurchaseLimit] = (0,
|
|
61747
|
-
const [limitReachedAmount, setLimitReachedAmount] = (0,
|
|
61748
|
-
const [requiredStepUp, setRequiredStepUp] = (0,
|
|
61749
|
-
(0,
|
|
62492
|
+
const [quoteError, setQuoteError] = (0, import_react22.useState)(null);
|
|
62493
|
+
const [quoteNonce, setQuoteNonce] = (0, import_react22.useState)(0);
|
|
62494
|
+
const quoteNonceAtReviewRef = (0, import_react22.useRef)(quoteNonce);
|
|
62495
|
+
const [purchaseLimit, setPurchaseLimit] = (0, import_react22.useState)(null);
|
|
62496
|
+
const [limitReachedAmount, setLimitReachedAmount] = (0, import_react22.useState)(null);
|
|
62497
|
+
const [requiredStepUp, setRequiredStepUp] = (0, import_react22.useState)(null);
|
|
62498
|
+
(0, import_react22.useEffect)(() => {
|
|
61750
62499
|
if (step !== "amount" || !customerId || !onrampWalletAddress) return;
|
|
61751
62500
|
if (!accessTokenRef.current) return;
|
|
61752
62501
|
let cancelled = false;
|
|
@@ -61799,7 +62548,7 @@ function PayWithStripeLink({
|
|
|
61799
62548
|
setQuoteError(null);
|
|
61800
62549
|
setRequiredStepUp(null);
|
|
61801
62550
|
};
|
|
61802
|
-
(0,
|
|
62551
|
+
(0, import_react22.useEffect)(() => {
|
|
61803
62552
|
if (step === "review") {
|
|
61804
62553
|
const existing = sessionForCheckoutRef.current;
|
|
61805
62554
|
const hasFreshSession = !!(existing && existing.amount === amount && existing.paymentToken === selectedPaymentToken);
|
|
@@ -61931,9 +62680,9 @@ function PayWithStripeLink({
|
|
|
61931
62680
|
quoteNonce
|
|
61932
62681
|
]);
|
|
61933
62682
|
const QUOTE_TTL = 30;
|
|
61934
|
-
const [quoteCountdown, setQuoteCountdown] = (0,
|
|
62683
|
+
const [quoteCountdown, setQuoteCountdown] = (0, import_react22.useState)(QUOTE_TTL);
|
|
61935
62684
|
const hasReviewSession = !!(customerId && selectedPaymentToken && onrampWalletAddress);
|
|
61936
|
-
(0,
|
|
62685
|
+
(0, import_react22.useEffect)(() => {
|
|
61937
62686
|
if (step !== "review" || !hasReviewSession) return;
|
|
61938
62687
|
quoteNonceAtReviewRef.current = quoteNonce;
|
|
61939
62688
|
setQuoteCountdown(QUOTE_TTL);
|
|
@@ -62578,7 +63327,8 @@ function PayWithStripeLink({
|
|
|
62578
63327
|
{
|
|
62579
63328
|
brand: display.brand,
|
|
62580
63329
|
size: 28,
|
|
62581
|
-
fallbackColor: colors2.foregroundMuted
|
|
63330
|
+
fallbackColor: colors2.foregroundMuted,
|
|
63331
|
+
monochromeColor: monochromeOn(components.card.backgroundColor)
|
|
62582
63332
|
}
|
|
62583
63333
|
)
|
|
62584
63334
|
}
|
|
@@ -63163,7 +63913,8 @@ function PayWithStripeLink({
|
|
|
63163
63913
|
{
|
|
63164
63914
|
brand: paymentDisplay.brand,
|
|
63165
63915
|
size: 20,
|
|
63166
|
-
fallbackColor: colors2.foregroundMuted
|
|
63916
|
+
fallbackColor: colors2.foregroundMuted,
|
|
63917
|
+
monochromeColor: monochromeOn(components.card.backgroundColor)
|
|
63167
63918
|
}
|
|
63168
63919
|
),
|
|
63169
63920
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
@@ -63647,6 +64398,20 @@ function PayWithStripeLink({
|
|
|
63647
64398
|
}
|
|
63648
64399
|
return null;
|
|
63649
64400
|
}
|
|
64401
|
+
function useProjectConfig({
|
|
64402
|
+
publishableKey,
|
|
64403
|
+
enabled = true
|
|
64404
|
+
}) {
|
|
64405
|
+
const { data: projectConfig, isLoading } = useQuery({
|
|
64406
|
+
queryKey: ["unifold", "projectConfig", publishableKey],
|
|
64407
|
+
queryFn: () => getProjectConfig(publishableKey),
|
|
64408
|
+
enabled,
|
|
64409
|
+
staleTime: 1e3 * 60 * 30,
|
|
64410
|
+
refetchOnMount: true,
|
|
64411
|
+
refetchOnWindowFocus: true
|
|
64412
|
+
});
|
|
64413
|
+
return { projectConfig, isLoading };
|
|
64414
|
+
}
|
|
63650
64415
|
function useSupportedDepositTokens(publishableKey, options2) {
|
|
63651
64416
|
const hasDestination = options2?.destination_token_address && options2?.destination_chain_id && options2?.destination_chain_type;
|
|
63652
64417
|
const filteredOptions = {
|
|
@@ -63758,12 +64523,12 @@ function CoinbaseConnect({
|
|
|
63758
64523
|
destination_chain_id: destinationChainId,
|
|
63759
64524
|
destination_chain_type: destinationChainType
|
|
63760
64525
|
});
|
|
63761
|
-
const supportedSymbols = (0,
|
|
64526
|
+
const supportedSymbols = (0, import_react24.useMemo)(() => {
|
|
63762
64527
|
const set = /* @__PURE__ */ new Set();
|
|
63763
64528
|
supportedTokensData?.data.forEach((token) => set.add(token.symbol.toLowerCase()));
|
|
63764
64529
|
return set;
|
|
63765
64530
|
}, [supportedTokensData]);
|
|
63766
|
-
const stablecoinSymbols = (0,
|
|
64531
|
+
const stablecoinSymbols = (0, import_react24.useMemo)(() => {
|
|
63767
64532
|
const set = /* @__PURE__ */ new Set();
|
|
63768
64533
|
supportedTokensData?.data.forEach((token) => {
|
|
63769
64534
|
if (token.is_stablecoin) set.add(token.symbol.toLowerCase());
|
|
@@ -63773,35 +64538,35 @@ function CoinbaseConnect({
|
|
|
63773
64538
|
const appName = projectConfig?.project_name ?? "Unifold";
|
|
63774
64539
|
const t13 = i18n2.connectExchange;
|
|
63775
64540
|
const initialView = skipToHoldings && getStoredIntegrationToken(IntegrationProvider.COINBASE) ? "holdings" : "select_exchange";
|
|
63776
|
-
const [view, setView] = (0,
|
|
63777
|
-
const [prevView, setPrevView] = (0,
|
|
63778
|
-
const [isTransitioning, setIsTransitioning] = (0,
|
|
63779
|
-
const [exchanges, setExchanges] = (0,
|
|
63780
|
-
const [exchangesLoading, setExchangesLoading] = (0,
|
|
63781
|
-
const [selectedExchange, setSelectedExchange] = (0,
|
|
63782
|
-
const [accessToken, setAccessToken] = (0,
|
|
63783
|
-
const [holdings, setHoldings] = (0,
|
|
63784
|
-
const [selectedHolding, setSelectedHolding] = (0,
|
|
63785
|
-
const [selectedAsset, setSelectedAsset] = (0,
|
|
63786
|
-
const [sendAmount, setSendAmount] = (0,
|
|
63787
|
-
const [transferIntent, setTransferIntent] = (0,
|
|
64541
|
+
const [view, setView] = (0, import_react24.useState)(initialView);
|
|
64542
|
+
const [prevView, setPrevView] = (0, import_react24.useState)(initialView);
|
|
64543
|
+
const [isTransitioning, setIsTransitioning] = (0, import_react24.useState)(false);
|
|
64544
|
+
const [exchanges, setExchanges] = (0, import_react24.useState)([]);
|
|
64545
|
+
const [exchangesLoading, setExchangesLoading] = (0, import_react24.useState)(true);
|
|
64546
|
+
const [selectedExchange, setSelectedExchange] = (0, import_react24.useState)(null);
|
|
64547
|
+
const [accessToken, setAccessToken] = (0, import_react24.useState)(null);
|
|
64548
|
+
const [holdings, setHoldings] = (0, import_react24.useState)([]);
|
|
64549
|
+
const [selectedHolding, setSelectedHolding] = (0, import_react24.useState)(null);
|
|
64550
|
+
const [selectedAsset, setSelectedAsset] = (0, import_react24.useState)(null);
|
|
64551
|
+
const [sendAmount, setSendAmount] = (0, import_react24.useState)("");
|
|
64552
|
+
const [transferIntent, setTransferIntent] = (0, import_react24.useState)(
|
|
63788
64553
|
null
|
|
63789
64554
|
);
|
|
63790
|
-
const [mfaCode, setMfaCode] = (0,
|
|
63791
|
-
const [mfaError, setMfaError] = (0,
|
|
63792
|
-
const [errorMessage, setErrorMessage] = (0,
|
|
63793
|
-
const [isLoading, setIsLoading] = (0,
|
|
63794
|
-
const [confirmResult, setConfirmResult] = (0,
|
|
63795
|
-
const [showTransferDetails, setShowTransferDetails] = (0,
|
|
63796
|
-
const [transferDepositWalletId, setTransferDepositWalletId] = (0,
|
|
64555
|
+
const [mfaCode, setMfaCode] = (0, import_react24.useState)("");
|
|
64556
|
+
const [mfaError, setMfaError] = (0, import_react24.useState)(false);
|
|
64557
|
+
const [errorMessage, setErrorMessage] = (0, import_react24.useState)("");
|
|
64558
|
+
const [isLoading, setIsLoading] = (0, import_react24.useState)(initialView === "holdings");
|
|
64559
|
+
const [confirmResult, setConfirmResult] = (0, import_react24.useState)(null);
|
|
64560
|
+
const [showTransferDetails, setShowTransferDetails] = (0, import_react24.useState)(false);
|
|
64561
|
+
const [transferDepositWalletId, setTransferDepositWalletId] = (0, import_react24.useState)(
|
|
63797
64562
|
void 0
|
|
63798
64563
|
);
|
|
63799
|
-
const exchangeSupportedCurrencies = (0,
|
|
64564
|
+
const exchangeSupportedCurrencies = (0, import_react24.useMemo)(() => {
|
|
63800
64565
|
const set = /* @__PURE__ */ new Set();
|
|
63801
64566
|
selectedExchange?.supported_currencies.forEach((c) => set.add(c.toLowerCase()));
|
|
63802
64567
|
return set;
|
|
63803
64568
|
}, [selectedExchange]);
|
|
63804
|
-
const defaultTokenParams = (0,
|
|
64569
|
+
const defaultTokenParams = (0, import_react24.useMemo)(
|
|
63805
64570
|
() => selectedAsset ? {
|
|
63806
64571
|
integration_provider: IntegrationProvider.COINBASE,
|
|
63807
64572
|
source_currency: selectedAsset.currency.toLowerCase(),
|
|
@@ -63824,7 +64589,7 @@ function CoinbaseConnect({
|
|
|
63824
64589
|
params: defaultTokenParams,
|
|
63825
64590
|
publishableKey
|
|
63826
64591
|
});
|
|
63827
|
-
const defaultSourceCurrency = (0,
|
|
64592
|
+
const defaultSourceCurrency = (0, import_react24.useMemo)(
|
|
63828
64593
|
() => resolveDefaultSourceSymbol(supportedTokensData?.data, {
|
|
63829
64594
|
defaultSourceChainType,
|
|
63830
64595
|
defaultSourceChainId,
|
|
@@ -63839,7 +64604,7 @@ function CoinbaseConnect({
|
|
|
63839
64604
|
defaultSourceSymbol
|
|
63840
64605
|
]
|
|
63841
64606
|
);
|
|
63842
|
-
const sortedHoldings = (0,
|
|
64607
|
+
const sortedHoldings = (0, import_react24.useMemo)(() => {
|
|
63843
64608
|
const supported = [];
|
|
63844
64609
|
const unsupported = [];
|
|
63845
64610
|
holdings.forEach((account) => {
|
|
@@ -63859,12 +64624,12 @@ function CoinbaseConnect({
|
|
|
63859
64624
|
}
|
|
63860
64625
|
return [...supported, ...unsupported];
|
|
63861
64626
|
}, [holdings, supportedSymbols, exchangeSupportedCurrencies, defaultSourceCurrency]);
|
|
63862
|
-
const selectedHoldingIsSupported = (0,
|
|
64627
|
+
const selectedHoldingIsSupported = (0, import_react24.useMemo)(() => {
|
|
63863
64628
|
if (!selectedHolding) return false;
|
|
63864
64629
|
const currencyLower = selectedHolding.currency.toLowerCase();
|
|
63865
64630
|
return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
|
|
63866
64631
|
}, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
|
|
63867
|
-
(0,
|
|
64632
|
+
(0, import_react24.useEffect)(() => {
|
|
63868
64633
|
if (!defaultSourceCurrency || selectedHolding) return;
|
|
63869
64634
|
const defaultHolding = sortedHoldings.find((account) => {
|
|
63870
64635
|
const currencyLower = account.currency.toLowerCase();
|
|
@@ -63900,13 +64665,13 @@ function CoinbaseConnect({
|
|
|
63900
64665
|
onTransferError?.({ message: error.message });
|
|
63901
64666
|
} : void 0
|
|
63902
64667
|
});
|
|
63903
|
-
(0,
|
|
64668
|
+
(0, import_react24.useEffect)(() => {
|
|
63904
64669
|
onExecutionsChange?.(depositExecutions);
|
|
63905
64670
|
}, [depositExecutions, onExecutionsChange]);
|
|
63906
|
-
const pollRef = (0,
|
|
63907
|
-
const popupRef = (0,
|
|
63908
|
-
const viewRef = (0,
|
|
63909
|
-
const transitionTo = (0,
|
|
64671
|
+
const pollRef = (0, import_react24.useRef)(null);
|
|
64672
|
+
const popupRef = (0, import_react24.useRef)(null);
|
|
64673
|
+
const viewRef = (0, import_react24.useRef)(initialView);
|
|
64674
|
+
const transitionTo = (0, import_react24.useCallback)((nextView) => {
|
|
63910
64675
|
if (nextView === viewRef.current) return;
|
|
63911
64676
|
setIsTransitioning(true);
|
|
63912
64677
|
setTimeout(() => {
|
|
@@ -63916,7 +64681,7 @@ function CoinbaseConnect({
|
|
|
63916
64681
|
setIsTransitioning(false);
|
|
63917
64682
|
}, 150);
|
|
63918
64683
|
}, []);
|
|
63919
|
-
const tryRefreshToken = (0,
|
|
64684
|
+
const tryRefreshToken = (0, import_react24.useCallback)(
|
|
63920
64685
|
async (currentToken) => {
|
|
63921
64686
|
try {
|
|
63922
64687
|
const result = await refreshIntegrationToken(currentToken, publishableKey);
|
|
@@ -63935,7 +64700,7 @@ function CoinbaseConnect({
|
|
|
63935
64700
|
},
|
|
63936
64701
|
[publishableKey]
|
|
63937
64702
|
);
|
|
63938
|
-
(0,
|
|
64703
|
+
(0, import_react24.useEffect)(() => {
|
|
63939
64704
|
getIntegrationExchanges(publishableKey).then((res) => {
|
|
63940
64705
|
setExchanges(res.data);
|
|
63941
64706
|
if (!selectedExchange) {
|
|
@@ -63954,7 +64719,7 @@ function CoinbaseConnect({
|
|
|
63954
64719
|
}
|
|
63955
64720
|
}
|
|
63956
64721
|
}, []);
|
|
63957
|
-
const loadHoldings = (0,
|
|
64722
|
+
const loadHoldings = (0, import_react24.useCallback)(
|
|
63958
64723
|
async (token) => {
|
|
63959
64724
|
setIsLoading(true);
|
|
63960
64725
|
try {
|
|
@@ -64001,12 +64766,12 @@ function CoinbaseConnect({
|
|
|
64001
64766
|
},
|
|
64002
64767
|
[publishableKey, transitionTo, tryRefreshToken]
|
|
64003
64768
|
);
|
|
64004
|
-
(0,
|
|
64769
|
+
(0, import_react24.useEffect)(() => {
|
|
64005
64770
|
return () => {
|
|
64006
64771
|
if (pollRef.current) clearInterval(pollRef.current);
|
|
64007
64772
|
};
|
|
64008
64773
|
}, []);
|
|
64009
|
-
const minDepositUsd = (0,
|
|
64774
|
+
const minDepositUsd = (0, import_react24.useMemo)(() => {
|
|
64010
64775
|
if (!selectedAsset || !defaultTokenData) return 0;
|
|
64011
64776
|
const supportedToken = supportedTokensData?.data.find(
|
|
64012
64777
|
(t14) => t14.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
|
|
@@ -64017,7 +64782,7 @@ function CoinbaseConnect({
|
|
|
64017
64782
|
);
|
|
64018
64783
|
return matchingChain?.minimum_deposit_amount_usd ?? Math.min(...supportedToken.chains.map((c) => c.minimum_deposit_amount_usd));
|
|
64019
64784
|
}, [selectedAsset, supportedTokensData, defaultTokenData]);
|
|
64020
|
-
const estimatedProcessingTime = (0,
|
|
64785
|
+
const estimatedProcessingTime = (0, import_react24.useMemo)(() => {
|
|
64021
64786
|
if (!selectedAsset || !defaultTokenData) return null;
|
|
64022
64787
|
const supportedToken = supportedTokensData?.data.find(
|
|
64023
64788
|
(t14) => t14.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
|
|
@@ -66034,9 +66799,9 @@ function DepositsModal({
|
|
|
66034
66799
|
themeClass = ""
|
|
66035
66800
|
}) {
|
|
66036
66801
|
const { colors: colors2, fonts, components } = useTheme();
|
|
66037
|
-
const [allExecutions, setAllExecutions] = (0,
|
|
66038
|
-
const [selectedExecution, setSelectedExecution] = (0,
|
|
66039
|
-
(0,
|
|
66802
|
+
const [allExecutions, setAllExecutions] = (0, import_react26.useState)(sessionExecutions);
|
|
66803
|
+
const [selectedExecution, setSelectedExecution] = (0, import_react26.useState)(null);
|
|
66804
|
+
(0, import_react26.useEffect)(() => {
|
|
66040
66805
|
if (!open || !userId) return;
|
|
66041
66806
|
const fetchExecutions = async () => {
|
|
66042
66807
|
try {
|
|
@@ -66058,7 +66823,7 @@ function DepositsModal({
|
|
|
66058
66823
|
clearInterval(pollInterval);
|
|
66059
66824
|
};
|
|
66060
66825
|
}, [open, userId, publishableKey, sessionExecutions]);
|
|
66061
|
-
(0,
|
|
66826
|
+
(0, import_react26.useEffect)(() => {
|
|
66062
66827
|
if (!open) {
|
|
66063
66828
|
setSelectedExecution(null);
|
|
66064
66829
|
}
|
|
@@ -66181,13 +66946,13 @@ function TokenSelectorSheet({
|
|
|
66181
66946
|
}) {
|
|
66182
66947
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
66183
66948
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
66184
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
66185
|
-
const [recentTokens, setRecentTokens] = (0,
|
|
66186
|
-
const [hoveredTokenKey, setHoveredTokenKey] = (0,
|
|
66187
|
-
(0,
|
|
66949
|
+
const [searchQuery, setSearchQuery] = (0, import_react27.useState)("");
|
|
66950
|
+
const [recentTokens, setRecentTokens] = (0, import_react27.useState)([]);
|
|
66951
|
+
const [hoveredTokenKey, setHoveredTokenKey] = (0, import_react27.useState)(null);
|
|
66952
|
+
(0, import_react27.useEffect)(() => {
|
|
66188
66953
|
setRecentTokens(getRecentTokens());
|
|
66189
66954
|
}, []);
|
|
66190
|
-
const allOptions = (0,
|
|
66955
|
+
const allOptions = (0, import_react27.useMemo)(() => {
|
|
66191
66956
|
const options2 = [];
|
|
66192
66957
|
tokens.forEach((token) => {
|
|
66193
66958
|
token.chains.forEach((chain) => {
|
|
@@ -66196,7 +66961,7 @@ function TokenSelectorSheet({
|
|
|
66196
66961
|
});
|
|
66197
66962
|
return options2;
|
|
66198
66963
|
}, [tokens]);
|
|
66199
|
-
const quickSelectOptions = (0,
|
|
66964
|
+
const quickSelectOptions = (0, import_react27.useMemo)(() => {
|
|
66200
66965
|
const result = [];
|
|
66201
66966
|
const seen = /* @__PURE__ */ new Set();
|
|
66202
66967
|
const addOption = (symbol, chainType, chainId, isRecent) => {
|
|
@@ -66228,7 +66993,7 @@ function TokenSelectorSheet({
|
|
|
66228
66993
|
});
|
|
66229
66994
|
setRecentTokens(updated);
|
|
66230
66995
|
};
|
|
66231
|
-
const fuse = (0,
|
|
66996
|
+
const fuse = (0, import_react27.useMemo)(
|
|
66232
66997
|
() => new Fuse(allOptions, {
|
|
66233
66998
|
keys: [
|
|
66234
66999
|
{ name: "token.symbol", weight: 2 },
|
|
@@ -66241,7 +67006,7 @@ function TokenSelectorSheet({
|
|
|
66241
67006
|
}),
|
|
66242
67007
|
[allOptions]
|
|
66243
67008
|
);
|
|
66244
|
-
const filteredOptions = (0,
|
|
67009
|
+
const filteredOptions = (0, import_react27.useMemo)(() => {
|
|
66245
67010
|
if (!searchQuery.trim()) return allOptions;
|
|
66246
67011
|
const query = searchQuery.trim();
|
|
66247
67012
|
const results = fuse.search(query);
|
|
@@ -66665,11 +67430,11 @@ function useDefaultToken({
|
|
|
66665
67430
|
defaultTokenAddress,
|
|
66666
67431
|
defaultSymbol
|
|
66667
67432
|
}) {
|
|
66668
|
-
const [token, setToken] = (0,
|
|
66669
|
-
const [chain, setChain] = (0,
|
|
66670
|
-
const [initialSelectionDone, setInitialSelectionDone] = (0,
|
|
66671
|
-
const appliedDefaultsRef = (0,
|
|
66672
|
-
(0,
|
|
67433
|
+
const [token, setToken] = (0, import_react28.useState)(null);
|
|
67434
|
+
const [chain, setChain] = (0, import_react28.useState)(null);
|
|
67435
|
+
const [initialSelectionDone, setInitialSelectionDone] = (0, import_react28.useState)(false);
|
|
67436
|
+
const appliedDefaultsRef = (0, import_react28.useRef)("");
|
|
67437
|
+
(0, import_react28.useEffect)(() => {
|
|
66673
67438
|
if (!tokens.length) return;
|
|
66674
67439
|
const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
|
|
66675
67440
|
const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
|
|
@@ -66695,7 +67460,7 @@ function useDefaultToken({
|
|
|
66695
67460
|
defaultChainId,
|
|
66696
67461
|
initialSelectionDone
|
|
66697
67462
|
]);
|
|
66698
|
-
(0,
|
|
67463
|
+
(0, import_react28.useEffect)(() => {
|
|
66699
67464
|
if (!tokens.length || !token) return;
|
|
66700
67465
|
const currentToken = tokens.find((t13) => t13.symbol === token);
|
|
66701
67466
|
if (!currentToken || currentToken.chains.length === 0) return;
|
|
@@ -66994,7 +67759,7 @@ function GlossaryModal({
|
|
|
66994
67759
|
) });
|
|
66995
67760
|
}
|
|
66996
67761
|
function useCopyAddress() {
|
|
66997
|
-
const [copied, setCopied] = (0,
|
|
67762
|
+
const [copied, setCopied] = (0, import_react29.useState)(false);
|
|
66998
67763
|
const handleCopy = (address) => {
|
|
66999
67764
|
if (!address) return;
|
|
67000
67765
|
navigator.clipboard.writeText(address);
|
|
@@ -67138,12 +67903,12 @@ function TransferCryptoSingleInput({
|
|
|
67138
67903
|
}) {
|
|
67139
67904
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
67140
67905
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
67141
|
-
const [copied, setCopied] = (0,
|
|
67906
|
+
const [copied, setCopied] = (0, import_react25.useState)(false);
|
|
67142
67907
|
const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
|
|
67143
|
-
const [glossaryOpen, setGlossaryOpen] = (0,
|
|
67144
|
-
const [detailsExpanded, setDetailsExpanded] = (0,
|
|
67145
|
-
const [depositsModalOpen, setDepositsModalOpen] = (0,
|
|
67146
|
-
const [tokenSelectorOpen, setTokenSelectorOpen] = (0,
|
|
67908
|
+
const [glossaryOpen, setGlossaryOpen] = (0, import_react25.useState)(false);
|
|
67909
|
+
const [detailsExpanded, setDetailsExpanded] = (0, import_react25.useState)(false);
|
|
67910
|
+
const [depositsModalOpen, setDepositsModalOpen] = (0, import_react25.useState)(false);
|
|
67911
|
+
const [tokenSelectorOpen, setTokenSelectorOpen] = (0, import_react25.useState)(false);
|
|
67147
67912
|
const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(
|
|
67148
67913
|
publishableKey,
|
|
67149
67914
|
{
|
|
@@ -67178,7 +67943,7 @@ function TransferCryptoSingleInput({
|
|
|
67178
67943
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
67179
67944
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
67180
67945
|
const error = walletsError?.message ?? null;
|
|
67181
|
-
const allAvailableChains = (0,
|
|
67946
|
+
const allAvailableChains = (0, import_react25.useMemo)(() => {
|
|
67182
67947
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
67183
67948
|
supportedTokens.forEach((t13) => {
|
|
67184
67949
|
t13.chains.forEach((c) => {
|
|
@@ -67223,7 +67988,7 @@ function TransferCryptoSingleInput({
|
|
|
67223
67988
|
publishableKey,
|
|
67224
67989
|
enabled: !!depositAddress && !!recipientAddress
|
|
67225
67990
|
});
|
|
67226
|
-
(0,
|
|
67991
|
+
(0, import_react25.useEffect)(() => {
|
|
67227
67992
|
if (!onSourceTokenChange || !token || !chain || !initialSelectionDone) return;
|
|
67228
67993
|
const { chainType, chainId } = parseChainKey(chain);
|
|
67229
67994
|
const matchedToken = supportedTokens.find((t13) => t13.symbol === token);
|
|
@@ -67240,7 +68005,7 @@ function TransferCryptoSingleInput({
|
|
|
67240
68005
|
isStablecoin: matchedToken?.is_stablecoin ?? false
|
|
67241
68006
|
});
|
|
67242
68007
|
}, [token, chain, initialSelectionDone, onSourceTokenChange, supportedTokens]);
|
|
67243
|
-
(0,
|
|
68008
|
+
(0, import_react25.useEffect)(() => {
|
|
67244
68009
|
if (onExecutionsChange) {
|
|
67245
68010
|
onExecutionsChange(depositExecutions);
|
|
67246
68011
|
}
|
|
@@ -67916,11 +68681,11 @@ function TransferCryptoDoubleInput({
|
|
|
67916
68681
|
}) {
|
|
67917
68682
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
67918
68683
|
const isDarkMode = themeClass.includes("uf-dark");
|
|
67919
|
-
const [copied, setCopied] = (0,
|
|
68684
|
+
const [copied, setCopied] = (0, import_react31.useState)(false);
|
|
67920
68685
|
const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
|
|
67921
|
-
const [glossaryOpen, setGlossaryOpen] = (0,
|
|
67922
|
-
const [detailsExpanded, setDetailsExpanded] = (0,
|
|
67923
|
-
const [depositsModalOpen, setDepositsModalOpen] = (0,
|
|
68686
|
+
const [glossaryOpen, setGlossaryOpen] = (0, import_react31.useState)(false);
|
|
68687
|
+
const [detailsExpanded, setDetailsExpanded] = (0, import_react31.useState)(false);
|
|
68688
|
+
const [depositsModalOpen, setDepositsModalOpen] = (0, import_react31.useState)(false);
|
|
67924
68689
|
const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(
|
|
67925
68690
|
publishableKey,
|
|
67926
68691
|
{
|
|
@@ -67954,7 +68719,7 @@ function TransferCryptoDoubleInput({
|
|
|
67954
68719
|
const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
|
|
67955
68720
|
const loading = externalWallets?.length ? false : walletsLoading;
|
|
67956
68721
|
const error = walletsError?.message ?? null;
|
|
67957
|
-
const allAvailableChains = (0,
|
|
68722
|
+
const allAvailableChains = (0, import_react31.useMemo)(() => {
|
|
67958
68723
|
const chainsMap = /* @__PURE__ */ new Map();
|
|
67959
68724
|
supportedTokens.forEach((t13) => {
|
|
67960
68725
|
t13.chains.forEach((c) => {
|
|
@@ -67998,7 +68763,7 @@ function TransferCryptoDoubleInput({
|
|
|
67998
68763
|
publishableKey,
|
|
67999
68764
|
enabled: !!depositAddress && !!recipientAddress
|
|
68000
68765
|
});
|
|
68001
|
-
(0,
|
|
68766
|
+
(0, import_react31.useEffect)(() => {
|
|
68002
68767
|
if (onExecutionsChange) {
|
|
68003
68768
|
onExecutionsChange(depositExecutions);
|
|
68004
68769
|
}
|
|
@@ -69444,13 +70209,13 @@ function ConfirmingView({
|
|
|
69444
70209
|
amountReceivedUsdAtSubmission
|
|
69445
70210
|
}) {
|
|
69446
70211
|
const { colors: colors2, fonts, components } = useTheme();
|
|
69447
|
-
const [fallbackSettled, setFallbackSettled] = (0,
|
|
70212
|
+
const [fallbackSettled, setFallbackSettled] = (0, import_react34.useState)(false);
|
|
69448
70213
|
const hasExecution = executions.length > 0;
|
|
69449
70214
|
const isCheckoutMode = paymentIntentStatus != null;
|
|
69450
70215
|
const isPaymentComplete = paymentIntentStatus === "succeeded";
|
|
69451
70216
|
const amountChanged = amountReceivedUsdAtSubmission != null && amountReceivedUsd != null && amountReceivedUsd !== amountReceivedUsdAtSubmission;
|
|
69452
70217
|
const piSettled = !isCheckoutMode || isPaymentComplete || amountChanged || fallbackSettled;
|
|
69453
|
-
(0,
|
|
70218
|
+
(0, import_react34.useEffect)(() => {
|
|
69454
70219
|
if (!hasExecution || piSettled) return;
|
|
69455
70220
|
const timeout = setTimeout(() => setFallbackSettled(true), SETTLE_FALLBACK_MS);
|
|
69456
70221
|
return () => clearTimeout(timeout);
|
|
@@ -71184,10 +71949,9 @@ function DepositModal({
|
|
|
71184
71949
|
applePaySubTitle = "Instant",
|
|
71185
71950
|
enableBankTransfer,
|
|
71186
71951
|
enableStripeLink = false,
|
|
71187
|
-
|
|
71952
|
+
userEmail,
|
|
71188
71953
|
hideDepositFlowInfo = false,
|
|
71189
71954
|
hideDisplayDescription = false,
|
|
71190
|
-
externalUserEmail,
|
|
71191
71955
|
onDepositSuccess,
|
|
71192
71956
|
onDepositError,
|
|
71193
71957
|
onEvent,
|
|
@@ -71618,11 +72382,18 @@ function DepositModal({
|
|
|
71618
72382
|
return "Success";
|
|
71619
72383
|
case "guest_limit_reached":
|
|
71620
72384
|
return "Limit reached";
|
|
72385
|
+
case "limit_upgrade_intro":
|
|
72386
|
+
case "limit_upgrade_failed":
|
|
72387
|
+
return "Limit reached";
|
|
72388
|
+
case "limit_upgrade_form":
|
|
72389
|
+
return "Verify identity";
|
|
72390
|
+
case "limit_upgrade_submitting":
|
|
72391
|
+
return "Verifying";
|
|
71621
72392
|
default:
|
|
71622
72393
|
return "Pay with Apple Pay";
|
|
71623
72394
|
}
|
|
71624
72395
|
})();
|
|
71625
|
-
const applePayShowBack = sessionOpenedFromMenu || applePayView === "phone_input" || applePayView === "email_otp" || applePayView === "phone_otp" || applePayView === "submitting_session" || applePayView === "checking_deposit";
|
|
72396
|
+
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";
|
|
71626
72397
|
const handleBack = () => {
|
|
71627
72398
|
if (view === "card" && cardView === "quotes") {
|
|
71628
72399
|
setCardView("amount");
|
|
@@ -72301,7 +73072,7 @@ function DepositModal({
|
|
|
72301
73072
|
destinationChainId,
|
|
72302
73073
|
destinationTokenAddress,
|
|
72303
73074
|
wallets,
|
|
72304
|
-
email:
|
|
73075
|
+
email: userEmail,
|
|
72305
73076
|
iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/link.svg` : void 0,
|
|
72306
73077
|
step: stripeLinkStep,
|
|
72307
73078
|
onStepChange: setStripeLinkStep,
|
|
@@ -72364,13 +73135,10 @@ function DepositModal({
|
|
|
72364
73135
|
ref: applePayHandleRef,
|
|
72365
73136
|
userId,
|
|
72366
73137
|
publishableKey,
|
|
72367
|
-
recipientAddress,
|
|
72368
73138
|
destinationChainType,
|
|
72369
73139
|
destinationChainId,
|
|
72370
73140
|
destinationTokenAddress,
|
|
72371
|
-
|
|
72372
|
-
externalUserEmail,
|
|
72373
|
-
enableApplePay,
|
|
73141
|
+
userEmail,
|
|
72374
73142
|
wallets,
|
|
72375
73143
|
onViewChange: setApplePayView,
|
|
72376
73144
|
onEvent,
|
|
@@ -72480,12 +73248,12 @@ function CheckoutModal({
|
|
|
72480
73248
|
onEvent
|
|
72481
73249
|
}) {
|
|
72482
73250
|
const { colors: colors2, fonts, components } = useTheme();
|
|
72483
|
-
const [view, setView] = (0,
|
|
72484
|
-
const resetViewTimeoutRef = (0,
|
|
72485
|
-
const [browserWalletInfo, setBrowserWalletInfo] = (0,
|
|
72486
|
-
const [browserWalletChainType, setBrowserWalletChainType] = (0,
|
|
72487
|
-
const lastCheckoutMethodRef = (0,
|
|
72488
|
-
const emitCheckoutSuccess = (0,
|
|
73251
|
+
const [view, setView] = (0, import_react35.useState)("main");
|
|
73252
|
+
const resetViewTimeoutRef = (0, import_react35.useRef)(null);
|
|
73253
|
+
const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react35.useState)(null);
|
|
73254
|
+
const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react35.useState)(() => getStoredWalletState()?.chainType);
|
|
73255
|
+
const lastCheckoutMethodRef = (0, import_react35.useRef)(void 0);
|
|
73256
|
+
const emitCheckoutSuccess = (0, import_react35.useCallback)(
|
|
72489
73257
|
(data, method) => {
|
|
72490
73258
|
const isSucceeded = data.status === "succeeded";
|
|
72491
73259
|
const richIntent = isSucceeded && data.paymentIntent ? mapToCheckoutPaymentIntent(data.paymentIntent) : void 0;
|
|
@@ -72508,10 +73276,10 @@ function CheckoutModal({
|
|
|
72508
73276
|
},
|
|
72509
73277
|
[onCheckoutSuccess, onEvent]
|
|
72510
73278
|
);
|
|
72511
|
-
const [resolvedTheme, setResolvedTheme] = (0,
|
|
73279
|
+
const [resolvedTheme, setResolvedTheme] = (0, import_react35.useState)(
|
|
72512
73280
|
theme === "auto" ? "dark" : theme
|
|
72513
73281
|
);
|
|
72514
|
-
(0,
|
|
73282
|
+
(0, import_react35.useEffect)(() => {
|
|
72515
73283
|
if (theme === "auto") {
|
|
72516
73284
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
72517
73285
|
setResolvedTheme(mediaQuery.matches ? "dark" : "light");
|
|
@@ -72541,15 +73309,15 @@ function CheckoutModal({
|
|
|
72541
73309
|
});
|
|
72542
73310
|
const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
|
|
72543
73311
|
const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
|
|
72544
|
-
(0,
|
|
73312
|
+
(0, import_react35.useEffect)(() => {
|
|
72545
73313
|
if (view === "transfer" && !showTransferCrypto) {
|
|
72546
73314
|
setView("main");
|
|
72547
73315
|
} else if (view === "wallet_connect" && !showConnectWallet) {
|
|
72548
73316
|
setView("main");
|
|
72549
73317
|
}
|
|
72550
73318
|
}, [showConnectWallet, showTransferCrypto, view]);
|
|
72551
|
-
const prevStatusRef = (0,
|
|
72552
|
-
(0,
|
|
73319
|
+
const prevStatusRef = (0, import_react35.useRef)(null);
|
|
73320
|
+
(0, import_react35.useEffect)(() => {
|
|
72553
73321
|
if (!paymentIntent) return;
|
|
72554
73322
|
const prev = prevStatusRef.current;
|
|
72555
73323
|
prevStatusRef.current = paymentIntent.status;
|
|
@@ -72567,11 +73335,11 @@ function CheckoutModal({
|
|
|
72567
73335
|
);
|
|
72568
73336
|
}
|
|
72569
73337
|
}, [emitCheckoutSuccess, paymentIntent, view]);
|
|
72570
|
-
const wallets = (0,
|
|
73338
|
+
const wallets = (0, import_react35.useMemo)(() => {
|
|
72571
73339
|
if (!paymentIntent) return [];
|
|
72572
73340
|
return mapDepositAddressesToWallets(paymentIntent.deposit_addresses, paymentIntent);
|
|
72573
73341
|
}, [paymentIntent]);
|
|
72574
|
-
const formatCryptoAmount = (0,
|
|
73342
|
+
const formatCryptoAmount = (0, import_react35.useMemo)(() => {
|
|
72575
73343
|
if (!paymentIntent) return (_) => "";
|
|
72576
73344
|
const decimals = paymentIntent.destination_token_decimals ?? 6;
|
|
72577
73345
|
const symbol = paymentIntent.currency.toUpperCase();
|
|
@@ -72581,7 +73349,7 @@ function CheckoutModal({
|
|
|
72581
73349
|
return `${formatted} ${symbol}`;
|
|
72582
73350
|
};
|
|
72583
73351
|
}, [paymentIntent]);
|
|
72584
|
-
const remainingAmountUsd = (0,
|
|
73352
|
+
const remainingAmountUsd = (0, import_react35.useMemo)(() => {
|
|
72585
73353
|
if (!paymentIntent) return void 0;
|
|
72586
73354
|
const total = parseFloat(paymentIntent.destination_amount_usd || paymentIntent.amount_usd);
|
|
72587
73355
|
const received = parseFloat(
|
|
@@ -72592,8 +73360,8 @@ function CheckoutModal({
|
|
|
72592
73360
|
const remaining = total - received;
|
|
72593
73361
|
return remaining > 0 ? remaining.toFixed(2) : "0.00";
|
|
72594
73362
|
}, [paymentIntent]);
|
|
72595
|
-
const [selectedSource, setSelectedSource] = (0,
|
|
72596
|
-
const remainingDestinationAmount = (0,
|
|
73363
|
+
const [selectedSource, setSelectedSource] = (0, import_react35.useState)(null);
|
|
73364
|
+
const remainingDestinationAmount = (0, import_react35.useMemo)(() => {
|
|
72597
73365
|
if (!paymentIntent) return "0";
|
|
72598
73366
|
const remaining = BigInt(paymentIntent.destination_amount) - BigInt(paymentIntent.destination_amount_received);
|
|
72599
73367
|
return remaining > 0n ? remaining.toString() : "0";
|
|
@@ -72615,7 +73383,7 @@ function CheckoutModal({
|
|
|
72615
73383
|
stablecoinParity: paymentIntent?.stablecoin_parity ?? false,
|
|
72616
73384
|
enabled: open && view === "transfer" && !!paymentIntent && !!selectedSource && remainingDestinationAmount !== "0"
|
|
72617
73385
|
});
|
|
72618
|
-
const effectiveCheckoutQuote = (0,
|
|
73386
|
+
const effectiveCheckoutQuote = (0, import_react35.useMemo)(() => {
|
|
72619
73387
|
if (!sourceQuote || !selectedSource) return null;
|
|
72620
73388
|
const baseQuote = {
|
|
72621
73389
|
sourceAmount: sourceQuote.source_amount,
|
|
@@ -72636,7 +73404,7 @@ function CheckoutModal({
|
|
|
72636
73404
|
sourceAmountUsd: minUsd.toFixed(2)
|
|
72637
73405
|
};
|
|
72638
73406
|
}, [sourceQuote, selectedSource]);
|
|
72639
|
-
const handleBrowserWalletClick = (0,
|
|
73407
|
+
const handleBrowserWalletClick = (0, import_react35.useCallback)(
|
|
72640
73408
|
(walletInfo) => {
|
|
72641
73409
|
const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
|
|
72642
73410
|
setStoredWalletState(walletInfo.type);
|
|
@@ -72659,19 +73427,19 @@ function CheckoutModal({
|
|
|
72659
73427
|
},
|
|
72660
73428
|
[wallets, onCheckoutError]
|
|
72661
73429
|
);
|
|
72662
|
-
const handleWalletConnectClick = (0,
|
|
73430
|
+
const handleWalletConnectClick = (0, import_react35.useCallback)(() => {
|
|
72663
73431
|
setBrowserWalletInfo(null);
|
|
72664
73432
|
lastCheckoutMethodRef.current = "wallet_connect";
|
|
72665
73433
|
setView("wallet_connect");
|
|
72666
73434
|
}, []);
|
|
72667
|
-
const handleWalletDisconnect = (0,
|
|
73435
|
+
const handleWalletDisconnect = (0, import_react35.useCallback)(() => {
|
|
72668
73436
|
setUserDisconnectedWallet(true);
|
|
72669
73437
|
clearStoredWalletState();
|
|
72670
73438
|
setBrowserWalletChainType(void 0);
|
|
72671
73439
|
setBrowserWalletInfo(null);
|
|
72672
73440
|
setView("main");
|
|
72673
73441
|
}, []);
|
|
72674
|
-
const handleClose = (0,
|
|
73442
|
+
const handleClose = (0, import_react35.useCallback)(() => {
|
|
72675
73443
|
onOpenChange(false);
|
|
72676
73444
|
if (resetViewTimeoutRef.current) {
|
|
72677
73445
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -72683,7 +73451,7 @@ function CheckoutModal({
|
|
|
72683
73451
|
resetViewTimeoutRef.current = null;
|
|
72684
73452
|
}, 200);
|
|
72685
73453
|
}, [onOpenChange]);
|
|
72686
|
-
(0,
|
|
73454
|
+
(0, import_react35.useLayoutEffect)(() => {
|
|
72687
73455
|
if (!open) return;
|
|
72688
73456
|
if (resetViewTimeoutRef.current) {
|
|
72689
73457
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -72693,7 +73461,7 @@ function CheckoutModal({
|
|
|
72693
73461
|
setBrowserWalletInfo(null);
|
|
72694
73462
|
lastCheckoutMethodRef.current = void 0;
|
|
72695
73463
|
}, [open]);
|
|
72696
|
-
(0,
|
|
73464
|
+
(0, import_react35.useEffect)(
|
|
72697
73465
|
() => () => {
|
|
72698
73466
|
if (resetViewTimeoutRef.current) {
|
|
72699
73467
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -72701,7 +73469,7 @@ function CheckoutModal({
|
|
|
72701
73469
|
},
|
|
72702
73470
|
[]
|
|
72703
73471
|
);
|
|
72704
|
-
const handleBack = (0,
|
|
73472
|
+
const handleBack = (0, import_react35.useCallback)(() => {
|
|
72705
73473
|
setView("main");
|
|
72706
73474
|
}, []);
|
|
72707
73475
|
const poweredByFooter = /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "uf-pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
@@ -73264,20 +74032,20 @@ function useWithdrawPolling({
|
|
|
73264
74032
|
status: execution.status,
|
|
73265
74033
|
failureReason: execution.failure_reason
|
|
73266
74034
|
});
|
|
73267
|
-
const [executions, setExecutions] = (0,
|
|
73268
|
-
const [isPolling, setIsPolling] = (0,
|
|
73269
|
-
const enabledAtRef = (0,
|
|
73270
|
-
const trackedRef = (0,
|
|
73271
|
-
const prevEnabledRef = (0,
|
|
73272
|
-
const onSuccessRef = (0,
|
|
73273
|
-
const onErrorRef = (0,
|
|
73274
|
-
(0,
|
|
74035
|
+
const [executions, setExecutions] = (0, import_react37.useState)([]);
|
|
74036
|
+
const [isPolling, setIsPolling] = (0, import_react37.useState)(false);
|
|
74037
|
+
const enabledAtRef = (0, import_react37.useRef)(/* @__PURE__ */ new Date());
|
|
74038
|
+
const trackedRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
|
|
74039
|
+
const prevEnabledRef = (0, import_react37.useRef)(false);
|
|
74040
|
+
const onSuccessRef = (0, import_react37.useRef)(onWithdrawSuccess);
|
|
74041
|
+
const onErrorRef = (0, import_react37.useRef)(onWithdrawError);
|
|
74042
|
+
(0, import_react37.useEffect)(() => {
|
|
73275
74043
|
onSuccessRef.current = onWithdrawSuccess;
|
|
73276
74044
|
}, [onWithdrawSuccess]);
|
|
73277
|
-
(0,
|
|
74045
|
+
(0, import_react37.useEffect)(() => {
|
|
73278
74046
|
onErrorRef.current = onWithdrawError;
|
|
73279
74047
|
}, [onWithdrawError]);
|
|
73280
|
-
(0,
|
|
74048
|
+
(0, import_react37.useEffect)(() => {
|
|
73281
74049
|
if (enabled && !prevEnabledRef.current) {
|
|
73282
74050
|
enabledAtRef.current = /* @__PURE__ */ new Date();
|
|
73283
74051
|
trackedRef.current.clear();
|
|
@@ -73287,7 +74055,7 @@ function useWithdrawPolling({
|
|
|
73287
74055
|
}
|
|
73288
74056
|
prevEnabledRef.current = enabled;
|
|
73289
74057
|
}, [enabled]);
|
|
73290
|
-
(0,
|
|
74058
|
+
(0, import_react37.useEffect)(() => {
|
|
73291
74059
|
if (!userId || !enabled) return;
|
|
73292
74060
|
const enabledAt = enabledAtRef.current;
|
|
73293
74061
|
const poll = async () => {
|
|
@@ -73367,7 +74135,7 @@ function useWithdrawPolling({
|
|
|
73367
74135
|
setIsPolling(false);
|
|
73368
74136
|
};
|
|
73369
74137
|
}, [userId, publishableKey, enabled]);
|
|
73370
|
-
(0,
|
|
74138
|
+
(0, import_react37.useEffect)(() => {
|
|
73371
74139
|
if (!enabled || !depositWalletId) return;
|
|
73372
74140
|
const trigger = async () => {
|
|
73373
74141
|
try {
|
|
@@ -73650,7 +74418,7 @@ function useHypercoreWithdrawActivation(params) {
|
|
|
73650
74418
|
actionType: ActionType.Withdraw,
|
|
73651
74419
|
enabled: enabled && isHypercore(sourceChainId)
|
|
73652
74420
|
});
|
|
73653
|
-
const depositWalletAddress = (0,
|
|
74421
|
+
const depositWalletAddress = (0, import_react39.useMemo)(() => {
|
|
73654
74422
|
const wallets = depositWalletLookup.data?.data ?? [];
|
|
73655
74423
|
return wallets.find((w) => w.chain_type === sourceChainType)?.address;
|
|
73656
74424
|
}, [depositWalletLookup.data, sourceChainType]);
|
|
@@ -73736,22 +74504,22 @@ function WithdrawForm({
|
|
|
73736
74504
|
footerLeft
|
|
73737
74505
|
}) {
|
|
73738
74506
|
const { colors: colors2, fonts, components } = useTheme();
|
|
73739
|
-
const [recipientAddress, setRecipientAddress] = (0,
|
|
73740
|
-
const [amount, setAmount] = (0,
|
|
73741
|
-
const [inputUnit, setInputUnit] = (0,
|
|
73742
|
-
const [isSubmitting, setIsSubmitting] = (0,
|
|
73743
|
-
const [submitError, setSubmitError] = (0,
|
|
73744
|
-
const [detailsExpanded, setDetailsExpanded] = (0,
|
|
73745
|
-
const [glossaryOpen, setGlossaryOpen] = (0,
|
|
73746
|
-
const [isMaxed, setIsMaxed] = (0,
|
|
73747
|
-
(0,
|
|
74507
|
+
const [recipientAddress, setRecipientAddress] = (0, import_react38.useState)(recipientAddressProp || "");
|
|
74508
|
+
const [amount, setAmount] = (0, import_react38.useState)("");
|
|
74509
|
+
const [inputUnit, setInputUnit] = (0, import_react38.useState)("fiat");
|
|
74510
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react38.useState)(false);
|
|
74511
|
+
const [submitError, setSubmitError] = (0, import_react38.useState)(null);
|
|
74512
|
+
const [detailsExpanded, setDetailsExpanded] = (0, import_react38.useState)(false);
|
|
74513
|
+
const [glossaryOpen, setGlossaryOpen] = (0, import_react38.useState)(false);
|
|
74514
|
+
const [isMaxed, setIsMaxed] = (0, import_react38.useState)(false);
|
|
74515
|
+
(0, import_react38.useEffect)(() => {
|
|
73748
74516
|
setRecipientAddress(recipientAddressProp || "");
|
|
73749
74517
|
setAmount("");
|
|
73750
74518
|
setInputUnit("fiat");
|
|
73751
74519
|
setSubmitError(null);
|
|
73752
74520
|
setIsMaxed(false);
|
|
73753
74521
|
}, [recipientAddressProp]);
|
|
73754
|
-
(0,
|
|
74522
|
+
(0, import_react38.useEffect)(() => {
|
|
73755
74523
|
setIsMaxed(false);
|
|
73756
74524
|
}, [balanceData?.balanceBaseUnit]);
|
|
73757
74525
|
const trimmedAddress = recipientAddress.trim();
|
|
@@ -73769,7 +74537,7 @@ function WithdrawForm({
|
|
|
73769
74537
|
enabled: debouncedAddress.length > 5 && !!selectedChain
|
|
73770
74538
|
});
|
|
73771
74539
|
const isDebouncing = trimmedAddress !== debouncedAddress;
|
|
73772
|
-
const addressError = (0,
|
|
74540
|
+
const addressError = (0, import_react38.useMemo)(() => {
|
|
73773
74541
|
if (!trimmedAddress || trimmedAddress.length <= 5) return null;
|
|
73774
74542
|
if (isDebouncing || isVerifyingAddress) return null;
|
|
73775
74543
|
if (verifyError) return t10.invalidAddress;
|
|
@@ -73803,33 +74571,33 @@ function WithdrawForm({
|
|
|
73803
74571
|
destinationTokenAddress: selectedChain?.token_address,
|
|
73804
74572
|
enabled: isAddressValid
|
|
73805
74573
|
});
|
|
73806
|
-
const exchangeRate = (0,
|
|
74574
|
+
const exchangeRate = (0, import_react38.useMemo)(() => {
|
|
73807
74575
|
if (!balanceData?.exchangeRate) return 0;
|
|
73808
74576
|
return parseFloat(balanceData.exchangeRate);
|
|
73809
74577
|
}, [balanceData]);
|
|
73810
|
-
const balanceCrypto = (0,
|
|
74578
|
+
const balanceCrypto = (0, import_react38.useMemo)(() => {
|
|
73811
74579
|
if (!balanceData?.balanceHuman) return 0;
|
|
73812
74580
|
return parseFloat(balanceData.balanceHuman);
|
|
73813
74581
|
}, [balanceData]);
|
|
73814
|
-
const balanceUsdNum = (0,
|
|
74582
|
+
const balanceUsdNum = (0, import_react38.useMemo)(() => {
|
|
73815
74583
|
if (!balanceData?.balanceUsd) return 0;
|
|
73816
74584
|
return parseFloat(balanceData.balanceUsd);
|
|
73817
74585
|
}, [balanceData]);
|
|
73818
74586
|
const tokenSymbol = sourceTokenSymbol || balanceData?.symbol || "TOKEN";
|
|
73819
74587
|
const sourceDecimals = balanceData?.decimals ?? 6;
|
|
73820
|
-
const cryptoAmountFromInput = (0,
|
|
74588
|
+
const cryptoAmountFromInput = (0, import_react38.useMemo)(() => {
|
|
73821
74589
|
const val = parseFloat(amount);
|
|
73822
74590
|
if (!val || val <= 0) return 0;
|
|
73823
74591
|
if (inputUnit === "crypto") return val;
|
|
73824
74592
|
return exchangeRate > 0 ? val / exchangeRate : 0;
|
|
73825
74593
|
}, [amount, inputUnit, exchangeRate]);
|
|
73826
|
-
const fiatAmountFromInput = (0,
|
|
74594
|
+
const fiatAmountFromInput = (0, import_react38.useMemo)(() => {
|
|
73827
74595
|
const val = parseFloat(amount);
|
|
73828
74596
|
if (!val || val <= 0) return 0;
|
|
73829
74597
|
if (inputUnit === "fiat") return val;
|
|
73830
74598
|
return val * exchangeRate;
|
|
73831
74599
|
}, [amount, inputUnit, exchangeRate]);
|
|
73832
|
-
const convertedDisplay = (0,
|
|
74600
|
+
const convertedDisplay = (0, import_react38.useMemo)(() => {
|
|
73833
74601
|
if (!amount || parseFloat(amount) <= 0) return null;
|
|
73834
74602
|
if (inputUnit === "crypto") {
|
|
73835
74603
|
return `$${fiatAmountFromInput.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
@@ -73848,7 +74616,7 @@ function WithdrawForm({
|
|
|
73848
74616
|
isMaxed,
|
|
73849
74617
|
isStablecoin
|
|
73850
74618
|
]);
|
|
73851
|
-
const balanceDisplay = (0,
|
|
74619
|
+
const balanceDisplay = (0, import_react38.useMemo)(() => {
|
|
73852
74620
|
if (isLoadingBalance || !balanceData) return null;
|
|
73853
74621
|
if (inputUnit === "crypto") {
|
|
73854
74622
|
const displayDecimals = isStablecoin ? 2 : 6;
|
|
@@ -73871,7 +74639,7 @@ function WithdrawForm({
|
|
|
73871
74639
|
tokenSymbol,
|
|
73872
74640
|
isStablecoin
|
|
73873
74641
|
]);
|
|
73874
|
-
const handleSwitchUnit = (0,
|
|
74642
|
+
const handleSwitchUnit = (0, import_react38.useCallback)(() => {
|
|
73875
74643
|
if (isMaxed && balanceData) {
|
|
73876
74644
|
if (inputUnit === "crypto") {
|
|
73877
74645
|
setAmount((Math.round(balanceUsdNum * 100) / 100).toFixed(2));
|
|
@@ -73898,7 +74666,7 @@ function WithdrawForm({
|
|
|
73898
74666
|
setInputUnit("crypto");
|
|
73899
74667
|
}
|
|
73900
74668
|
}, [amount, inputUnit, exchangeRate, sourceDecimals, isMaxed, balanceData, balanceUsdNum]);
|
|
73901
|
-
const handleMaxClick = (0,
|
|
74669
|
+
const handleMaxClick = (0, import_react38.useCallback)(() => {
|
|
73902
74670
|
if (inputUnit === "crypto") {
|
|
73903
74671
|
if (balanceCrypto <= 0) return;
|
|
73904
74672
|
setAmount(balanceData?.balanceHuman ?? "0");
|
|
@@ -73912,7 +74680,7 @@ function WithdrawForm({
|
|
|
73912
74680
|
const isBelowMinimum = minimumWithdrawAmountUsd !== null && fiatAmountFromInput > 0 && Math.round(fiatAmountFromInput * 100) / 100 < minimumWithdrawAmountUsd;
|
|
73913
74681
|
const isOverBalance = inputUnit === "crypto" ? cryptoAmountFromInput > 0 && balanceCrypto > 0 && cryptoAmountFromInput > balanceCrypto : fiatAmountFromInput > 0 && balanceUsdNum > 0 && Math.round(fiatAmountFromInput * 100) / 100 > Math.round(balanceUsdNum * 100) / 100;
|
|
73914
74682
|
const isFormValid = trimmedAddress.length > 0 && amount.trim().length > 0 && cryptoAmountFromInput > 0 && isAddressValid && !isBelowMinimum && !isOverBalance && !isBalanceBelowMinimum && !!balanceData;
|
|
73915
|
-
const handleWithdraw = (0,
|
|
74683
|
+
const handleWithdraw = (0, import_react38.useCallback)(async () => {
|
|
73916
74684
|
if (!selectedToken || !selectedChain) return;
|
|
73917
74685
|
if (!isFormValid) return;
|
|
73918
74686
|
setIsSubmitting(true);
|
|
@@ -74539,9 +75307,9 @@ function WithdrawConfirmingView({
|
|
|
74539
75307
|
onViewTracker
|
|
74540
75308
|
}) {
|
|
74541
75309
|
const { colors: colors2, fonts, components } = useTheme();
|
|
74542
|
-
const [showButton, setShowButton] = (0,
|
|
75310
|
+
const [showButton, setShowButton] = (0, import_react40.useState)(false);
|
|
74543
75311
|
const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
|
|
74544
|
-
(0,
|
|
75312
|
+
(0, import_react40.useEffect)(() => {
|
|
74545
75313
|
if (latestExecution) return;
|
|
74546
75314
|
const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
|
|
74547
75315
|
return () => clearTimeout(timer);
|
|
@@ -74685,7 +75453,7 @@ function WithdrawModal({
|
|
|
74685
75453
|
theme = "dark",
|
|
74686
75454
|
hideOverlay = false
|
|
74687
75455
|
}) {
|
|
74688
|
-
const onWithdrawSuccessFor = (0,
|
|
75456
|
+
const onWithdrawSuccessFor = (0, import_react36.useCallback)(
|
|
74689
75457
|
(data) => {
|
|
74690
75458
|
onWithdrawSuccess?.(data);
|
|
74691
75459
|
if (data.execution) {
|
|
@@ -74695,14 +75463,14 @@ function WithdrawModal({
|
|
|
74695
75463
|
[onWithdrawSuccess, onEvent]
|
|
74696
75464
|
);
|
|
74697
75465
|
const { colors: colors2, fonts, components } = useTheme();
|
|
74698
|
-
const [containerEl, setContainerEl] = (0,
|
|
74699
|
-
const containerCallbackRef = (0,
|
|
75466
|
+
const [containerEl, setContainerEl] = (0, import_react36.useState)(null);
|
|
75467
|
+
const containerCallbackRef = (0, import_react36.useCallback)((el) => {
|
|
74700
75468
|
setContainerEl(el);
|
|
74701
75469
|
}, []);
|
|
74702
|
-
const [resolvedTheme, setResolvedTheme] = (0,
|
|
75470
|
+
const [resolvedTheme, setResolvedTheme] = (0, import_react36.useState)(
|
|
74703
75471
|
theme === "auto" ? "dark" : theme
|
|
74704
75472
|
);
|
|
74705
|
-
(0,
|
|
75473
|
+
(0, import_react36.useEffect)(() => {
|
|
74706
75474
|
if (theme === "auto") {
|
|
74707
75475
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
74708
75476
|
setResolvedTheme(mq.matches ? "dark" : "light");
|
|
@@ -74751,10 +75519,10 @@ function WithdrawModal({
|
|
|
74751
75519
|
const selectedChain = selectedToken && selectedChainKey ? selectedToken.chains.find(
|
|
74752
75520
|
(c) => getChainKey5(c.chain_id, c.chain_type) === selectedChainKey
|
|
74753
75521
|
) ?? null : null;
|
|
74754
|
-
const [view, setView] = (0,
|
|
74755
|
-
const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0,
|
|
74756
|
-
const [selectedExecution, setSelectedExecution] = (0,
|
|
74757
|
-
const [submittedTxInfo, setSubmittedTxInfo] = (0,
|
|
75522
|
+
const [view, setView] = (0, import_react36.useState)("form");
|
|
75523
|
+
const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react36.useState)();
|
|
75524
|
+
const [selectedExecution, setSelectedExecution] = (0, import_react36.useState)(null);
|
|
75525
|
+
const [submittedTxInfo, setSubmittedTxInfo] = (0, import_react36.useState)(null);
|
|
74758
75526
|
const { executions: realtimeExecutions } = useWithdrawPolling({
|
|
74759
75527
|
userId: externalUserId,
|
|
74760
75528
|
publishableKey,
|
|
@@ -74769,7 +75537,7 @@ function WithdrawModal({
|
|
|
74769
75537
|
refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
|
|
74770
75538
|
});
|
|
74771
75539
|
const allWithdrawals = allWithdrawalsData?.data ?? [];
|
|
74772
|
-
const handleDepositWalletCreation = (0,
|
|
75540
|
+
const handleDepositWalletCreation = (0, import_react36.useCallback)(
|
|
74773
75541
|
async (params) => {
|
|
74774
75542
|
const { data: wallets } = await createDepositAddress(
|
|
74775
75543
|
{
|
|
@@ -74792,12 +75560,12 @@ function WithdrawModal({
|
|
|
74792
75560
|
},
|
|
74793
75561
|
[externalUserId, publishableKey, sourceChainType]
|
|
74794
75562
|
);
|
|
74795
|
-
const handleWithdrawSubmitted = (0,
|
|
75563
|
+
const handleWithdrawSubmitted = (0, import_react36.useCallback)((txInfo) => {
|
|
74796
75564
|
setSubmittedTxInfo(txInfo);
|
|
74797
75565
|
setView("confirming");
|
|
74798
75566
|
}, []);
|
|
74799
|
-
const resetViewTimeoutRef = (0,
|
|
74800
|
-
const handleClose = (0,
|
|
75567
|
+
const resetViewTimeoutRef = (0, import_react36.useRef)(null);
|
|
75568
|
+
const handleClose = (0, import_react36.useCallback)(() => {
|
|
74801
75569
|
onOpenChange(false);
|
|
74802
75570
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
74803
75571
|
resetViewTimeoutRef.current = setTimeout(() => {
|
|
@@ -74808,7 +75576,7 @@ function WithdrawModal({
|
|
|
74808
75576
|
resetViewTimeoutRef.current = null;
|
|
74809
75577
|
}, 200);
|
|
74810
75578
|
}, [onOpenChange]);
|
|
74811
|
-
(0,
|
|
75579
|
+
(0, import_react36.useLayoutEffect)(() => {
|
|
74812
75580
|
if (!open) return;
|
|
74813
75581
|
if (resetViewTimeoutRef.current) {
|
|
74814
75582
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -74819,19 +75587,19 @@ function WithdrawModal({
|
|
|
74819
75587
|
setSubmittedTxInfo(null);
|
|
74820
75588
|
setWithdrawDepositWalletId(void 0);
|
|
74821
75589
|
}, [open]);
|
|
74822
|
-
(0,
|
|
75590
|
+
(0, import_react36.useEffect)(
|
|
74823
75591
|
() => () => {
|
|
74824
75592
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
74825
75593
|
},
|
|
74826
75594
|
[]
|
|
74827
75595
|
);
|
|
74828
|
-
const handleTokenSymbolChange = (0,
|
|
75596
|
+
const handleTokenSymbolChange = (0, import_react36.useCallback)(
|
|
74829
75597
|
(symbol) => {
|
|
74830
75598
|
setSelectedTokenSymbol(symbol);
|
|
74831
75599
|
},
|
|
74832
75600
|
[setSelectedTokenSymbol]
|
|
74833
75601
|
);
|
|
74834
|
-
const handleChainKeyChange = (0,
|
|
75602
|
+
const handleChainKeyChange = (0, import_react36.useCallback)(
|
|
74835
75603
|
(chainKey) => {
|
|
74836
75604
|
setSelectedChainKey(chainKey);
|
|
74837
75605
|
},
|
|
@@ -75380,7 +76148,7 @@ function UnifoldProvider2({
|
|
|
75380
76148
|
defaultSourceChainId: depositConfig.defaultSourceChainId,
|
|
75381
76149
|
defaultSourceTokenAddress: depositConfig.defaultSourceTokenAddress,
|
|
75382
76150
|
defaultSourceSymbol: depositConfig.defaultSourceSymbol,
|
|
75383
|
-
|
|
76151
|
+
userEmail: depositConfig.user?.email,
|
|
75384
76152
|
depositConfirmationMode: depositConfig.depositConfirmationMode ?? "auto_ui",
|
|
75385
76153
|
hideDepositTracker: config?.hideDepositTracker,
|
|
75386
76154
|
showBalanceHeader: config?.showBalanceHeader,
|
|
@@ -75393,7 +76161,6 @@ function UnifoldProvider2({
|
|
|
75393
76161
|
enableConnectExchange: config?.enableConnectExchange,
|
|
75394
76162
|
enableCashApp: config?.enableCashApp,
|
|
75395
76163
|
enableStripeLink: config?.enableStripeLink,
|
|
75396
|
-
email: depositConfig?.email,
|
|
75397
76164
|
enableApplePay: config?.enableApplePay,
|
|
75398
76165
|
applePayTitle: config?.applePayTitle,
|
|
75399
76166
|
applePaySubTitle: config?.applePaySubTitle,
|
|
@@ -75449,9 +76216,9 @@ function useUnifold2() {
|
|
|
75449
76216
|
}
|
|
75450
76217
|
|
|
75451
76218
|
// src/unifold.tsx
|
|
75452
|
-
var UnifoldBridge = (0,
|
|
76219
|
+
var UnifoldBridge = (0, import_react42.forwardRef)((_, ref) => {
|
|
75453
76220
|
const { beginDeposit, closeDeposit, beginWithdraw, closeWithdraw } = useUnifold2();
|
|
75454
|
-
(0,
|
|
76221
|
+
(0, import_react42.useImperativeHandle)(ref, () => ({ beginDeposit, closeDeposit, beginWithdraw, closeWithdraw }), [
|
|
75455
76222
|
beginDeposit,
|
|
75456
76223
|
closeDeposit,
|
|
75457
76224
|
beginWithdraw,
|
|
@@ -75460,7 +76227,7 @@ var UnifoldBridge = (0, import_react41.forwardRef)((_, ref) => {
|
|
|
75460
76227
|
return null;
|
|
75461
76228
|
});
|
|
75462
76229
|
UnifoldBridge.displayName = "UnifoldBridge";
|
|
75463
|
-
var RenderErrorBoundary = class extends
|
|
76230
|
+
var RenderErrorBoundary = class extends import_react42.Component {
|
|
75464
76231
|
constructor() {
|
|
75465
76232
|
super(...arguments);
|
|
75466
76233
|
this.state = { hasError: false };
|
|
@@ -75532,13 +76299,13 @@ function createUnifold(publishableKey, config) {
|
|
|
75532
76299
|
};
|
|
75533
76300
|
try {
|
|
75534
76301
|
root.render(
|
|
75535
|
-
|
|
76302
|
+
import_react42.default.createElement(
|
|
75536
76303
|
RenderErrorBoundary,
|
|
75537
76304
|
{ onError: handleRenderError },
|
|
75538
|
-
|
|
76305
|
+
import_react42.default.createElement(
|
|
75539
76306
|
UnifoldProvider2,
|
|
75540
76307
|
{ publishableKey, config },
|
|
75541
|
-
|
|
76308
|
+
import_react42.default.createElement(UnifoldBridge, { ref: refCallback })
|
|
75542
76309
|
)
|
|
75543
76310
|
)
|
|
75544
76311
|
);
|