@unifold/ui-web 0.1.68-beta.1 → 0.1.68-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -34407,7 +34407,7 @@ __export(index_exports, {
34407
34407
  module.exports = __toCommonJS(index_exports);
34408
34408
 
34409
34409
  // src/unifold.tsx
34410
- var import_react41 = __toESM(require_react());
34410
+ var import_react42 = __toESM(require_react());
34411
34411
  var import_client = __toESM(require_client());
34412
34412
 
34413
34413
  // ../connect-react/dist/index.mjs
@@ -37133,15 +37133,16 @@ var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
37133
37133
  var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
37134
37134
  var React522 = __toESM(require_react(), 1);
37135
37135
  var import_react15 = __toESM(require_react(), 1);
37136
- var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
37137
37136
  var import_react16 = __toESM(require_react(), 1);
37138
- var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
37137
+ var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
37139
37138
  var import_react17 = __toESM(require_react(), 1);
37139
+ var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
37140
37140
  var import_react18 = __toESM(require_react(), 1);
37141
- var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
37142
37141
  var import_react19 = __toESM(require_react(), 1);
37143
- var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
37142
+ var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
37144
37143
  var import_react20 = __toESM(require_react(), 1);
37144
+ var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
37145
+ var import_react21 = __toESM(require_react(), 1);
37145
37146
  var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
37146
37147
  var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
37147
37148
  var React622 = __toESM(require_react(), 1);
@@ -37194,29 +37195,29 @@ var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
37194
37195
  var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
37195
37196
  var React292 = __toESM(require_react(), 1);
37196
37197
  var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
37197
- var import_react21 = __toESM(require_react(), 1);
37198
- var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
37199
37198
  var import_react22 = __toESM(require_react(), 1);
37200
- var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
37199
+ var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
37201
37200
  var import_react23 = __toESM(require_react(), 1);
37202
- var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
37201
+ var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
37203
37202
  var import_react24 = __toESM(require_react(), 1);
37203
+ var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
37204
37204
  var import_react25 = __toESM(require_react(), 1);
37205
+ var import_react26 = __toESM(require_react(), 1);
37205
37206
  var React312 = __toESM(require_react(), 1);
37206
37207
  var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
37207
37208
  var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
37208
37209
  var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
37209
- var import_react26 = __toESM(require_react(), 1);
37210
- var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
37211
37210
  var import_react27 = __toESM(require_react(), 1);
37211
+ var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
37212
+ var import_react28 = __toESM(require_react(), 1);
37212
37213
  var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
37213
37214
  var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
37214
- var import_react28 = __toESM(require_react(), 1);
37215
+ var import_react29 = __toESM(require_react(), 1);
37215
37216
  var React322 = __toESM(require_react(), 1);
37216
37217
  var React31 = __toESM(require_react(), 1);
37217
37218
  var React29 = __toESM(require_react(), 1);
37218
37219
  var React26 = __toESM(require_react(), 1);
37219
- var import_react29 = __toESM(require_react(), 1);
37220
+ var import_react30 = __toESM(require_react(), 1);
37220
37221
  var ReactDOM3 = __toESM(require_react_dom(), 1);
37221
37222
  var React27 = __toESM(require_react(), 1);
37222
37223
  var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
@@ -37228,13 +37229,13 @@ var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
37228
37229
  var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
37229
37230
  var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
37230
37231
  var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
37231
- var import_react30 = __toESM(require_react(), 1);
37232
+ var import_react31 = __toESM(require_react(), 1);
37232
37233
  var React332 = __toESM(require_react(), 1);
37233
37234
  var React35 = __toESM(require_react(), 1);
37234
37235
  var ReactDOM4 = __toESM(require_react_dom(), 1);
37235
- var import_react31 = __toESM(require_react(), 1);
37236
- var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
37237
37236
  var import_react32 = __toESM(require_react(), 1);
37237
+ var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
37238
+ var import_react33 = __toESM(require_react(), 1);
37238
37239
  var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
37239
37240
  var React33 = __toESM(require_react(), 1);
37240
37241
  var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
@@ -37247,23 +37248,23 @@ var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1);
37247
37248
  var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
37248
37249
  var import_jsx_runtime78 = __toESM(require_jsx_runtime(), 1);
37249
37250
  var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1);
37250
- var import_react33 = __toESM(require_react(), 1);
37251
+ var import_react34 = __toESM(require_react(), 1);
37251
37252
  var import_jsx_runtime80 = __toESM(require_jsx_runtime(), 1);
37252
37253
  var import_jsx_runtime81 = __toESM(require_jsx_runtime(), 1);
37253
37254
  var import_jsx_runtime82 = __toESM(require_jsx_runtime(), 1);
37254
- var import_react34 = __toESM(require_react(), 1);
37255
- var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1);
37256
37255
  var import_react35 = __toESM(require_react(), 1);
37256
+ var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1);
37257
37257
  var import_react36 = __toESM(require_react(), 1);
37258
- var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1);
37259
37258
  var import_react37 = __toESM(require_react(), 1);
37259
+ var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1);
37260
37260
  var import_react38 = __toESM(require_react(), 1);
37261
+ var import_react39 = __toESM(require_react(), 1);
37261
37262
  var import_jsx_runtime85 = __toESM(require_jsx_runtime(), 1);
37262
37263
  var import_jsx_runtime86 = __toESM(require_jsx_runtime(), 1);
37263
- var import_react39 = __toESM(require_react(), 1);
37264
+ var import_react40 = __toESM(require_react(), 1);
37264
37265
  var import_jsx_runtime87 = __toESM(require_jsx_runtime(), 1);
37265
37266
  var import_jsx_runtime88 = __toESM(require_jsx_runtime(), 1);
37266
- var import_react40 = __toESM(require_react(), 1);
37267
+ var import_react41 = __toESM(require_react(), 1);
37267
37268
  var import_jsx_runtime89 = __toESM(require_jsx_runtime(), 1);
37268
37269
  var import_jsx_runtime90 = __toESM(require_jsx_runtime(), 1);
37269
37270
  var __create2 = Object.create;
@@ -44541,6 +44542,59 @@ async function exchangeOnrampVerificationToken(id, clientSecret, publishableKey)
44541
44542
  "Failed to exchange verification token"
44542
44543
  );
44543
44544
  }
