@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.mjs CHANGED
@@ -34394,7 +34394,7 @@ var require_jsx_runtime = __commonJS({
34394
34394
  });
34395
34395
 
34396
34396
  // src/unifold.tsx
34397
- var import_react41 = __toESM(require_react());
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 import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
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 import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
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 import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
37186
+ var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
37188
37187
  var import_react23 = __toESM(require_react(), 1);
37189
- var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
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 import_react28 = __toESM(require_react(), 1);
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 import_react29 = __toESM(require_react(), 1);
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 import_react30 = __toESM(require_react(), 1);
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 import_react33 = __toESM(require_react(), 1);
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 import_react39 = __toESM(require_react(), 1);
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 import_react40 = __toESM(require_react(), 1);
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 ? import_react29.useLayoutEffect : noop2;
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 = import_react31.default.useRef(null);
49461
- const itemMap = import_react31.default.useRef(/* @__PURE__ */ new Map()).current;
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 = import_react31.default.forwardRef(
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 = import_react31.default.forwardRef(
49533
+ const CollectionItemSlot = import_react32.default.forwardRef(
49480
49534
  (props, forwardedRef) => {
49481
49535
  const { scope, children, ...itemData } = props;
49482
- const ref = import_react31.default.useRef(null);
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
- import_react31.default.useEffect(() => {
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 = import_react31.default.useCallback(() => {
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 preparing your purchase. This will only take a moment.",
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 COINBASE_PAY_ORIGIN = "https://pay.coinbase.com";
54092
- var DEFAULT_MIN_USD = 5;
54093
- var DEFAULT_MAX_USD = 500;
54094
- var DEFAULT_SUGGESTED = [25, 50, 100];
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 formatPhoneInput(raw) {
54098
- const digits = raw.replace(/\D/g, "");
54099
- if (raw.startsWith("+")) {
54100
- return `+${digits}`;
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 maskEmail(email) {
54107
- const [local, domain] = email.split("@");
54108
- if (!local || !domain) return email;
54109
- const visible = local.slice(0, Math.min(2, local.length));
54110
- return `${visible}${"*".repeat(Math.max(local.length - visible.length, 1))}@${domain}`;
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 maskPhone(phone) {
54113
- if (!/^\+1\d{10}$/.test(phone)) return phone;
54114
- return `+1 (***) ***-${phone.slice(-4)}`;
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
- destinationTokenSymbol = "USDC",
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: externalWallets,
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)(externalUserEmail ?? "");
54145
- const [phoneInput, setPhoneInput] = (0, import_react15.useState)("");
54146
- const [, setTosAccepted] = (0, import_react15.useState)(false);
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 { data: depositAddressResponse } = useDepositAddress({
54169
- userId,
54370
+ const { userIpInfo, isLoading: userIpInfoLoading } = useUserIp2();
54371
+ const {
54372
+ defaultToken,
54373
+ isLoading: defaultTokenLoading,
54374
+ isError: defaultTokenError
54375
+ } = useDefaultOnrampToken({
54170
54376
  publishableKey,
54171
- recipientAddress,
54172
- destinationChainType,
54173
- destinationChainId,
54174
- destinationTokenAddress,
54175
- enabled: !externalWallets?.length
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
- if (!destinationChainType) return void 0;
54180
- return getWalletByChainType(wallets, destinationChainType);
54181
- }, [wallets, destinationChainType]);
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)(false);
54206
- (0, import_react15.useEffect)(() => {
54207
- if (configLoading) return;
54208
- if (!applePayEnabled) {
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 !== COINBASE_PAY_ORIGIN) return;
54257
- let parsed = null;
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 (parsed.eventName) {
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 = EMAIL_REGEX.test(email) && PHONE_REGEX.test(normalizedPhone);
54347
- const persistContact = (0, import_react15.useCallback)(
54514
+ const isContactValid = EMAIL_REGEX2.test(email) && PHONE_REGEX2.test(normalizedPhone);
54515
+ const storeApplePaySession = (0, import_react15.useCallback)(
54348
54516
  (patch = {}) => {
54349
- const base = {
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, base);
54523
+ setStoredApplePaySession(userId, session);
54356
54524
  },
54357
54525
  [email, normalizedPhone, userId]
54358
54526
  );
54359
- const startVerification = (0, import_react15.useCallback)(async () => {
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
- persistContact();
54379
- if (session.email.status === "verified") {
54380
- await sendOnrampVerificationOtp(
54381
- session.id,
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
- }, [isContactValid, email, normalizedPhone, publishableKey, persistContact]);
54404
- const submitEmailOtp = (0, import_react15.useCallback)(async () => {
54405
- if (!verificationSession || !clientSecret || emailCode.length !== 6) return;
54406
- if (otpSubmitting) return;
54407
- setOtpError(null);
54408
- setOtpSubmitting(true);
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
- const updated = await verifyOnrampVerificationOtp(
54411
- verificationSession.id,
54412
- "email",
54413
- clientSecret,
54414
- emailCode,
54415
- publishableKey
54416
- );
54417
- setVerificationSession(updated);
54418
- if (updated.email.status === "verified") {
54419
- persistContact({ emailVerifiedAt: updated.email.verified_at });
54420
- await sendOnrampVerificationOtp(updated.id, "phone", clientSecret, publishableKey);
54421
- setEmailCode("");
54422
- setResendCooldown(30);
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
- setOtpError("Incorrect code. Please try again.");
54426
- setEmailCode("");
54648
+ setLimitUpgradeError(null);
54427
54649
  }
54428
- } catch (err) {
54429
- setOtpError(
54430
- prettifyVerificationError(err instanceof Error ? err.message : "Verification failed")
54431
- );
54432
- setEmailCode("");
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
- setOtpSubmitting(false);
54721
+ setUpgradeSubmitting(false);
54435
54722
  }
54436
54723
  }, [
54437
- verificationSession,
54438
- clientSecret,
54439
- emailCode,
54724
+ upgradeSubmitting,
54725
+ dobInput,
54726
+ ssnLast4,
54727
+ normalizedPhone,
54440
54728
  publishableKey,
54441
- persistContact,
54442
- otpSubmitting
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
- persistContact({
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
- } else {
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
- persistContact,
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
- const destinationNetwork = destinationChainNameFor(
54503
- destinationChainType,
54504
- destinationChainId
54505
- );
54506
- if (!destinationNetwork) {
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: destinationTokenSymbol.toLowerCase(),
54527
- destination_network: destinationNetwork,
54828
+ destination_currency: defaultToken.destination_currency,
54829
+ destination_network: defaultToken.destination_network,
54528
54830
  wallet_address: settlementAddress,
54529
54831
  external_id: externalId,
54530
- ...externalUserEmail ? { email: externalUserEmail } : {}
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
- externalUserEmail,
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 = EMAIL_REGEX.test(email);
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 = PHONE_REGEX.test(normalizedPhone);
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 === "email_otp" || view === "phone_otp") {
54828
- const isEmail = view === "email_otp";
54829
- const code = isEmail ? emailCode : phoneCode;
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
- const v = e.target.value.replace(/\D/g, "").slice(0, 6);
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 submit();
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
- isEmail ? "email" : "phone",
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: () => void submit(),
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: "Return if the payment is not made."
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 has reached Apple Pay limit. It's not eligible for an increase right now."
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 LegalDisclaimer({ legalAgreements, loading, colors: colors2, fonts }) {
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, import_react16.useState)("providers");
55279
- const [exchangeSession, setExchangeSession] = (0, import_react16.useState)(null);
55280
- const [sessionError, setSessionError] = (0, import_react16.useState)(null);
55281
- const [hoveredIndex, setHoveredIndex] = (0, import_react16.useState)(null);
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, import_react18.useMemo)(() => {
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, import_react18.useRef)(null);
55617
- const qrRef = (0, import_react18.useRef)(null);
55618
- const [ready, setReady] = (0, import_react18.useState)(false);
55619
- (0, import_react18.useEffect)(() => {
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, import_react19.useState)(() => isMobileViewport());
55651
- (0, import_react19.useEffect)(() => {
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, import_react17.useState)("");
55704
- const [loading, setLoading] = (0, import_react17.useState)(false);
55705
- const [session, setSession] = (0, import_react17.useState)(null);
55706
- const [status, setStatus] = (0, import_react17.useState)("pending");
55707
- const [error, setError] = (0, import_react17.useState)(null);
55708
- const [copied, setCopied] = (0, import_react17.useState)(false);
55709
- const [view, setViewInternal] = (0, import_react17.useState)(controlledView ?? "amount");
55710
- const setView = (0, import_react17.useCallback)(
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, import_react17.useEffect)(() => {
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, import_react17.useState)(null);
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, import_react17.useCallback)(
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, import_react17.useCallback)(async () => {
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, import_react17.useEffect)(() => {
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, import_react17.useState)(false);
55826
- (0, import_react17.useEffect)(() => {
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, import_react17.useCallback)(async (text) => {
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, import_react17.useCallback)(() => {
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, import_react20.useState)("providers");
56259
- const [sessionError, setSessionError] = (0, import_react20.useState)(null);
56260
- const [hoveredId, setHoveredId] = (0, import_react20.useState)(null);
56261
- const [activeProvider, setActiveProvider] = (0, import_react20.useState)(null);
56262
- const [requestBase, setRequestBase] = (0, import_react20.useState)(null);
56263
- const [activeRequest, setActiveRequest] = (0, import_react20.useState)(null);
56264
- const [amount, setAmount] = (0, import_react20.useState)("");
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, import_react20.useEffect)(() => {
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, import_react20.useMemo)(() => {
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, import_react20.useMemo)(
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 brand = token.card.brand ?? "Card";
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(brand)} \u2022\u2022\u2022\u2022 ${token.card.last4}`,
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, import_react22.useState)(null);
60323
- const [isLoading, setIsLoading] = (0, import_react22.useState)(false);
60324
- const [error, setError] = (0, import_react22.useState)(null);
60325
- const coordinatorRef = (0, import_react22.useRef)(null);
60326
- const initialize = (0, import_react22.useCallback)(async () => {
60327
- if (coordinatorRef.current) return coordinatorRef.current;
60328
- if (!stripePublishableKey) return null;
60329
- setIsLoading(true);
60330
- setError(null);
60331
- try {
60332
- console.log("[PayWithStripeLink] Importing @stripe/crypto...");
60333
- const { loadCryptoOnrampAndInitialize } = await import(
60334
- /* @vite-ignore */
60335
- "@stripe/crypto"
60336
- );
60337
- console.log(
60338
- "[PayWithStripeLink] @stripe/crypto imported, initializing with key:",
60339
- stripePublishableKey?.slice(0, 12) + "..."
60340
- );
60341
- const initPromise = loadCryptoOnrampAndInitialize(stripePublishableKey, { theme: "stripe" });
60342
- const timeoutPromise = new Promise(
60343
- (_, reject) => setTimeout(
60344
- () => reject(
60345
- new Error(
60346
- "Stripe SDK initialization timed out after 15 seconds. Check that your Stripe account has the Crypto Onramp feature enabled."
60347
- )
60348
- ),
60349
- 15e3
60350
- )
60351
- );
60352
- const instance = await Promise.race([initPromise, timeoutPromise]);
60353
- if (!instance) {
60354
- throw new Error("Stripe SDK returned null.");
60355
- }
60356
- console.log("[PayWithStripeLink] Stripe SDK initialized successfully");
60357
- coordinatorRef.current = instance;
60358
- setCoordinator(instance);
60359
- return coordinatorRef.current;
60360
- } catch (err) {
60361
- const raw = err instanceof Error ? err.message : String(err);
60362
- 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}`;
60363
- setError(msg);
60364
- console.error("[PayWithStripeLink]", msg);
60365
- return null;
60366
- } finally {
60367
- setIsLoading(false);
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, import_react22.useEffect)(() => {
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, import_react21.useState)(controlledStep ?? "amount");
60526
- const setStep = (0, import_react21.useCallback)(
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, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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, import_react21.useState)();
60548
- const [configError, setConfigError] = (0, import_react21.useState)(null);
60549
- (0, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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, import_react21.useState)(emailProp ?? "");
60613
- const [phone, setPhone] = (0, import_react21.useState)("");
60614
- const [country, setCountry] = (0, import_react21.useState)("US");
60615
- const [loading, setLoading] = (0, import_react21.useState)(false);
60616
- const [error, setError] = (0, import_react21.useState)(null);
60617
- const [kycPendingMessage, setKycPendingMessage] = (0, import_react21.useState)(null);
60618
- const [kycRejectionReason, setKycRejectionReason] = (0, import_react21.useState)(null);
60619
- const [restoring, setRestoring] = (0, import_react21.useState)(true);
60620
- const [errorReturnStep, setErrorReturnStep] = (0, import_react21.useState)("email");
60621
- const [authIntentId, setAuthIntentId] = (0, import_react21.useState)(null);
60622
- const sdkAuthenticatedRef = (0, import_react21.useRef)(false);
60623
- const pendingAddPaymentRef = (0, import_react21.useRef)(false);
60624
- const autoOpenedAddPaymentRef = (0, import_react21.useRef)(false);
60625
- const checkoutGenRef = (0, import_react21.useRef)(0);
60626
- const [stripePaymentUIReady, setStripePaymentUIReady] = (0, import_react21.useState)(false);
60627
- const [oauthToken, setOauthToken] = (0, import_react21.useState)(null);
60628
- const [refreshTokenValue, setRefreshTokenValue] = (0, import_react21.useState)(null);
60629
- const [customerId, setCustomerId] = (0, import_react21.useState)(null);
60630
- const accessTokenRef = (0, import_react21.useRef)("");
60631
- const refreshTokenRef = (0, import_react21.useRef)("");
60632
- const persistSession = (0, import_react21.useCallback)(
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, import_react21.useRef)(null);
60647
- const tryRefreshToken = (0, import_react21.useCallback)(async () => {
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, import_react21.useCallback)(
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, import_react21.useEffect)(() => {
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, import_react21.useState)(null);
60797
- const [kycFormMode, setKycFormMode] = (0, import_react21.useState)("name");
60798
- const [kycForm, setKycForm] = (0, import_react21.useState)({
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, import_react21.useEffect)(() => {
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, import_react21.useState)([]);
60832
- const [paymentTokens, setPaymentTokens] = (0, import_react21.useState)([]);
60833
- const [storedSelectedToken, setStoredSelectedTokenState] = (0, import_react21.useState)(
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, import_react21.useState)(null);
60837
- const [paymentDisplay, setPaymentDisplay] = (0, import_react21.useState)(null);
60838
- const selectPaymentToken = (0, import_react21.useCallback)(
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, import_react21.useEffect)(() => {
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, import_react21.useState)("");
60868
- (0, import_react21.useEffect)(() => {
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, import_react21.useState)("usdc");
60874
- const [stripeDestNetwork, setStripeDestNetwork] = (0, import_react21.useState)("base");
60875
- const [stripeDestChainType, setStripeDestChainType] = (0, import_react21.useState)("ethereum");
60876
- const [stripeTokenSymbol, setStripeTokenSymbol] = (0, import_react21.useState)("USDC");
60877
- const [stripeTokenIconUrl, setStripeTokenIconUrl] = (0, import_react21.useState)(null);
60878
- const [stripeNetworkName, setStripeNetworkName] = (0, import_react21.useState)("Base");
60879
- (0, import_react21.useEffect)(() => {
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, import_react21.useRef)(null);
60908
- const paymentInnerRef = (0, import_react21.useRef)(null);
60909
- const [authReady, setAuthReady] = (0, import_react21.useState)(false);
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, import_react21.useCallback)((node) => {
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, import_react21.useCallback)((node) => {
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, import_react21.useEffect)(() => {
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, import_react21.useState)(null);
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, import_react21.useEffect)(() => {
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, import_react21.useState)(null);
60971
- const [sessionStatus, setSessionStatus] = (0, import_react21.useState)(null);
60972
- const handledTerminalSessionRef = (0, import_react21.useRef)(null);
60973
- const executionReconciledSessionRef = (0, import_react21.useRef)(null);
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, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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
- const handleAuthInterrupted = (0, import_react21.useCallback)(
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, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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
- }, [step, oauthToken, customerId, publishableKey, onrampWalletAddress, coordinator]);
61366
- (0, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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 (!display) {
61524
- const dd = result.displayData;
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, import_react21.useState)(null);
61727
- const [quoteLoading, setQuoteLoading] = (0, import_react21.useState)(false);
61728
- const quoteTimerRef = (0, import_react21.useRef)(null);
61729
- const [sessionForCheckout, setSessionForCheckoutState] = (0, import_react21.useState)(null);
61730
- const sessionForCheckoutRef = (0, import_react21.useRef)(sessionForCheckout);
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, import_react21.useState)(null);
61744
- const [quoteNonce, setQuoteNonce] = (0, import_react21.useState)(0);
61745
- const quoteNonceAtReviewRef = (0, import_react21.useRef)(quoteNonce);
61746
- const [purchaseLimit, setPurchaseLimit] = (0, import_react21.useState)(null);
61747
- const [limitReachedAmount, setLimitReachedAmount] = (0, import_react21.useState)(null);
61748
- const [requiredStepUp, setRequiredStepUp] = (0, import_react21.useState)(null);
61749
- (0, import_react21.useEffect)(() => {
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, import_react21.useEffect)(() => {
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, import_react21.useState)(QUOTE_TTL);
62683
+ const [quoteCountdown, setQuoteCountdown] = (0, import_react22.useState)(QUOTE_TTL);
61935
62684
  const hasReviewSession = !!(customerId && selectedPaymentToken && onrampWalletAddress);
61936
- (0, import_react21.useEffect)(() => {
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, import_react23.useMemo)(() => {
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, import_react23.useMemo)(() => {
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, import_react23.useState)(initialView);
63777
- const [prevView, setPrevView] = (0, import_react23.useState)(initialView);
63778
- const [isTransitioning, setIsTransitioning] = (0, import_react23.useState)(false);
63779
- const [exchanges, setExchanges] = (0, import_react23.useState)([]);
63780
- const [exchangesLoading, setExchangesLoading] = (0, import_react23.useState)(true);
63781
- const [selectedExchange, setSelectedExchange] = (0, import_react23.useState)(null);
63782
- const [accessToken, setAccessToken] = (0, import_react23.useState)(null);
63783
- const [holdings, setHoldings] = (0, import_react23.useState)([]);
63784
- const [selectedHolding, setSelectedHolding] = (0, import_react23.useState)(null);
63785
- const [selectedAsset, setSelectedAsset] = (0, import_react23.useState)(null);
63786
- const [sendAmount, setSendAmount] = (0, import_react23.useState)("");
63787
- const [transferIntent, setTransferIntent] = (0, import_react23.useState)(
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, import_react23.useState)("");
63791
- const [mfaError, setMfaError] = (0, import_react23.useState)(false);
63792
- const [errorMessage, setErrorMessage] = (0, import_react23.useState)("");
63793
- const [isLoading, setIsLoading] = (0, import_react23.useState)(initialView === "holdings");
63794
- const [confirmResult, setConfirmResult] = (0, import_react23.useState)(null);
63795
- const [showTransferDetails, setShowTransferDetails] = (0, import_react23.useState)(false);
63796
- const [transferDepositWalletId, setTransferDepositWalletId] = (0, import_react23.useState)(
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, import_react23.useMemo)(() => {
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, import_react23.useMemo)(
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, import_react23.useMemo)(
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, import_react23.useMemo)(() => {
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, import_react23.useMemo)(() => {
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, import_react23.useEffect)(() => {
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, import_react23.useEffect)(() => {
64668
+ (0, import_react24.useEffect)(() => {
63904
64669
  onExecutionsChange?.(depositExecutions);
63905
64670
  }, [depositExecutions, onExecutionsChange]);
63906
- const pollRef = (0, import_react23.useRef)(null);
63907
- const popupRef = (0, import_react23.useRef)(null);
63908
- const viewRef = (0, import_react23.useRef)(initialView);
63909
- const transitionTo = (0, import_react23.useCallback)((nextView) => {
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, import_react23.useCallback)(
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, import_react23.useEffect)(() => {
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, import_react23.useCallback)(
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, import_react23.useEffect)(() => {
64769
+ (0, import_react24.useEffect)(() => {
64005
64770
  return () => {
64006
64771
  if (pollRef.current) clearInterval(pollRef.current);
64007
64772
  };
64008
64773
  }, []);
64009
- const minDepositUsd = (0, import_react23.useMemo)(() => {
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, import_react23.useMemo)(() => {
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, import_react25.useState)(sessionExecutions);
66038
- const [selectedExecution, setSelectedExecution] = (0, import_react25.useState)(null);
66039
- (0, import_react25.useEffect)(() => {
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, import_react25.useEffect)(() => {
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, import_react26.useState)("");
66185
- const [recentTokens, setRecentTokens] = (0, import_react26.useState)([]);
66186
- const [hoveredTokenKey, setHoveredTokenKey] = (0, import_react26.useState)(null);
66187
- (0, import_react26.useEffect)(() => {
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, import_react26.useMemo)(() => {
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, import_react26.useMemo)(() => {
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, import_react26.useMemo)(
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, import_react26.useMemo)(() => {
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, import_react27.useState)(null);
66669
- const [chain, setChain] = (0, import_react27.useState)(null);
66670
- const [initialSelectionDone, setInitialSelectionDone] = (0, import_react27.useState)(false);
66671
- const appliedDefaultsRef = (0, import_react27.useRef)("");
66672
- (0, import_react27.useEffect)(() => {
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, import_react27.useEffect)(() => {
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, import_react28.useState)(false);
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, import_react24.useState)(false);
67906
+ const [copied, setCopied] = (0, import_react25.useState)(false);
67142
67907
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
67143
- const [glossaryOpen, setGlossaryOpen] = (0, import_react24.useState)(false);
67144
- const [detailsExpanded, setDetailsExpanded] = (0, import_react24.useState)(false);
67145
- const [depositsModalOpen, setDepositsModalOpen] = (0, import_react24.useState)(false);
67146
- const [tokenSelectorOpen, setTokenSelectorOpen] = (0, import_react24.useState)(false);
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, import_react24.useMemo)(() => {
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, import_react24.useEffect)(() => {
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, import_react24.useEffect)(() => {
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, import_react30.useState)(false);
68684
+ const [copied, setCopied] = (0, import_react31.useState)(false);
67920
68685
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
67921
- const [glossaryOpen, setGlossaryOpen] = (0, import_react30.useState)(false);
67922
- const [detailsExpanded, setDetailsExpanded] = (0, import_react30.useState)(false);
67923
- const [depositsModalOpen, setDepositsModalOpen] = (0, import_react30.useState)(false);
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, import_react30.useMemo)(() => {
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, import_react30.useEffect)(() => {
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, import_react33.useState)(false);
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, import_react33.useEffect)(() => {
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
- email: emailProp,
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: emailProp,
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
- destinationTokenSymbol,
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, import_react34.useState)("main");
72484
- const resetViewTimeoutRef = (0, import_react34.useRef)(null);
72485
- const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react34.useState)(null);
72486
- const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react34.useState)(() => getStoredWalletState()?.chainType);
72487
- const lastCheckoutMethodRef = (0, import_react34.useRef)(void 0);
72488
- const emitCheckoutSuccess = (0, import_react34.useCallback)(
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, import_react34.useState)(
73279
+ const [resolvedTheme, setResolvedTheme] = (0, import_react35.useState)(
72512
73280
  theme === "auto" ? "dark" : theme
72513
73281
  );
72514
- (0, import_react34.useEffect)(() => {
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, import_react34.useEffect)(() => {
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, import_react34.useRef)(null);
72552
- (0, import_react34.useEffect)(() => {
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, import_react34.useMemo)(() => {
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, import_react34.useMemo)(() => {
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, import_react34.useMemo)(() => {
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, import_react34.useState)(null);
72596
- const remainingDestinationAmount = (0, import_react34.useMemo)(() => {
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, import_react34.useMemo)(() => {
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, import_react34.useCallback)(
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, import_react34.useCallback)(() => {
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, import_react34.useCallback)(() => {
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, import_react34.useCallback)(() => {
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, import_react34.useLayoutEffect)(() => {
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, import_react34.useEffect)(
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, import_react34.useCallback)(() => {
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, import_react36.useState)([]);
73268
- const [isPolling, setIsPolling] = (0, import_react36.useState)(false);
73269
- const enabledAtRef = (0, import_react36.useRef)(/* @__PURE__ */ new Date());
73270
- const trackedRef = (0, import_react36.useRef)(/* @__PURE__ */ new Map());
73271
- const prevEnabledRef = (0, import_react36.useRef)(false);
73272
- const onSuccessRef = (0, import_react36.useRef)(onWithdrawSuccess);
73273
- const onErrorRef = (0, import_react36.useRef)(onWithdrawError);
73274
- (0, import_react36.useEffect)(() => {
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, import_react36.useEffect)(() => {
74045
+ (0, import_react37.useEffect)(() => {
73278
74046
  onErrorRef.current = onWithdrawError;
73279
74047
  }, [onWithdrawError]);
73280
- (0, import_react36.useEffect)(() => {
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, import_react36.useEffect)(() => {
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, import_react36.useEffect)(() => {
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, import_react38.useMemo)(() => {
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, import_react37.useState)(recipientAddressProp || "");
73740
- const [amount, setAmount] = (0, import_react37.useState)("");
73741
- const [inputUnit, setInputUnit] = (0, import_react37.useState)("fiat");
73742
- const [isSubmitting, setIsSubmitting] = (0, import_react37.useState)(false);
73743
- const [submitError, setSubmitError] = (0, import_react37.useState)(null);
73744
- const [detailsExpanded, setDetailsExpanded] = (0, import_react37.useState)(false);
73745
- const [glossaryOpen, setGlossaryOpen] = (0, import_react37.useState)(false);
73746
- const [isMaxed, setIsMaxed] = (0, import_react37.useState)(false);
73747
- (0, import_react37.useEffect)(() => {
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, import_react37.useEffect)(() => {
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, import_react37.useMemo)(() => {
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, import_react37.useMemo)(() => {
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, import_react37.useMemo)(() => {
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, import_react37.useMemo)(() => {
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, import_react37.useMemo)(() => {
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, import_react37.useMemo)(() => {
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, import_react37.useMemo)(() => {
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, import_react37.useMemo)(() => {
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, import_react37.useCallback)(() => {
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, import_react37.useCallback)(() => {
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, import_react37.useCallback)(async () => {
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, import_react39.useState)(false);
75310
+ const [showButton, setShowButton] = (0, import_react40.useState)(false);
74543
75311
  const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
74544
- (0, import_react39.useEffect)(() => {
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, import_react35.useCallback)(
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, import_react35.useState)(null);
74699
- const containerCallbackRef = (0, import_react35.useCallback)((el) => {
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, import_react35.useState)(
75470
+ const [resolvedTheme, setResolvedTheme] = (0, import_react36.useState)(
74703
75471
  theme === "auto" ? "dark" : theme
74704
75472
  );
74705
- (0, import_react35.useEffect)(() => {
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, import_react35.useState)("form");
74755
- const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react35.useState)();
74756
- const [selectedExecution, setSelectedExecution] = (0, import_react35.useState)(null);
74757
- const [submittedTxInfo, setSubmittedTxInfo] = (0, import_react35.useState)(null);
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, import_react35.useCallback)(
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, import_react35.useCallback)((txInfo) => {
75563
+ const handleWithdrawSubmitted = (0, import_react36.useCallback)((txInfo) => {
74796
75564
  setSubmittedTxInfo(txInfo);
74797
75565
  setView("confirming");
74798
75566
  }, []);
74799
- const resetViewTimeoutRef = (0, import_react35.useRef)(null);
74800
- const handleClose = (0, import_react35.useCallback)(() => {
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, import_react35.useLayoutEffect)(() => {
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, import_react35.useEffect)(
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, import_react35.useCallback)(
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, import_react35.useCallback)(
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
- externalUserEmail: depositConfig.externalUserEmail,
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, import_react41.forwardRef)((_, ref) => {
76219
+ var UnifoldBridge = (0, import_react42.forwardRef)((_, ref) => {
75453
76220
  const { beginDeposit, closeDeposit, beginWithdraw, closeWithdraw } = useUnifold2();
75454
- (0, import_react41.useImperativeHandle)(ref, () => ({ beginDeposit, closeDeposit, beginWithdraw, closeWithdraw }), [
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 import_react41.Component {
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
- import_react41.default.createElement(
76302
+ import_react42.default.createElement(
75536
76303
  RenderErrorBoundary,
75537
76304
  { onError: handleRenderError },
75538
- import_react41.default.createElement(
76305
+ import_react42.default.createElement(
75539
76306
  UnifoldProvider2,
75540
76307
  { publishableKey, config },
75541
- import_react41.default.createElement(UnifoldBridge, { ref: refCallback })
76308
+ import_react42.default.createElement(UnifoldBridge, { ref: refCallback })
75542
76309
  )
75543
76310
  )
75544
76311
  );