44545
+ function isApplePayLimitReached(response) {
44546
+ return response.limits.some((l) => l.remaining === "0");
44547
+ }
44548
+ function getApplePayLimitUpgradeStatus(response) {
44549
+ const opt = response.limit_upgrade_options?.[0];
44550
+ if (!opt || typeof opt.status !== "string") return null;
44551
+ return opt.status;
44552
+ }
44553
+ async function getCoinbaseApplePayLimits(phone, publishableKey, signal) {
44554
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
44555
+ validatePublishableKey(pk);
44556
+ const response = await fetch(
44557
+ `${API_BASE_URL}/v1/public/onramps/headless/coinbase/apple_pay/limits`,
44558
+ {
44559
+ method: "POST",
44560
+ headers: {
44561
+ accept: "application/json",
44562
+ "x-publishable-key": pk,
44563
+ "Content-Type": "application/json"
44564
+ },
44565
+ body: JSON.stringify({ phone }),
44566
+ signal
44567
+ }
44568
+ );
44569
+ const raw = await jsonOrThrow(response, "Failed to fetch Apple Pay limits");
44570
+ return {
44571
+ limits: raw.limits,
44572
+ limit_upgrade_options: raw.limit_upgrade_options,
44573
+ limit_reached: isApplePayLimitReached(raw),
44574
+ upgrade_status: getApplePayLimitUpgradeStatus(raw)
44575
+ };
44576
+ }
44577
+ async function requestCoinbaseApplePayLimitUpgrade(request, publishableKey, signal) {
44578
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
44579
+ validatePublishableKey(pk);
44580
+ const response = await fetch(
44581
+ `${API_BASE_URL}/v1/public/onramps/headless/coinbase/apple_pay/limits/upgrade`,
44582
+ {
44583
+ method: "POST",
44584
+ headers: {
44585
+ accept: "application/json",
44586
+ "x-publishable-key": pk,
44587
+ "Content-Type": "application/json"
44588
+ },
44589
+ body: JSON.stringify(request),
44590
+ signal
44591
+ }
44592
+ );
44593
+ return jsonOrThrow(
44594
+ response,
44595
+ "Failed to request Apple Pay limit upgrade"
44596
+ );
44597
+ }
44544
44598
  async function createCoinbaseApplePaySession(request, onrampToken, publishableKey, signal) {
44545
44599
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
44546
44600
  validatePublishableKey(pk);
@@ -48361,7 +48415,7 @@ var computePosition2 = (reference, floating, options2) => {
48361
48415
  var isClient = typeof document !== "undefined";
48362
48416
  var noop2 = function noop22() {
48363
48417
  };
48364
- var index = isClient ? import_react29.useLayoutEffect : noop2;
48418
+ var index = isClient ? import_react30.useLayoutEffect : noop2;
48365
48419
  function deepEqual(a, b) {
48366
48420
  if (a === b) {
48367
48421
  return true;
@@ -49470,14 +49524,14 @@ function createCollection(name) {
49470
49524
  );
49471
49525
  const CollectionProvider = (props) => {
49472
49526
  const { scope, children } = props;
49473
- const ref = import_react31.default.useRef(null);
49474
- const itemMap = import_react31.default.useRef(/* @__PURE__ */ new Map()).current;
49527
+ const ref = import_react32.default.useRef(null);
49528
+ const itemMap = import_react32.default.useRef(/* @__PURE__ */ new Map()).current;
49475
49529
  return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
49476
49530
  };
49477
49531
  CollectionProvider.displayName = PROVIDER_NAME2;
49478
49532
  const COLLECTION_SLOT_NAME = name + "CollectionSlot";
49479
49533
  const CollectionSlotImpl = /* @__PURE__ */ createSlot(COLLECTION_SLOT_NAME);
49480
- const CollectionSlot = import_react31.default.forwardRef(
49534
+ const CollectionSlot = import_react32.default.forwardRef(
49481
49535
  (props, forwardedRef) => {
49482
49536
  const { scope, children } = props;
49483
49537
  const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
@@ -49489,13 +49543,13 @@ function createCollection(name) {
49489
49543
  const ITEM_SLOT_NAME = name + "CollectionItemSlot";
49490
49544
  const ITEM_DATA_ATTR = "data-radix-collection-item";
49491
49545
  const CollectionItemSlotImpl = /* @__PURE__ */ createSlot(ITEM_SLOT_NAME);
49492
- const CollectionItemSlot = import_react31.default.forwardRef(
49546
+ const CollectionItemSlot = import_react32.default.forwardRef(
49493
49547
  (props, forwardedRef) => {
49494
49548
  const { scope, children, ...itemData } = props;
49495
- const ref = import_react31.default.useRef(null);
49549
+ const ref = import_react32.default.useRef(null);
49496
49550
  const composedRefs = useComposedRefs(forwardedRef, ref);
49497
49551
  const context = useCollectionContext(ITEM_SLOT_NAME, scope);
49498
- import_react31.default.useEffect(() => {
49552
+ import_react32.default.useEffect(() => {
49499
49553
  context.itemMap.set(ref, { ref, ...itemData });
49500
49554
  return () => void context.itemMap.delete(ref);
49501
49555
  });
@@ -49505,7 +49559,7 @@ function createCollection(name) {
49505
49559
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
49506
49560
  function useCollection2(scope) {
49507
49561
  const context = useCollectionContext(name + "CollectionConsumer", scope);
49508
- const getItems = import_react31.default.useCallback(() => {
49562
+ const getItems = import_react32.default.useCallback(() => {
49509
49563
  const collectionNode = context.collectionRef.current;
49510
49564
  if (!collectionNode) return [];
49511
49565
  const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
@@ -52056,7 +52110,7 @@ var en_default2 = {
52056
52110
  payWithStripeLink: {
52057
52111
  success: {
52058
52112
  processingTitle: "Payment confirmed",
52059
- processingSubtitle: "We\u2019ve received your payment and are preparing your purchase. This will only take a moment.",
52113
+ processingSubtitle: "We\u2019ve received your payment and are sending your purchase to your wallet. This usually takes just a few minutes.",
52060
52114
  completeTitle: "Your purchase is on the way",
52061
52115
  completeSubtitle: "Your purchase is complete and is being sent to your wallet.",
52062
52116
  failedTitle: "Purchase didn\u2019t go through",
@@ -54040,20 +54094,6 @@ function BuyWithCard({
54040
54094
  }
54041
54095
  );
54042
54096
  }
54043
- function useProjectConfig({
54044
- publishableKey,
54045
- enabled = true
54046
- }) {
54047
- const { data: projectConfig, isLoading } = useQuery({
54048
- queryKey: ["unifold", "projectConfig", publishableKey],
54049
- queryFn: () => getProjectConfig(publishableKey),
54050
- enabled,
54051
- staleTime: 1e3 * 60 * 30,
54052
- refetchOnMount: true,
54053
- refetchOnWindowFocus: true
54054
- });
54055
- return { projectConfig, isLoading };
54056
- }
54057
54097
  var STORAGE_KEY_PREFIX = "unifold:apple-pay:session";
54058
54098
  var PHONE_FRESH_MS = 55 * 24 * 60 * 60 * 1e3;
54059
54099
  function isBrowser() {
@@ -54101,47 +54141,200 @@ function useCoinbaseLegalAgreements({
54101
54141
  retry: 1
54102
54142
  });
54103
54143
  }
54104
- var COINBASE_PAY_ORIGIN = "https://pay.coinbase.com";
54105
- var DEFAULT_MIN_USD = 5;
54106
- var DEFAULT_MAX_USD = 500;
54107
- var DEFAULT_SUGGESTED = [25, 50, 100];
54144
+ var US_E164_REGEX = /^\+1\d{10}$/;
54145
+ function useApplePayLimits({
54146
+ phone,
54147
+ publishableKey,
54148
+ enabled = true
54149
+ }) {
54150
+ const phoneValid = US_E164_REGEX.test(phone);
54151
+ return useQuery({
54152
+ queryKey: ["unifold", "applePayLimits", phone, publishableKey],
54153
+ queryFn: ({ signal }) => getCoinbaseApplePayLimits(phone, publishableKey, signal),
54154
+ enabled: enabled && phoneValid && !!publishableKey,
54155
+ // Coinbase's caps don't change second-to-second; 30s is plenty fresh
54156
+ // for the "user opened the modal, edited their phone, opened it
54157
+ // again" usage pattern, while keeping us off their API on rapid
54158
+ // tap-throughs.
54159
+ staleTime: 3e4,
54160
+ gcTime: 5 * 6e4,
54161
+ refetchOnWindowFocus: false,
54162
+ retry: false
54163
+ });
54164
+ }
54108
54165
  var PHONE_REGEX = /^\+1\d{10}$/;
54109
54166
  var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
54110
- function formatPhoneInput(raw) {
54111
- const digits = raw.replace(/\D/g, "");
54112
- if (raw.startsWith("+")) {
54113
- return `+${digits}`;
54167
+ function getViewForLimitStatus(limits) {
54168
+ if (!limits.limit_reached) return void 0;
54169
+ switch (limits.upgrade_status) {
54170
+ case "unrequested":
54171
+ return "limit_upgrade_intro";
54172
+ case "resubmit":
54173
+ return "limit_upgrade_form";
54174
+ case "pending":
54175
+ return "limit_upgrade_submitting";
54176
+ case "active":
54177
+ return void 0;
54178
+ default:
54179
+ return "guest_limit_reached";
54114
54180
  }
54115
- if (digits.length === 10) return `+1${digits}`;
54116
- if (digits.length === 11 && digits.startsWith("1")) return `+${digits}`;
54117
- return digits.length > 0 ? `+${digits}` : "";
54118
54181
  }
54119
- function maskEmail(email) {
54120
- const [local, domain] = email.split("@");
54121
- if (!local || !domain) return email;
54122
- const visible = local.slice(0, Math.min(2, local.length));
54123
- return `${visible}${"*".repeat(Math.max(local.length - visible.length, 1))}@${domain}`;
54182
+ function useApplePayInitialScreen({
54183
+ userId,
54184
+ publishableKey,
54185
+ normalizedPhone,
54186
+ userEmail,
54187
+ sessionPhoneVerified,
54188
+ isWaiting
54189
+ }) {
54190
+ const initialStoredSession = (0, import_react16.useMemo)(() => getStoredApplePaySession(userId), [userId]);
54191
+ const phoneVerified = PHONE_REGEX.test(normalizedPhone) && (sessionPhoneVerified || initialStoredSession?.phone === normalizedPhone && !!initialStoredSession?.phoneVerifiedAt);
54192
+ const {
54193
+ data: applePayLimits,
54194
+ isLoading: applePayLimitsLoading,
54195
+ refetch: refetchApplePayLimits
54196
+ } = useApplePayLimits({
54197
+ phone: normalizedPhone,
54198
+ publishableKey,
54199
+ enabled: phoneVerified
54200
+ });
54201
+ const action = (0, import_react16.useMemo)(() => {
54202
+ if (isWaiting || applePayLimitsLoading) return { kind: "pending" };
54203
+ const stored = initialStoredSession;
54204
+ const hasUserEmail = !!userEmail && EMAIL_REGEX.test(userEmail);
54205
+ if (!stored) {
54206
+ return { kind: "navigate", view: hasUserEmail ? "phone_input" : "email_input" };
54207
+ }
54208
+ if (hasUserEmail && stored.email.toLowerCase() !== userEmail.toLowerCase()) {
54209
+ return { kind: "navigate", view: "phone_input" };
54210
+ }
54211
+ if (applePayLimits) {
54212
+ const limitView = getViewForLimitStatus(applePayLimits);
54213
+ if (limitView) {
54214
+ return { kind: "limit_upgrade", view: limitView, status: applePayLimits.upgrade_status };
54215
+ }
54216
+ }
54217
+ if (isOnrampTokenFresh(stored) && stored.onrampToken && stored.onrampTokenExpiresAtMs) {
54218
+ return {
54219
+ kind: "resume_with_token",
54220
+ token: {
54221
+ token: stored.onrampToken,
54222
+ token_type: "Bearer",
54223
+ expires_in: Math.max(0, Math.floor((stored.onrampTokenExpiresAtMs - Date.now()) / 1e3))
54224
+ }
54225
+ };
54226
+ }
54227
+ return { kind: "resume_send_sms" };
54228
+ }, [isWaiting, applePayLimitsLoading, initialStoredSession, userEmail, applePayLimits]);
54229
+ return {
54230
+ action,
54231
+ applePayLimits,
54232
+ applePayLimitsLoading,
54233
+ refetchApplePayLimits,
54234
+ phoneVerified
54235
+ };
54124
54236
  }
54125
- function maskPhone(phone) {
54126
- if (!/^\+1\d{10}$/.test(phone)) return phone;
54127
- return `+1 (***) ***-${phone.slice(-4)}`;
54237
+ function useDefaultOnrampToken({
54238
+ publishableKey,
54239
+ tokenAddress,
54240
+ chainId,
54241
+ chainType,
54242
+ countryCode,
54243
+ subdivisionCode,
54244
+ enabled = true
54245
+ }) {
54246
+ const {
54247
+ data: defaultToken,
54248
+ isLoading,
54249
+ isError,
54250
+ error
54251
+ } = useQuery({
54252
+ queryKey: [
54253
+ "unifold",
54254
+ "defaultOnrampToken",
54255
+ publishableKey,
54256
+ tokenAddress,
54257
+ chainId,
54258
+ chainType,
54259
+ countryCode,
54260
+ subdivisionCode
54261
+ ],
54262
+ queryFn: () => getDefaultOnrampToken(
54263
+ {
54264
+ token_address: tokenAddress,
54265
+ chain_id: chainId,
54266
+ chain_type: chainType,
54267
+ country_code: countryCode,
54268
+ subdivision_code: subdivisionCode
54269
+ },
54270
+ publishableKey
54271
+ ),
54272
+ enabled: enabled && !!tokenAddress && !!chainId && !!chainType,
54273
+ staleTime: 1e3 * 60 * 60,
54274
+ refetchOnMount: false,
54275
+ refetchOnWindowFocus: false
54276
+ });
54277
+ return { defaultToken, isLoading, isError, error: error ?? null };
54278
+ }
54279
+ var COINBASE_PAY_ORIGIN = "https://pay.coinbase.com";
54280
+ var COINBASE_ALLOWED_POSTMESSAGE_ORIGINS = /* @__PURE__ */ new Set([
54281
+ COINBASE_PAY_ORIGIN,
54282
+ "https://www.coinbase.com"
54283
+ ]);
54284
+ var UNIFOLD_SUPPORT_URL = "https://unifold.io/support";
54285
+ var DEFAULT_MIN_USD = 5;
54286
+ var DEFAULT_MAX_USD = 500;
54287
+ var DEFAULT_SUGGESTED = [25, 50, 100];
54288
+ var PHONE_REGEX2 = /^\+1\d{10}$/;
54289
+ var EMAIL_REGEX2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
54290
+ function parseCoinbasePostMessage(raw) {
54291
+ const parseString = (s) => {
54292
+ try {
54293
+ return JSON.parse(s);
54294
+ } catch {
54295
+ return null;
54296
+ }
54297
+ };
54298
+ const asObject = (value) => value && typeof value === "object" ? value : null;
54299
+ let candidate = raw;
54300
+ if (typeof candidate === "string") {
54301
+ candidate = parseString(candidate);
54302
+ }
54303
+ const obj = asObject(candidate);
54304
+ if (!obj) return null;
54305
+ const nestedData = obj.data;
54306
+ let eventName = typeof obj.eventName === "string" && obj.eventName || typeof obj.event_name === "string" && obj.event_name || typeof obj.type === "string" && obj.type || null;
54307
+ let dataObj = asObject(nestedData);
54308
+ if (!eventName && typeof nestedData === "string") {
54309
+ const nestedParsed = parseString(nestedData);
54310
+ const nestedObj = asObject(nestedParsed);
54311
+ if (nestedObj) {
54312
+ eventName = typeof nestedObj.eventName === "string" && nestedObj.eventName || typeof nestedObj.event_name === "string" && nestedObj.event_name || typeof nestedObj.type === "string" && nestedObj.type || null;
54313
+ dataObj = asObject(nestedObj.data);
54314
+ }
54315
+ }
54316
+ if (!eventName || !/^onramp_api\./i.test(eventName)) return null;
54317
+ return {
54318
+ eventName,
54319
+ data: dataObj ? {
54320
+ errorCode: typeof dataObj.errorCode === "string" ? dataObj.errorCode : typeof dataObj.error_code === "string" ? dataObj.error_code : void 0,
54321
+ errorMessage: typeof dataObj.errorMessage === "string" ? dataObj.errorMessage : typeof dataObj.error_message === "string" ? dataObj.error_message : void 0
54322
+ } : void 0
54323
+ };
54128
54324
  }
54129
54325
  var BuyWithApplePay = React522.forwardRef(
54130
54326
  function BuyWithApplePay2({
54131
54327
  userId,
54132
54328
  publishableKey,
54133
- recipientAddress,
54134
54329
  destinationChainType,
54135
54330
  destinationChainId,
54136
54331
  destinationTokenAddress,
54137
- destinationTokenSymbol = "USDC",
54138
- externalUserEmail,
54139
- enableApplePay,
54332
+ userEmail,
54140
54333
  amountUsd,
54141
54334
  minAmountUsd = DEFAULT_MIN_USD,
54142
54335
  maxAmountUsd = DEFAULT_MAX_USD,
54143
54336
  suggestedAmountsUsd = DEFAULT_SUGGESTED,
54144
- wallets: externalWallets,
54337
+ wallets: depositWallets,
54145
54338
  onDepositSuccess,
54146
54339
  onDepositError,
54147
54340
  onEvent,
@@ -54150,48 +54343,61 @@ var BuyWithApplePay = React522.forwardRef(
54150
54343
  onExit
54151
54344
  }, ref) {
54152
54345
  const { colors: colors2, fonts, components } = useTheme();
54153
- const { projectConfig, isLoading: configLoading } = useProjectConfig({ publishableKey });
54154
- const applePayEnabled = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
54155
54346
  const [view, setView] = (0, import_react15.useState)("loading_config");
54156
54347
  const [errorMessage, setErrorMessage] = (0, import_react15.useState)("");
54157
- const [email, setEmail] = (0, import_react15.useState)(externalUserEmail ?? "");
54158
- const [phoneInput, setPhoneInput] = (0, import_react15.useState)("");
54159
- const [, setTosAccepted] = (0, import_react15.useState)(false);
54348
+ const [email, setEmail] = (0, import_react15.useState)(() => {
54349
+ if (userEmail && EMAIL_REGEX2.test(userEmail)) return userEmail;
54350
+ return getStoredApplePaySession(userId)?.email ?? "";
54351
+ });
54352
+ const [phoneInput, setPhoneInput] = (0, import_react15.useState)(() => {
54353
+ const stored = getStoredApplePaySession(userId);
54354
+ if (!stored) return "";
54355
+ if (userEmail && EMAIL_REGEX2.test(userEmail) && stored.email.toLowerCase() !== userEmail.toLowerCase()) {
54356
+ return "";
54357
+ }
54358
+ return stored.phone;
54359
+ });
54160
54360
  const { data: legalAgreementsData, isLoading: legalAgreementsLoading } = useCoinbaseLegalAgreements({
54161
- publishableKey,
54162
- enabled: applePayEnabled
54361
+ publishableKey
54163
54362
  });
54164
54363
  const legalAgreements = legalAgreementsData ?? null;
54165
54364
  const [verificationSession, setVerificationSession] = (0, import_react15.useState)(null);
54166
54365
  const [clientSecret, setClientSecret] = (0, import_react15.useState)(null);
54167
- const [emailCode, setEmailCode] = (0, import_react15.useState)("");
54168
54366
  const [phoneCode, setPhoneCode] = (0, import_react15.useState)("");
54169
54367
  const [otpError, setOtpError] = (0, import_react15.useState)(null);
54170
54368
  const [otpSubmitting, setOtpSubmitting] = (0, import_react15.useState)(false);
54171
54369
  const [resendCooldown, setResendCooldown] = (0, import_react15.useState)(0);
54370
+ const [dobInput, setDobInput] = (0, import_react15.useState)("");
54371
+ const [ssnLast4, setSsnLast4] = (0, import_react15.useState)("");
54372
+ const [limitUpgradeError, setLimitUpgradeError] = (0, import_react15.useState)(null);
54373
+ const [upgradeSubmitting, setUpgradeSubmitting] = (0, import_react15.useState)(false);
54374
+ const upgradeFlowAbortRef = (0, import_react15.useRef)(null);
54172
54375
  const [amount, setAmount] = (0, import_react15.useState)(amountUsd ?? "");
54173
54376
  const [paymentSession, setPaymentSession] = (0, import_react15.useState)(
54174
54377
  null
54175
54378
  );
54176
54379
  const [paymentSessionAmount, setPaymentSessionAmount] = (0, import_react15.useState)(null);
54177
- const [preparingSession, setPreparingSession] = (0, import_react15.useState)(false);
54178
54380
  const popupRef = (0, import_react15.useRef)(null);
54179
54381
  const sessionAbortRef = (0, import_react15.useRef)(null);
54180
54382
  const [onrampToken, setOnrampToken] = (0, import_react15.useState)(null);
54181
- const { data: depositAddressResponse } = useDepositAddress({
54182
- userId,
54383
+ const { userIpInfo, isLoading: userIpInfoLoading } = useUserIp2();
54384
+ const {
54385
+ defaultToken,
54386
+ isLoading: defaultTokenLoading,
54387
+ isError: defaultTokenError
54388
+ } = useDefaultOnrampToken({
54183
54389
  publishableKey,
54184
- recipientAddress,
54185
- destinationChainType,
54186
- destinationChainId,
54187
- destinationTokenAddress,
54188
- enabled: !externalWallets?.length
54390
+ tokenAddress: destinationTokenAddress,
54391
+ chainId: destinationChainId,
54392
+ chainType: destinationChainType,
54393
+ countryCode: userIpInfo?.alpha2,
54394
+ subdivisionCode: userIpInfo?.subdivisionCode ?? void 0
54189
54395
  });
54190
- const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
54191
54396
  const depositWallet = (0, import_react15.useMemo)(() => {
54192
- if (!destinationChainType) return void 0;
54193
- return getWalletByChainType(wallets, destinationChainType);
54194
- }, [wallets, destinationChainType]);
54397
+ const routingChainType = defaultToken?.destination_token_metadata?.chain_type;
54398
+ if (!routingChainType) return void 0;
54399
+ return getWalletByChainType(depositWallets ?? [], routingChainType);
54400
+ }, [depositWallets, defaultToken]);
54195
54401
  const depositWalletId = depositWallet?.id;
54196
54402
  const { executions } = useDepositPolling({
54197
54403
  userId,
@@ -54215,49 +54421,10 @@ var BuyWithApplePay = React522.forwardRef(
54215
54421
  onDepositError(error);
54216
54422
  } : void 0
54217
54423
  });
54218
- const [emailLocked, setEmailLocked] = (0, import_react15.useState)(false);
54219
- (0, import_react15.useEffect)(() => {
54220
- if (configLoading) return;
54221
- if (!applePayEnabled) {
54222
- setView("disabled");
54223
- return;
54224
- }
54225
- setTosAccepted(true);
54226
- const applyStoredOnrampToken = (stored2) => {
54227
- if (!isOnrampTokenFresh(stored2) || !stored2.onrampToken || !stored2.onrampTokenExpiresAtMs) {
54228
- return false;
54229
- }
54230
- setOnrampToken({
54231
- token: stored2.onrampToken,
54232
- token_type: "Bearer",
54233
- expires_in: Math.max(0, Math.floor((stored2.onrampTokenExpiresAtMs - Date.now()) / 1e3))
54234
- });
54235
- setView("amount");
54236
- return true;
54237
- };
54238
- if (externalUserEmail && EMAIL_REGEX.test(externalUserEmail)) {
54239
- setEmail(externalUserEmail);
54240
- setEmailLocked(true);
54241
- const stored2 = getStoredApplePaySession(userId);
54242
- if (stored2?.email?.toLowerCase() === externalUserEmail.toLowerCase()) {
54243
- setPhoneInput(stored2.phone);
54244
- if (applyStoredOnrampToken(stored2)) return;
54245
- }
54246
- setView("phone_input");
54247
- return;
54248
- }
54249
- const stored = getStoredApplePaySession(userId);
54250
- if (stored) {
54251
- setEmail(stored.email);
54252
- setPhoneInput(stored.phone);
54253
- setEmailLocked(true);
54254
- if (applyStoredOnrampToken(stored)) return;
54255
- setView("phone_input");
54256
- return;
54257
- }
54258
- setEmailLocked(false);
54259
- setView("email_input");
54260
- }, [configLoading, applePayEnabled, externalUserEmail, userId]);
54424
+ const [emailLocked, setEmailLocked] = (0, import_react15.useState)(() => {
54425
+ if (userEmail && EMAIL_REGEX2.test(userEmail)) return true;
54426
+ return !!getStoredApplePaySession(userId);
54427
+ });
54261
54428
  (0, import_react15.useEffect)(() => {
54262
54429
  if (resendCooldown <= 0) return;
54263
54430
  const t13 = setInterval(() => setResendCooldown((c) => Math.max(0, c - 1)), 1e3);
@@ -54266,19 +54433,10 @@ var BuyWithApplePay = React522.forwardRef(
54266
54433
  (0, import_react15.useEffect)(() => {
54267
54434
  if (view !== "checking_deposit") return;
54268
54435
  const onMessage = (event) => {
54269
- if (event.origin !== COINBASE_PAY_ORIGIN) return;
54270
- let parsed = null;
54271
- const data = event.data;
54272
- if (typeof data === "string") {
54273
- try {
54274
- parsed = JSON.parse(data);
54275
- } catch {
54276
- return;
54277
- }
54278
- } else if (data && typeof data === "object" && "eventName" in data) {
54279
- parsed = data;
54280
- }
54436
+ if (!COINBASE_ALLOWED_POSTMESSAGE_ORIGINS.has(event.origin)) return;
54437
+ const parsed = parseCoinbasePostMessage(event.data);
54281
54438
  if (!parsed) return;
54439
+ const eventName = parsed.eventName.toLowerCase();
54282
54440
  const code = parsed.data?.errorCode;
54283
54441
  const closePopup = () => {
54284
54442
  try {
@@ -54287,16 +54445,20 @@ var BuyWithApplePay = React522.forwardRef(
54287
54445
  }
54288
54446
  popupRef.current = null;
54289
54447
  };
54290
- switch (parsed.eventName) {
54448
+ switch (eventName) {
54291
54449
  case "onramp_api.commit_success":
54292
54450
  case "onramp_api.polling_success":
54451
+ case "onramp_api.cancel":
54293
54452
  closePopup();
54294
54453
  break;
54295
54454
  case "onramp_api.commit_error":
54455
+ case "onramp_api.polling_failed":
54296
54456
  if (code === "ERROR_CODE_GUEST_TRANSACTION_COUNT" || code === "ERROR_CODE_GUEST_DAILY_TRANSACTION_COUNT" || code === "ERROR_CODE_GUEST_TRANSACTION_LIMIT") {
54297
54457
  closePopup();
54298
54458
  setView("guest_limit_reached");
54459
+ return;
54299
54460
  }
54461
+ closePopup();
54300
54462
  break;
54301
54463
  default:
54302
54464
  break;
@@ -54308,17 +54470,17 @@ var BuyWithApplePay = React522.forwardRef(
54308
54470
  (0, import_react15.useEffect)(() => {
54309
54471
  onViewChange?.(view);
54310
54472
  }, [view, onViewChange]);
54311
- (0, import_react15.useEffect)(
54312
- () => () => {
54473
+ (0, import_react15.useEffect)(() => {
54474
+ return () => {
54313
54475
  sessionAbortRef.current?.abort();
54476
+ upgradeFlowAbortRef.current?.abort();
54314
54477
  try {
54315
54478
  popupRef.current?.close();
54316
54479
  } catch {
54317
54480
  }
54318
54481
  popupRef.current = null;
54319
- },
54320
- []
54321
- );
54482
+ };
54483
+ }, []);
54322
54484
  React522.useImperativeHandle(
54323
54485
  ref,
54324
54486
  () => ({
@@ -54328,14 +54490,20 @@ var BuyWithApplePay = React522.forwardRef(
54328
54490
  setView("email_input");
54329
54491
  return true;
54330
54492
  }
54331
- if (view === "email_otp") {
54332
- setView("phone_input");
54333
- setEmailCode("");
54334
- return true;
54335
- }
54336
54493
  if (view === "phone_otp") {
54337
54494
  setView("phone_input");
54338
54495
  setPhoneCode("");
54496
+ setOtpSubmitting(false);
54497
+ return true;
54498
+ }
54499
+ if (view === "limit_upgrade_intro" || view === "limit_upgrade_failed") {
54500
+ return false;
54501
+ }
54502
+ if (view === "limit_upgrade_form") {
54503
+ setView("limit_upgrade_intro");
54504
+ return true;
54505
+ }
54506
+ if (view === "limit_upgrade_submitting") {
54339
54507
  return true;
54340
54508
  }
54341
54509
  if (view === "checking_deposit") {
@@ -54356,21 +54524,20 @@ var BuyWithApplePay = React522.forwardRef(
54356
54524
  [view, emailLocked]
54357
54525
  );
54358
54526
  const normalizedPhone = (0, import_react15.useMemo)(() => formatPhoneInput(phoneInput), [phoneInput]);
54359
- const isContactValid = EMAIL_REGEX.test(email) && PHONE_REGEX.test(normalizedPhone);
54360
- const persistContact = (0, import_react15.useCallback)(
54527
+ const isContactValid = EMAIL_REGEX2.test(email) && PHONE_REGEX2.test(normalizedPhone);
54528
+ const storeApplePaySession = (0, import_react15.useCallback)(
54361
54529
  (patch = {}) => {
54362
- const base = {
54530
+ const session = {
54363
54531
  email,
54364
54532
  phone: normalizedPhone,
54365
54533
  termsAcceptedAt: (/* @__PURE__ */ new Date()).toISOString(),
54366
54534
  ...patch
54367
54535
  };
54368
- setStoredApplePaySession(userId, base);
54536
+ setStoredApplePaySession(userId, session);
54369
54537
  },
54370
54538
  [email, normalizedPhone, userId]
54371
54539
  );
54372
- const startVerification = (0, import_react15.useCallback)(async () => {
54373
- if (!isContactValid) return;
54540
+ const createSessionAndSendOtp = (0, import_react15.useCallback)(async () => {
54374
54541
  setView("submitting_session");
54375
54542
  setErrorMessage("");
54376
54543
  try {
@@ -54388,71 +54555,192 @@ var BuyWithApplePay = React522.forwardRef(
54388
54555
  throw new Error("Server did not return a client_secret");
54389
54556
  }
54390
54557
  setClientSecret(session.client_secret);
54391
- persistContact();
54392
- if (session.email.status === "verified") {
54393
- await sendOnrampVerificationOtp(
54394
- session.id,
54395
- "phone",
54396
- session.client_secret,
54397
- publishableKey
54398
- );
54399
- setResendCooldown(30);
54400
- setView("phone_otp");
54401
- } else {
54402
- await sendOnrampVerificationOtp(
54403
- session.id,
54404
- "email",
54405
- session.client_secret,
54406
- publishableKey
54407
- );
54408
- setResendCooldown(30);
54409
- setView("email_otp");
54410
- }
54558
+ storeApplePaySession();
54559
+ await sendOnrampVerificationOtp(session.id, "phone", session.client_secret, publishableKey);
54560
+ setResendCooldown(30);
54561
+ setView("phone_otp");
54411
54562
  } catch (err) {
54412
54563
  const raw = err instanceof Error ? err.message : "Failed to start verification";
54413
54564
  setErrorMessage(prettifyVerificationError(raw));
54414
54565
  setView("phone_input");
54415
54566
  }
54416
- }, [isContactValid, email, normalizedPhone, publishableKey, persistContact]);
54417
- const submitEmailOtp = (0, import_react15.useCallback)(async () => {
54418
- if (!verificationSession || !clientSecret || emailCode.length !== 6) return;
54419
- if (otpSubmitting) return;
54420
- setOtpError(null);
54421
- setOtpSubmitting(true);
54567
+ }, [email, normalizedPhone, publishableKey, storeApplePaySession]);
54568
+ const clearUpgradeFields = (0, import_react15.useCallback)(() => {
54569
+ setSsnLast4("");
54570
+ setDobInput("");
54571
+ }, []);
54572
+ const { action: initialAction, refetchApplePayLimits } = useApplePayInitialScreen({
54573
+ userId,
54574
+ publishableKey,
54575
+ normalizedPhone,
54576
+ userEmail,
54577
+ sessionPhoneVerified: verificationSession?.phone?.status === "verified",
54578
+ isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
54579
+ });
54580
+ const pollLimitUpgradeStatus = (0, import_react15.useCallback)(
54581
+ async (signal) => {
54582
+ const POLL_INTERVAL_MS4 = 1500;
54583
+ const POLL_TIMEOUT_MS = 3e4;
54584
+ const startedAt = Date.now();
54585
+ let firstIteration = true;
54586
+ while (Date.now() - startedAt < POLL_TIMEOUT_MS) {
54587
+ if (signal.aborted) return;
54588
+ if (!firstIteration) {
54589
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS4));
54590
+ }
54591
+ firstIteration = false;
54592
+ if (signal.aborted) return;
54593
+ let fresh;
54594
+ try {
54595
+ fresh = await getCoinbaseApplePayLimits(normalizedPhone, publishableKey, signal);
54596
+ } catch {
54597
+ if (signal.aborted) return;
54598
+ continue;
54599
+ }
54600
+ const { upgrade_status: status, limit_reached: stillCapped } = fresh;
54601
+ if (status === "active" || !stillCapped) {
54602
+ await refetchApplePayLimits();
54603
+ clearUpgradeFields();
54604
+ setLimitUpgradeError(null);
54605
+ if (onrampToken) {
54606
+ setView("amount");
54607
+ } else {
54608
+ if (signal.aborted) return;
54609
+ await createSessionAndSendOtp();
54610
+ }
54611
+ return;
54612
+ }
54613
+ if (status === "inactive") {
54614
+ await refetchApplePayLimits();
54615
+ clearUpgradeFields();
54616
+ setLimitUpgradeError(null);
54617
+ setView("guest_limit_reached");
54618
+ return;
54619
+ }
54620
+ if (status === "resubmit") {
54621
+ await refetchApplePayLimits();
54622
+ setSsnLast4("");
54623
+ setLimitUpgradeError(
54624
+ "We couldn't verify your information. Please check your SSN and date of birth and try again."
54625
+ );
54626
+ setView("limit_upgrade_form");
54627
+ return;
54628
+ }
54629
+ }
54630
+ setLimitUpgradeError(null);
54631
+ setView("limit_upgrade_failed");
54632
+ },
54633
+ [
54634
+ normalizedPhone,
54635
+ publishableKey,
54636
+ refetchApplePayLimits,
54637
+ onrampToken,
54638
+ createSessionAndSendOtp,
54639
+ clearUpgradeFields
54640
+ ]
54641
+ );
54642
+ const startUpgradePolling = (0, import_react15.useCallback)(async () => {
54643
+ upgradeFlowAbortRef.current?.abort();
54644
+ const controller = new AbortController();
54645
+ upgradeFlowAbortRef.current = controller;
54422
54646
  try {
54423
- const updated = await verifyOnrampVerificationOtp(
54424
- verificationSession.id,
54425
- "email",
54426
- clientSecret,
54427
- emailCode,
54428
- publishableKey
54429
- );
54430
- setVerificationSession(updated);
54431
- if (updated.email.status === "verified") {
54432
- persistContact({ emailVerifiedAt: updated.email.verified_at });
54433
- await sendOnrampVerificationOtp(updated.id, "phone", clientSecret, publishableKey);
54434
- setEmailCode("");
54435
- setResendCooldown(30);
54436
- setView("phone_otp");
54647
+ await pollLimitUpgradeStatus(controller.signal);
54648
+ } finally {
54649
+ if (upgradeFlowAbortRef.current === controller) {
54650
+ upgradeFlowAbortRef.current = null;
54651
+ }
54652
+ }
54653
+ }, [pollLimitUpgradeStatus]);
54654
+ const applyLimitRouting = (0, import_react15.useCallback)(
54655
+ (nextView, status) => {
54656
+ if (nextView === "limit_upgrade_form" && status === "resubmit") {
54657
+ setLimitUpgradeError(
54658
+ "We couldn't verify your information. Please check your SSN and date of birth and try again."
54659
+ );
54437
54660
  } else {
54438
- setOtpError("Incorrect code. Please try again.");
54439
- setEmailCode("");
54661
+ setLimitUpgradeError(null);
54440
54662
  }
54441
- } catch (err) {
54442
- setOtpError(
54443
- prettifyVerificationError(err instanceof Error ? err.message : "Verification failed")
54444
- );
54445
- setEmailCode("");
54663
+ setView(nextView);
54664
+ if (nextView === "limit_upgrade_submitting") {
54665
+ void startUpgradePolling();
54666
+ }
54667
+ },
54668
+ [startUpgradePolling]
54669
+ );
54670
+ const hasInitializedRef = (0, import_react15.useRef)(false);
54671
+ (0, import_react15.useEffect)(() => {
54672
+ if (hasInitializedRef.current) return;
54673
+ if (initialAction.kind === "pending") return;
54674
+ hasInitializedRef.current = true;
54675
+ switch (initialAction.kind) {
54676
+ case "navigate":
54677
+ setView(initialAction.view);
54678
+ break;
54679
+ case "limit_upgrade":
54680
+ applyLimitRouting(initialAction.view, initialAction.status);
54681
+ break;
54682
+ case "resume_with_token":
54683
+ setOnrampToken(initialAction.token);
54684
+ setView("amount");
54685
+ break;
54686
+ case "resume_send_sms":
54687
+ void createSessionAndSendOtp();
54688
+ break;
54689
+ }
54690
+ }, [initialAction, applyLimitRouting, createSessionAndSendOtp]);
54691
+ const startVerification = (0, import_react15.useCallback)(async () => {
54692
+ if (!isContactValid) return;
54693
+ await createSessionAndSendOtp();
54694
+ }, [isContactValid, createSessionAndSendOtp]);
54695
+ const submitLimitUpgrade = (0, import_react15.useCallback)(async () => {
54696
+ if (upgradeSubmitting) return;
54697
+ try {
54698
+ const dob = parseDobInput(dobInput);
54699
+ if (!dob || !/^\d{4}$/.test(ssnLast4)) return;
54700
+ setUpgradeSubmitting(true);
54701
+ setLimitUpgradeError(null);
54702
+ setView("limit_upgrade_submitting");
54703
+ const requestController = new AbortController();
54704
+ upgradeFlowAbortRef.current?.abort();
54705
+ upgradeFlowAbortRef.current = requestController;
54706
+ try {
54707
+ await requestCoinbaseApplePayLimitUpgrade(
54708
+ {
54709
+ phone: normalizedPhone,
54710
+ fields: { ssnLast4, dateOfBirth: dob }
54711
+ },
54712
+ publishableKey,
54713
+ requestController.signal
54714
+ );
54715
+ } catch (err) {
54716
+ if (requestController.signal.aborted) return;
54717
+ const raw = err instanceof Error ? err.message : "Failed to request limit upgrade";
54718
+ if (isLimitUpgradeTerminalBlock(raw)) {
54719
+ clearUpgradeFields();
54720
+ setLimitUpgradeError(null);
54721
+ setView("guest_limit_reached");
54722
+ return;
54723
+ }
54724
+ setLimitUpgradeError(prettifyVerificationError(raw));
54725
+ setView("limit_upgrade_form");
54726
+ return;
54727
+ } finally {
54728
+ if (upgradeFlowAbortRef.current === requestController) {
54729
+ upgradeFlowAbortRef.current = null;
54730
+ }
54731
+ }
54732
+ await startUpgradePolling();
54446
54733
  } finally {
54447
- setOtpSubmitting(false);
54734
+ setUpgradeSubmitting(false);
54448
54735
  }
54449
54736
  }, [
54450
- verificationSession,
54451
- clientSecret,
54452
- emailCode,
54737
+ upgradeSubmitting,
54738
+ dobInput,
54739
+ ssnLast4,
54740
+ normalizedPhone,
54453
54741
  publishableKey,
54454
- persistContact,
54455
- otpSubmitting
54742
+ startUpgradePolling,
54743
+ clearUpgradeFields
54456
54744
  ]);
54457
54745
  const submitPhoneOtp = (0, import_react15.useCallback)(async () => {
54458
54746
  if (!verificationSession || !clientSecret || phoneCode.length !== 6) return;
@@ -54475,7 +54763,7 @@ var BuyWithApplePay = React522.forwardRef(
54475
54763
  publishableKey
54476
54764
  );
54477
54765
  setOnrampToken(tokenRes);
54478
- persistContact({
54766
+ storeApplePaySession({
54479
54767
  emailVerifiedAt: updated.email.verified_at,
54480
54768
  phoneVerifiedAt: updated.phone.verified_at,
54481
54769
  onrampToken: tokenRes.token,
@@ -54484,17 +54772,30 @@ var BuyWithApplePay = React522.forwardRef(
54484
54772
  setEmailLocked(true);
54485
54773
  setPhoneCode("");
54486
54774
  if (amountUsd) setAmount(amountUsd);
54775
+ try {
54776
+ const result = await refetchApplePayLimits();
54777
+ if (result.data) {
54778
+ const nextView = getViewForLimitStatus(result.data);
54779
+ if (nextView) {
54780
+ setOtpSubmitting(false);
54781
+ applyLimitRouting(nextView, result.data.upgrade_status);
54782
+ return;
54783
+ }
54784
+ }
54785
+ } catch {
54786
+ }
54787
+ setOtpSubmitting(false);
54487
54788
  setView("amount");
54488
- } else {
54489
- setOtpError("Incorrect code. Please try again.");
54490
- setPhoneCode("");
54789
+ return;
54491
54790
  }
54791
+ setOtpError("Incorrect code. Please try again.");
54792
+ setPhoneCode("");
54793
+ setOtpSubmitting(false);
54492
54794
  } catch (err) {
54493
54795
  setOtpError(
54494
54796
  prettifyVerificationError(err instanceof Error ? err.message : "Verification failed")
54495
54797
  );
54496
54798
  setPhoneCode("");
54497
- } finally {
54498
54799
  setOtpSubmitting(false);
54499
54800
  }
54500
54801
  }, [
@@ -54502,22 +54803,25 @@ var BuyWithApplePay = React522.forwardRef(
54502
54803
  clientSecret,
54503
54804
  phoneCode,
54504
54805
  publishableKey,
54505
- persistContact,
54806
+ storeApplePaySession,
54506
54807
  amountUsd,
54507
- otpSubmitting
54808
+ otpSubmitting,
54809
+ refetchApplePayLimits,
54810
+ getViewForLimitStatus,
54811
+ applyLimitRouting
54508
54812
  ]);
54509
54813
  const prepareSession = (0, import_react15.useCallback)(
54510
54814
  async (token, amt) => {
54815
+ setErrorMessage("");
54511
54816
  if (!destinationChainType || !destinationChainId) {
54512
54817
  setErrorMessage("Deposit destination not configured. Please contact support.");
54513
54818
  return;
54514
54819
  }
54515
- const destinationNetwork = destinationChainNameFor(
54516
- destinationChainType,
54517
- destinationChainId
54518
- );
54519
- if (!destinationNetwork) {
54520
- setErrorMessage("Coinbase Apple Pay is not available for this network.");
54820
+ if (defaultTokenLoading) {
54821
+ return;
54822
+ }
54823
+ if (defaultTokenError || !defaultToken) {
54824
+ setErrorMessage("Unable to load token information. Please try again.");
54521
54825
  return;
54522
54826
  }
54523
54827
  const settlementAddress = depositWallet?.address;
@@ -54528,19 +54832,17 @@ var BuyWithApplePay = React522.forwardRef(
54528
54832
  sessionAbortRef.current?.abort();
54529
54833
  const controller = new AbortController();
54530
54834
  sessionAbortRef.current = controller;
54531
- setPreparingSession(true);
54532
- setErrorMessage("");
54533
54835
  try {
54534
54836
  const externalId = generatePrefixedKSUID("orsext");
54535
54837
  const session = await createCoinbaseApplePaySession(
54536
54838
  {
54537
54839
  source_currency: "usd",
54538
54840
  source_amount: amt,
54539
- destination_currency: destinationTokenSymbol.toLowerCase(),
54540
- destination_network: destinationNetwork,
54841
+ destination_currency: defaultToken.destination_currency,
54842
+ destination_network: defaultToken.destination_network,
54541
54843
  wallet_address: settlementAddress,
54542
54844
  external_id: externalId,
54543
- ...externalUserEmail ? { email: externalUserEmail } : {}
54845
+ ...userEmail ? { email: userEmail } : {}
54544
54846
  },
54545
54847
  token,
54546
54848
  publishableKey,
@@ -54584,18 +54886,16 @@ var BuyWithApplePay = React522.forwardRef(
54584
54886
  setPaymentSession(null);
54585
54887
  setPaymentSessionAmount(null);
54586
54888
  setErrorMessage("Unable to process your request. Please try again later.");
54587
- } finally {
54588
- if (sessionAbortRef.current === controller) {
54589
- setPreparingSession(false);
54590
- }
54591
54889
  }
54592
54890
  },
54593
54891
  [
54594
- destinationTokenSymbol,
54595
54892
  destinationChainType,
54596
54893
  destinationChainId,
54894
+ defaultToken,
54895
+ defaultTokenLoading,
54896
+ defaultTokenError,
54597
54897
  depositWallet?.address,
54598
- externalUserEmail,
54898
+ userEmail,
54599
54899
  publishableKey,
54600
54900
  onEvent,
54601
54901
  userId
@@ -54639,42 +54939,8 @@ var BuyWithApplePay = React522.forwardRef(
54639
54939
  if (view === "loading_config") {
54640
54940
  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 } }) });
54641
54941
  }
54642
- if (view === "disabled") {
54643
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
54644
- "div",
54645
- {
54646
- className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-12 uf-px-4",
54647
- style: containerStyle,
54648
- children: [
54649
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
54650
- CircleAlert,
54651
- {
54652
- className: "uf-w-8 uf-h-8 uf-mb-4",
54653
- style: { color: colors2.foregroundMuted }
54654
- }
54655
- ),
54656
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
54657
- "h3",
54658
- {
54659
- className: "uf-text-base uf-font-medium uf-mb-1",
54660
- style: { color: colors2.foreground, fontFamily: fonts.medium },
54661
- children: "Apple Pay is unavailable"
54662
- }
54663
- ),
54664
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
54665
- "p",
54666
- {
54667
- className: "uf-text-sm uf-text-center",
54668
- style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
54669
- children: "Apple Pay is disabled for this project. Try another payment method."
54670
- }
54671
- )
54672
- ]
54673
- }
54674
- );
54675
- }
54676
54942
  if (view === "email_input") {
54677
- const emailValid = EMAIL_REGEX.test(email);
54943
+ const emailValid = EMAIL_REGEX2.test(email);
54678
54944
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "uf-flex uf-flex-col uf-pb-1 uf-pt-2", style: containerStyle, children: [
54679
54945
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
54680
54946
  "label",
@@ -54691,9 +54957,7 @@ var BuyWithApplePay = React522.forwardRef(
54691
54957
  value: email,
54692
54958
  onChange: (e) => setEmail(e.target.value.trim()),
54693
54959
  onKeyDown: (e) => {
54694
- if (e.key === "Enter" && emailValid) {
54695
- setView("phone_input");
54696
- }
54960
+ if (e.key === "Enter" && emailValid) setView("phone_input");
54697
54961
  },
54698
54962
  placeholder: "you@example.com",
54699
54963
  autoComplete: "email",
@@ -54729,7 +54993,7 @@ var BuyWithApplePay = React522.forwardRef(
54729
54993
  }
54730
54994
  if (view === "phone_input" || view === "submitting_session") {
54731
54995
  const submitting = view === "submitting_session";
54732
- const phoneValid = PHONE_REGEX.test(normalizedPhone);
54996
+ const phoneValid = PHONE_REGEX2.test(normalizedPhone);
54733
54997
  const rawDigits = (() => {
54734
54998
  const digits = phoneInput.replace(/\D/g, "");
54735
54999
  return digits.startsWith("1") ? digits.slice(1, 11) : digits.slice(0, 10);
@@ -54810,15 +55074,7 @@ var BuyWithApplePay = React522.forwardRef(
54810
55074
  !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." }),
54811
55075
  errorMessage && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-text-xs uf-mt-2 uf-px-1", style: { color: colors2.error }, children: errorMessage }),
54812
55076
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-flex-1" }),
54813
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
54814
- LegalDisclaimer,
54815
- {
54816
- legalAgreements,
54817
- loading: legalAgreementsLoading,
54818
- colors: colors2,
54819
- fonts
54820
- }
54821
- ),
55077
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LegalDisclaimer, { legalAgreements, loading: legalAgreementsLoading }),
54822
55078
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
54823
55079
  "button",
54824
55080
  {
@@ -54837,12 +55093,9 @@ var BuyWithApplePay = React522.forwardRef(
54837
55093
  )
54838
55094
  ] });
54839
55095
  }
54840
- if (view === "email_otp" || view === "phone_otp") {
54841
- const isEmail = view === "email_otp";
54842
- const code = isEmail ? emailCode : phoneCode;
54843
- const setCode = isEmail ? setEmailCode : setPhoneCode;
54844
- const target = isEmail ? maskEmail(email) : maskPhone(normalizedPhone);
54845
- const submit = isEmail ? submitEmailOtp : submitPhoneOtp;
55096
+ if (view === "phone_otp") {
55097
+ const code = phoneCode;
55098
+ const target = maskPhone(normalizedPhone);
54846
55099
  const canSubmit = code.length === 6 && !otpSubmitting;
54847
55100
  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: [
54848
55101
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
@@ -54865,13 +55118,12 @@ var BuyWithApplePay = React522.forwardRef(
54865
55118
  maxLength: 6,
54866
55119
  value: code,
54867
55120
  onChange: (e) => {
54868
- const v = e.target.value.replace(/\D/g, "").slice(0, 6);
54869
- setCode(v);
55121
+ setPhoneCode(e.target.value.replace(/\D/g, "").slice(0, 6));
54870
55122
  setOtpError(null);
54871
55123
  },
54872
55124
  onKeyDown: (e) => {
54873
55125
  if (e.key === "Enter" && code.length === 6 && !otpSubmitting) {
54874
- void submit();
55126
+ void submitPhoneOtp();
54875
55127
  }
54876
55128
  },
54877
55129
  autoFocus: true,
@@ -54898,7 +55150,7 @@ var BuyWithApplePay = React522.forwardRef(
54898
55150
  if (!verificationSession || !clientSecret) return;
54899
55151
  void sendOnrampVerificationOtp(
54900
55152
  verificationSession.id,
54901
- isEmail ? "email" : "phone",
55153
+ "phone",
54902
55154
  clientSecret,
54903
55155
  publishableKey
54904
55156
  ).then(() => setResendCooldown(30));
@@ -54911,7 +55163,7 @@ var BuyWithApplePay = React522.forwardRef(
54911
55163
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
54912
55164
  "button",
54913
55165
  {
54914
- onClick: () => void submit(),
55166
+ onClick: submitPhoneOtp,
54915
55167
  disabled: !canSubmit,
54916
55168
  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",
54917
55169
  style: {
@@ -55059,7 +55311,7 @@ var BuyWithApplePay = React522.forwardRef(
55059
55311
  border: `${components.button.borderWidth}px solid ${components.button.borderColor}`,
55060
55312
  opacity: 0.5
55061
55313
  },
55062
- children: !hasInput || !validAmount ? "Enter amount" : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
55314
+ 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: [
55063
55315
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
55064
55316
  "Preparing Apple Pay"
55065
55317
  ] })
@@ -55097,7 +55349,104 @@ var BuyWithApplePay = React522.forwardRef(
55097
55349
  {
55098
55350
  className: "uf-text-xl uf-mb-2 uf-text-center",
55099
55351
  style: { color: colors2.foreground, fontFamily: fonts.medium },
55100
- children: "Checking for your deposit\u2026"
55352
+ children: "Checking for your deposit\u2026"
55353
+ }
55354
+ ),
55355
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55356
+ "p",
55357
+ {
55358
+ className: "uf-text-sm uf-text-center uf-max-w-[280px]",
55359
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
55360
+ children: "Return if the payment is not made."
55361
+ }
55362
+ )
55363
+ ]
55364
+ }
55365
+ );
55366
+ }
55367
+ if (view === "limit_upgrade_intro") {
55368
+ 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: [
55369
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55370
+ "h3",
55371
+ {
55372
+ className: "uf-text-xl uf-mb-3 uf-text-center",
55373
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
55374
+ children: "Apple Pay limit reached"
55375
+ }
55376
+ ),
55377
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55378
+ "p",
55379
+ {
55380
+ className: "uf-text-sm uf-text-center uf-mb-10 uf-max-w-[320px] uf-mx-auto",
55381
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
55382
+ children: "Submit your date of birth and SSN to increase your Apple Pay limit."
55383
+ }
55384
+ ),
55385
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55386
+ "button",
55387
+ {
55388
+ onClick: () => {
55389
+ setLimitUpgradeError(null);
55390
+ setView("limit_upgrade_form");
55391
+ },
55392
+ className: "uf-w-full uf-py-3 uf-mb-2 uf-text-sm uf-font-medium uf-transition-colors",
55393
+ style: {
55394
+ backgroundColor: colors2.primary,
55395
+ color: colors2.primaryForeground,
55396
+ fontFamily: fonts.medium,
55397
+ borderRadius: components.button.borderRadius,
55398
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
55399
+ },
55400
+ children: "Continue"
55401
+ }
55402
+ ),
55403
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55404
+ "button",
55405
+ {
55406
+ onClick: () => {
55407
+ setLimitUpgradeError(null);
55408
+ onExit?.();
55409
+ },
55410
+ className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors",
55411
+ style: {
55412
+ backgroundColor: "transparent",
55413
+ color: colors2.error,
55414
+ fontFamily: fonts.medium,
55415
+ borderRadius: components.button.borderRadius,
55416
+ border: `${components.button.borderWidth}px solid transparent`
55417
+ },
55418
+ children: "Cancel"
55419
+ }
55420
+ )
55421
+ ] });
55422
+ }
55423
+ if (view === "limit_upgrade_submitting") {
55424
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
55425
+ "div",
55426
+ {
55427
+ className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16 uf-px-4",
55428
+ style: containerStyle,
55429
+ children: [
55430
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55431
+ "div",
55432
+ {
55433
+ className: "uf-w-20 uf-h-20 uf-rounded-full uf-flex uf-items-center uf-justify-center uf-mb-6",
55434
+ style: { backgroundColor: `${colors2.primary}20` },
55435
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55436
+ LoaderCircle,
55437
+ {
55438
+ className: "uf-w-10 uf-h-10 uf-animate-spin",
55439
+ style: { color: colors2.primary }
55440
+ }
55441
+ )
55442
+ }
55443
+ ),
55444
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55445
+ "h3",
55446
+ {
55447
+ className: "uf-text-xl uf-mb-2 uf-text-center",
55448
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
55449
+ children: "Verifying your information"
55101
55450
  }
55102
55451
  ),
55103
55452
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
@@ -55105,13 +55454,184 @@ var BuyWithApplePay = React522.forwardRef(
55105
55454
  {
55106
55455
  className: "uf-text-sm uf-text-center uf-max-w-[280px]",
55107
55456
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
55108
- children: "Return if the payment is not made."
55457
+ children: "Your limit increase request is under review. This usually takes just a few seconds."
55109
55458
  }
55110
55459
  )
55111
55460
  ]
55112
55461
  }
55113
55462
  );
55114
55463
  }
55464
+ if (view === "limit_upgrade_form") {
55465
+ const dobValid = isDobInputValid(dobInput);
55466
+ const ssnValid = /^\d{4}$/.test(ssnLast4);
55467
+ const formValid = dobValid && ssnValid;
55468
+ const formInputStyle = {
55469
+ backgroundColor: components.card.backgroundColor,
55470
+ color: components.input.textColor,
55471
+ fontFamily: fonts.regular,
55472
+ borderRadius: components.card.borderRadius,
55473
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
55474
+ };
55475
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "uf-flex uf-flex-col uf-pb-1 uf-pt-2", style: containerStyle, children: [
55476
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55477
+ "label",
55478
+ {
55479
+ className: "uf-text-xs uf-font-medium uf-mb-1.5 uf-px-1",
55480
+ style: { color: components.card.labelColor, fontFamily: fonts.medium },
55481
+ children: "Date of birth"
55482
+ }
55483
+ ),
55484
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55485
+ "input",
55486
+ {
55487
+ type: "text",
55488
+ inputMode: "numeric",
55489
+ maxLength: 10,
55490
+ value: dobInput,
55491
+ onChange: (e) => {
55492
+ setDobInput(formatDobInput(e.target.value));
55493
+ if (limitUpgradeError) setLimitUpgradeError(null);
55494
+ },
55495
+ onKeyDown: (e) => {
55496
+ if (e.key === "Enter" && formValid) void submitLimitUpgrade();
55497
+ },
55498
+ placeholder: "MM/DD/YYYY",
55499
+ autoComplete: "bday",
55500
+ "aria-label": "Date of birth",
55501
+ className: "uf-w-full uf-px-3 uf-py-3 uf-mb-3 uf-text-sm uf-outline-none",
55502
+ style: formInputStyle
55503
+ }
55504
+ ),
55505
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55506
+ "label",
55507
+ {
55508
+ className: "uf-text-xs uf-font-medium uf-mb-1.5 uf-px-1",
55509
+ style: { color: components.card.labelColor, fontFamily: fonts.medium },
55510
+ children: "Last 4 of SSN"
55511
+ }
55512
+ ),
55513
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55514
+ "input",
55515
+ {
55516
+ type: "password",
55517
+ inputMode: "numeric",
55518
+ pattern: "[0-9]*",
55519
+ maxLength: 4,
55520
+ value: ssnLast4,
55521
+ onChange: (e) => {
55522
+ setSsnLast4(e.target.value.replace(/\D/g, "").slice(0, 4));
55523
+ if (limitUpgradeError) setLimitUpgradeError(null);
55524
+ },
55525
+ onKeyDown: (e) => {
55526
+ if (e.key === "Enter" && formValid) void submitLimitUpgrade();
55527
+ },
55528
+ placeholder: "\u2022\u2022\u2022\u2022",
55529
+ autoComplete: "off",
55530
+ name: "off",
55531
+ autoCorrect: "off",
55532
+ autoCapitalize: "none",
55533
+ spellCheck: false,
55534
+ "data-1p-ignore": "true",
55535
+ "data-lpignore": "true",
55536
+ "data-form-type": "other",
55537
+ "aria-label": "Last 4 digits of SSN",
55538
+ "aria-autocomplete": "none",
55539
+ className: "uf-w-full uf-px-3 uf-py-3 uf-mb-2 uf-text-sm uf-outline-none",
55540
+ style: formInputStyle
55541
+ }
55542
+ ),
55543
+ limitUpgradeError && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55544
+ "div",
55545
+ {
55546
+ className: "uf-text-xs uf-mt-2 uf-px-1",
55547
+ style: { color: colors2.error, fontFamily: fonts.regular },
55548
+ children: limitUpgradeError
55549
+ }
55550
+ ),
55551
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-flex-1" }),
55552
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55553
+ "button",
55554
+ {
55555
+ onClick: () => void submitLimitUpgrade(),
55556
+ disabled: !formValid || upgradeSubmitting,
55557
+ 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",
55558
+ style: {
55559
+ backgroundColor: colors2.primary,
55560
+ color: colors2.primaryForeground,
55561
+ fontFamily: fonts.medium,
55562
+ borderRadius: components.button.borderRadius,
55563
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
55564
+ },
55565
+ children: upgradeSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2", children: [
55566
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
55567
+ "Submitting\u2026"
55568
+ ] }) : "Submit"
55569
+ }
55570
+ )
55571
+ ] });
55572
+ }
55573
+ if (view === "limit_upgrade_failed") {
55574
+ 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: [
55575
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55576
+ "h3",
55577
+ {
55578
+ className: "uf-text-xl uf-mb-3 uf-text-center",
55579
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
55580
+ children: "Apple Pay limit reached"
55581
+ }
55582
+ ),
55583
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
55584
+ "p",
55585
+ {
55586
+ className: "uf-text-sm uf-text-center uf-mb-2 uf-max-w-[320px] uf-mx-auto",
55587
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
55588
+ children: [
55589
+ "Failed to increase. Please try again later or",
55590
+ " ",
55591
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55592
+ "a",
55593
+ {
55594
+ href: UNIFOLD_SUPPORT_URL,
55595
+ target: "_blank",
55596
+ rel: "noreferrer noopener",
55597
+ className: "uf-underline",
55598
+ style: { color: colors2.primary },
55599
+ children: "contact support"
55600
+ }
55601
+ ),
55602
+ "."
55603
+ ]
55604
+ }
55605
+ ),
55606
+ limitUpgradeError && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55607
+ "p",
55608
+ {
55609
+ className: "uf-text-xs uf-text-center uf-mb-2 uf-px-2",
55610
+ style: { color: colors2.error, fontFamily: fonts.regular },
55611
+ children: limitUpgradeError
55612
+ }
55613
+ ),
55614
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "uf-mb-8" }),
55615
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55616
+ "button",
55617
+ {
55618
+ onClick: () => {
55619
+ setLimitUpgradeError(null);
55620
+ onExit?.();
55621
+ },
55622
+ className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors",
55623
+ style: {
55624
+ backgroundColor: colors2.primary,
55625
+ color: colors2.primaryForeground,
55626
+ fontFamily: fonts.medium,
55627
+ borderRadius: components.button.borderRadius,
55628
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
55629
+ },
55630
+ children: "Return"
55631
+ }
55632
+ )
55633
+ ] });
55634
+ }
55115
55635
  if (view === "guest_limit_reached") {
55116
55636
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
55117
55637
  "div",
@@ -55132,7 +55652,7 @@ var BuyWithApplePay = React522.forwardRef(
55132
55652
  {
55133
55653
  className: "uf-text-sm uf-text-center uf-mb-12 uf-max-w-[300px]",
55134
55654
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
55135
- children: "Your account has reached Apple Pay limit. It's not eligible for an increase right now."
55655
+ children: "Your account is not eligible for a limit increase at this time."
55136
55656
  }
55137
55657
  ),
55138
55658
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
@@ -55158,7 +55678,95 @@ var BuyWithApplePay = React522.forwardRef(
55158
55678
  }
55159
55679
  );
55160
55680
  BuyWithApplePay.displayName = "BuyWithApplePay";
55161
- function LegalDisclaimer({ legalAgreements, loading, colors: colors2, fonts }) {
55681
+ function formatPhoneInput(raw) {
55682
+ const digits = raw.replace(/\D/g, "");
55683
+ if (raw.startsWith("+")) {
55684
+ return `+${digits}`;
55685
+ }
55686
+ if (digits.length === 10) return `+1${digits}`;
55687
+ if (digits.length === 11 && digits.startsWith("1")) return `+${digits}`;
55688
+ return digits.length > 0 ? `+${digits}` : "";
55689
+ }
55690
+ function maskPhone(phone) {
55691
+ if (!/^\+1\d{10}$/.test(phone)) return phone;
55692
+ return `+1 (***) ***-${phone.slice(-4)}`;
55693
+ }
55694
+ function isGuestLimitError(err) {
55695
+ const message = err instanceof Error ? err.message : String(err ?? "");
55696
+ if (/coinbase_onramp_guest_limit_reached/i.test(message)) return true;
55697
+ if (/guest_(daily_)?transaction_(count|limit)/i.test(message)) return true;
55698
+ return false;
55699
+ }
55700
+ function isLimitUpgradeTerminalBlock(message) {
55701
+ if (/coinbase_onramp_guest_limit_reached/i.test(message)) return true;
55702
+ if (/limit upgrade is not available/i.test(message)) return true;
55703
+ if (/limits.?upgrade.?blocked/i.test(message)) return true;
55704
+ return false;
55705
+ }
55706
+ function prettifyVerificationError(message) {
55707
+ if (/\b429\b|too many requests|rate.?limit|throttle/i.test(message)) {
55708
+ return "Too many attempts. Please wait a few minutes and try again.";
55709
+ }
55710
+ if (/network|failed to fetch|abort/i.test(message)) {
55711
+ return "Network error. Check your connection and try again.";
55712
+ }
55713
+ if (/voip|not a valid US|not a cell/i.test(message)) {
55714
+ return "We can only verify real US cell phones (not VoIP). Try a different number.";
55715
+ }
55716
+ const cleaned = message.replace(/\s*\[[\w_]+\]:\s*.*$/, "").trim();
55717
+ return cleaned || message;
55718
+ }
55719
+ function formatDobInput(raw) {
55720
+ const digits = raw.replace(/\D/g, "").slice(0, 8);
55721
+ if (digits.length <= 2) return digits;
55722
+ if (digits.length <= 4) return `${digits.slice(0, 2)}/${digits.slice(2)}`;
55723
+ return `${digits.slice(0, 2)}/${digits.slice(2, 4)}/${digits.slice(4)}`;
55724
+ }
55725
+ function isDobInputValid(input) {
55726
+ return parseDobInput(input) !== null;
55727
+ }
55728
+ function parseDobInput(input) {
55729
+ const m = /^(\d{2})\/(\d{2})\/(\d{4})$/.exec(input);
55730
+ if (!m) return null;
55731
+ const [, month, day, year] = m;
55732
+ if (!/^(0[1-9]|1[0-2])$/.test(month)) return null;
55733
+ if (!/^(0[1-9]|[12]\d|3[01])$/.test(day)) return null;
55734
+ if (!/^(19|20)\d{2}$/.test(year)) return null;
55735
+ return { month, day, year };
55736
+ }
55737
+ var POPUP_W = 500;
55738
+ var POPUP_H = 700;
55739
+ function openCoinbasePaymentPopup(url) {
55740
+ if (typeof window === "undefined") return null;
55741
+ const screenW = window.screen.availWidth ?? window.innerWidth;
55742
+ const screenH = window.screen.availHeight ?? window.innerHeight;
55743
+ const left = Math.max(0, Math.round((screenW - POPUP_W) / 2));
55744
+ const top = Math.max(0, Math.round((screenH - POPUP_H) / 2));
55745
+ return window.open(
55746
+ url,
55747
+ "unifold_coinbase_apple_pay",
55748
+ `popup,width=${POPUP_W},height=${POPUP_H},left=${left},top=${top}`
55749
+ );
55750
+ }
55751
+ var FALLBACK_AGREEMENTS = [
55752
+ {
55753
+ key: "guest_checkout_terms",
55754
+ name: "Guest Checkout Terms of Service",
55755
+ url: "https://www.coinbase.com/legal/cb-pay/onramp-guest-checkout-terms"
55756
+ },
55757
+ {
55758
+ key: "user_agreement",
55759
+ name: "User Agreement",
55760
+ url: "https://www.coinbase.com/legal/user_agreement"
55761
+ },
55762
+ {
55763
+ key: "privacy_policy",
55764
+ name: "Privacy Policy",
55765
+ url: "https://www.coinbase.com/legal/privacy"
55766
+ }
55767
+ ];
55768
+ function LegalDisclaimer({ legalAgreements, loading }) {
55769
+ const { colors: colors2, fonts } = useTheme();
55162
55770
  if (loading) {
55163
55771
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
55164
55772
  "div",
@@ -55202,78 +55810,6 @@ function LegalDisclaimer({ legalAgreements, loading, colors: colors2, fonts }) {
55202
55810
  }
55203
55811
  );
55204
55812
  }
55205
- function isGuestLimitError(err) {
55206
- const message = err instanceof Error ? err.message : String(err ?? "");
55207
- if (/coinbase_onramp_guest_limit_reached/i.test(message)) return true;
55208
- if (/guest_(daily_)?transaction_(count|limit)/i.test(message)) return true;
55209
- return false;
55210
- }
55211
- function prettifyVerificationError(message) {
55212
- if (/\b429\b|too many requests|rate.?limit|throttle/i.test(message)) {
55213
- return "Too many attempts. Please wait a few minutes and try again.";
55214
- }
55215
- if (/network|failed to fetch|abort/i.test(message)) {
55216
- return "Network error. Check your connection and try again.";
55217
- }
55218
- if (/voip|not a valid US|not a cell/i.test(message)) {
55219
- return "We can only verify real US cell phones (not VoIP). Try a different number.";
55220
- }
55221
- return message;
55222
- }
55223
- var FALLBACK_AGREEMENTS = [
55224
- {
55225
- key: "guest_checkout_terms",
55226
- name: "Guest Checkout Terms of Service",
55227
- url: "https://www.coinbase.com/legal/cb-pay/onramp-guest-checkout-terms"
55228
- },
55229
- {
55230
- key: "user_agreement",
55231
- name: "User Agreement",
55232
- url: "https://www.coinbase.com/legal/user_agreement"
55233
- },
55234
- {
55235
- key: "privacy_policy",
55236
- name: "Privacy Policy",
55237
- url: "https://www.coinbase.com/legal/privacy"
55238
- }
55239
- ];
55240
- var POPUP_W = 500;
55241
- var POPUP_H = 700;
55242
- function openCoinbasePaymentPopup(url) {
55243
- if (typeof window === "undefined") return null;
55244
- const screenW = window.screen.availWidth ?? window.innerWidth;
55245
- const screenH = window.screen.availHeight ?? window.innerHeight;
55246
- const left = Math.max(0, Math.round((screenW - POPUP_W) / 2));
55247
- const top = Math.max(0, Math.round((screenH - POPUP_H) / 2));
55248
- return window.open(
55249
- url,
55250
- "unifold_coinbase_apple_pay",
55251
- `popup,width=${POPUP_W},height=${POPUP_H},left=${left},top=${top}`
55252
- );
55253
- }
55254
- function destinationChainNameFor(chainType, chainId) {
55255
- if (chainType === "solana") return "solana";
55256
- if (chainType === "bitcoin") return "bitcoin";
55257
- if (chainType === "ethereum") {
55258
- switch (chainId) {
55259
- case "1":
55260
- return "ethereum";
55261
- case "8453":
55262
- return "base";
55263
- case "137":
55264
- return "polygon";
55265
- case "43114":
55266
- return "avalanche";
55267
- case "42161":
55268
- return "arbitrum";
55269
- case "10":
55270
- return "optimism";
55271
- default:
55272
- return null;
55273
- }
55274
- }
55275
- return null;
55276
- }
55277
55813
  var t2 = i18n2.payWithExchange;
55278
55814
  function PayWithExchange({
55279
55815
  userId,
@@ -55288,10 +55824,10 @@ function PayWithExchange({
55288
55824
  defaultToken
55289
55825
  }) {
55290
55826
  const { colors: colors2, fonts, components } = useTheme();
55291
- const [internalView, setInternalView] = (0, import_react16.useState)("providers");
55292
- const [exchangeSession, setExchangeSession] = (0, import_react16.useState)(null);
55293
- const [sessionError, setSessionError] = (0, import_react16.useState)(null);
55294
- const [hoveredIndex, setHoveredIndex] = (0, import_react16.useState)(null);
55827
+ const [internalView, setInternalView] = (0, import_react17.useState)("providers");
55828
+ const [exchangeSession, setExchangeSession] = (0, import_react17.useState)(null);
55829
+ const [sessionError, setSessionError] = (0, import_react17.useState)(null);
55830
+ const [hoveredIndex, setHoveredIndex] = (0, import_react17.useState)(null);
55295
55831
  const currentView = externalView ?? internalView;
55296
55832
  const depositWalletId = wallets.find((w) => ["ethereum", "solana"].includes(w.chain_type))?.id;
55297
55833
  const handleViewChange = (newView) => {
@@ -55571,7 +56107,7 @@ function QRCodeSkeleton({ size: size4 = 180, darkMode = false }) {
55571
56107
  const spacing = size4 / gridCount;
55572
56108
  const fillColor = darkMode ? "rgba(255,255,255,0.10)" : "rgba(0,0,0,0.08)";
55573
56109
  const cornerColor = darkMode ? "rgba(255,255,255,0.14)" : "rgba(0,0,0,0.12)";
55574
- const dots = (0, import_react18.useMemo)(() => {
56110
+ const dots = (0, import_react19.useMemo)(() => {
55575
56111
  const result = [];
55576
56112
  const cornerSize = 7;
55577
56113
  const centerStart = Math.floor(gridCount / 2) - 2;
@@ -55626,10 +56162,10 @@ function StyledQRCode({
55626
56162
  imageSize = 45,
55627
56163
  darkMode = false
55628
56164
  }) {
55629
- const containerRef = (0, import_react18.useRef)(null);
55630
- const qrRef = (0, import_react18.useRef)(null);
55631
- const [ready, setReady] = (0, import_react18.useState)(false);
55632
- (0, import_react18.useEffect)(() => {
56165
+ const containerRef = (0, import_react19.useRef)(null);
56166
+ const qrRef = (0, import_react19.useRef)(null);
56167
+ const [ready, setReady] = (0, import_react19.useState)(false);
56168
+ (0, import_react19.useEffect)(() => {
55633
56169
  if (!containerRef.current || !value) return;
55634
56170
  const config = createQRConfig(value, size4, imageUrl, imageSize, darkMode);
55635
56171
  if (!qrRef.current) {
@@ -55660,8 +56196,8 @@ function StyledQRCode({
55660
56196
  ] });
55661
56197
  }
55662
56198
  function useIsMobileViewport() {
55663
- const [isMobile, setIsMobile] = (0, import_react19.useState)(() => isMobileViewport());
55664
- (0, import_react19.useEffect)(() => {
56199
+ const [isMobile, setIsMobile] = (0, import_react20.useState)(() => isMobileViewport());
56200
+ (0, import_react20.useEffect)(() => {
55665
56201
  setIsMobile(isMobileViewport());
55666
56202
  const mql = window.matchMedia(MOBILE_VIEWPORT_MEDIA_QUERY);
55667
56203
  const update = () => setIsMobile(mql.matches);
@@ -55713,21 +56249,21 @@ function PayWithCashApp({
55713
56249
  const { data: limits, isLoading: limitsLoading } = useCashAppLimits({ publishableKey });
55714
56250
  const minUsd = limits?.minimum_amount ?? FALLBACK_MIN_USD;
55715
56251
  const maxUsd = limits?.maximum_amount ?? null;
55716
- const [amount, setAmount] = (0, import_react17.useState)("");
55717
- const [loading, setLoading] = (0, import_react17.useState)(false);
55718
- const [session, setSession] = (0, import_react17.useState)(null);
55719
- const [status, setStatus] = (0, import_react17.useState)("pending");
55720
- const [error, setError] = (0, import_react17.useState)(null);
55721
- const [copied, setCopied] = (0, import_react17.useState)(false);
55722
- const [view, setViewInternal] = (0, import_react17.useState)(controlledView ?? "amount");
55723
- const setView = (0, import_react17.useCallback)(
56252
+ const [amount, setAmount] = (0, import_react18.useState)("");
56253
+ const [loading, setLoading] = (0, import_react18.useState)(false);
56254
+ const [session, setSession] = (0, import_react18.useState)(null);
56255
+ const [status, setStatus] = (0, import_react18.useState)("pending");
56256
+ const [error, setError] = (0, import_react18.useState)(null);
56257
+ const [copied, setCopied] = (0, import_react18.useState)(false);
56258
+ const [view, setViewInternal] = (0, import_react18.useState)(controlledView ?? "amount");
56259
+ const setView = (0, import_react18.useCallback)(
55724
56260
  (v) => {
55725
56261
  setViewInternal(v);
55726
56262
  onViewChange?.(v);
55727
56263
  },
55728
56264
  [onViewChange]
55729
56265
  );
55730
- (0, import_react17.useEffect)(() => {
56266
+ (0, import_react18.useEffect)(() => {
55731
56267
  if (controlledView && controlledView !== view) {
55732
56268
  setViewInternal(controlledView);
55733
56269
  if (controlledView === "amount") {
@@ -55739,7 +56275,7 @@ function PayWithCashApp({
55739
56275
  }
55740
56276
  }
55741
56277
  }, [controlledView]);
55742
- const [timeLeft, setTimeLeft] = (0, import_react17.useState)(null);
56278
+ const [timeLeft, setTimeLeft] = (0, import_react18.useState)(null);
55743
56279
  const depositWalletId = wallets.find((w) => w.chain_type === "ethereum")?.id;
55744
56280
  const { executions, isPolling } = useDepositPolling({
55745
56281
  userId,
@@ -55750,7 +56286,7 @@ function PayWithCashApp({
55750
56286
  onDepositSuccess,
55751
56287
  onDepositError
55752
56288
  });
55753
- const handleAmountChange = (0, import_react17.useCallback)(
56289
+ const handleAmountChange = (0, import_react18.useCallback)(
55754
56290
  (raw) => {
55755
56291
  const cleaned = raw.replace(/[^0-9.]/g, "");
55756
56292
  const parts = cleaned.split(".");
@@ -55762,7 +56298,7 @@ function PayWithCashApp({
55762
56298
  },
55763
56299
  [onAmountChange]
55764
56300
  );
55765
- const handleCreateSession = (0, import_react17.useCallback)(async () => {
56301
+ const handleCreateSession = (0, import_react18.useCallback)(async () => {
55766
56302
  if (!amount || !recipientAddress || !destinationChainType || !destinationChainId || !destinationTokenAddress) {
55767
56303
  setError("Missing required fields");
55768
56304
  return;
@@ -55811,7 +56347,7 @@ function PayWithCashApp({
55811
56347
  onEvent,
55812
56348
  onDepositError
55813
56349
  ]);
55814
- (0, import_react17.useEffect)(() => {
56350
+ (0, import_react18.useEffect)(() => {
55815
56351
  if (!session || view !== "payment" && view !== "confirming") return;
55816
56352
  if (status === "completed" || status === "failed") return;
55817
56353
  const poll = async () => {
@@ -55835,8 +56371,8 @@ function PayWithCashApp({
55835
56371
  poll();
55836
56372
  return () => clearInterval(interval);
55837
56373
  }, [session, view, status, publishableKey, onDepositSuccess, onDepositError]);
55838
- const [softExpired, setSoftExpired] = (0, import_react17.useState)(false);
55839
- (0, import_react17.useEffect)(() => {
56374
+ const [softExpired, setSoftExpired] = (0, import_react18.useState)(false);
56375
+ (0, import_react18.useEffect)(() => {
55840
56376
  if (!session?.expires_at || view !== "payment") return;
55841
56377
  const expiresMs = new Date(session.expires_at).getTime();
55842
56378
  const tick = () => {
@@ -55850,12 +56386,12 @@ function PayWithCashApp({
55850
56386
  const interval = setInterval(tick, 1e3);
55851
56387
  return () => clearInterval(interval);
55852
56388
  }, [session, view, status]);
55853
- const handleCopy = (0, import_react17.useCallback)(async (text) => {
56389
+ const handleCopy = (0, import_react18.useCallback)(async (text) => {
55854
56390
  await navigator.clipboard.writeText(text);
55855
56391
  setCopied(true);
55856
56392
  setTimeout(() => setCopied(false), 2e3);
55857
56393
  }, []);
55858
- const handleRecreate = (0, import_react17.useCallback)(() => {
56394
+ const handleRecreate = (0, import_react18.useCallback)(() => {
55859
56395
  setSession(null);
55860
56396
  setStatus("pending");
55861
56397
  setError(null);
@@ -56184,43 +56720,6 @@ function PayWithCashApp({
56184
56720
  }
56185
56721
  return null;
56186
56722
  }
56187
- function useDefaultOnrampToken({
56188
- publishableKey,
56189
- tokenAddress,
56190
- chainId,
56191
- chainType,
56192
- countryCode,
56193
- subdivisionCode,
56194
- enabled = true
56195
- }) {
56196
- const { data: defaultToken, isLoading } = useQuery({
56197
- queryKey: [
56198
- "unifold",
56199
- "defaultOnrampToken",
56200
- publishableKey,
56201
- tokenAddress,
56202
- chainId,
56203
- chainType,
56204
- countryCode,
56205
- subdivisionCode
56206
- ],
56207
- queryFn: () => getDefaultOnrampToken(
56208
- {
56209
- token_address: tokenAddress,
56210
- chain_id: chainId,
56211
- chain_type: chainType,
56212
- country_code: countryCode,
56213
- subdivision_code: subdivisionCode
56214
- },
56215
- publishableKey
56216
- ),
56217
- enabled: enabled && !!tokenAddress && !!chainId && !!chainType,
56218
- staleTime: 1e3 * 60 * 60,
56219
- refetchOnMount: false,
56220
- refetchOnWindowFocus: false
56221
- });
56222
- return { defaultToken, isLoading };
56223
- }
56224
56723
  function useBankTransferProviders({
56225
56724
  publishableKey,
56226
56725
  enabled = true,
@@ -56268,19 +56767,19 @@ function BankTransfer({
56268
56767
  onDepositError
56269
56768
  }) {
56270
56769
  const { colors: colors2, fonts, components } = useTheme();
56271
- const [internalView, setInternalView] = (0, import_react20.useState)("providers");
56272
- const [sessionError, setSessionError] = (0, import_react20.useState)(null);
56273
- const [hoveredId, setHoveredId] = (0, import_react20.useState)(null);
56274
- const [activeProvider, setActiveProvider] = (0, import_react20.useState)(null);
56275
- const [requestBase, setRequestBase] = (0, import_react20.useState)(null);
56276
- const [activeRequest, setActiveRequest] = (0, import_react20.useState)(null);
56277
- const [amount, setAmount] = (0, import_react20.useState)("");
56770
+ const [internalView, setInternalView] = (0, import_react21.useState)("providers");
56771
+ const [sessionError, setSessionError] = (0, import_react21.useState)(null);
56772
+ const [hoveredId, setHoveredId] = (0, import_react21.useState)(null);
56773
+ const [activeProvider, setActiveProvider] = (0, import_react21.useState)(null);
56774
+ const [requestBase, setRequestBase] = (0, import_react21.useState)(null);
56775
+ const [activeRequest, setActiveRequest] = (0, import_react21.useState)(null);
56776
+ const [amount, setAmount] = (0, import_react21.useState)("");
56278
56777
  const currentView = externalView ?? internalView;
56279
56778
  const setView = (v) => {
56280
56779
  setInternalView(v);
56281
56780
  onViewChange?.(v);
56282
56781
  };
56283
- (0, import_react20.useEffect)(() => {
56782
+ (0, import_react21.useEffect)(() => {
56284
56783
  if (externalView) setInternalView(externalView);
56285
56784
  }, [externalView]);
56286
56785
  const { userIpInfo } = useUserIp2();
@@ -56299,7 +56798,7 @@ function BankTransfer({
56299
56798
  countryCode: userIpInfo?.alpha2
56300
56799
  });
56301
56800
  const providers = providersResponse?.data ?? [];
56302
- const pollingWalletId = (0, import_react20.useMemo)(() => {
56801
+ const pollingWalletId = (0, import_react21.useMemo)(() => {
56303
56802
  if (!defaultToken) return void 0;
56304
56803
  return getWalletByChainType(
56305
56804
  wallets,
@@ -56320,7 +56819,7 @@ function BankTransfer({
56320
56819
  const currencySymbol = getCurrencySymbol2(sourceCurrency);
56321
56820
  const parsedAmount = parseFloat(amount);
56322
56821
  const amountValid = !!amount && Number.isFinite(parsedAmount) && parsedAmount >= MIN_AMOUNT;
56323
- const displayTokenSymbol = (0, import_react20.useMemo)(
56822
+ const displayTokenSymbol = (0, import_react21.useMemo)(
56324
56823
  () => destinationTokenSymbol?.toUpperCase() ?? defaultToken?.destination_token_metadata?.symbol?.toUpperCase() ?? defaultToken?.destination_currency?.toUpperCase() ?? "USDC",
56325
56824
  [destinationTokenSymbol, defaultToken]
56326
56825
  );
@@ -60295,16 +60794,114 @@ function AmexIcon({ size: size4 = 24 }) {
60295
60794
  )
60296
60795
  ] });
60297
60796
  }
60797
+ function ApplePayIcon({ size: size4 = 24, color = "#000" }) {
60798
+ const h = size4 * 0.62;
60799
+ const w = h * (512 / 210.2);
60800
+ 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)(
60801
+ "path",
60802
+ {
60803
+ fill: color,
60804
+ 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"
60805
+ }
60806
+ ) });
60807
+ }
60808
+ function GooglePayIcon({ size: size4 = 24, color = "#202124" }) {
60809
+ const h = size4 * 0.62;
60810
+ const w = h * (80 / 38.1);
60811
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("svg", { width: w, height: h, viewBox: "0 0 80 38.1", fill: "none", children: [
60812
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
60813
+ "path",
60814
+ {
60815
+ fill: color,
60816
+ 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"
60817
+ }
60818
+ ),
60819
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
60820
+ "path",
60821
+ {
60822
+ fill: color,
60823
+ 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"
60824
+ }
60825
+ ),
60826
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
60827
+ "path",
60828
+ {
60829
+ fill: color,
60830
+ d: "M80,13.3l-9.9,22.7h-3l3.7-7.9l-6.5-14.7h3.2l4.7,11.3h0.1l4.6-11.3H80z"
60831
+ }
60832
+ ),
60833
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
60834
+ "path",
60835
+ {
60836
+ fill: "#4285F4",
60837
+ 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"
60838
+ }
60839
+ ),
60840
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
60841
+ "path",
60842
+ {
60843
+ fill: "#34A853",
60844
+ 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"
60845
+ }
60846
+ ),
60847
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
60848
+ "path",
60849
+ {
60850
+ fill: "#FBBC04",
60851
+ 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"
60852
+ }
60853
+ ),
60854
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
60855
+ "path",
60856
+ {
60857
+ fill: "#EA4335",
60858
+ 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"
60859
+ }
60860
+ )
60861
+ ] });
60862
+ }
60298
60863
  function GenericCardIcon({ size: size4 = 24, color = "#888" }) {
60299
60864
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(CreditCard, { width: size4 * 0.8, height: size4 * 0.8, style: { color }, strokeWidth: 1.5 });
60300
60865
  }
60866
+ function parseColor(input) {
60867
+ if (!input) return null;
60868
+ const s = input.trim();
60869
+ if (s.startsWith("#")) {
60870
+ let hex = s.slice(1);
60871
+ if (hex.length === 3)
60872
+ hex = hex.split("").map((c) => c + c).join("");
60873
+ if (hex.length !== 6) return null;
60874
+ const n = parseInt(hex, 16);
60875
+ if (Number.isNaN(n)) return null;
60876
+ return [n >> 16 & 255, n >> 8 & 255, n & 255];
60877
+ }
60878
+ const m = s.match(/rgba?\(([^)]+)\)/i);
60879
+ if (m) {
60880
+ const parts = m[1].split(",").map((p) => parseFloat(p));
60881
+ if (parts.length >= 3 && parts.every((p) => !Number.isNaN(p)))
60882
+ return [parts[0], parts[1], parts[2]];
60883
+ }
60884
+ return null;
60885
+ }
60886
+ function monochromeOn(background) {
60887
+ const rgb = parseColor(background);
60888
+ if (!rgb) return "#000000";
60889
+ const [r2, g, b] = rgb;
60890
+ const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
60891
+ return luminance > 0.6 ? "#000000" : "#FFFFFF";
60892
+ }
60301
60893
  function CardBrandIcon({
60302
60894
  brand,
60303
60895
  size: size4 = 24,
60304
- fallbackColor = "#888"
60896
+ fallbackColor = "#888",
60897
+ monochromeColor = "#000000"
60305
60898
  }) {
60306
60899
  if (!brand) return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(GenericCardIcon, { size: size4, color: fallbackColor });
60307
60900
  const lower = brand.toLowerCase();
60901
+ if (lower.includes("apple_pay") || lower.includes("apple pay") || lower === "applepay")
60902
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ApplePayIcon, { size: size4, color: monochromeColor });
60903
+ if (lower.includes("google_pay") || lower.includes("google pay") || lower === "googlepay")
60904
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(GooglePayIcon, { size: size4, color: monochromeColor === "#FFFFFF" ? "#FFFFFF" : "#202124" });
60308
60905
  if (lower.includes("visa")) return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(VisaIcon, { size: size4 });
60309
60906
  if (lower.includes("mastercard") || lower.includes("master"))
60310
60907
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(MastercardIcon, { size: size4 });
@@ -60313,17 +60910,28 @@ function CardBrandIcon({
60313
60910
  }
60314
60911
  function formatPaymentToken(token) {
60315
60912
  if (token.card) {
60316
- const brand = token.card.brand ?? "Card";
60913
+ const cardBrand = token.card.brand ?? "Card";
60914
+ const last4 = token.card.last4;
60915
+ const walletType = token.card.wallet?.type;
60916
+ if (walletType === "apple_pay" || walletType === "google_pay") {
60917
+ const funding = token.card.funding ? capitalize(token.card.funding) : null;
60918
+ return {
60919
+ label: last4 ? `${capitalize(cardBrand)} \u2022\u2022\u2022\u2022 ${last4}` : capitalize(cardBrand),
60920
+ sublabel: funding ?? "",
60921
+ brand: walletType
60922
+ };
60923
+ }
60317
60924
  return {
60318
- label: `${capitalize(brand)} \u2022\u2022\u2022\u2022 ${token.card.last4}`,
60925
+ label: `${capitalize(cardBrand)} \u2022\u2022\u2022\u2022 ${last4}`,
60319
60926
  sublabel: `${capitalize(token.card.funding ?? "card")} \xB7 Expires ${token.card.exp_month}/${token.card.exp_year}`,
60320
- brand
60927
+ brand: cardBrand
60321
60928
  };
60322
60929
  }
60323
60930
  if (token.us_bank_account) {
60931
+ const accountType = token.us_bank_account.account_type;
60324
60932
  return {
60325
60933
  label: `${token.us_bank_account.bank_name ?? "Bank"} \u2022\u2022\u2022\u2022 ${token.us_bank_account.last4}`,
60326
- sublabel: "Bank account"
60934
+ sublabel: accountType ? `${capitalize(accountType)} account` : "Bank account"
60327
60935
  };
60328
60936
  }
60329
60937
  return { label: "Payment method", sublabel: token.type };
@@ -60331,59 +60939,82 @@ function formatPaymentToken(token) {
60331
60939
  function capitalize(s) {
60332
60940
  return s.charAt(0).toUpperCase() + s.slice(1);
60333
60941
  }
60334
- function useStripeOnramp(stripePublishableKey) {
60335
- const [coordinator, setCoordinator] = (0, import_react22.useState)(null);
60336
- const [isLoading, setIsLoading] = (0, import_react22.useState)(false);
60337
- const [error, setError] = (0, import_react22.useState)(null);
60338
- const coordinatorRef = (0, import_react22.useRef)(null);
60339
- const initialize = (0, import_react22.useCallback)(async () => {
60340
- if (coordinatorRef.current) return coordinatorRef.current;
60341
- if (!stripePublishableKey) return null;
60342
- setIsLoading(true);
60343
- setError(null);
60344
- try {
60345
- console.log("[PayWithStripeLink] Importing @stripe/crypto...");
60346
- const { loadCryptoOnrampAndInitialize } = await import(
60347
- /* @vite-ignore */
60348
- "@stripe/crypto"
60349
- );
60350
- console.log(
60351
- "[PayWithStripeLink] @stripe/crypto imported, initializing with key:",
60352
- stripePublishableKey?.slice(0, 12) + "..."
60353
- );
60354
- const initPromise = loadCryptoOnrampAndInitialize(stripePublishableKey, { theme: "stripe" });
60355
- const timeoutPromise = new Promise(
60356
- (_, reject) => setTimeout(
60357
- () => reject(
60358
- new Error(
60359
- "Stripe SDK initialization timed out after 15 seconds. Check that your Stripe account has the Crypto Onramp feature enabled."
60360
- )
60361
- ),
60362
- 15e3
60363
- )
60364
- );
60365
- const instance = await Promise.race([initPromise, timeoutPromise]);
60366
- if (!instance) {
60367
- throw new Error("Stripe SDK returned null.");
60368
- }
60369
- console.log("[PayWithStripeLink] Stripe SDK initialized successfully");
60370
- coordinatorRef.current = instance;
60371
- setCoordinator(instance);
60372
- return coordinatorRef.current;
60373
- } catch (err) {
60374
- const raw = err instanceof Error ? err.message : String(err);
60375
- 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}`;
60376
- setError(msg);
60377
- console.error("[PayWithStripeLink]", msg);
60378
- return null;
60379
- } finally {
60380
- setIsLoading(false);
60381
- }
60942
+ function useStripeOnramp(stripePublishableKey, isDark = false) {
60943
+ const [coordinator, setCoordinator] = (0, import_react23.useState)(null);
60944
+ const [isLoading, setIsLoading] = (0, import_react23.useState)(false);
60945
+ const [error, setError] = (0, import_react23.useState)(null);
60946
+ const coordinatorRef = (0, import_react23.useRef)(null);
60947
+ const coordinatorThemeRef = (0, import_react23.useRef)(null);
60948
+ const initPromiseRef = (0, import_react23.useRef)(null);
60949
+ const isDarkRef = (0, import_react23.useRef)(isDark);
60950
+ isDarkRef.current = isDark;
60951
+ const initialize = (0, import_react23.useCallback)(() => {
60952
+ if (coordinatorRef.current) return Promise.resolve(coordinatorRef.current);
60953
+ if (initPromiseRef.current) return initPromiseRef.current;
60954
+ if (!stripePublishableKey) return Promise.resolve(null);
60955
+ const theme = isDarkRef.current;
60956
+ const promise = (async () => {
60957
+ setIsLoading(true);
60958
+ setError(null);
60959
+ try {
60960
+ console.log("[PayWithStripeLink] Importing @stripe/crypto...");
60961
+ const { loadCryptoOnrampAndInitialize } = await import(
60962
+ /* @vite-ignore */
60963
+ "@stripe/crypto"
60964
+ );
60965
+ console.log(
60966
+ "[PayWithStripeLink] @stripe/crypto imported, initializing with key:",
60967
+ stripePublishableKey?.slice(0, 12) + "..."
60968
+ );
60969
+ const initPromise = loadCryptoOnrampAndInitialize(stripePublishableKey, {
60970
+ theme: theme ? "night" : "stripe"
60971
+ });
60972
+ const timeoutPromise = new Promise(
60973
+ (_, reject) => setTimeout(
60974
+ () => reject(
60975
+ new Error(
60976
+ "Stripe SDK initialization timed out after 15 seconds. Check that your Stripe account has the Crypto Onramp feature enabled."
60977
+ )
60978
+ ),
60979
+ 15e3
60980
+ )
60981
+ );
60982
+ const instance = await Promise.race([initPromise, timeoutPromise]);
60983
+ if (!instance) {
60984
+ throw new Error("Stripe SDK returned null.");
60985
+ }
60986
+ console.log("[PayWithStripeLink] Stripe SDK initialized successfully");
60987
+ coordinatorRef.current = instance;
60988
+ coordinatorThemeRef.current = theme;
60989
+ setCoordinator(instance);
60990
+ return coordinatorRef.current;
60991
+ } catch (err) {
60992
+ const raw = err instanceof Error ? err.message : String(err);
60993
+ 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}`;
60994
+ setError(msg);
60995
+ console.error("[PayWithStripeLink]", msg);
60996
+ return null;
60997
+ } finally {
60998
+ setIsLoading(false);
60999
+ initPromiseRef.current = null;
61000
+ }
61001
+ })();
61002
+ initPromiseRef.current = promise;
61003
+ return promise;
60382
61004
  }, [stripePublishableKey]);
60383
- (0, import_react22.useEffect)(() => {
61005
+ (0, import_react23.useEffect)(() => {
61006
+ if (!coordinatorRef.current) return;
61007
+ if (coordinatorThemeRef.current === isDark) return;
61008
+ coordinatorRef.current.destroy();
61009
+ coordinatorRef.current = null;
61010
+ coordinatorThemeRef.current = null;
61011
+ setCoordinator(null);
61012
+ }, [isDark, coordinator]);
61013
+ (0, import_react23.useEffect)(() => {
60384
61014
  return () => {
60385
61015
  coordinatorRef.current?.destroy();
60386
61016
  coordinatorRef.current = null;
61017
+ coordinatorThemeRef.current = null;
60387
61018
  };
60388
61019
  }, []);
60389
61020
  return { coordinator, isLoading, error, initialize };
@@ -60534,21 +61165,23 @@ function PayWithStripeLink({
60534
61165
  onDepositSuccess,
60535
61166
  onDepositError
60536
61167
  }) {
60537
- const { colors: colors2, fonts, components } = useTheme();
60538
- const [step, setStepInternal] = (0, import_react21.useState)(controlledStep ?? "amount");
60539
- const setStep = (0, import_react21.useCallback)(
61168
+ const { colors: colors2, fonts, components, isDark } = useTheme();
61169
+ const [step, setStepInternal] = (0, import_react22.useState)(controlledStep ?? "amount");
61170
+ const setStep = (0, import_react22.useCallback)(
60540
61171
  (s) => {
60541
61172
  setStepInternal(s);
60542
61173
  onStepChange?.(s);
60543
61174
  },
60544
61175
  [onStepChange]
60545
61176
  );
60546
- (0, import_react21.useEffect)(() => {
61177
+ const stepRef = (0, import_react22.useRef)(step);
61178
+ stepRef.current = step;
61179
+ (0, import_react22.useEffect)(() => {
60547
61180
  if (controlledStep && controlledStep !== step) {
60548
61181
  setStepInternal(controlledStep);
60549
61182
  }
60550
61183
  }, [controlledStep]);
60551
- (0, import_react21.useEffect)(() => {
61184
+ (0, import_react22.useEffect)(() => {
60552
61185
  setLoading(false);
60553
61186
  setError(null);
60554
61187
  setKycPendingMessage(null);
@@ -60557,9 +61190,9 @@ function PayWithStripeLink({
60557
61190
  checkoutGenRef.current++;
60558
61191
  }
60559
61192
  }, [step]);
60560
- const [resolvedStripeKey, setResolvedStripeKey] = (0, import_react21.useState)();
60561
- const [configError, setConfigError] = (0, import_react21.useState)(null);
60562
- (0, import_react21.useEffect)(() => {
61193
+ const [resolvedStripeKey, setResolvedStripeKey] = (0, import_react22.useState)();
61194
+ const [configError, setConfigError] = (0, import_react22.useState)(null);
61195
+ (0, import_react22.useEffect)(() => {
60563
61196
  let active = true;
60564
61197
  const fetchConfig = async () => {
60565
61198
  try {
@@ -60582,7 +61215,7 @@ function PayWithStripeLink({
60582
61215
  active = false;
60583
61216
  };
60584
61217
  }, [publishableKey]);
60585
- (0, import_react21.useEffect)(() => {
61218
+ (0, import_react22.useEffect)(() => {
60586
61219
  if (step !== "auth" || resolvedStripeKey || configError) return;
60587
61220
  let active = true;
60588
61221
  const retryConfig = async () => {
@@ -60610,8 +61243,8 @@ function PayWithStripeLink({
60610
61243
  isLoading: sdkLoading,
60611
61244
  error: sdkError,
60612
61245
  initialize
60613
- } = useStripeOnramp(resolvedStripeKey);
60614
- (0, import_react21.useEffect)(() => {
61246
+ } = useStripeOnramp(resolvedStripeKey, isDark);
61247
+ (0, import_react22.useEffect)(() => {
60615
61248
  if (step === "auth") {
60616
61249
  console.log("[PayWithStripeLink] Auth step state:", {
60617
61250
  resolvedStripeKey: resolvedStripeKey ? resolvedStripeKey.slice(0, 15) + "..." : void 0,
@@ -60622,27 +61255,30 @@ function PayWithStripeLink({
60622
61255
  });
60623
61256
  }
60624
61257
  }, [step, resolvedStripeKey, coordinator, sdkLoading, sdkError, configError]);
60625
- const [email, setEmail] = (0, import_react21.useState)(emailProp ?? "");
60626
- const [phone, setPhone] = (0, import_react21.useState)("");
60627
- const [country, setCountry] = (0, import_react21.useState)("US");
60628
- const [loading, setLoading] = (0, import_react21.useState)(false);
60629
- const [error, setError] = (0, import_react21.useState)(null);
60630
- const [kycPendingMessage, setKycPendingMessage] = (0, import_react21.useState)(null);
60631
- const [kycRejectionReason, setKycRejectionReason] = (0, import_react21.useState)(null);
60632
- const [restoring, setRestoring] = (0, import_react21.useState)(true);
60633
- const [errorReturnStep, setErrorReturnStep] = (0, import_react21.useState)("email");
60634
- const [authIntentId, setAuthIntentId] = (0, import_react21.useState)(null);
60635
- const sdkAuthenticatedRef = (0, import_react21.useRef)(false);
60636
- const pendingAddPaymentRef = (0, import_react21.useRef)(false);
60637
- const autoOpenedAddPaymentRef = (0, import_react21.useRef)(false);
60638
- const checkoutGenRef = (0, import_react21.useRef)(0);
60639
- const [stripePaymentUIReady, setStripePaymentUIReady] = (0, import_react21.useState)(false);
60640
- const [oauthToken, setOauthToken] = (0, import_react21.useState)(null);
60641
- const [refreshTokenValue, setRefreshTokenValue] = (0, import_react21.useState)(null);
60642
- const [customerId, setCustomerId] = (0, import_react21.useState)(null);
60643
- const accessTokenRef = (0, import_react21.useRef)("");
60644
- const refreshTokenRef = (0, import_react21.useRef)("");
60645
- const persistSession = (0, import_react21.useCallback)(
61258
+ const [email, setEmail] = (0, import_react22.useState)(emailProp ?? "");
61259
+ const [phone, setPhone] = (0, import_react22.useState)("");
61260
+ const [country, setCountry] = (0, import_react22.useState)("US");
61261
+ const [loading, setLoading] = (0, import_react22.useState)(false);
61262
+ const [error, setError] = (0, import_react22.useState)(null);
61263
+ const [kycPendingMessage, setKycPendingMessage] = (0, import_react22.useState)(null);
61264
+ const [kycRejectionReason, setKycRejectionReason] = (0, import_react22.useState)(null);
61265
+ const [restoring, setRestoring] = (0, import_react22.useState)(true);
61266
+ const [errorReturnStep, setErrorReturnStep] = (0, import_react22.useState)("email");
61267
+ const [authIntentId, setAuthIntentId] = (0, import_react22.useState)(null);
61268
+ const sdkAuthenticatedRef = (0, import_react22.useRef)(false);
61269
+ const everAuthenticatedRef = (0, import_react22.useRef)(false);
61270
+ const reauthReturnStepRef = (0, import_react22.useRef)(null);
61271
+ const attemptedWalletReauthRef = (0, import_react22.useRef)(false);
61272
+ const pendingAddPaymentRef = (0, import_react22.useRef)(false);
61273
+ const autoOpenedAddPaymentRef = (0, import_react22.useRef)(false);
61274
+ const checkoutGenRef = (0, import_react22.useRef)(0);
61275
+ const [stripePaymentUIReady, setStripePaymentUIReady] = (0, import_react22.useState)(false);
61276
+ const [oauthToken, setOauthToken] = (0, import_react22.useState)(null);
61277
+ const [refreshTokenValue, setRefreshTokenValue] = (0, import_react22.useState)(null);
61278
+ const [customerId, setCustomerId] = (0, import_react22.useState)(null);
61279
+ const accessTokenRef = (0, import_react22.useRef)("");
61280
+ const refreshTokenRef = (0, import_react22.useRef)("");
61281
+ const persistSession = (0, import_react22.useCallback)(
60646
61282
  (cid, token, refresh, expiresIn, loginEmail) => {
60647
61283
  accessTokenRef.current = token;
60648
61284
  refreshTokenRef.current = refresh;
@@ -60656,8 +61292,8 @@ function PayWithStripeLink({
60656
61292
  },
60657
61293
  [userId, email]
60658
61294
  );
60659
- const refreshInFlightRef = (0, import_react21.useRef)(null);
60660
- const tryRefreshToken = (0, import_react21.useCallback)(async () => {
61295
+ const refreshInFlightRef = (0, import_react22.useRef)(null);
61296
+ const tryRefreshToken = (0, import_react22.useCallback)(async () => {
60661
61297
  if (refreshInFlightRef.current) return refreshInFlightRef.current;
60662
61298
  const rt = refreshTokenRef.current;
60663
61299
  if (!rt) return null;
@@ -60687,7 +61323,7 @@ function PayWithStripeLink({
60687
61323
  refreshInFlightRef.current = doRefresh();
60688
61324
  return refreshInFlightRef.current;
60689
61325
  }, [publishableKey, customerId, persistSession, userId]);
60690
- const withTokenRefresh = (0, import_react21.useCallback)(
61326
+ const withTokenRefresh = (0, import_react22.useCallback)(
60691
61327
  async (fn) => {
60692
61328
  const token = accessTokenRef.current;
60693
61329
  if (!token) {
@@ -60715,7 +61351,7 @@ function PayWithStripeLink({
60715
61351
  },
60716
61352
  [tryRefreshToken, setStep]
60717
61353
  );
60718
- (0, import_react21.useEffect)(() => {
61354
+ (0, import_react22.useEffect)(() => {
60719
61355
  const stored = getStoredStripeSession(userId);
60720
61356
  console.log("[PayWithStripeLink] Restore check:", {
60721
61357
  hasStored: !!stored,
@@ -60806,9 +61442,9 @@ function PayWithStripeLink({
60806
61442
  cancelled = true;
60807
61443
  };
60808
61444
  }, [userId, publishableKey]);
60809
- const [customer, setCustomer] = (0, import_react21.useState)(null);
60810
- const [kycFormMode, setKycFormMode] = (0, import_react21.useState)("name");
60811
- const [kycForm, setKycForm] = (0, import_react21.useState)({
61445
+ const [customer, setCustomer] = (0, import_react22.useState)(null);
61446
+ const [kycFormMode, setKycFormMode] = (0, import_react22.useState)("name");
61447
+ const [kycForm, setKycForm] = (0, import_react22.useState)({
60812
61448
  givenName: "",
60813
61449
  surname: "",
60814
61450
  dob: { day: "", month: "", year: "" },
@@ -60820,7 +61456,7 @@ function PayWithStripeLink({
60820
61456
  addressPostalCode: "",
60821
61457
  addressCountry: "US"
60822
61458
  });
60823
- (0, import_react21.useEffect)(() => {
61459
+ (0, import_react22.useEffect)(() => {
60824
61460
  if (!backHandlerRef) return;
60825
61461
  backHandlerRef.current = () => {
60826
61462
  if (step === "kyc_form" && kycFormMode === "address") {
@@ -60831,6 +61467,7 @@ function PayWithStripeLink({
60831
61467
  if (step === "auth" && (pendingAddPaymentRef.current || !!accessTokenRef.current)) {
60832
61468
  pendingAddPaymentRef.current = false;
60833
61469
  autoOpenedAddPaymentRef.current = false;
61470
+ reauthReturnStepRef.current = null;
60834
61471
  setError(null);
60835
61472
  setStep("amount");
60836
61473
  return true;
@@ -60841,24 +61478,41 @@ function PayWithStripeLink({
60841
61478
  backHandlerRef.current = null;
60842
61479
  };
60843
61480
  }, [backHandlerRef, step, kycFormMode]);
60844
- const [wallets, setWallets] = (0, import_react21.useState)([]);
60845
- const [paymentTokens, setPaymentTokens] = (0, import_react21.useState)([]);
60846
- const [storedSelectedToken, setStoredSelectedTokenState] = (0, import_react21.useState)(
61481
+ const [wallets, setWallets] = (0, import_react22.useState)([]);
61482
+ const [paymentTokens, setPaymentTokens] = (0, import_react22.useState)([]);
61483
+ const [storedSelectedToken, setStoredSelectedTokenState] = (0, import_react22.useState)(
60847
61484
  null
60848
61485
  );
60849
- const [selectedPaymentToken, setSelectedPaymentToken] = (0, import_react21.useState)(null);
60850
- const [paymentDisplay, setPaymentDisplay] = (0, import_react21.useState)(null);
60851
- const selectPaymentToken = (0, import_react21.useCallback)(
61486
+ const [selectedPaymentToken, setSelectedPaymentToken] = (0, import_react22.useState)(null);
61487
+ const [paymentDisplay, setPaymentDisplay] = (0, import_react22.useState)(null);
61488
+ const selectedTokenSingleUseRef = (0, import_react22.useRef)(false);
61489
+ const selectPaymentToken = (0, import_react22.useCallback)(
60852
61490
  (token) => {
61491
+ selectedTokenSingleUseRef.current = !!token.singleUse;
60853
61492
  setSelectedPaymentToken(token.id);
60854
61493
  setPaymentDisplay(
60855
61494
  token.label ? { label: token.label, sublabel: token.sublabel, brand: token.brand } : null
60856
61495
  );
60857
61496
  setStoredSelectedTokenState(token);
60858
- if (customerId) setStoredSelectedToken(customerId, token);
61497
+ if (customerId && !token.singleUse) setStoredSelectedToken(customerId, token);
60859
61498
  },
60860
61499
  [customerId]
60861
61500
  );
61501
+ const clearSelectedPaymentToken = (0, import_react22.useCallback)(() => {
61502
+ selectedTokenSingleUseRef.current = false;
61503
+ const persisted = customerId ? getStoredSelectedToken(customerId) : null;
61504
+ if (persisted && !persisted.singleUse) {
61505
+ setSelectedPaymentToken(persisted.id);
61506
+ setPaymentDisplay(
61507
+ persisted.label ? { label: persisted.label, sublabel: persisted.sublabel, brand: persisted.brand } : null
61508
+ );
61509
+ setStoredSelectedTokenState(persisted);
61510
+ } else {
61511
+ setSelectedPaymentToken(null);
61512
+ setPaymentDisplay(null);
61513
+ setStoredSelectedTokenState(null);
61514
+ }
61515
+ }, [customerId]);
60862
61516
  const displayPaymentTokens = (() => {
60863
61517
  const apiDisplay = paymentTokens.map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) }));
60864
61518
  if (storedSelectedToken && !paymentTokens.some((t13) => t13.id === storedSelectedToken.id)) {
@@ -60866,7 +61520,7 @@ function PayWithStripeLink({
60866
61520
  }
60867
61521
  return apiDisplay;
60868
61522
  })();
60869
- (0, import_react21.useEffect)(() => {
61523
+ (0, import_react22.useEffect)(() => {
60870
61524
  if (!customerId) return;
60871
61525
  const stored = getStoredSelectedToken(customerId);
60872
61526
  if (stored) {
@@ -60877,19 +61531,19 @@ function PayWithStripeLink({
60877
61531
  );
60878
61532
  }
60879
61533
  }, [customerId]);
60880
- const [amount, setAmount] = (0, import_react21.useState)("");
60881
- (0, import_react21.useEffect)(() => {
61534
+ const [amount, setAmount] = (0, import_react22.useState)("");
61535
+ (0, import_react22.useEffect)(() => {
60882
61536
  console.log("[PayWithStripeLink] Component mounted/remounted. Amount:", amount, "Step:", step);
60883
61537
  }, []);
60884
61538
  const sourceCurrency = "usd";
60885
61539
  const extractRefreshToken = (res) => res.refresh_token ?? res.refresh?.refresh_token ?? "";
60886
- const [stripeDestCurrency, setStripeDestCurrency] = (0, import_react21.useState)("usdc");
60887
- const [stripeDestNetwork, setStripeDestNetwork] = (0, import_react21.useState)("base");
60888
- const [stripeDestChainType, setStripeDestChainType] = (0, import_react21.useState)("ethereum");
60889
- const [stripeTokenSymbol, setStripeTokenSymbol] = (0, import_react21.useState)("USDC");
60890
- const [stripeTokenIconUrl, setStripeTokenIconUrl] = (0, import_react21.useState)(null);
60891
- const [stripeNetworkName, setStripeNetworkName] = (0, import_react21.useState)("Base");
60892
- (0, import_react21.useEffect)(() => {
61540
+ const [stripeDestCurrency, setStripeDestCurrency] = (0, import_react22.useState)("usdc");
61541
+ const [stripeDestNetwork, setStripeDestNetwork] = (0, import_react22.useState)("base");
61542
+ const [stripeDestChainType, setStripeDestChainType] = (0, import_react22.useState)("ethereum");
61543
+ const [stripeTokenSymbol, setStripeTokenSymbol] = (0, import_react22.useState)("USDC");
61544
+ const [stripeTokenIconUrl, setStripeTokenIconUrl] = (0, import_react22.useState)(null);
61545
+ const [stripeNetworkName, setStripeNetworkName] = (0, import_react22.useState)("Base");
61546
+ (0, import_react22.useEffect)(() => {
60893
61547
  if (!destinationTokenAddress || !destinationChainId || !destinationChainType) return;
60894
61548
  let cancelled = false;
60895
61549
  stripeGetDefaultToken(
@@ -60917,26 +61571,26 @@ function PayWithStripeLink({
60917
61571
  };
60918
61572
  }, [publishableKey, destinationTokenAddress, destinationChainId, destinationChainType]);
60919
61573
  const destinationCurrency = stripeDestCurrency;
60920
- const authInnerRef = (0, import_react21.useRef)(null);
60921
- const paymentInnerRef = (0, import_react21.useRef)(null);
60922
- const [authReady, setAuthReady] = (0, import_react21.useState)(false);
61574
+ const authInnerRef = (0, import_react22.useRef)(null);
61575
+ const paymentInnerRef = (0, import_react22.useRef)(null);
61576
+ const [authReady, setAuthReady] = (0, import_react22.useState)(false);
60923
61577
  if (typeof document !== "undefined" && !authInnerRef.current) {
60924
61578
  authInnerRef.current = document.createElement("div");
60925
61579
  }
60926
61580
  if (typeof document !== "undefined" && !paymentInnerRef.current) {
60927
61581
  paymentInnerRef.current = document.createElement("div");
60928
61582
  }
60929
- const authMountRef = (0, import_react21.useCallback)((node) => {
61583
+ const authMountRef = (0, import_react22.useCallback)((node) => {
60930
61584
  if (node && !node.contains(authInnerRef.current)) {
60931
61585
  node.appendChild(authInnerRef.current);
60932
61586
  }
60933
61587
  }, []);
60934
- const paymentMountRef = (0, import_react21.useCallback)((node) => {
61588
+ const paymentMountRef = (0, import_react22.useCallback)((node) => {
60935
61589
  if (node && !node.contains(paymentInnerRef.current)) {
60936
61590
  node.appendChild(paymentInnerRef.current);
60937
61591
  }
60938
61592
  }, []);
60939
- (0, import_react21.useEffect)(() => {
61593
+ (0, import_react22.useEffect)(() => {
60940
61594
  return () => {
60941
61595
  authInnerRef.current?.remove();
60942
61596
  paymentInnerRef.current?.remove();
@@ -60954,10 +61608,10 @@ function PayWithStripeLink({
60954
61608
  });
60955
61609
  const depositWallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
60956
61610
  const onrampWalletAddress = getWalletByChainType(depositWallets, stripeDestChainType)?.address;
60957
- const [registeredWalletKey, setRegisteredWalletKey] = (0, import_react21.useState)(null);
61611
+ const [registeredWalletKey, setRegisteredWalletKey] = (0, import_react22.useState)(null);
60958
61612
  const walletKeyFor = (address) => `${stripeDestNetwork}:${stripeDestChainType === "ethereum" ? address.toLowerCase() : address}`;
60959
61613
  const isOnrampWalletRegistered = !!onrampWalletAddress && registeredWalletKey === walletKeyFor(onrampWalletAddress);
60960
- (0, import_react21.useEffect)(() => {
61614
+ (0, import_react22.useEffect)(() => {
60961
61615
  if (depositWallets.length > 0 && !onrampWalletAddress) {
60962
61616
  console.warn(
60963
61617
  "[PayWithStripeLink] No deposit-intent wallet matches Stripe chain type",
@@ -60980,14 +61634,14 @@ function PayWithStripeLink({
60980
61634
  onDepositSuccess,
60981
61635
  onDepositError
60982
61636
  });
60983
- const [confirmedSessionId, setConfirmedSessionId] = (0, import_react21.useState)(null);
60984
- const [sessionStatus, setSessionStatus] = (0, import_react21.useState)(null);
60985
- const handledTerminalSessionRef = (0, import_react21.useRef)(null);
60986
- const executionReconciledSessionRef = (0, import_react21.useRef)(null);
61637
+ const [confirmedSessionId, setConfirmedSessionId] = (0, import_react22.useState)(null);
61638
+ const [sessionStatus, setSessionStatus] = (0, import_react22.useState)(null);
61639
+ const handledTerminalSessionRef = (0, import_react22.useRef)(null);
61640
+ const executionReconciledSessionRef = (0, import_react22.useRef)(null);
60987
61641
  const hasExecution = executions.length > 0;
60988
61642
  const isSessionFulfilled = sessionStatus === STRIPE_SESSION_STATUS.FULFILLMENT_COMPLETE || hasExecution;
60989
61643
  const isSessionFailed = !hasExecution && (sessionStatus === STRIPE_SESSION_STATUS.REJECTED || sessionStatus === STRIPE_SESSION_STATUS.EXPIRED);
60990
- (0, import_react21.useEffect)(() => {
61644
+ (0, import_react22.useEffect)(() => {
60991
61645
  if (step !== "success" || !hasExecution || !confirmedSessionId) return;
60992
61646
  if (executionReconciledSessionRef.current === confirmedSessionId) return;
60993
61647
  executionReconciledSessionRef.current = confirmedSessionId;
@@ -61005,7 +61659,7 @@ function PayWithStripeLink({
61005
61659
  cancelled = true;
61006
61660
  };
61007
61661
  }, [step, hasExecution, confirmedSessionId, withTokenRefresh, publishableKey]);
61008
- (0, import_react21.useEffect)(() => {
61662
+ (0, import_react22.useEffect)(() => {
61009
61663
  if (step !== "success" || !confirmedSessionId) return;
61010
61664
  if (hasExecution) return;
61011
61665
  if (handledTerminalSessionRef.current === confirmedSessionId) return;
@@ -61092,12 +61746,16 @@ function PayWithStripeLink({
61092
61746
  setLoading(false);
61093
61747
  }
61094
61748
  };
61095
- (0, import_react21.useEffect)(() => {
61749
+ (0, import_react22.useEffect)(() => {
61096
61750
  if (coordinator || sdkLoading || sdkError) return;
61097
61751
  if (!resolvedStripeKey) return;
61098
61752
  initialize();
61099
61753
  }, [coordinator, sdkLoading, sdkError, resolvedStripeKey, initialize]);
61100
- const handleAuthInterrupted = (0, import_react21.useCallback)(
61754
+ (0, import_react22.useEffect)(() => {
61755
+ sdkAuthenticatedRef.current = false;
61756
+ attemptedWalletReauthRef.current = false;
61757
+ }, [coordinator]);
61758
+ const handleAuthInterrupted = (0, import_react22.useCallback)(
61101
61759
  (message) => {
61102
61760
  const alreadySignedIn = !!accessTokenRef.current;
61103
61761
  if (alreadySignedIn || emailProp) {
@@ -61110,7 +61768,27 @@ function PayWithStripeLink({
61110
61768
  },
61111
61769
  [emailProp, setStep]
61112
61770
  );
61113
- (0, import_react21.useEffect)(() => {
61771
+ const reauthenticateSdk = (0, import_react22.useCallback)(async () => {
61772
+ const current = stepRef.current;
61773
+ const preAuthSteps = ["email", "register", "auth"];
61774
+ reauthReturnStepRef.current = preAuthSteps.includes(current) ? null : current;
61775
+ const knownEmail = (email || emailProp || "").trim();
61776
+ if (!knownEmail) {
61777
+ reauthReturnStepRef.current = null;
61778
+ setStep("email");
61779
+ return;
61780
+ }
61781
+ try {
61782
+ const authResult = await stripeCreateAuthIntent(knownEmail, publishableKey);
61783
+ setAuthIntentId(authResult.auth_intent_id);
61784
+ setStep("auth");
61785
+ } catch (err) {
61786
+ reauthReturnStepRef.current = null;
61787
+ setError(err instanceof Error ? err.message : "Failed to re-verify. Please try again.");
61788
+ setStep("email");
61789
+ }
61790
+ }, [email, emailProp, publishableKey]);
61791
+ (0, import_react22.useEffect)(() => {
61114
61792
  if (step !== "auth" || !coordinator || !authIntentId) return;
61115
61793
  let mounted = true;
61116
61794
  const runAuth = async () => {
@@ -61120,6 +61798,7 @@ function PayWithStripeLink({
61120
61798
  if (result.result === "success" && result.crypto_customer_id) {
61121
61799
  setCustomerId(result.crypto_customer_id);
61122
61800
  sdkAuthenticatedRef.current = true;
61801
+ everAuthenticatedRef.current = true;
61123
61802
  const tokens = await stripeExchangeTokens(authIntentId, publishableKey);
61124
61803
  setOauthToken(tokens.access_token);
61125
61804
  const refresh = extractRefreshToken(tokens);
@@ -61133,16 +61812,22 @@ function PayWithStripeLink({
61133
61812
  tokens.expires_in ?? 3600,
61134
61813
  email.trim()
61135
61814
  );
61815
+ const resumeStep = reauthReturnStepRef.current;
61816
+ reauthReturnStepRef.current = null;
61136
61817
  if (pendingAddPaymentRef.current) {
61137
61818
  setStep("payment");
61819
+ } else if (resumeStep) {
61820
+ setStep(resumeStep);
61138
61821
  } else {
61139
61822
  setStep("kyc");
61140
61823
  }
61141
61824
  } else if (result.result === "abandoned") {
61142
61825
  pendingAddPaymentRef.current = false;
61826
+ reauthReturnStepRef.current = null;
61143
61827
  handleAuthInterrupted("Verification was cancelled.");
61144
61828
  } else if (result.result === "declined") {
61145
61829
  pendingAddPaymentRef.current = false;
61830
+ reauthReturnStepRef.current = null;
61146
61831
  handleAuthInterrupted("You must consent to continue.");
61147
61832
  }
61148
61833
  });
@@ -61154,6 +61839,7 @@ function PayWithStripeLink({
61154
61839
  }
61155
61840
  } catch (err) {
61156
61841
  if (!mounted) return;
61842
+ reauthReturnStepRef.current = null;
61157
61843
  const msg = err instanceof Error ? err.message : "Verification was cancelled.";
61158
61844
  handleAuthInterrupted(msg);
61159
61845
  }
@@ -61165,7 +61851,7 @@ function PayWithStripeLink({
61165
61851
  authInnerRef.current.replaceChildren();
61166
61852
  };
61167
61853
  }, [step, coordinator, authIntentId, publishableKey]);
61168
- (0, import_react21.useEffect)(() => {
61854
+ (0, import_react22.useEffect)(() => {
61169
61855
  if (step !== "kyc" || !oauthToken || !customerId) return;
61170
61856
  let mounted = true;
61171
61857
  let pollTimer = null;
@@ -61255,6 +61941,10 @@ function PayWithStripeLink({
61255
61941
  };
61256
61942
  const handleKycSubmit = async () => {
61257
61943
  if (!coordinator) return;
61944
+ if (!sdkAuthenticatedRef.current) {
61945
+ await reauthenticateSdk();
61946
+ return;
61947
+ }
61258
61948
  let kycInfo;
61259
61949
  if (kycFormMode === "address") {
61260
61950
  if (!kycForm.givenName.trim() || !kycForm.surname.trim()) {
@@ -61309,11 +61999,15 @@ function PayWithStripeLink({
61309
61999
  setLoading(false);
61310
62000
  }
61311
62001
  };
61312
- (0, import_react21.useEffect)(() => {
62002
+ (0, import_react22.useEffect)(() => {
61313
62003
  if (step !== "kyc_document" || !coordinator) return;
61314
62004
  let mounted = true;
61315
62005
  const verify = async () => {
61316
62006
  try {
62007
+ if (!sdkAuthenticatedRef.current) {
62008
+ await reauthenticateSdk();
62009
+ return;
62010
+ }
61317
62011
  const result = await coordinator.verifyDocuments();
61318
62012
  if (!mounted) return;
61319
62013
  const outcome = typeof result === "string" ? result : result?.result;
@@ -61333,8 +62027,8 @@ function PayWithStripeLink({
61333
62027
  return () => {
61334
62028
  mounted = false;
61335
62029
  };
61336
- }, [step, coordinator]);
61337
- (0, import_react21.useEffect)(() => {
62030
+ }, [step, coordinator, reauthenticateSdk]);
62031
+ (0, import_react22.useEffect)(() => {
61338
62032
  if (step !== "wallet" || !oauthToken || !customerId) return;
61339
62033
  let mounted = true;
61340
62034
  const setupWallet = async () => {
@@ -61359,6 +62053,10 @@ function PayWithStripeLink({
61359
62053
  if (!coordinator) {
61360
62054
  return;
61361
62055
  }
62056
+ if (!sdkAuthenticatedRef.current) {
62057
+ await reauthenticateSdk();
62058
+ return;
62059
+ }
61362
62060
  await coordinator.registerWalletAddress(onrampWalletAddress, network);
61363
62061
  }
61364
62062
  if (mounted) setRegisteredWalletKey(walletKeyFor(onrampWalletAddress));
@@ -61375,8 +62073,16 @@ function PayWithStripeLink({
61375
62073
  return () => {
61376
62074
  mounted = false;
61377
62075
  };
61378
- }, [step, oauthToken, customerId, publishableKey, onrampWalletAddress, coordinator]);
61379
- (0, import_react21.useEffect)(() => {
62076
+ }, [
62077
+ step,
62078
+ oauthToken,
62079
+ customerId,
62080
+ publishableKey,
62081
+ onrampWalletAddress,
62082
+ coordinator,
62083
+ reauthenticateSdk
62084
+ ]);
62085
+ (0, import_react22.useEffect)(() => {
61380
62086
  if (step !== "amount" && step !== "review") return;
61381
62087
  if (!customerId || !oauthToken || !onrampWalletAddress) return;
61382
62088
  if (isOnrampWalletRegistered) return;
@@ -61404,6 +62110,10 @@ function PayWithStripeLink({
61404
62110
  if (coordinator && sdkAuthenticatedRef.current) {
61405
62111
  await coordinator.registerWalletAddress(onrampWalletAddress, network);
61406
62112
  if (!cancelled) setRegisteredWalletKey(walletKeyFor(onrampWalletAddress));
62113
+ } else if (coordinator && everAuthenticatedRef.current && !attemptedWalletReauthRef.current) {
62114
+ attemptedWalletReauthRef.current = true;
62115
+ await reauthenticateSdk();
62116
+ return;
61407
62117
  }
61408
62118
  } catch {
61409
62119
  }
@@ -61421,9 +62131,10 @@ function PayWithStripeLink({
61421
62131
  coordinator,
61422
62132
  stripeDestNetwork,
61423
62133
  stripeDestChainType,
61424
- publishableKey
62134
+ publishableKey,
62135
+ reauthenticateSdk
61425
62136
  ]);
61426
- (0, import_react21.useEffect)(() => {
62137
+ (0, import_react22.useEffect)(() => {
61427
62138
  if (step !== "payment" || !oauthToken || !customerId) return;
61428
62139
  if (pendingAddPaymentRef.current) {
61429
62140
  pendingAddPaymentRef.current = false;
@@ -61486,7 +62197,7 @@ function PayWithStripeLink({
61486
62197
  paymentInnerRef.current.replaceChildren();
61487
62198
  };
61488
62199
  }, [step, oauthToken, customerId, publishableKey, coordinator]);
61489
- (0, import_react21.useEffect)(() => {
62200
+ (0, import_react22.useEffect)(() => {
61490
62201
  if (step !== "add_payment") return;
61491
62202
  if (!isCustomerVerified(customer)) {
61492
62203
  setStep("kyc");
@@ -61518,6 +62229,32 @@ function PayWithStripeLink({
61518
62229
  if (!mounted) return;
61519
62230
  const tokenId = result.cryptoPaymentToken;
61520
62231
  let display = null;
62232
+ const pmd = result.paymentMethodDetails;
62233
+ if (pmd) {
62234
+ display = formatPaymentToken(pmd);
62235
+ }
62236
+ const singleUse = pmd?.type === "card" && !!pmd.card.wallet;
62237
+ const applyAndAdvance = () => {
62238
+ selectPaymentToken({
62239
+ id: tokenId,
62240
+ label: display?.label ?? "",
62241
+ sublabel: display?.sublabel ?? "",
62242
+ brand: display?.brand,
62243
+ singleUse
62244
+ });
62245
+ autoOpenedAddPaymentRef.current = false;
62246
+ setStep("amount");
62247
+ };
62248
+ if (display) {
62249
+ applyAndAdvance();
62250
+ if (customerId && accessTokenRef.current) {
62251
+ stripeListPaymentTokens(customerId, accessTokenRef.current, publishableKey).then((tokens) => {
62252
+ if (mounted) setPaymentTokens(tokens.data);
62253
+ }).catch(() => {
62254
+ });
62255
+ }
62256
+ return;
62257
+ }
61521
62258
  try {
61522
62259
  if (customerId && accessTokenRef.current) {
61523
62260
  const tokens = await stripeListPaymentTokens(
@@ -61525,28 +62262,15 @@ function PayWithStripeLink({
61525
62262
  accessTokenRef.current,
61526
62263
  publishableKey
61527
62264
  );
62265
+ if (!mounted) return;
62266
+ setPaymentTokens(tokens.data);
61528
62267
  const match = tokens.data.find((t13) => t13.id === tokenId);
61529
- if (match) {
61530
- display = formatPaymentToken(match);
61531
- setPaymentTokens(tokens.data);
61532
- }
62268
+ if (match) display = formatPaymentToken(match);
61533
62269
  }
61534
62270
  } catch {
61535
62271
  }
61536
- if (!display) {
61537
- const dd = result.displayData;
61538
- if (dd?.label) {
61539
- display = { label: dd.label, sublabel: dd.sublabel ?? "", brand: dd.type };
61540
- }
61541
- }
61542
- selectPaymentToken({
61543
- id: tokenId,
61544
- label: display?.label ?? "",
61545
- sublabel: display?.sublabel ?? "",
61546
- brand: display?.brand
61547
- });
61548
- autoOpenedAddPaymentRef.current = false;
61549
- setStep("amount");
62272
+ if (!mounted) return;
62273
+ applyAndAdvance();
61550
62274
  }
61551
62275
  );
61552
62276
  if (mounted && el) {
@@ -61583,6 +62307,10 @@ function PayWithStripeLink({
61583
62307
  const handleCheckout = async () => {
61584
62308
  if (!amount || !oauthToken || !customerId || !selectedPaymentToken || !onrampWalletAddress || !isOnrampWalletRegistered || !coordinator)
61585
62309
  return;
62310
+ if (!sdkAuthenticatedRef.current) {
62311
+ await reauthenticateSdk();
62312
+ return;
62313
+ }
61586
62314
  const gen = ++checkoutGenRef.current;
61587
62315
  const isStale2 = () => checkoutGenRef.current !== gen;
61588
62316
  const surfaceStepUpOnAmount = (err, message, tier) => {
@@ -61694,6 +62422,7 @@ function PayWithStripeLink({
61694
62422
  executionReconciledSessionRef.current = null;
61695
62423
  setConfirmedSessionId(activeSessionId);
61696
62424
  setSessionStatus(STRIPE_SESSION_STATUS.FULFILLMENT_PROCESSING);
62425
+ if (selectedTokenSingleUseRef.current) clearSelectedPaymentToken();
61697
62426
  setStep("success");
61698
62427
  } else if (lastError === "quote_rate_drifted" || lastError === "charged_with_expired_quote") {
61699
62428
  setSessionForCheckout(null);
@@ -61736,15 +62465,34 @@ function PayWithStripeLink({
61736
62465
  setLoading(false);
61737
62466
  }
61738
62467
  };
61739
- const [quote, setQuote] = (0, import_react21.useState)(null);
61740
- const [quoteLoading, setQuoteLoading] = (0, import_react21.useState)(false);
61741
- const quoteTimerRef = (0, import_react21.useRef)(null);
61742
- const [sessionForCheckout, setSessionForCheckoutState] = (0, import_react21.useState)(null);
61743
- const sessionForCheckoutRef = (0, import_react21.useRef)(sessionForCheckout);
62468
+ const [quote, setQuote] = (0, import_react22.useState)(null);
62469
+ const [quoteLoading, setQuoteLoading] = (0, import_react22.useState)(false);
62470
+ const quoteTimerRef = (0, import_react22.useRef)(null);
62471
+ const [sessionForCheckout, setSessionForCheckoutState] = (0, import_react22.useState)(null);
62472
+ const sessionForCheckoutRef = (0, import_react22.useRef)(sessionForCheckout);
61744
62473
  const setSessionForCheckout = (s) => {
61745
62474
  sessionForCheckoutRef.current = s;
61746
62475
  setSessionForCheckoutState(s);
61747
62476
  };
62477
+ const loadAndSelectPreferredToken = (0, import_react22.useCallback)(async () => {
62478
+ if (!customerId) return;
62479
+ try {
62480
+ const existing = await withTokenRefresh(
62481
+ (tok) => stripeListPaymentTokens(customerId, tok, publishableKey)
62482
+ );
62483
+ setPaymentTokens(existing.data);
62484
+ const stored = getStoredSelectedToken(customerId);
62485
+ const merged = [
62486
+ ...existing.data.map((t13) => ({ id: t13.id, ...formatPaymentToken(t13) })),
62487
+ ...stored && !existing.data.some((t13) => t13.id === stored.id) ? [stored] : []
62488
+ ];
62489
+ if (merged.length > 0) {
62490
+ const preferred = stored && merged.find((m) => m.id === stored.id) || merged[0];
62491
+ selectPaymentToken(preferred);
62492
+ }
62493
+ } catch {
62494
+ }
62495
+ }, [customerId, publishableKey, selectPaymentToken, withTokenRefresh]);
61748
62496
  const handleDone = () => {
61749
62497
  handledTerminalSessionRef.current = null;
61750
62498
  executionReconciledSessionRef.current = null;
@@ -61752,14 +62500,15 @@ function PayWithStripeLink({
61752
62500
  setSessionStatus(null);
61753
62501
  setSessionForCheckout(null);
61754
62502
  setStep("amount");
62503
+ if (!selectedPaymentToken) void loadAndSelectPreferredToken();
61755
62504
  };
61756
- const [quoteError, setQuoteError] = (0, import_react21.useState)(null);
61757
- const [quoteNonce, setQuoteNonce] = (0, import_react21.useState)(0);
61758
- const quoteNonceAtReviewRef = (0, import_react21.useRef)(quoteNonce);
61759
- const [purchaseLimit, setPurchaseLimit] = (0, import_react21.useState)(null);
61760
- const [limitReachedAmount, setLimitReachedAmount] = (0, import_react21.useState)(null);
61761
- const [requiredStepUp, setRequiredStepUp] = (0, import_react21.useState)(null);
61762
- (0, import_react21.useEffect)(() => {
62505
+ const [quoteError, setQuoteError] = (0, import_react22.useState)(null);
62506
+ const [quoteNonce, setQuoteNonce] = (0, import_react22.useState)(0);
62507
+ const quoteNonceAtReviewRef = (0, import_react22.useRef)(quoteNonce);
62508
+ const [purchaseLimit, setPurchaseLimit] = (0, import_react22.useState)(null);
62509
+ const [limitReachedAmount, setLimitReachedAmount] = (0, import_react22.useState)(null);
62510
+ const [requiredStepUp, setRequiredStepUp] = (0, import_react22.useState)(null);
62511
+ (0, import_react22.useEffect)(() => {
61763
62512
  if (step !== "amount" || !customerId || !onrampWalletAddress) return;
61764
62513
  if (!accessTokenRef.current) return;
61765
62514
  let cancelled = false;
@@ -61812,7 +62561,7 @@ function PayWithStripeLink({
61812
62561
  setQuoteError(null);
61813
62562
  setRequiredStepUp(null);
61814
62563
  };
61815
- (0, import_react21.useEffect)(() => {
62564
+ (0, import_react22.useEffect)(() => {
61816
62565
  if (step === "review") {
61817
62566
  const existing = sessionForCheckoutRef.current;
61818
62567
  const hasFreshSession = !!(existing && existing.amount === amount && existing.paymentToken === selectedPaymentToken);
@@ -61944,9 +62693,9 @@ function PayWithStripeLink({
61944
62693
  quoteNonce
61945
62694
  ]);
61946
62695
  const QUOTE_TTL = 30;
61947
- const [quoteCountdown, setQuoteCountdown] = (0, import_react21.useState)(QUOTE_TTL);
62696
+ const [quoteCountdown, setQuoteCountdown] = (0, import_react22.useState)(QUOTE_TTL);
61948
62697
  const hasReviewSession = !!(customerId && selectedPaymentToken && onrampWalletAddress);
61949
- (0, import_react21.useEffect)(() => {
62698
+ (0, import_react22.useEffect)(() => {
61950
62699
  if (step !== "review" || !hasReviewSession) return;
61951
62700
  quoteNonceAtReviewRef.current = quoteNonce;
61952
62701
  setQuoteCountdown(QUOTE_TTL);
@@ -62591,7 +63340,8 @@ function PayWithStripeLink({
62591
63340
  {
62592
63341
  brand: display.brand,
62593
63342
  size: 28,
62594
- fallbackColor: colors2.foregroundMuted
63343
+ fallbackColor: colors2.foregroundMuted,
63344
+ monochromeColor: monochromeOn(components.card.backgroundColor)
62595
63345
  }
62596
63346
  )
62597
63347
  }
@@ -63176,7 +63926,8 @@ function PayWithStripeLink({
63176
63926
  {
63177
63927
  brand: paymentDisplay.brand,
63178
63928
  size: 20,
63179
- fallbackColor: colors2.foregroundMuted
63929
+ fallbackColor: colors2.foregroundMuted,
63930
+ monochromeColor: monochromeOn(components.card.backgroundColor)
63180
63931
  }
63181
63932
  ),
63182
63933
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
@@ -63660,6 +64411,20 @@ function PayWithStripeLink({
63660
64411
  }
63661
64412
  return null;
63662
64413
  }
64414
+ function useProjectConfig({
64415
+ publishableKey,
64416
+ enabled = true
64417
+ }) {
64418
+ const { data: projectConfig, isLoading } = useQuery({
64419
+ queryKey: ["unifold", "projectConfig", publishableKey],
64420
+ queryFn: () => getProjectConfig(publishableKey),
64421
+ enabled,
64422
+ staleTime: 1e3 * 60 * 30,
64423
+ refetchOnMount: true,
64424
+ refetchOnWindowFocus: true
64425
+ });
64426
+ return { projectConfig, isLoading };
64427
+ }
63663
64428
  function useSupportedDepositTokens(publishableKey, options2) {
63664
64429
  const hasDestination = options2?.destination_token_address && options2?.destination_chain_id && options2?.destination_chain_type;
63665
64430
  const filteredOptions = {
@@ -63771,12 +64536,12 @@ function CoinbaseConnect({
63771
64536
  destination_chain_id: destinationChainId,
63772
64537
  destination_chain_type: destinationChainType
63773
64538
  });
63774
- const supportedSymbols = (0, import_react23.useMemo)(() => {
64539
+ const supportedSymbols = (0, import_react24.useMemo)(() => {
63775
64540
  const set = /* @__PURE__ */ new Set();
63776
64541
  supportedTokensData?.data.forEach((token) => set.add(token.symbol.toLowerCase()));
63777
64542
  return set;
63778
64543
  }, [supportedTokensData]);
63779
- const stablecoinSymbols = (0, import_react23.useMemo)(() => {
64544
+ const stablecoinSymbols = (0, import_react24.useMemo)(() => {
63780
64545
  const set = /* @__PURE__ */ new Set();
63781
64546
  supportedTokensData?.data.forEach((token) => {
63782
64547
  if (token.is_stablecoin) set.add(token.symbol.toLowerCase());
@@ -63786,35 +64551,35 @@ function CoinbaseConnect({
63786
64551
  const appName = projectConfig?.project_name ?? "Unifold";
63787
64552
  const t13 = i18n2.connectExchange;
63788
64553
  const initialView = skipToHoldings && getStoredIntegrationToken(IntegrationProvider.COINBASE) ? "holdings" : "select_exchange";
63789
- const [view, setView] = (0, import_react23.useState)(initialView);
63790
- const [prevView, setPrevView] = (0, import_react23.useState)(initialView);
63791
- const [isTransitioning, setIsTransitioning] = (0, import_react23.useState)(false);
63792
- const [exchanges, setExchanges] = (0, import_react23.useState)([]);
63793
- const [exchangesLoading, setExchangesLoading] = (0, import_react23.useState)(true);
63794
- const [selectedExchange, setSelectedExchange] = (0, import_react23.useState)(null);
63795
- const [accessToken, setAccessToken] = (0, import_react23.useState)(null);
63796
- const [holdings, setHoldings] = (0, import_react23.useState)([]);
63797
- const [selectedHolding, setSelectedHolding] = (0, import_react23.useState)(null);
63798
- const [selectedAsset, setSelectedAsset] = (0, import_react23.useState)(null);
63799
- const [sendAmount, setSendAmount] = (0, import_react23.useState)("");
63800
- const [transferIntent, setTransferIntent] = (0, import_react23.useState)(
64554
+ const [view, setView] = (0, import_react24.useState)(initialView);
64555
+ const [prevView, setPrevView] = (0, import_react24.useState)(initialView);
64556
+ const [isTransitioning, setIsTransitioning] = (0, import_react24.useState)(false);
64557
+ const [exchanges, setExchanges] = (0, import_react24.useState)([]);
64558
+ const [exchangesLoading, setExchangesLoading] = (0, import_react24.useState)(true);
64559
+ const [selectedExchange, setSelectedExchange] = (0, import_react24.useState)(null);
64560
+ const [accessToken, setAccessToken] = (0, import_react24.useState)(null);
64561
+ const [holdings, setHoldings] = (0, import_react24.useState)([]);
64562
+ const [selectedHolding, setSelectedHolding] = (0, import_react24.useState)(null);
64563
+ const [selectedAsset, setSelectedAsset] = (0, import_react24.useState)(null);
64564
+ const [sendAmount, setSendAmount] = (0, import_react24.useState)("");
64565
+ const [transferIntent, setTransferIntent] = (0, import_react24.useState)(
63801
64566
  null
63802
64567
  );
63803
- const [mfaCode, setMfaCode] = (0, import_react23.useState)("");
63804
- const [mfaError, setMfaError] = (0, import_react23.useState)(false);
63805
- const [errorMessage, setErrorMessage] = (0, import_react23.useState)("");
63806
- const [isLoading, setIsLoading] = (0, import_react23.useState)(initialView === "holdings");
63807
- const [confirmResult, setConfirmResult] = (0, import_react23.useState)(null);
63808
- const [showTransferDetails, setShowTransferDetails] = (0, import_react23.useState)(false);
63809
- const [transferDepositWalletId, setTransferDepositWalletId] = (0, import_react23.useState)(
64568
+ const [mfaCode, setMfaCode] = (0, import_react24.useState)("");
64569
+ const [mfaError, setMfaError] = (0, import_react24.useState)(false);
64570
+ const [errorMessage, setErrorMessage] = (0, import_react24.useState)("");
64571
+ const [isLoading, setIsLoading] = (0, import_react24.useState)(initialView === "holdings");
64572
+ const [confirmResult, setConfirmResult] = (0, import_react24.useState)(null);
64573
+ const [showTransferDetails, setShowTransferDetails] = (0, import_react24.useState)(false);
64574
+ const [transferDepositWalletId, setTransferDepositWalletId] = (0, import_react24.useState)(
63810
64575
  void 0
63811
64576
  );
63812
- const exchangeSupportedCurrencies = (0, import_react23.useMemo)(() => {
64577
+ const exchangeSupportedCurrencies = (0, import_react24.useMemo)(() => {
63813
64578
  const set = /* @__PURE__ */ new Set();
63814
64579
  selectedExchange?.supported_currencies.forEach((c) => set.add(c.toLowerCase()));
63815
64580
  return set;
63816
64581
  }, [selectedExchange]);
63817
- const defaultTokenParams = (0, import_react23.useMemo)(
64582
+ const defaultTokenParams = (0, import_react24.useMemo)(
63818
64583
  () => selectedAsset ? {
63819
64584
  integration_provider: IntegrationProvider.COINBASE,
63820
64585
  source_currency: selectedAsset.currency.toLowerCase(),
@@ -63837,7 +64602,7 @@ function CoinbaseConnect({
63837
64602
  params: defaultTokenParams,
63838
64603
  publishableKey
63839
64604
  });
63840
- const defaultSourceCurrency = (0, import_react23.useMemo)(
64605
+ const defaultSourceCurrency = (0, import_react24.useMemo)(
63841
64606
  () => resolveDefaultSourceSymbol(supportedTokensData?.data, {
63842
64607
  defaultSourceChainType,
63843
64608
  defaultSourceChainId,
@@ -63852,7 +64617,7 @@ function CoinbaseConnect({
63852
64617
  defaultSourceSymbol
63853
64618
  ]
63854
64619
  );
63855
- const sortedHoldings = (0, import_react23.useMemo)(() => {
64620
+ const sortedHoldings = (0, import_react24.useMemo)(() => {
63856
64621
  const supported = [];
63857
64622
  const unsupported = [];
63858
64623
  holdings.forEach((account) => {
@@ -63872,12 +64637,12 @@ function CoinbaseConnect({
63872
64637
  }
63873
64638
  return [...supported, ...unsupported];
63874
64639
  }, [holdings, supportedSymbols, exchangeSupportedCurrencies, defaultSourceCurrency]);
63875
- const selectedHoldingIsSupported = (0, import_react23.useMemo)(() => {
64640
+ const selectedHoldingIsSupported = (0, import_react24.useMemo)(() => {
63876
64641
  if (!selectedHolding) return false;
63877
64642
  const currencyLower = selectedHolding.currency.toLowerCase();
63878
64643
  return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
63879
64644
  }, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
63880
- (0, import_react23.useEffect)(() => {
64645
+ (0, import_react24.useEffect)(() => {
63881
64646
  if (!defaultSourceCurrency || selectedHolding) return;
63882
64647
  const defaultHolding = sortedHoldings.find((account) => {
63883
64648
  const currencyLower = account.currency.toLowerCase();
@@ -63913,13 +64678,13 @@ function CoinbaseConnect({
63913
64678
  onTransferError?.({ message: error.message });
63914
64679
  } : void 0
63915
64680
  });
63916
- (0, import_react23.useEffect)(() => {
64681
+ (0, import_react24.useEffect)(() => {
63917
64682
  onExecutionsChange?.(depositExecutions);
63918
64683
  }, [depositExecutions, onExecutionsChange]);
63919
- const pollRef = (0, import_react23.useRef)(null);
63920
- const popupRef = (0, import_react23.useRef)(null);
63921
- const viewRef = (0, import_react23.useRef)(initialView);
63922
- const transitionTo = (0, import_react23.useCallback)((nextView) => {
64684
+ const pollRef = (0, import_react24.useRef)(null);
64685
+ const popupRef = (0, import_react24.useRef)(null);
64686
+ const viewRef = (0, import_react24.useRef)(initialView);
64687
+ const transitionTo = (0, import_react24.useCallback)((nextView) => {
63923
64688
  if (nextView === viewRef.current) return;
63924
64689
  setIsTransitioning(true);
63925
64690
  setTimeout(() => {
@@ -63929,7 +64694,7 @@ function CoinbaseConnect({
63929
64694
  setIsTransitioning(false);
63930
64695
  }, 150);
63931
64696
  }, []);
63932
- const tryRefreshToken = (0, import_react23.useCallback)(
64697
+ const tryRefreshToken = (0, import_react24.useCallback)(
63933
64698
  async (currentToken) => {
63934
64699
  try {
63935
64700
  const result = await refreshIntegrationToken(currentToken, publishableKey);
@@ -63948,7 +64713,7 @@ function CoinbaseConnect({
63948
64713
  },
63949
64714
  [publishableKey]
63950
64715
  );
63951
- (0, import_react23.useEffect)(() => {
64716
+ (0, import_react24.useEffect)(() => {
63952
64717
  getIntegrationExchanges(publishableKey).then((res) => {
63953
64718
  setExchanges(res.data);
63954
64719
  if (!selectedExchange) {
@@ -63967,7 +64732,7 @@ function CoinbaseConnect({
63967
64732
  }
63968
64733
  }
63969
64734
  }, []);
63970
- const loadHoldings = (0, import_react23.useCallback)(
64735
+ const loadHoldings = (0, import_react24.useCallback)(
63971
64736
  async (token) => {
63972
64737
  setIsLoading(true);
63973
64738
  try {
@@ -64014,12 +64779,12 @@ function CoinbaseConnect({
64014
64779
  },
64015
64780
  [publishableKey, transitionTo, tryRefreshToken]
64016
64781
  );
64017
- (0, import_react23.useEffect)(() => {
64782
+ (0, import_react24.useEffect)(() => {
64018
64783
  return () => {
64019
64784
  if (pollRef.current) clearInterval(pollRef.current);
64020
64785
  };
64021
64786
  }, []);
64022
- const minDepositUsd = (0, import_react23.useMemo)(() => {
64787
+ const minDepositUsd = (0, import_react24.useMemo)(() => {
64023
64788
  if (!selectedAsset || !defaultTokenData) return 0;
64024
64789
  const supportedToken = supportedTokensData?.data.find(
64025
64790
  (t14) => t14.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
@@ -64030,7 +64795,7 @@ function CoinbaseConnect({
64030
64795
  );
64031
64796
  return matchingChain?.minimum_deposit_amount_usd ?? Math.min(...supportedToken.chains.map((c) => c.minimum_deposit_amount_usd));
64032
64797
  }, [selectedAsset, supportedTokensData, defaultTokenData]);
64033
- const estimatedProcessingTime = (0, import_react23.useMemo)(() => {
64798
+ const estimatedProcessingTime = (0, import_react24.useMemo)(() => {
64034
64799
  if (!selectedAsset || !defaultTokenData) return null;
64035
64800
  const supportedToken = supportedTokensData?.data.find(
64036
64801
  (t14) => t14.symbol.toLowerCase() === selectedAsset.currency.toLowerCase()
@@ -66047,9 +66812,9 @@ function DepositsModal({
66047
66812
  themeClass = ""
66048
66813
  }) {
66049
66814
  const { colors: colors2, fonts, components } = useTheme();
66050
- const [allExecutions, setAllExecutions] = (0, import_react25.useState)(sessionExecutions);
66051
- const [selectedExecution, setSelectedExecution] = (0, import_react25.useState)(null);
66052
- (0, import_react25.useEffect)(() => {
66815
+ const [allExecutions, setAllExecutions] = (0, import_react26.useState)(sessionExecutions);
66816
+ const [selectedExecution, setSelectedExecution] = (0, import_react26.useState)(null);
66817
+ (0, import_react26.useEffect)(() => {
66053
66818
  if (!open || !userId) return;
66054
66819
  const fetchExecutions = async () => {
66055
66820
  try {
@@ -66071,7 +66836,7 @@ function DepositsModal({
66071
66836
  clearInterval(pollInterval);
66072
66837
  };
66073
66838
  }, [open, userId, publishableKey, sessionExecutions]);
66074
- (0, import_react25.useEffect)(() => {
66839
+ (0, import_react26.useEffect)(() => {
66075
66840
  if (!open) {
66076
66841
  setSelectedExecution(null);
66077
66842
  }
@@ -66194,13 +66959,13 @@ function TokenSelectorSheet({
66194
66959
  }) {
66195
66960
  const { themeClass, colors: colors2, fonts, components } = useTheme();
66196
66961
  const isDarkMode = themeClass.includes("uf-dark");
66197
- const [searchQuery, setSearchQuery] = (0, import_react26.useState)("");
66198
- const [recentTokens, setRecentTokens] = (0, import_react26.useState)([]);
66199
- const [hoveredTokenKey, setHoveredTokenKey] = (0, import_react26.useState)(null);
66200
- (0, import_react26.useEffect)(() => {
66962
+ const [searchQuery, setSearchQuery] = (0, import_react27.useState)("");
66963
+ const [recentTokens, setRecentTokens] = (0, import_react27.useState)([]);
66964
+ const [hoveredTokenKey, setHoveredTokenKey] = (0, import_react27.useState)(null);
66965
+ (0, import_react27.useEffect)(() => {
66201
66966
  setRecentTokens(getRecentTokens());
66202
66967
  }, []);
66203
- const allOptions = (0, import_react26.useMemo)(() => {
66968
+ const allOptions = (0, import_react27.useMemo)(() => {
66204
66969
  const options2 = [];
66205
66970
  tokens.forEach((token) => {
66206
66971
  token.chains.forEach((chain) => {
@@ -66209,7 +66974,7 @@ function TokenSelectorSheet({
66209
66974
  });
66210
66975
  return options2;
66211
66976
  }, [tokens]);
66212
- const quickSelectOptions = (0, import_react26.useMemo)(() => {
66977
+ const quickSelectOptions = (0, import_react27.useMemo)(() => {
66213
66978
  const result = [];
66214
66979
  const seen = /* @__PURE__ */ new Set();
66215
66980
  const addOption = (symbol, chainType, chainId, isRecent) => {
@@ -66241,7 +67006,7 @@ function TokenSelectorSheet({
66241
67006
  });
66242
67007
  setRecentTokens(updated);
66243
67008
  };
66244
- const fuse = (0, import_react26.useMemo)(
67009
+ const fuse = (0, import_react27.useMemo)(
66245
67010
  () => new Fuse(allOptions, {
66246
67011
  keys: [
66247
67012
  { name: "token.symbol", weight: 2 },
@@ -66254,7 +67019,7 @@ function TokenSelectorSheet({
66254
67019
  }),
66255
67020
  [allOptions]
66256
67021
  );
66257
- const filteredOptions = (0, import_react26.useMemo)(() => {
67022
+ const filteredOptions = (0, import_react27.useMemo)(() => {
66258
67023
  if (!searchQuery.trim()) return allOptions;
66259
67024
  const query = searchQuery.trim();
66260
67025
  const results = fuse.search(query);
@@ -66678,11 +67443,11 @@ function useDefaultToken({
66678
67443
  defaultTokenAddress,
66679
67444
  defaultSymbol
66680
67445
  }) {
66681
- const [token, setToken] = (0, import_react27.useState)(null);
66682
- const [chain, setChain] = (0, import_react27.useState)(null);
66683
- const [initialSelectionDone, setInitialSelectionDone] = (0, import_react27.useState)(false);
66684
- const appliedDefaultsRef = (0, import_react27.useRef)("");
66685
- (0, import_react27.useEffect)(() => {
67446
+ const [token, setToken] = (0, import_react28.useState)(null);
67447
+ const [chain, setChain] = (0, import_react28.useState)(null);
67448
+ const [initialSelectionDone, setInitialSelectionDone] = (0, import_react28.useState)(false);
67449
+ const appliedDefaultsRef = (0, import_react28.useRef)("");
67450
+ (0, import_react28.useEffect)(() => {
66686
67451
  if (!tokens.length) return;
66687
67452
  const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
66688
67453
  const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
@@ -66708,7 +67473,7 @@ function useDefaultToken({
66708
67473
  defaultChainId,
66709
67474
  initialSelectionDone
66710
67475
  ]);
66711
- (0, import_react27.useEffect)(() => {
67476
+ (0, import_react28.useEffect)(() => {
66712
67477
  if (!tokens.length || !token) return;
66713
67478
  const currentToken = tokens.find((t13) => t13.symbol === token);
66714
67479
  if (!currentToken || currentToken.chains.length === 0) return;
@@ -67007,7 +67772,7 @@ function GlossaryModal({
67007
67772
  ) });
67008
67773
  }
67009
67774
  function useCopyAddress() {
67010
- const [copied, setCopied] = (0, import_react28.useState)(false);
67775
+ const [copied, setCopied] = (0, import_react29.useState)(false);
67011
67776
  const handleCopy = (address) => {
67012
67777
  if (!address) return;
67013
67778
  navigator.clipboard.writeText(address);
@@ -67151,12 +67916,12 @@ function TransferCryptoSingleInput({
67151
67916
  }) {
67152
67917
  const { themeClass, colors: colors2, fonts, components } = useTheme();
67153
67918
  const isDarkMode = themeClass.includes("uf-dark");
67154
- const [copied, setCopied] = (0, import_react24.useState)(false);
67919
+ const [copied, setCopied] = (0, import_react25.useState)(false);
67155
67920
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
67156
- const [glossaryOpen, setGlossaryOpen] = (0, import_react24.useState)(false);
67157
- const [detailsExpanded, setDetailsExpanded] = (0, import_react24.useState)(false);
67158
- const [depositsModalOpen, setDepositsModalOpen] = (0, import_react24.useState)(false);
67159
- const [tokenSelectorOpen, setTokenSelectorOpen] = (0, import_react24.useState)(false);
67921
+ const [glossaryOpen, setGlossaryOpen] = (0, import_react25.useState)(false);
67922
+ const [detailsExpanded, setDetailsExpanded] = (0, import_react25.useState)(false);
67923
+ const [depositsModalOpen, setDepositsModalOpen] = (0, import_react25.useState)(false);
67924
+ const [tokenSelectorOpen, setTokenSelectorOpen] = (0, import_react25.useState)(false);
67160
67925
  const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(
67161
67926
  publishableKey,
67162
67927
  {
@@ -67191,7 +67956,7 @@ function TransferCryptoSingleInput({
67191
67956
  const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
67192
67957
  const loading = externalWallets?.length ? false : walletsLoading;
67193
67958
  const error = walletsError?.message ?? null;
67194
- const allAvailableChains = (0, import_react24.useMemo)(() => {
67959
+ const allAvailableChains = (0, import_react25.useMemo)(() => {
67195
67960
  const chainsMap = /* @__PURE__ */ new Map();
67196
67961
  supportedTokens.forEach((t13) => {
67197
67962
  t13.chains.forEach((c) => {
@@ -67236,7 +68001,7 @@ function TransferCryptoSingleInput({
67236
68001
  publishableKey,
67237
68002
  enabled: !!depositAddress && !!recipientAddress
67238
68003
  });
67239
- (0, import_react24.useEffect)(() => {
68004
+ (0, import_react25.useEffect)(() => {
67240
68005
  if (!onSourceTokenChange || !token || !chain || !initialSelectionDone) return;
67241
68006
  const { chainType, chainId } = parseChainKey(chain);
67242
68007
  const matchedToken = supportedTokens.find((t13) => t13.symbol === token);
@@ -67253,7 +68018,7 @@ function TransferCryptoSingleInput({
67253
68018
  isStablecoin: matchedToken?.is_stablecoin ?? false
67254
68019
  });
67255
68020
  }, [token, chain, initialSelectionDone, onSourceTokenChange, supportedTokens]);
67256
- (0, import_react24.useEffect)(() => {
68021
+ (0, import_react25.useEffect)(() => {
67257
68022
  if (onExecutionsChange) {
67258
68023
  onExecutionsChange(depositExecutions);
67259
68024
  }
@@ -67929,11 +68694,11 @@ function TransferCryptoDoubleInput({
67929
68694
  }) {
67930
68695
  const { themeClass, colors: colors2, fonts, components } = useTheme();
67931
68696
  const isDarkMode = themeClass.includes("uf-dark");
67932
- const [copied, setCopied] = (0, import_react30.useState)(false);
68697
+ const [copied, setCopied] = (0, import_react31.useState)(false);
67933
68698
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
67934
- const [glossaryOpen, setGlossaryOpen] = (0, import_react30.useState)(false);
67935
- const [detailsExpanded, setDetailsExpanded] = (0, import_react30.useState)(false);
67936
- const [depositsModalOpen, setDepositsModalOpen] = (0, import_react30.useState)(false);
68699
+ const [glossaryOpen, setGlossaryOpen] = (0, import_react31.useState)(false);
68700
+ const [detailsExpanded, setDetailsExpanded] = (0, import_react31.useState)(false);
68701
+ const [depositsModalOpen, setDepositsModalOpen] = (0, import_react31.useState)(false);
67937
68702
  const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(
67938
68703
  publishableKey,
67939
68704
  {
@@ -67967,7 +68732,7 @@ function TransferCryptoDoubleInput({
67967
68732
  const wallets = externalWallets?.length ? externalWallets : depositAddressResponse?.data ?? [];
67968
68733
  const loading = externalWallets?.length ? false : walletsLoading;
67969
68734
  const error = walletsError?.message ?? null;
67970
- const allAvailableChains = (0, import_react30.useMemo)(() => {
68735
+ const allAvailableChains = (0, import_react31.useMemo)(() => {
67971
68736
  const chainsMap = /* @__PURE__ */ new Map();
67972
68737
  supportedTokens.forEach((t13) => {
67973
68738
  t13.chains.forEach((c) => {
@@ -68011,7 +68776,7 @@ function TransferCryptoDoubleInput({
68011
68776
  publishableKey,
68012
68777
  enabled: !!depositAddress && !!recipientAddress
68013
68778
  });
68014
- (0, import_react30.useEffect)(() => {
68779
+ (0, import_react31.useEffect)(() => {
68015
68780
  if (onExecutionsChange) {
68016
68781
  onExecutionsChange(depositExecutions);
68017
68782
  }
@@ -69457,13 +70222,13 @@ function ConfirmingView({
69457
70222
  amountReceivedUsdAtSubmission
69458
70223
  }) {
69459
70224
  const { colors: colors2, fonts, components } = useTheme();
69460
- const [fallbackSettled, setFallbackSettled] = (0, import_react33.useState)(false);
70225
+ const [fallbackSettled, setFallbackSettled] = (0, import_react34.useState)(false);
69461
70226
  const hasExecution = executions.length > 0;
69462
70227
  const isCheckoutMode = paymentIntentStatus != null;
69463
70228
  const isPaymentComplete = paymentIntentStatus === "succeeded";
69464
70229
  const amountChanged = amountReceivedUsdAtSubmission != null && amountReceivedUsd != null && amountReceivedUsd !== amountReceivedUsdAtSubmission;
69465
70230
  const piSettled = !isCheckoutMode || isPaymentComplete || amountChanged || fallbackSettled;
69466
- (0, import_react33.useEffect)(() => {
70231
+ (0, import_react34.useEffect)(() => {
69467
70232
  if (!hasExecution || piSettled) return;
69468
70233
  const timeout = setTimeout(() => setFallbackSettled(true), SETTLE_FALLBACK_MS);
69469
70234
  return () => clearTimeout(timeout);
@@ -71197,10 +71962,9 @@ function DepositModal({
71197
71962
  applePaySubTitle = "Instant",
71198
71963
  enableBankTransfer,
71199
71964
  enableStripeLink = false,
71200
- email: emailProp,
71965
+ userEmail,
71201
71966
  hideDepositFlowInfo = false,
71202
71967
  hideDisplayDescription = false,
71203
- externalUserEmail,
71204
71968
  onDepositSuccess,
71205
71969
  onDepositError,
71206
71970
  onEvent,
@@ -71631,11 +72395,18 @@ function DepositModal({
71631
72395
  return "Success";
71632
72396
  case "guest_limit_reached":
71633
72397
  return "Limit reached";
72398
+ case "limit_upgrade_intro":
72399
+ case "limit_upgrade_failed":
72400
+ return "Limit reached";
72401
+ case "limit_upgrade_form":
72402
+ return "Verify identity";
72403
+ case "limit_upgrade_submitting":
72404
+ return "Verifying";
71634
72405
  default:
71635
72406
  return "Pay with Apple Pay";
71636
72407
  }
71637
72408
  })();
71638
- const applePayShowBack = sessionOpenedFromMenu || applePayView === "phone_input" || applePayView === "email_otp" || applePayView === "phone_otp" || applePayView === "submitting_session" || applePayView === "checking_deposit";
72409
+ 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";
71639
72410
  const handleBack = () => {
71640
72411
  if (view === "card" && cardView === "quotes") {
71641
72412
  setCardView("amount");
@@ -72314,7 +73085,7 @@ function DepositModal({
72314
73085
  destinationChainId,
72315
73086
  destinationTokenAddress,
72316
73087
  wallets,
72317
- email: emailProp,
73088
+ email: userEmail,
72318
73089
  iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/link.svg` : void 0,
72319
73090
  step: stripeLinkStep,
72320
73091
  onStepChange: setStripeLinkStep,
@@ -72377,13 +73148,10 @@ function DepositModal({
72377
73148
  ref: applePayHandleRef,
72378
73149
  userId,
72379
73150
  publishableKey,
72380
- recipientAddress,
72381
73151
  destinationChainType,
72382
73152
  destinationChainId,
72383
73153
  destinationTokenAddress,
72384
- destinationTokenSymbol,
72385
- externalUserEmail,
72386
- enableApplePay,
73154
+ userEmail,
72387
73155
  wallets,
72388
73156
  onViewChange: setApplePayView,
72389
73157
  onEvent,
@@ -72493,12 +73261,12 @@ function CheckoutModal({
72493
73261
  onEvent
72494
73262
  }) {
72495
73263
  const { colors: colors2, fonts, components } = useTheme();
72496
- const [view, setView] = (0, import_react34.useState)("main");
72497
- const resetViewTimeoutRef = (0, import_react34.useRef)(null);
72498
- const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react34.useState)(null);
72499
- const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react34.useState)(() => getStoredWalletState()?.chainType);
72500
- const lastCheckoutMethodRef = (0, import_react34.useRef)(void 0);
72501
- const emitCheckoutSuccess = (0, import_react34.useCallback)(
73264
+ const [view, setView] = (0, import_react35.useState)("main");
73265
+ const resetViewTimeoutRef = (0, import_react35.useRef)(null);
73266
+ const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react35.useState)(null);
73267
+ const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react35.useState)(() => getStoredWalletState()?.chainType);
73268
+ const lastCheckoutMethodRef = (0, import_react35.useRef)(void 0);
73269
+ const emitCheckoutSuccess = (0, import_react35.useCallback)(
72502
73270
  (data, method) => {
72503
73271
  const isSucceeded = data.status === "succeeded";
72504
73272
  const richIntent = isSucceeded && data.paymentIntent ? mapToCheckoutPaymentIntent(data.paymentIntent) : void 0;
@@ -72521,10 +73289,10 @@ function CheckoutModal({
72521
73289
  },
72522
73290
  [onCheckoutSuccess, onEvent]
72523
73291
  );
72524
- const [resolvedTheme, setResolvedTheme] = (0, import_react34.useState)(
73292
+ const [resolvedTheme, setResolvedTheme] = (0, import_react35.useState)(
72525
73293
  theme === "auto" ? "dark" : theme
72526
73294
  );
72527
- (0, import_react34.useEffect)(() => {
73295
+ (0, import_react35.useEffect)(() => {
72528
73296
  if (theme === "auto") {
72529
73297
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
72530
73298
  setResolvedTheme(mediaQuery.matches ? "dark" : "light");
@@ -72554,15 +73322,15 @@ function CheckoutModal({
72554
73322
  });
72555
73323
  const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
72556
73324
  const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
72557
- (0, import_react34.useEffect)(() => {
73325
+ (0, import_react35.useEffect)(() => {
72558
73326
  if (view === "transfer" && !showTransferCrypto) {
72559
73327
  setView("main");
72560
73328
  } else if (view === "wallet_connect" && !showConnectWallet) {
72561
73329
  setView("main");
72562
73330
  }
72563
73331
  }, [showConnectWallet, showTransferCrypto, view]);
72564
- const prevStatusRef = (0, import_react34.useRef)(null);
72565
- (0, import_react34.useEffect)(() => {
73332
+ const prevStatusRef = (0, import_react35.useRef)(null);
73333
+ (0, import_react35.useEffect)(() => {
72566
73334
  if (!paymentIntent) return;
72567
73335
  const prev = prevStatusRef.current;
72568
73336
  prevStatusRef.current = paymentIntent.status;
@@ -72580,11 +73348,11 @@ function CheckoutModal({
72580
73348
  );
72581
73349
  }
72582
73350
  }, [emitCheckoutSuccess, paymentIntent, view]);
72583
- const wallets = (0, import_react34.useMemo)(() => {
73351
+ const wallets = (0, import_react35.useMemo)(() => {
72584
73352
  if (!paymentIntent) return [];
72585
73353
  return mapDepositAddressesToWallets(paymentIntent.deposit_addresses, paymentIntent);
72586
73354
  }, [paymentIntent]);
72587
- const formatCryptoAmount = (0, import_react34.useMemo)(() => {
73355
+ const formatCryptoAmount = (0, import_react35.useMemo)(() => {
72588
73356
  if (!paymentIntent) return (_) => "";
72589
73357
  const decimals = paymentIntent.destination_token_decimals ?? 6;
72590
73358
  const symbol = paymentIntent.currency.toUpperCase();
@@ -72594,7 +73362,7 @@ function CheckoutModal({
72594
73362
  return `${formatted} ${symbol}`;
72595
73363
  };
72596
73364
  }, [paymentIntent]);
72597
- const remainingAmountUsd = (0, import_react34.useMemo)(() => {
73365
+ const remainingAmountUsd = (0, import_react35.useMemo)(() => {
72598
73366
  if (!paymentIntent) return void 0;
72599
73367
  const total = parseFloat(paymentIntent.destination_amount_usd || paymentIntent.amount_usd);
72600
73368
  const received = parseFloat(
@@ -72605,8 +73373,8 @@ function CheckoutModal({
72605
73373
  const remaining = total - received;
72606
73374
  return remaining > 0 ? remaining.toFixed(2) : "0.00";
72607
73375
  }, [paymentIntent]);
72608
- const [selectedSource, setSelectedSource] = (0, import_react34.useState)(null);
72609
- const remainingDestinationAmount = (0, import_react34.useMemo)(() => {
73376
+ const [selectedSource, setSelectedSource] = (0, import_react35.useState)(null);
73377
+ const remainingDestinationAmount = (0, import_react35.useMemo)(() => {
72610
73378
  if (!paymentIntent) return "0";
72611
73379
  const remaining = BigInt(paymentIntent.destination_amount) - BigInt(paymentIntent.destination_amount_received);
72612
73380
  return remaining > 0n ? remaining.toString() : "0";
@@ -72628,7 +73396,7 @@ function CheckoutModal({
72628
73396
  stablecoinParity: paymentIntent?.stablecoin_parity ?? false,
72629
73397
  enabled: open && view === "transfer" && !!paymentIntent && !!selectedSource && remainingDestinationAmount !== "0"
72630
73398
  });
72631
- const effectiveCheckoutQuote = (0, import_react34.useMemo)(() => {
73399
+ const effectiveCheckoutQuote = (0, import_react35.useMemo)(() => {
72632
73400
  if (!sourceQuote || !selectedSource) return null;
72633
73401
  const baseQuote = {
72634
73402
  sourceAmount: sourceQuote.source_amount,
@@ -72649,7 +73417,7 @@ function CheckoutModal({
72649
73417
  sourceAmountUsd: minUsd.toFixed(2)
72650
73418
  };
72651
73419
  }, [sourceQuote, selectedSource]);
72652
- const handleBrowserWalletClick = (0, import_react34.useCallback)(
73420
+ const handleBrowserWalletClick = (0, import_react35.useCallback)(
72653
73421
  (walletInfo) => {
72654
73422
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
72655
73423
  setStoredWalletState(walletInfo.type);
@@ -72672,19 +73440,19 @@ function CheckoutModal({
72672
73440
  },
72673
73441
  [wallets, onCheckoutError]
72674
73442
  );
72675
- const handleWalletConnectClick = (0, import_react34.useCallback)(() => {
73443
+ const handleWalletConnectClick = (0, import_react35.useCallback)(() => {
72676
73444
  setBrowserWalletInfo(null);
72677
73445
  lastCheckoutMethodRef.current = "wallet_connect";
72678
73446
  setView("wallet_connect");
72679
73447
  }, []);
72680
- const handleWalletDisconnect = (0, import_react34.useCallback)(() => {
73448
+ const handleWalletDisconnect = (0, import_react35.useCallback)(() => {
72681
73449
  setUserDisconnectedWallet(true);
72682
73450
  clearStoredWalletState();
72683
73451
  setBrowserWalletChainType(void 0);
72684
73452
  setBrowserWalletInfo(null);
72685
73453
  setView("main");
72686
73454
  }, []);
72687
- const handleClose = (0, import_react34.useCallback)(() => {
73455
+ const handleClose = (0, import_react35.useCallback)(() => {
72688
73456
  onOpenChange(false);
72689
73457
  if (resetViewTimeoutRef.current) {
72690
73458
  clearTimeout(resetViewTimeoutRef.current);
@@ -72696,7 +73464,7 @@ function CheckoutModal({
72696
73464
  resetViewTimeoutRef.current = null;
72697
73465
  }, 200);
72698
73466
  }, [onOpenChange]);
72699
- (0, import_react34.useLayoutEffect)(() => {
73467
+ (0, import_react35.useLayoutEffect)(() => {
72700
73468
  if (!open) return;
72701
73469
  if (resetViewTimeoutRef.current) {
72702
73470
  clearTimeout(resetViewTimeoutRef.current);
@@ -72706,7 +73474,7 @@ function CheckoutModal({
72706
73474
  setBrowserWalletInfo(null);
72707
73475
  lastCheckoutMethodRef.current = void 0;
72708
73476
  }, [open]);
72709
- (0, import_react34.useEffect)(
73477
+ (0, import_react35.useEffect)(
72710
73478
  () => () => {
72711
73479
  if (resetViewTimeoutRef.current) {
72712
73480
  clearTimeout(resetViewTimeoutRef.current);
@@ -72714,7 +73482,7 @@ function CheckoutModal({
72714
73482
  },
72715
73483
  []
72716
73484
  );
72717
- const handleBack = (0, import_react34.useCallback)(() => {
73485
+ const handleBack = (0, import_react35.useCallback)(() => {
72718
73486
  setView("main");
72719
73487
  }, []);
72720
73488
  const poweredByFooter = /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "uf-pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
@@ -73277,20 +74045,20 @@ function useWithdrawPolling({
73277
74045
  status: execution.status,
73278
74046
  failureReason: execution.failure_reason
73279
74047
  });
73280
- const [executions, setExecutions] = (0, import_react36.useState)([]);
73281
- const [isPolling, setIsPolling] = (0, import_react36.useState)(false);
73282
- const enabledAtRef = (0, import_react36.useRef)(/* @__PURE__ */ new Date());
73283
- const trackedRef = (0, import_react36.useRef)(/* @__PURE__ */ new Map());
73284
- const prevEnabledRef = (0, import_react36.useRef)(false);
73285
- const onSuccessRef = (0, import_react36.useRef)(onWithdrawSuccess);
73286
- const onErrorRef = (0, import_react36.useRef)(onWithdrawError);
73287
- (0, import_react36.useEffect)(() => {
74048
+ const [executions, setExecutions] = (0, import_react37.useState)([]);
74049
+ const [isPolling, setIsPolling] = (0, import_react37.useState)(false);
74050
+ const enabledAtRef = (0, import_react37.useRef)(/* @__PURE__ */ new Date());
74051
+ const trackedRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
74052
+ const prevEnabledRef = (0, import_react37.useRef)(false);
74053
+ const onSuccessRef = (0, import_react37.useRef)(onWithdrawSuccess);
74054
+ const onErrorRef = (0, import_react37.useRef)(onWithdrawError);
74055
+ (0, import_react37.useEffect)(() => {
73288
74056
  onSuccessRef.current = onWithdrawSuccess;
73289
74057
  }, [onWithdrawSuccess]);
73290
- (0, import_react36.useEffect)(() => {
74058
+ (0, import_react37.useEffect)(() => {
73291
74059
  onErrorRef.current = onWithdrawError;
73292
74060
  }, [onWithdrawError]);
73293
- (0, import_react36.useEffect)(() => {
74061
+ (0, import_react37.useEffect)(() => {
73294
74062
  if (enabled && !prevEnabledRef.current) {
73295
74063
  enabledAtRef.current = /* @__PURE__ */ new Date();
73296
74064
  trackedRef.current.clear();
@@ -73300,7 +74068,7 @@ function useWithdrawPolling({
73300
74068
  }
73301
74069
  prevEnabledRef.current = enabled;
73302
74070
  }, [enabled]);
73303
- (0, import_react36.useEffect)(() => {
74071
+ (0, import_react37.useEffect)(() => {
73304
74072
  if (!userId || !enabled) return;
73305
74073
  const enabledAt = enabledAtRef.current;
73306
74074
  const poll = async () => {
@@ -73380,7 +74148,7 @@ function useWithdrawPolling({
73380
74148
  setIsPolling(false);
73381
74149
  };
73382
74150
  }, [userId, publishableKey, enabled]);
73383
- (0, import_react36.useEffect)(() => {
74151
+ (0, import_react37.useEffect)(() => {
73384
74152
  if (!enabled || !depositWalletId) return;
73385
74153
  const trigger = async () => {
73386
74154
  try {
@@ -73663,7 +74431,7 @@ function useHypercoreWithdrawActivation(params) {
73663
74431
  actionType: ActionType.Withdraw,
73664
74432
  enabled: enabled && isHypercore(sourceChainId)
73665
74433
  });
73666
- const depositWalletAddress = (0, import_react38.useMemo)(() => {
74434
+ const depositWalletAddress = (0, import_react39.useMemo)(() => {
73667
74435
  const wallets = depositWalletLookup.data?.data ?? [];
73668
74436
  return wallets.find((w) => w.chain_type === sourceChainType)?.address;
73669
74437
  }, [depositWalletLookup.data, sourceChainType]);
@@ -73749,22 +74517,22 @@ function WithdrawForm({
73749
74517
  footerLeft
73750
74518
  }) {
73751
74519
  const { colors: colors2, fonts, components } = useTheme();
73752
- const [recipientAddress, setRecipientAddress] = (0, import_react37.useState)(recipientAddressProp || "");
73753
- const [amount, setAmount] = (0, import_react37.useState)("");
73754
- const [inputUnit, setInputUnit] = (0, import_react37.useState)("fiat");
73755
- const [isSubmitting, setIsSubmitting] = (0, import_react37.useState)(false);
73756
- const [submitError, setSubmitError] = (0, import_react37.useState)(null);
73757
- const [detailsExpanded, setDetailsExpanded] = (0, import_react37.useState)(false);
73758
- const [glossaryOpen, setGlossaryOpen] = (0, import_react37.useState)(false);
73759
- const [isMaxed, setIsMaxed] = (0, import_react37.useState)(false);
73760
- (0, import_react37.useEffect)(() => {
74520
+ const [recipientAddress, setRecipientAddress] = (0, import_react38.useState)(recipientAddressProp || "");
74521
+ const [amount, setAmount] = (0, import_react38.useState)("");
74522
+ const [inputUnit, setInputUnit] = (0, import_react38.useState)("fiat");
74523
+ const [isSubmitting, setIsSubmitting] = (0, import_react38.useState)(false);
74524
+ const [submitError, setSubmitError] = (0, import_react38.useState)(null);
74525
+ const [detailsExpanded, setDetailsExpanded] = (0, import_react38.useState)(false);
74526
+ const [glossaryOpen, setGlossaryOpen] = (0, import_react38.useState)(false);
74527
+ const [isMaxed, setIsMaxed] = (0, import_react38.useState)(false);
74528
+ (0, import_react38.useEffect)(() => {
73761
74529
  setRecipientAddress(recipientAddressProp || "");
73762
74530
  setAmount("");
73763
74531
  setInputUnit("fiat");
73764
74532
  setSubmitError(null);
73765
74533
  setIsMaxed(false);
73766
74534
  }, [recipientAddressProp]);
73767
- (0, import_react37.useEffect)(() => {
74535
+ (0, import_react38.useEffect)(() => {
73768
74536
  setIsMaxed(false);
73769
74537
  }, [balanceData?.balanceBaseUnit]);
73770
74538
  const trimmedAddress = recipientAddress.trim();
@@ -73782,7 +74550,7 @@ function WithdrawForm({
73782
74550
  enabled: debouncedAddress.length > 5 && !!selectedChain
73783
74551
  });
73784
74552
  const isDebouncing = trimmedAddress !== debouncedAddress;
73785
- const addressError = (0, import_react37.useMemo)(() => {
74553
+ const addressError = (0, import_react38.useMemo)(() => {
73786
74554
  if (!trimmedAddress || trimmedAddress.length <= 5) return null;
73787
74555
  if (isDebouncing || isVerifyingAddress) return null;
73788
74556
  if (verifyError) return t10.invalidAddress;
@@ -73816,33 +74584,33 @@ function WithdrawForm({
73816
74584
  destinationTokenAddress: selectedChain?.token_address,
73817
74585
  enabled: isAddressValid
73818
74586
  });
73819
- const exchangeRate = (0, import_react37.useMemo)(() => {
74587
+ const exchangeRate = (0, import_react38.useMemo)(() => {
73820
74588
  if (!balanceData?.exchangeRate) return 0;
73821
74589
  return parseFloat(balanceData.exchangeRate);
73822
74590
  }, [balanceData]);
73823
- const balanceCrypto = (0, import_react37.useMemo)(() => {
74591
+ const balanceCrypto = (0, import_react38.useMemo)(() => {
73824
74592
  if (!balanceData?.balanceHuman) return 0;
73825
74593
  return parseFloat(balanceData.balanceHuman);
73826
74594
  }, [balanceData]);
73827
- const balanceUsdNum = (0, import_react37.useMemo)(() => {
74595
+ const balanceUsdNum = (0, import_react38.useMemo)(() => {
73828
74596
  if (!balanceData?.balanceUsd) return 0;
73829
74597
  return parseFloat(balanceData.balanceUsd);
73830
74598
  }, [balanceData]);
73831
74599
  const tokenSymbol = sourceTokenSymbol || balanceData?.symbol || "TOKEN";
73832
74600
  const sourceDecimals = balanceData?.decimals ?? 6;
73833
- const cryptoAmountFromInput = (0, import_react37.useMemo)(() => {
74601
+ const cryptoAmountFromInput = (0, import_react38.useMemo)(() => {
73834
74602
  const val = parseFloat(amount);
73835
74603
  if (!val || val <= 0) return 0;
73836
74604
  if (inputUnit === "crypto") return val;
73837
74605
  return exchangeRate > 0 ? val / exchangeRate : 0;
73838
74606
  }, [amount, inputUnit, exchangeRate]);
73839
- const fiatAmountFromInput = (0, import_react37.useMemo)(() => {
74607
+ const fiatAmountFromInput = (0, import_react38.useMemo)(() => {
73840
74608
  const val = parseFloat(amount);
73841
74609
  if (!val || val <= 0) return 0;
73842
74610
  if (inputUnit === "fiat") return val;
73843
74611
  return val * exchangeRate;
73844
74612
  }, [amount, inputUnit, exchangeRate]);
73845
- const convertedDisplay = (0, import_react37.useMemo)(() => {
74613
+ const convertedDisplay = (0, import_react38.useMemo)(() => {
73846
74614
  if (!amount || parseFloat(amount) <= 0) return null;
73847
74615
  if (inputUnit === "crypto") {
73848
74616
  return `$${fiatAmountFromInput.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
@@ -73861,7 +74629,7 @@ function WithdrawForm({
73861
74629
  isMaxed,
73862
74630
  isStablecoin
73863
74631
  ]);
73864
- const balanceDisplay = (0, import_react37.useMemo)(() => {
74632
+ const balanceDisplay = (0, import_react38.useMemo)(() => {
73865
74633
  if (isLoadingBalance || !balanceData) return null;
73866
74634
  if (inputUnit === "crypto") {
73867
74635
  const displayDecimals = isStablecoin ? 2 : 6;
@@ -73884,7 +74652,7 @@ function WithdrawForm({
73884
74652
  tokenSymbol,
73885
74653
  isStablecoin
73886
74654
  ]);
73887
- const handleSwitchUnit = (0, import_react37.useCallback)(() => {
74655
+ const handleSwitchUnit = (0, import_react38.useCallback)(() => {
73888
74656
  if (isMaxed && balanceData) {
73889
74657
  if (inputUnit === "crypto") {
73890
74658
  setAmount((Math.round(balanceUsdNum * 100) / 100).toFixed(2));
@@ -73911,7 +74679,7 @@ function WithdrawForm({
73911
74679
  setInputUnit("crypto");
73912
74680
  }
73913
74681
  }, [amount, inputUnit, exchangeRate, sourceDecimals, isMaxed, balanceData, balanceUsdNum]);
73914
- const handleMaxClick = (0, import_react37.useCallback)(() => {
74682
+ const handleMaxClick = (0, import_react38.useCallback)(() => {
73915
74683
  if (inputUnit === "crypto") {
73916
74684
  if (balanceCrypto <= 0) return;
73917
74685
  setAmount(balanceData?.balanceHuman ?? "0");
@@ -73925,7 +74693,7 @@ function WithdrawForm({
73925
74693
  const isBelowMinimum = minimumWithdrawAmountUsd !== null && fiatAmountFromInput > 0 && Math.round(fiatAmountFromInput * 100) / 100 < minimumWithdrawAmountUsd;
73926
74694
  const isOverBalance = inputUnit === "crypto" ? cryptoAmountFromInput > 0 && balanceCrypto > 0 && cryptoAmountFromInput > balanceCrypto : fiatAmountFromInput > 0 && balanceUsdNum > 0 && Math.round(fiatAmountFromInput * 100) / 100 > Math.round(balanceUsdNum * 100) / 100;
73927
74695
  const isFormValid = trimmedAddress.length > 0 && amount.trim().length > 0 && cryptoAmountFromInput > 0 && isAddressValid && !isBelowMinimum && !isOverBalance && !isBalanceBelowMinimum && !!balanceData;
73928
- const handleWithdraw = (0, import_react37.useCallback)(async () => {
74696
+ const handleWithdraw = (0, import_react38.useCallback)(async () => {
73929
74697
  if (!selectedToken || !selectedChain) return;
73930
74698
  if (!isFormValid) return;
73931
74699
  setIsSubmitting(true);
@@ -74552,9 +75320,9 @@ function WithdrawConfirmingView({
74552
75320
  onViewTracker
74553
75321
  }) {
74554
75322
  const { colors: colors2, fonts, components } = useTheme();
74555
- const [showButton, setShowButton] = (0, import_react39.useState)(false);
75323
+ const [showButton, setShowButton] = (0, import_react40.useState)(false);
74556
75324
  const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
74557
- (0, import_react39.useEffect)(() => {
75325
+ (0, import_react40.useEffect)(() => {
74558
75326
  if (latestExecution) return;
74559
75327
  const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
74560
75328
  return () => clearTimeout(timer);
@@ -74698,7 +75466,7 @@ function WithdrawModal({
74698
75466
  theme = "dark",
74699
75467
  hideOverlay = false
74700
75468
  }) {
74701
- const onWithdrawSuccessFor = (0, import_react35.useCallback)(
75469
+ const onWithdrawSuccessFor = (0, import_react36.useCallback)(
74702
75470
  (data) => {
74703
75471
  onWithdrawSuccess?.(data);
74704
75472
  if (data.execution) {
@@ -74708,14 +75476,14 @@ function WithdrawModal({
74708
75476
  [onWithdrawSuccess, onEvent]
74709
75477
  );
74710
75478
  const { colors: colors2, fonts, components } = useTheme();
74711
- const [containerEl, setContainerEl] = (0, import_react35.useState)(null);
74712
- const containerCallbackRef = (0, import_react35.useCallback)((el) => {
75479
+ const [containerEl, setContainerEl] = (0, import_react36.useState)(null);
75480
+ const containerCallbackRef = (0, import_react36.useCallback)((el) => {
74713
75481
  setContainerEl(el);
74714
75482
  }, []);
74715
- const [resolvedTheme, setResolvedTheme] = (0, import_react35.useState)(
75483
+ const [resolvedTheme, setResolvedTheme] = (0, import_react36.useState)(
74716
75484
  theme === "auto" ? "dark" : theme
74717
75485
  );
74718
- (0, import_react35.useEffect)(() => {
75486
+ (0, import_react36.useEffect)(() => {
74719
75487
  if (theme === "auto") {
74720
75488
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
74721
75489
  setResolvedTheme(mq.matches ? "dark" : "light");
@@ -74764,10 +75532,10 @@ function WithdrawModal({
74764
75532
  const selectedChain = selectedToken && selectedChainKey ? selectedToken.chains.find(
74765
75533
  (c) => getChainKey5(c.chain_id, c.chain_type) === selectedChainKey
74766
75534
  ) ?? null : null;
74767
- const [view, setView] = (0, import_react35.useState)("form");
74768
- const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react35.useState)();
74769
- const [selectedExecution, setSelectedExecution] = (0, import_react35.useState)(null);
74770
- const [submittedTxInfo, setSubmittedTxInfo] = (0, import_react35.useState)(null);
75535
+ const [view, setView] = (0, import_react36.useState)("form");
75536
+ const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react36.useState)();
75537
+ const [selectedExecution, setSelectedExecution] = (0, import_react36.useState)(null);
75538
+ const [submittedTxInfo, setSubmittedTxInfo] = (0, import_react36.useState)(null);
74771
75539
  const { executions: realtimeExecutions } = useWithdrawPolling({
74772
75540
  userId: externalUserId,
74773
75541
  publishableKey,
@@ -74782,7 +75550,7 @@ function WithdrawModal({
74782
75550
  refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
74783
75551
  });
74784
75552
  const allWithdrawals = allWithdrawalsData?.data ?? [];
74785
- const handleDepositWalletCreation = (0, import_react35.useCallback)(
75553
+ const handleDepositWalletCreation = (0, import_react36.useCallback)(
74786
75554
  async (params) => {
74787
75555
  const { data: wallets } = await createDepositAddress(
74788
75556
  {
@@ -74805,12 +75573,12 @@ function WithdrawModal({
74805
75573
  },
74806
75574
  [externalUserId, publishableKey, sourceChainType]
74807
75575
  );
74808
- const handleWithdrawSubmitted = (0, import_react35.useCallback)((txInfo) => {
75576
+ const handleWithdrawSubmitted = (0, import_react36.useCallback)((txInfo) => {
74809
75577
  setSubmittedTxInfo(txInfo);
74810
75578
  setView("confirming");
74811
75579
  }, []);
74812
- const resetViewTimeoutRef = (0, import_react35.useRef)(null);
74813
- const handleClose = (0, import_react35.useCallback)(() => {
75580
+ const resetViewTimeoutRef = (0, import_react36.useRef)(null);
75581
+ const handleClose = (0, import_react36.useCallback)(() => {
74814
75582
  onOpenChange(false);
74815
75583
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
74816
75584
  resetViewTimeoutRef.current = setTimeout(() => {
@@ -74821,7 +75589,7 @@ function WithdrawModal({
74821
75589
  resetViewTimeoutRef.current = null;
74822
75590
  }, 200);
74823
75591
  }, [onOpenChange]);
74824
- (0, import_react35.useLayoutEffect)(() => {
75592
+ (0, import_react36.useLayoutEffect)(() => {
74825
75593
  if (!open) return;
74826
75594
  if (resetViewTimeoutRef.current) {
74827
75595
  clearTimeout(resetViewTimeoutRef.current);
@@ -74832,19 +75600,19 @@ function WithdrawModal({
74832
75600
  setSubmittedTxInfo(null);
74833
75601
  setWithdrawDepositWalletId(void 0);
74834
75602
  }, [open]);
74835
- (0, import_react35.useEffect)(
75603
+ (0, import_react36.useEffect)(
74836
75604
  () => () => {
74837
75605
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
74838
75606
  },
74839
75607
  []
74840
75608
  );
74841
- const handleTokenSymbolChange = (0, import_react35.useCallback)(
75609
+ const handleTokenSymbolChange = (0, import_react36.useCallback)(
74842
75610
  (symbol) => {
74843
75611
  setSelectedTokenSymbol(symbol);
74844
75612
  },
74845
75613
  [setSelectedTokenSymbol]
74846
75614
  );
74847
- const handleChainKeyChange = (0, import_react35.useCallback)(
75615
+ const handleChainKeyChange = (0, import_react36.useCallback)(
74848
75616
  (chainKey) => {
74849
75617
  setSelectedChainKey(chainKey);
74850
75618
  },
@@ -75393,7 +76161,7 @@ function UnifoldProvider2({
75393
76161
  defaultSourceChainId: depositConfig.defaultSourceChainId,
75394
76162
  defaultSourceTokenAddress: depositConfig.defaultSourceTokenAddress,
75395
76163
  defaultSourceSymbol: depositConfig.defaultSourceSymbol,
75396
- externalUserEmail: depositConfig.externalUserEmail,
76164
+ userEmail: depositConfig.user?.email,
75397
76165
  depositConfirmationMode: depositConfig.depositConfirmationMode ?? "auto_ui",
75398
76166
  hideDepositTracker: config?.hideDepositTracker,
75399
76167
  showBalanceHeader: config?.showBalanceHeader,
@@ -75406,7 +76174,6 @@ function UnifoldProvider2({
75406
76174
  enableConnectExchange: config?.enableConnectExchange,
75407
76175
  enableCashApp: config?.enableCashApp,
75408
76176
  enableStripeLink: config?.enableStripeLink,
75409
- email: depositConfig?.email,
75410
76177
  enableApplePay: config?.enableApplePay,
75411
76178
  applePayTitle: config?.applePayTitle,
75412
76179
  applePaySubTitle: config?.applePaySubTitle,
@@ -75462,9 +76229,9 @@ function useUnifold2() {
75462
76229
  }
75463
76230
 
75464
76231
  // src/unifold.tsx
75465
- var UnifoldBridge = (0, import_react41.forwardRef)((_, ref) => {
76232
+ var UnifoldBridge = (0, import_react42.forwardRef)((_, ref) => {
75466
76233
  const { beginDeposit, closeDeposit, beginWithdraw, closeWithdraw } = useUnifold2();
75467
- (0, import_react41.useImperativeHandle)(ref, () => ({ beginDeposit, closeDeposit, beginWithdraw, closeWithdraw }), [
76234
+ (0, import_react42.useImperativeHandle)(ref, () => ({ beginDeposit, closeDeposit, beginWithdraw, closeWithdraw }), [
75468
76235
  beginDeposit,
75469
76236
  closeDeposit,
75470
76237
  beginWithdraw,
@@ -75473,7 +76240,7 @@ var UnifoldBridge = (0, import_react41.forwardRef)((_, ref) => {
75473
76240
  return null;
75474
76241
  });
75475
76242
  UnifoldBridge.displayName = "UnifoldBridge";
75476
- var RenderErrorBoundary = class extends import_react41.Component {
76243
+ var RenderErrorBoundary = class extends import_react42.Component {
75477
76244
  constructor() {
75478
76245
  super(...arguments);
75479
76246
  this.state = { hasError: false };
@@ -75545,13 +76312,13 @@ function createUnifold(publishableKey, config) {
75545
76312
  };
75546
76313
  try {
75547
76314
  root.render(
75548
- import_react41.default.createElement(
76315
+ import_react42.default.createElement(
75549
76316
  RenderErrorBoundary,
75550
76317
  { onError: handleRenderError },
75551
- import_react41.default.createElement(
76318
+ import_react42.default.createElement(
75552
76319
  UnifoldProvider2,
75553
76320
  { publishableKey, config },
75554
- import_react41.default.createElement(UnifoldBridge, { ref: refCallback })
76321
+ import_react42.default.createElement(UnifoldBridge, { ref: refCallback })
75555
76322
  )
75556
76323
  )
75557
76324
  );