@unifold/ui-react 0.1.77 → 0.1.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +341 -139
- package/dist/index.mjs +288 -86
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -564,6 +564,9 @@ var en_default = {
|
|
|
564
564
|
transactionBreakdown: "Transaction breakdown",
|
|
565
565
|
networkFee: "Network fee",
|
|
566
566
|
confirmOrder: "Confirm Order",
|
|
567
|
+
mfaEnrollmentTitle: "Enable SMS or Authy 2FA",
|
|
568
|
+
mfaEnrollmentMessage: "Please make sure you enable SMS or Authy 2FA in your Coinbase account. Press Continue after you enable it.",
|
|
569
|
+
mfaEnrollmentSettingsLink: "Open Coinbase security settings",
|
|
567
570
|
termsNoticePrefix: "By clicking on Confirm Order, you agree to our ",
|
|
568
571
|
termsNoticeLink: "terms",
|
|
569
572
|
termsNoticeSuffix: "."
|
|
@@ -694,7 +697,12 @@ var en_default = {
|
|
|
694
697
|
prefix: "By continuing, you agree to Coinbase's ",
|
|
695
698
|
separator: ", ",
|
|
696
699
|
lastSeparator: ", and ",
|
|
697
|
-
suffix: ".
|
|
700
|
+
suffix: ".",
|
|
701
|
+
agreements: {
|
|
702
|
+
guest_checkout_terms: "Terms of Service",
|
|
703
|
+
user_agreement: "User Agreement",
|
|
704
|
+
privacy_policy: "Privacy Policy"
|
|
705
|
+
}
|
|
698
706
|
},
|
|
699
707
|
errors: {
|
|
700
708
|
rateLimited: "Too many attempts. Please wait a few minutes and try again.",
|
|
@@ -1355,6 +1363,9 @@ var zh_default = {
|
|
|
1355
1363
|
transactionBreakdown: "\u4EA4\u6613\u660E\u7EC6",
|
|
1356
1364
|
networkFee: "\u7F51\u7EDC\u624B\u7EED\u8D39",
|
|
1357
1365
|
confirmOrder: "\u786E\u8BA4\u8BA2\u5355",
|
|
1366
|
+
mfaEnrollmentTitle: "\u8BF7\u542F\u7528\u77ED\u4FE1\u6216 Authy \u53CC\u91CD\u9A8C\u8BC1",
|
|
1367
|
+
mfaEnrollmentMessage: "\u8BF7\u786E\u8BA4\u60A8\u5DF2\u5728 Coinbase \u8D26\u6237\u4E2D\u542F\u7528\u77ED\u4FE1\u6216 Authy \u53CC\u91CD\u9A8C\u8BC1\u3002\u542F\u7528\u540E\u8BF7\u6309\u7EE7\u7EED\u3002",
|
|
1368
|
+
mfaEnrollmentSettingsLink: "\u6253\u5F00 Coinbase \u5B89\u5168\u8BBE\u7F6E",
|
|
1358
1369
|
termsNoticePrefix: "\u70B9\u51FB\u201C\u786E\u8BA4\u8BA2\u5355\u201D\u5373\u8868\u793A\u60A8\u540C\u610F\u6211\u4EEC\u7684",
|
|
1359
1370
|
termsNoticeLink: "\u6761\u6B3E",
|
|
1360
1371
|
termsNoticeSuffix: "\u3002"
|
|
@@ -1485,7 +1496,12 @@ var zh_default = {
|
|
|
1485
1496
|
prefix: "\u7EE7\u7EED\u5373\u8868\u793A\u60A8\u540C\u610F Coinbase \u7684",
|
|
1486
1497
|
separator: "\u3001",
|
|
1487
1498
|
lastSeparator: "\u548C",
|
|
1488
|
-
suffix: "\
|
|
1499
|
+
suffix: "\u3002",
|
|
1500
|
+
agreements: {
|
|
1501
|
+
guest_checkout_terms: "\u670D\u52A1\u6761\u6B3E",
|
|
1502
|
+
user_agreement: "\u7528\u6237\u534F\u8BAE",
|
|
1503
|
+
privacy_policy: "\u9690\u79C1\u653F\u7B56"
|
|
1504
|
+
}
|
|
1489
1505
|
},
|
|
1490
1506
|
errors: {
|
|
1491
1507
|
rateLimited: "\u5C1D\u8BD5\u6B21\u6570\u8FC7\u591A\u3002\u8BF7\u7A0D\u7B49\u51E0\u5206\u949F\u540E\u91CD\u8BD5\u3002",
|
|
@@ -2146,6 +2162,9 @@ var zh_TW_default = {
|
|
|
2146
2162
|
transactionBreakdown: "\u4EA4\u6613\u660E\u7D30",
|
|
2147
2163
|
networkFee: "\u7DB2\u8DEF\u624B\u7E8C\u8CBB",
|
|
2148
2164
|
confirmOrder: "\u78BA\u8A8D\u8A02\u55AE",
|
|
2165
|
+
mfaEnrollmentTitle: "\u8ACB\u555F\u7528\u7C21\u8A0A\u6216 Authy \u96D9\u91CD\u9A57\u8B49",
|
|
2166
|
+
mfaEnrollmentMessage: "\u8ACB\u78BA\u8A8D\u60A8\u5DF2\u5728 Coinbase \u5E33\u6236\u4E2D\u555F\u7528\u7C21\u8A0A\u6216 Authy \u96D9\u91CD\u9A57\u8B49\u3002\u555F\u7528\u5F8C\u8ACB\u6309\u7E7C\u7E8C\u3002",
|
|
2167
|
+
mfaEnrollmentSettingsLink: "\u958B\u555F Coinbase \u5B89\u5168\u8A2D\u5B9A",
|
|
2149
2168
|
termsNoticePrefix: "\u9EDE\u64CA\u300C\u78BA\u8A8D\u8A02\u55AE\u300D\u5373\u8868\u793A\u60A8\u540C\u610F\u6211\u5011\u7684",
|
|
2150
2169
|
termsNoticeLink: "\u689D\u6B3E",
|
|
2151
2170
|
termsNoticeSuffix: "\u3002"
|
|
@@ -2276,7 +2295,12 @@ var zh_TW_default = {
|
|
|
2276
2295
|
prefix: "\u7E7C\u7E8C\u5373\u8868\u793A\u60A8\u540C\u610F Coinbase \u7684",
|
|
2277
2296
|
separator: "\u3001",
|
|
2278
2297
|
lastSeparator: "\u548C",
|
|
2279
|
-
suffix: "\
|
|
2298
|
+
suffix: "\u3002",
|
|
2299
|
+
agreements: {
|
|
2300
|
+
guest_checkout_terms: "\u670D\u52D9\u689D\u6B3E",
|
|
2301
|
+
user_agreement: "\u4F7F\u7528\u8005\u5354\u8B70",
|
|
2302
|
+
privacy_policy: "\u96B1\u79C1\u6B0A\u653F\u7B56"
|
|
2303
|
+
}
|
|
2280
2304
|
},
|
|
2281
2305
|
errors: {
|
|
2282
2306
|
rateLimited: "\u5617\u8A66\u6B21\u6578\u904E\u591A\u3002\u8ACB\u7A0D\u7B49\u5E7E\u5206\u9418\u5F8C\u91CD\u8A66\u3002",
|
|
@@ -3203,10 +3227,12 @@ var import_lucide_react9 = require("lucide-react");
|
|
|
3203
3227
|
var import_core9 = require("@unifold/core");
|
|
3204
3228
|
|
|
3205
3229
|
// src/hooks/use-deposit-address.ts
|
|
3206
|
-
var import_react = require("react");
|
|
3207
3230
|
var import_react_query = require("@tanstack/react-query");
|
|
3208
3231
|
var import_core = require("@unifold/core");
|
|
3209
3232
|
|
|
3233
|
+
// src/hooks/use-internal-user-id.ts
|
|
3234
|
+
var import_react = require("react");
|
|
3235
|
+
|
|
3210
3236
|
// src/context/AnalyticsContext.tsx
|
|
3211
3237
|
var React5 = __toESM(require("react"));
|
|
3212
3238
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
@@ -3238,6 +3264,15 @@ function useAnalytics() {
|
|
|
3238
3264
|
return { track, startSession, endSession, getSessionId, setUserId, subscribe };
|
|
3239
3265
|
}
|
|
3240
3266
|
|
|
3267
|
+
// src/hooks/use-internal-user-id.ts
|
|
3268
|
+
function useStampInternalUserId({ internalUserId }) {
|
|
3269
|
+
const { setUserId } = useAnalytics();
|
|
3270
|
+
(0, import_react.useEffect)(() => {
|
|
3271
|
+
if (!internalUserId) return;
|
|
3272
|
+
setUserId(internalUserId);
|
|
3273
|
+
}, [internalUserId, setUserId]);
|
|
3274
|
+
}
|
|
3275
|
+
|
|
3241
3276
|
// src/hooks/use-deposit-address.ts
|
|
3242
3277
|
function useDepositAddress(params) {
|
|
3243
3278
|
const {
|
|
@@ -3251,7 +3286,6 @@ function useDepositAddress(params) {
|
|
|
3251
3286
|
contractCalls,
|
|
3252
3287
|
enabled = true
|
|
3253
3288
|
} = params;
|
|
3254
|
-
const { setUserId } = useAnalytics();
|
|
3255
3289
|
const query = (0, import_react_query.useQuery)({
|
|
3256
3290
|
queryKey: [
|
|
3257
3291
|
"unifold",
|
|
@@ -3294,11 +3328,7 @@ function useDepositAddress(params) {
|
|
|
3294
3328
|
retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
|
|
3295
3329
|
// 1s, 2s, 4s (max 10s)
|
|
3296
3330
|
});
|
|
3297
|
-
(
|
|
3298
|
-
if (query.data?.user_id) {
|
|
3299
|
-
setUserId(query.data.user_id);
|
|
3300
|
-
}
|
|
3301
|
-
}, [query.data?.user_id, setUserId]);
|
|
3331
|
+
useStampInternalUserId({ internalUserId: query.data?.user_id });
|
|
3302
3332
|
return query;
|
|
3303
3333
|
}
|
|
3304
3334
|
|
|
@@ -5589,7 +5619,11 @@ function BuyWithCard({
|
|
|
5589
5619
|
method: "card",
|
|
5590
5620
|
flow_type: "deposit",
|
|
5591
5621
|
provider: selectedProvider.service_provider,
|
|
5592
|
-
amount_usd: amount
|
|
5622
|
+
amount_usd: amount,
|
|
5623
|
+
// The execution only exists once the provider's payout lands on this
|
|
5624
|
+
// wallet, and it carries this id — so it's the join key for a purchase
|
|
5625
|
+
// that starts here and never reaches flow_completed.
|
|
5626
|
+
deposit_wallet_id: depositWalletId
|
|
5593
5627
|
});
|
|
5594
5628
|
onEvent?.({
|
|
5595
5629
|
id: (0, import_core9.generatePrefixedKSUID)("sevt"),
|
|
@@ -7090,6 +7124,8 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7090
7124
|
const [limitUpgradeError, setLimitUpgradeError] = (0, import_react15.useState)(null);
|
|
7091
7125
|
const [upgradeSubmitting, setUpgradeSubmitting] = (0, import_react15.useState)(false);
|
|
7092
7126
|
const upgradeFlowAbortRef = (0, import_react15.useRef)(null);
|
|
7127
|
+
const applyLimitRoutingRef = (0, import_react15.useRef)(() => {
|
|
7128
|
+
});
|
|
7093
7129
|
const [amount, setAmount] = (0, import_react15.useState)(amountUsd ?? "");
|
|
7094
7130
|
const [preparedOrder, setPreparedOrder] = (0, import_react15.useState)(null);
|
|
7095
7131
|
const sessionAbortRef = (0, import_react15.useRef)(null);
|
|
@@ -7224,6 +7260,14 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7224
7260
|
},
|
|
7225
7261
|
[email, normalizedPhone, userId]
|
|
7226
7262
|
);
|
|
7263
|
+
const { action: initialAction, refetchWalletPayLimits } = useWalletPayInitialScreen({
|
|
7264
|
+
userId,
|
|
7265
|
+
publishableKey,
|
|
7266
|
+
normalizedPhone,
|
|
7267
|
+
userEmail,
|
|
7268
|
+
sessionPhoneVerified: verificationSession?.phone?.status === "verified",
|
|
7269
|
+
isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
|
|
7270
|
+
});
|
|
7227
7271
|
const createSessionAndSendOtp = (0, import_react15.useCallback)(async () => {
|
|
7228
7272
|
setView("submitting_session");
|
|
7229
7273
|
setErrorMessage("");
|
|
@@ -7233,7 +7277,12 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7233
7277
|
email,
|
|
7234
7278
|
phone: normalizedPhone,
|
|
7235
7279
|
terms_accepted: true,
|
|
7236
|
-
|
|
7280
|
+
// TODO: when the API honors `false`, this will trigger email OTP.
|
|
7281
|
+
// Today `false` still skips email (we don't verify it) and JWT ev
|
|
7282
|
+
// is null. Don't send `true` — that was a fake attest.
|
|
7283
|
+
email_already_verified: false
|
|
7284
|
+
// Coinbase stays Redis-only + JWT until bank-transfer identity
|
|
7285
|
+
// is live. Do not persist from this path yet.
|
|
7237
7286
|
},
|
|
7238
7287
|
publishableKey
|
|
7239
7288
|
);
|
|
@@ -7243,6 +7292,34 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7243
7292
|
}
|
|
7244
7293
|
setClientSecret(session.client_secret);
|
|
7245
7294
|
storeWalletPaySession();
|
|
7295
|
+
if (session.status === "verified") {
|
|
7296
|
+
const tokenRes = await (0, import_core15.exchangeOnrampVerificationToken)(
|
|
7297
|
+
session.id,
|
|
7298
|
+
session.client_secret,
|
|
7299
|
+
publishableKey
|
|
7300
|
+
);
|
|
7301
|
+
setOnrampToken(tokenRes);
|
|
7302
|
+
storeWalletPaySession({
|
|
7303
|
+
emailVerifiedAt: session.email.verified_at,
|
|
7304
|
+
phoneVerifiedAt: session.phone.verified_at,
|
|
7305
|
+
onrampToken: tokenRes.token,
|
|
7306
|
+
onrampTokenExpiresAtMs: Date.now() + tokenRes.expires_in * 1e3
|
|
7307
|
+
});
|
|
7308
|
+
if (amountUsd) setAmount(amountUsd);
|
|
7309
|
+
try {
|
|
7310
|
+
const result = await refetchWalletPayLimits();
|
|
7311
|
+
if (result.data) {
|
|
7312
|
+
const nextView = getViewForLimitStatus(result.data);
|
|
7313
|
+
if (nextView) {
|
|
7314
|
+
applyLimitRoutingRef.current(nextView, result.data.upgrade_status);
|
|
7315
|
+
return;
|
|
7316
|
+
}
|
|
7317
|
+
}
|
|
7318
|
+
} catch {
|
|
7319
|
+
}
|
|
7320
|
+
setView("amount");
|
|
7321
|
+
return;
|
|
7322
|
+
}
|
|
7246
7323
|
await (0, import_core15.sendOnrampVerificationOtp)(session.id, "phone", session.client_secret, publishableKey);
|
|
7247
7324
|
setResendCooldown(30);
|
|
7248
7325
|
setView("phone_otp");
|
|
@@ -7251,19 +7328,19 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7251
7328
|
setErrorMessage(prettifyVerificationError(raw));
|
|
7252
7329
|
setView("phone_input");
|
|
7253
7330
|
}
|
|
7254
|
-
}, [
|
|
7331
|
+
}, [
|
|
7332
|
+
email,
|
|
7333
|
+
normalizedPhone,
|
|
7334
|
+
publishableKey,
|
|
7335
|
+
storeWalletPaySession,
|
|
7336
|
+
userId,
|
|
7337
|
+
amountUsd,
|
|
7338
|
+
refetchWalletPayLimits
|
|
7339
|
+
]);
|
|
7255
7340
|
const clearUpgradeFields = (0, import_react15.useCallback)(() => {
|
|
7256
7341
|
setSsnLast4("");
|
|
7257
7342
|
setDobInput("");
|
|
7258
7343
|
}, []);
|
|
7259
|
-
const { action: initialAction, refetchWalletPayLimits } = useWalletPayInitialScreen({
|
|
7260
|
-
userId,
|
|
7261
|
-
publishableKey,
|
|
7262
|
-
normalizedPhone,
|
|
7263
|
-
userEmail,
|
|
7264
|
-
sessionPhoneVerified: verificationSession?.phone?.status === "verified",
|
|
7265
|
-
isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
|
|
7266
|
-
});
|
|
7267
7344
|
const pollLimitUpgradeStatus = (0, import_react15.useCallback)(
|
|
7268
7345
|
async (signal) => {
|
|
7269
7346
|
const POLL_INTERVAL_MS5 = 1500;
|
|
@@ -7374,6 +7451,7 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7374
7451
|
},
|
|
7375
7452
|
[startUpgradePolling]
|
|
7376
7453
|
);
|
|
7454
|
+
applyLimitRoutingRef.current = applyLimitRouting;
|
|
7377
7455
|
const hasInitializedRef = (0, import_react15.useRef)(false);
|
|
7378
7456
|
(0, import_react15.useEffect)(() => {
|
|
7379
7457
|
if (hasInitializedRef.current) return;
|
|
@@ -7603,7 +7681,10 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7603
7681
|
track("flow_started", {
|
|
7604
7682
|
method,
|
|
7605
7683
|
flow_type: "deposit",
|
|
7606
|
-
amount_usd: walletPayAmountUsd
|
|
7684
|
+
amount_usd: walletPayAmountUsd,
|
|
7685
|
+
// No execution yet — one appears when the payout lands on this
|
|
7686
|
+
// wallet, carrying the same id.
|
|
7687
|
+
deposit_wallet_id: depositWalletId
|
|
7607
7688
|
});
|
|
7608
7689
|
onEvent?.({
|
|
7609
7690
|
id: (0, import_core15.generatePrefixedKSUID)("sevt"),
|
|
@@ -7653,6 +7734,7 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7653
7734
|
defaultTokenLoading,
|
|
7654
7735
|
defaultTokenError,
|
|
7655
7736
|
depositWallet?.address,
|
|
7737
|
+
depositWalletId,
|
|
7656
7738
|
userEmail,
|
|
7657
7739
|
publishableKey,
|
|
7658
7740
|
onEvent,
|
|
@@ -8627,7 +8709,7 @@ var FALLBACK_AGREEMENTS = [
|
|
|
8627
8709
|
{
|
|
8628
8710
|
key: "guest_checkout_terms",
|
|
8629
8711
|
name: "Guest Checkout Terms of Service",
|
|
8630
|
-
url: "https://www.coinbase.com/legal/
|
|
8712
|
+
url: "https://www.coinbase.com/legal/guest-checkout/us"
|
|
8631
8713
|
},
|
|
8632
8714
|
{
|
|
8633
8715
|
key: "user_agreement",
|
|
@@ -8647,22 +8729,24 @@ function LegalDisclaimer({ legalAgreements, loading }) {
|
|
|
8647
8729
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
8648
8730
|
"div",
|
|
8649
8731
|
{
|
|
8650
|
-
className: "uf-mt-3 uf-mb-3 uf-px-1 uf-space-y-1.5 uf-animate-pulse",
|
|
8732
|
+
className: "uf-mt-3 uf-mb-3 uf-px-1 uf-space-y-1.5 uf-animate-pulse uf-opacity-50",
|
|
8651
8733
|
"aria-hidden": true,
|
|
8652
8734
|
"aria-busy": "true",
|
|
8653
8735
|
children: [
|
|
8654
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "uf-h-2
|
|
8655
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "uf-h-2
|
|
8656
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "uf-h-2
|
|
8736
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "uf-h-2 uf-rounded uf-w-full", style: { backgroundColor: colors2.card } }),
|
|
8737
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "uf-h-2 uf-rounded uf-w-11/12", style: { backgroundColor: colors2.card } }),
|
|
8738
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "uf-h-2 uf-rounded uf-w-3/4", style: { backgroundColor: colors2.card } })
|
|
8657
8739
|
]
|
|
8658
8740
|
}
|
|
8659
8741
|
);
|
|
8660
8742
|
}
|
|
8661
8743
|
const agreements = legalAgreements?.agreements ?? FALLBACK_AGREEMENTS;
|
|
8744
|
+
const shortLabels = t.agreements;
|
|
8745
|
+
const lastSeparator = t.lastSeparator.replace(/\s+$/, "\xA0");
|
|
8662
8746
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
8663
8747
|
"p",
|
|
8664
8748
|
{
|
|
8665
|
-
className: "uf-text-[
|
|
8749
|
+
className: "uf-text-[10px] uf-leading-relaxed uf-mt-3 uf-mb-3 uf-opacity-60 uf-text-center",
|
|
8666
8750
|
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
8667
8751
|
children: [
|
|
8668
8752
|
t.prefix,
|
|
@@ -8673,12 +8757,12 @@ function LegalDisclaimer({ legalAgreements, loading }) {
|
|
|
8673
8757
|
href: a.url,
|
|
8674
8758
|
target: "_blank",
|
|
8675
8759
|
rel: "noopener noreferrer",
|
|
8676
|
-
className: "uf-underline",
|
|
8677
|
-
style: { color:
|
|
8678
|
-
children: a.name
|
|
8760
|
+
className: "uf-no-underline",
|
|
8761
|
+
style: { color: "inherit", textDecoration: "none", whiteSpace: "nowrap" },
|
|
8762
|
+
children: shortLabels[a.key] ?? a.name
|
|
8679
8763
|
}
|
|
8680
8764
|
),
|
|
8681
|
-
idx < arr.length - 2 ? t.separator : idx === arr.length - 2 ?
|
|
8765
|
+
idx < arr.length - 2 ? t.separator : idx === arr.length - 2 ? lastSeparator : ""
|
|
8682
8766
|
] }, a.key)),
|
|
8683
8767
|
t.suffix
|
|
8684
8768
|
]
|
|
@@ -9350,6 +9434,7 @@ function PayWithCashApp({
|
|
|
9350
9434
|
destinationChainType,
|
|
9351
9435
|
destinationChainId,
|
|
9352
9436
|
destinationTokenAddress,
|
|
9437
|
+
contractCalls,
|
|
9353
9438
|
cashAppIconUrl,
|
|
9354
9439
|
view: controlledView,
|
|
9355
9440
|
onViewChange,
|
|
@@ -9442,7 +9527,8 @@ function PayWithCashApp({
|
|
|
9442
9527
|
destination_token_address: destinationTokenAddress,
|
|
9443
9528
|
recipient_address: recipientAddress,
|
|
9444
9529
|
source_amount: amount,
|
|
9445
|
-
external_id: externalId
|
|
9530
|
+
external_id: externalId,
|
|
9531
|
+
...contractCalls?.length ? { contract_calls: contractCalls } : {}
|
|
9446
9532
|
},
|
|
9447
9533
|
publishableKey
|
|
9448
9534
|
);
|
|
@@ -9455,7 +9541,10 @@ function PayWithCashApp({
|
|
|
9455
9541
|
track("flow_started", {
|
|
9456
9542
|
method: "cashapp",
|
|
9457
9543
|
flow_type: "deposit",
|
|
9458
|
-
amount_usd: amount
|
|
9544
|
+
amount_usd: amount,
|
|
9545
|
+
// No execution yet — one appears when the payout lands on this
|
|
9546
|
+
// wallet, carrying the same id.
|
|
9547
|
+
deposit_wallet_id: depositWalletId
|
|
9459
9548
|
});
|
|
9460
9549
|
onEvent?.({
|
|
9461
9550
|
id: (0, import_core19.generatePrefixedKSUID)("sevt"),
|
|
@@ -9480,6 +9569,8 @@ function PayWithCashApp({
|
|
|
9480
9569
|
destinationChainType,
|
|
9481
9570
|
destinationChainId,
|
|
9482
9571
|
destinationTokenAddress,
|
|
9572
|
+
contractCalls,
|
|
9573
|
+
depositWalletId,
|
|
9483
9574
|
onEvent,
|
|
9484
9575
|
onDepositError,
|
|
9485
9576
|
track,
|
|
@@ -10093,7 +10184,10 @@ function BankTransfer({
|
|
|
10093
10184
|
method: "bank_transfer",
|
|
10094
10185
|
flow_type: "deposit",
|
|
10095
10186
|
provider: request.service_provider,
|
|
10096
|
-
amount_usd: request.source_amount
|
|
10187
|
+
amount_usd: request.source_amount,
|
|
10188
|
+
// No execution yet — one appears when the provider's payout lands on
|
|
10189
|
+
// this wallet, carrying the same id.
|
|
10190
|
+
deposit_wallet_id: pollingWalletId
|
|
10097
10191
|
});
|
|
10098
10192
|
onEvent?.({
|
|
10099
10193
|
id: (0, import_core21.generatePrefixedKSUID)("sevt"),
|
|
@@ -16333,7 +16427,11 @@ function PayWithStripeLink({
|
|
|
16333
16427
|
if (checkoutResult.successful) {
|
|
16334
16428
|
handledTerminalSessionRef.current = null;
|
|
16335
16429
|
executionReconciledSessionRef.current = null;
|
|
16336
|
-
track("flow_started", {
|
|
16430
|
+
track("flow_started", {
|
|
16431
|
+
method: "stripe_link",
|
|
16432
|
+
flow_type: "deposit",
|
|
16433
|
+
deposit_wallet_id: depositWalletId
|
|
16434
|
+
});
|
|
16337
16435
|
setConfirmedSessionId(activeSessionId);
|
|
16338
16436
|
setSessionStatus(STRIPE_SESSION_STATUS.FULFILLMENT_PROCESSING);
|
|
16339
16437
|
if (selectedTokenSingleUseRef.current) clearSelectedPaymentToken();
|
|
@@ -17830,7 +17928,14 @@ function PayWithStripeLink({
|
|
|
17830
17928
|
]
|
|
17831
17929
|
}
|
|
17832
17930
|
),
|
|
17833
|
-
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
17931
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
17932
|
+
"div",
|
|
17933
|
+
{
|
|
17934
|
+
ref: authMountRef,
|
|
17935
|
+
className: "uf-w-full uf-min-h-[200px]",
|
|
17936
|
+
style: { colorScheme: "only light" }
|
|
17937
|
+
}
|
|
17938
|
+
)
|
|
17834
17939
|
]
|
|
17835
17940
|
}
|
|
17836
17941
|
);
|
|
@@ -19111,6 +19216,9 @@ function CoinbaseConnect({
|
|
|
19111
19216
|
flow_type: "deposit",
|
|
19112
19217
|
method: "exchange_connect",
|
|
19113
19218
|
provider: import_core27.IntegrationProvider.COINBASE,
|
|
19219
|
+
// No execution yet — one appears when the exchange's transfer lands on
|
|
19220
|
+
// this wallet, carrying the same id.
|
|
19221
|
+
deposit_wallet_id: transferDepositWalletId,
|
|
19114
19222
|
amount_usd: sendAmount || void 0,
|
|
19115
19223
|
currency: selectedAsset?.currency.toLowerCase().replace(/[^a-z0-9]+/g, "_"),
|
|
19116
19224
|
chain: sourceChain?.chain_id,
|
|
@@ -19118,6 +19226,34 @@ function CoinbaseConnect({
|
|
|
19118
19226
|
network: sourceChain?.network
|
|
19119
19227
|
});
|
|
19120
19228
|
};
|
|
19229
|
+
const applyConfirmResult = (result) => {
|
|
19230
|
+
if (result.status === "mfa_required") {
|
|
19231
|
+
track("verification_started", {
|
|
19232
|
+
flow_type: "deposit",
|
|
19233
|
+
method: "exchange_connect",
|
|
19234
|
+
provider: import_core27.IntegrationProvider.COINBASE,
|
|
19235
|
+
verification_type: "mfa",
|
|
19236
|
+
verification_status: result.status
|
|
19237
|
+
});
|
|
19238
|
+
transitionTo("mfa");
|
|
19239
|
+
setMfaCode("");
|
|
19240
|
+
setMfaError(false);
|
|
19241
|
+
} else if (result.status === "mfa_enrollment_required") {
|
|
19242
|
+
transitionTo("mfa_enrollment");
|
|
19243
|
+
} else if (result.status === "completed") {
|
|
19244
|
+
trackTransferStarted();
|
|
19245
|
+
setConfirmResult(result);
|
|
19246
|
+
transitionTo("success");
|
|
19247
|
+
onTransferSuccess?.(result);
|
|
19248
|
+
} else {
|
|
19249
|
+
setErrorMessage(result.message || t.errors.transferFailed);
|
|
19250
|
+
transitionTo("error");
|
|
19251
|
+
onTransferError?.({
|
|
19252
|
+
message: result.message || t.errors.transferFailed,
|
|
19253
|
+
code: result.status
|
|
19254
|
+
});
|
|
19255
|
+
}
|
|
19256
|
+
};
|
|
19121
19257
|
const handleConfirmTransfer = async () => {
|
|
19122
19258
|
if (!transferIntent || !accessToken) return;
|
|
19123
19259
|
setIsLoading(true);
|
|
@@ -19152,30 +19288,7 @@ function CoinbaseConnect({
|
|
|
19152
19288
|
});
|
|
19153
19289
|
throw err;
|
|
19154
19290
|
});
|
|
19155
|
-
|
|
19156
|
-
track("verification_started", {
|
|
19157
|
-
flow_type: "deposit",
|
|
19158
|
-
method: "exchange_connect",
|
|
19159
|
-
provider: import_core27.IntegrationProvider.COINBASE,
|
|
19160
|
-
verification_type: "mfa",
|
|
19161
|
-
verification_status: result.status
|
|
19162
|
-
});
|
|
19163
|
-
transitionTo("mfa");
|
|
19164
|
-
setMfaCode("");
|
|
19165
|
-
setMfaError(false);
|
|
19166
|
-
} else if (result.status === "completed") {
|
|
19167
|
-
trackTransferStarted();
|
|
19168
|
-
setConfirmResult(result);
|
|
19169
|
-
transitionTo("success");
|
|
19170
|
-
onTransferSuccess?.(result);
|
|
19171
|
-
} else {
|
|
19172
|
-
setErrorMessage(result.message || t.errors.transferFailed);
|
|
19173
|
-
transitionTo("error");
|
|
19174
|
-
onTransferError?.({
|
|
19175
|
-
message: result.message || t.errors.transferFailed,
|
|
19176
|
-
code: result.status
|
|
19177
|
-
});
|
|
19178
|
-
}
|
|
19291
|
+
applyConfirmResult(result);
|
|
19179
19292
|
} catch (err) {
|
|
19180
19293
|
const message = err instanceof Error ? err.message : t.errors.transferFailed;
|
|
19181
19294
|
setErrorMessage(message);
|
|
@@ -19332,6 +19445,9 @@ function CoinbaseConnect({
|
|
|
19332
19445
|
setShowTransferDetails(false);
|
|
19333
19446
|
transitionTo("enter_amount");
|
|
19334
19447
|
break;
|
|
19448
|
+
case "mfa_enrollment":
|
|
19449
|
+
transitionTo("transfer_confirm");
|
|
19450
|
+
break;
|
|
19335
19451
|
case "mfa":
|
|
19336
19452
|
transitionTo("transfer_confirm");
|
|
19337
19453
|
break;
|
|
@@ -20888,6 +21004,55 @@ function CoinbaseConnect({
|
|
|
20888
21004
|
] })
|
|
20889
21005
|
] });
|
|
20890
21006
|
}
|
|
21007
|
+
if (view === "mfa_enrollment") {
|
|
21008
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
|
|
21009
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(DepositHeader, { title: t.title, showBack: true, onBack: handleBack, onClose }),
|
|
21010
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
21011
|
+
"div",
|
|
21012
|
+
{
|
|
21013
|
+
className: "uf-flex uf-flex-col uf-items-center uf-px-4 uf-pb-4",
|
|
21014
|
+
style: viewTransitionStyle,
|
|
21015
|
+
children: [
|
|
21016
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
21017
|
+
DepositErrorState,
|
|
21018
|
+
{
|
|
21019
|
+
title: t.transfer.mfaEnrollmentTitle,
|
|
21020
|
+
message: t.transfer.mfaEnrollmentMessage
|
|
21021
|
+
}
|
|
21022
|
+
),
|
|
21023
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
21024
|
+
"a",
|
|
21025
|
+
{
|
|
21026
|
+
href: "https://www.coinbase.com/settings/security",
|
|
21027
|
+
target: "_blank",
|
|
21028
|
+
rel: "noopener noreferrer",
|
|
21029
|
+
className: "uf-text-sm uf-underline uf-mb-8 uf-inline-flex uf-items-center uf-gap-1",
|
|
21030
|
+
style: { color: colors2.primary, fontFamily: fonts.medium },
|
|
21031
|
+
children: [
|
|
21032
|
+
t.transfer.mfaEnrollmentSettingsLink,
|
|
21033
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react29.ExternalLink, { className: "uf-w-3.5 uf-h-3.5" })
|
|
21034
|
+
]
|
|
21035
|
+
}
|
|
21036
|
+
),
|
|
21037
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
21038
|
+
"button",
|
|
21039
|
+
{
|
|
21040
|
+
onClick: handleConfirmTransfer,
|
|
21041
|
+
disabled: isLoading,
|
|
21042
|
+
className: "uf-w-full uf-rounded-xl uf-py-3.5 uf-text-sm uf-font-medium uf-transition-all hover:uf-opacity-90 disabled:uf-opacity-50 uf-flex uf-items-center uf-justify-center uf-gap-2",
|
|
21043
|
+
style: {
|
|
21044
|
+
backgroundColor: colors2.primary,
|
|
21045
|
+
color: "#fff",
|
|
21046
|
+
fontFamily: fonts.medium
|
|
21047
|
+
},
|
|
21048
|
+
children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react29.Loader2, { className: "uf-w-4 uf-h-4 uf-animate-spin" }) : t.continue
|
|
21049
|
+
}
|
|
21050
|
+
)
|
|
21051
|
+
]
|
|
21052
|
+
}
|
|
21053
|
+
)
|
|
21054
|
+
] });
|
|
21055
|
+
}
|
|
20891
21056
|
if (view === "mfa") {
|
|
20892
21057
|
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
|
|
20893
21058
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(DepositHeader, { title: t.title, showBack: true, onBack: handleBack, onClose }),
|
|
@@ -26994,7 +27159,11 @@ function WalletConnect({
|
|
|
26994
27159
|
chain: String(token.chain_id),
|
|
26995
27160
|
network: token.network,
|
|
26996
27161
|
token: token.symbol ?? token.token_address,
|
|
26997
|
-
currency: token.currency
|
|
27162
|
+
currency: token.currency,
|
|
27163
|
+
// No execution exists yet — it's created when this send lands on the
|
|
27164
|
+
// wallet. The wallet id is what that execution will carry, so it's
|
|
27165
|
+
// how a send that never completes is matched to what followed.
|
|
27166
|
+
deposit_wallet_id: activeDepositWallet?.id
|
|
26998
27167
|
});
|
|
26999
27168
|
setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
|
|
27000
27169
|
setHasSignedTransaction(true);
|
|
@@ -27584,7 +27753,7 @@ function DepositModal({
|
|
|
27584
27753
|
const applePaySubTitle = applePaySubTitleProp ?? t.applePayMenu.subtitle;
|
|
27585
27754
|
const googlePayTitle = googlePayTitleProp ?? t.googlePayMenu.title;
|
|
27586
27755
|
const googlePaySubTitle = googlePaySubTitleProp ?? t.googlePayMenu.subtitle;
|
|
27587
|
-
const { track, startSession, endSession, getSessionId, subscribe } = useAnalytics();
|
|
27756
|
+
const { track, startSession, endSession, getSessionId, setUserId, subscribe } = useAnalytics();
|
|
27588
27757
|
const normalizedPrefilledAmountUsd = (0, import_react31.useMemo)(
|
|
27589
27758
|
() => normalizePrefilledUsdAmount(prefilledAmountUsd),
|
|
27590
27759
|
[prefilledAmountUsd]
|
|
@@ -27592,6 +27761,7 @@ function DepositModal({
|
|
|
27592
27761
|
const analyticsMethod = (method) => method === "transfer" ? "transfer_crypto" : method;
|
|
27593
27762
|
const journeyActiveRef = (0, import_react31.useRef)(false);
|
|
27594
27763
|
const journeySessionIdRef = (0, import_react31.useRef)(void 0);
|
|
27764
|
+
const journeyExternalUserIdRef = (0, import_react31.useRef)(void 0);
|
|
27595
27765
|
const externalUserId = userId || void 0;
|
|
27596
27766
|
const emitEvent = (0, import_react31.useCallback)(
|
|
27597
27767
|
(event) => onEvent?.({ ...event, externalUserId }),
|
|
@@ -27619,6 +27789,9 @@ function DepositModal({
|
|
|
27619
27789
|
method: analyticsMethod(method),
|
|
27620
27790
|
flow_type: "deposit",
|
|
27621
27791
|
amount_usd: execution?.destinationAmountUsd ?? execution?.sourceAmountUsd,
|
|
27792
|
+
// The one high-cardinality field we do send: the join key from a
|
|
27793
|
+
// funnel session back to the execution row it produced.
|
|
27794
|
+
execution_id: data.executionId ?? execution?.id,
|
|
27622
27795
|
// Flat, low-cardinality execution dimensions for PostHog breakdowns
|
|
27623
27796
|
// (precise/opaque fields like base units, addresses, tx hashes live in
|
|
27624
27797
|
// the onEvent DirectExecution instead).
|
|
@@ -27646,6 +27819,7 @@ function DepositModal({
|
|
|
27646
27819
|
method: analyticsMethod(method),
|
|
27647
27820
|
flow_type: "deposit",
|
|
27648
27821
|
error_code: error.code,
|
|
27822
|
+
execution_id: execution?.id,
|
|
27649
27823
|
failure_reason: execution?.failureReason ?? void 0,
|
|
27650
27824
|
status: execution?.status,
|
|
27651
27825
|
source_chain_type: execution?.sourceChainType,
|
|
@@ -28074,8 +28248,10 @@ function DepositModal({
|
|
|
28074
28248
|
const beginJourney = (0, import_react31.useCallback)(() => {
|
|
28075
28249
|
journeySessionIdRef.current = startSession();
|
|
28076
28250
|
journeyActiveRef.current = true;
|
|
28251
|
+
journeyExternalUserIdRef.current = userId;
|
|
28252
|
+
setUserId(null);
|
|
28077
28253
|
track("widget_opened", { flow_type: "deposit" });
|
|
28078
|
-
}, [startSession, track]);
|
|
28254
|
+
}, [startSession, track, setUserId, userId]);
|
|
28079
28255
|
const handleClose = () => {
|
|
28080
28256
|
finalizeJourney();
|
|
28081
28257
|
onOpenChange(false);
|
|
@@ -28100,6 +28276,11 @@ function DepositModal({
|
|
|
28100
28276
|
}
|
|
28101
28277
|
beginJourney();
|
|
28102
28278
|
}, [open]);
|
|
28279
|
+
(0, import_react31.useLayoutEffect)(() => {
|
|
28280
|
+
if (!open || journeyExternalUserIdRef.current === userId) return;
|
|
28281
|
+
journeyExternalUserIdRef.current = userId;
|
|
28282
|
+
setUserId(null);
|
|
28283
|
+
}, [open, userId, setUserId]);
|
|
28103
28284
|
(0, import_react31.useLayoutEffect)(() => {
|
|
28104
28285
|
if (!open) return;
|
|
28105
28286
|
if (resetViewTimeoutRef.current) {
|
|
@@ -29011,6 +29192,7 @@ function DepositModal({
|
|
|
29011
29192
|
destinationChainType,
|
|
29012
29193
|
destinationChainId,
|
|
29013
29194
|
destinationTokenAddress,
|
|
29195
|
+
contractCalls,
|
|
29014
29196
|
cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
|
|
29015
29197
|
view: cashAppView,
|
|
29016
29198
|
onViewChange: setCashAppView,
|
|
@@ -29371,6 +29553,9 @@ function CheckoutModal({
|
|
|
29371
29553
|
flowCompletedRef.current = true;
|
|
29372
29554
|
track("flow_completed", {
|
|
29373
29555
|
flow_type: "checkout",
|
|
29556
|
+
// Checkout has no direct execution; the intent is what a funnel
|
|
29557
|
+
// session joins back to.
|
|
29558
|
+
payment_intent_id: data.paymentIntentId,
|
|
29374
29559
|
...method ? { method: method === "transfer" ? "transfer_crypto" : method } : {}
|
|
29375
29560
|
});
|
|
29376
29561
|
}
|
|
@@ -29591,7 +29776,7 @@ function CheckoutModal({
|
|
|
29591
29776
|
journeySessionIdRef.current = startSession();
|
|
29592
29777
|
journeyActiveRef.current = true;
|
|
29593
29778
|
flowCompletedRef.current = false;
|
|
29594
|
-
setUserId(null);
|
|
29779
|
+
setUserId(paymentIntentUserId ?? null);
|
|
29595
29780
|
track("widget_opened", { flow_type: "checkout" });
|
|
29596
29781
|
if (resetViewTimeoutRef.current) {
|
|
29597
29782
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -30032,7 +30217,7 @@ function CheckoutModal({
|
|
|
30032
30217
|
}
|
|
30033
30218
|
|
|
30034
30219
|
// src/components/withdrawals/WithdrawModal.tsx
|
|
30035
|
-
var
|
|
30220
|
+
var import_react38 = require("react");
|
|
30036
30221
|
var import_lucide_react44 = require("lucide-react");
|
|
30037
30222
|
|
|
30038
30223
|
// src/hooks/use-supported-destination-tokens.ts
|
|
@@ -30198,7 +30383,7 @@ var import_react_query24 = require("@tanstack/react-query");
|
|
|
30198
30383
|
var import_core50 = require("@unifold/core");
|
|
30199
30384
|
function useExecutions(userId, publishableKey, options) {
|
|
30200
30385
|
const actionType = options?.actionType ?? import_core50.ActionType.Deposit;
|
|
30201
|
-
|
|
30386
|
+
const query = (0, import_react_query24.useQuery)({
|
|
30202
30387
|
queryKey: ["unifold", "executions", actionType, userId, publishableKey],
|
|
30203
30388
|
queryFn: () => (0, import_core50.queryExecutions)(userId, publishableKey, actionType),
|
|
30204
30389
|
enabled: (options?.enabled ?? true) && !!userId,
|
|
@@ -30207,6 +30392,8 @@ function useExecutions(userId, publishableKey, options) {
|
|
|
30207
30392
|
gcTime: 1e3 * 60 * 5,
|
|
30208
30393
|
refetchOnWindowFocus: false
|
|
30209
30394
|
});
|
|
30395
|
+
useStampInternalUserId({ internalUserId: query.data?.data[0]?.user_id });
|
|
30396
|
+
return query;
|
|
30210
30397
|
}
|
|
30211
30398
|
|
|
30212
30399
|
// src/hooks/use-withdraw-polling.ts
|
|
@@ -30541,7 +30728,7 @@ function WithdrawDoubleInput({
|
|
|
30541
30728
|
}
|
|
30542
30729
|
|
|
30543
30730
|
// src/components/withdrawals/WithdrawForm.tsx
|
|
30544
|
-
var
|
|
30731
|
+
var import_react36 = require("react");
|
|
30545
30732
|
var import_lucide_react42 = require("lucide-react");
|
|
30546
30733
|
var import_core56 = require("@unifold/core");
|
|
30547
30734
|
|
|
@@ -30804,11 +30991,10 @@ async function detectBrowserWallet(chainType, senderAddress) {
|
|
|
30804
30991
|
}
|
|
30805
30992
|
|
|
30806
30993
|
// src/hooks/use-hypercore-withdraw-activation.ts
|
|
30807
|
-
var
|
|
30994
|
+
var import_react35 = require("react");
|
|
30808
30995
|
var import_core55 = require("@unifold/core");
|
|
30809
30996
|
|
|
30810
30997
|
// src/hooks/use-get-deposit-address.ts
|
|
30811
|
-
var import_react35 = require("react");
|
|
30812
30998
|
var import_react_query26 = require("@tanstack/react-query");
|
|
30813
30999
|
var import_core54 = require("@unifold/core");
|
|
30814
31000
|
function useGetDepositAddress(params) {
|
|
@@ -30822,7 +31008,6 @@ function useGetDepositAddress(params) {
|
|
|
30822
31008
|
actionType,
|
|
30823
31009
|
enabled = true
|
|
30824
31010
|
} = params;
|
|
30825
|
-
const { setUserId } = useAnalytics();
|
|
30826
31011
|
const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
30827
31012
|
const query = (0, import_react_query26.useQuery)({
|
|
30828
31013
|
queryKey: [
|
|
@@ -30854,11 +31039,7 @@ function useGetDepositAddress(params) {
|
|
|
30854
31039
|
refetchOnWindowFocus: false,
|
|
30855
31040
|
retry: 1
|
|
30856
31041
|
});
|
|
30857
|
-
(
|
|
30858
|
-
if (query.data?.user_id) {
|
|
30859
|
-
setUserId(query.data.user_id);
|
|
30860
|
-
}
|
|
30861
|
-
}, [query.data?.user_id, setUserId]);
|
|
31042
|
+
useStampInternalUserId({ internalUserId: query.data?.user_id });
|
|
30862
31043
|
return query;
|
|
30863
31044
|
}
|
|
30864
31045
|
|
|
@@ -30899,7 +31080,7 @@ function useHypercoreWithdrawActivation(params) {
|
|
|
30899
31080
|
actionType: import_core55.ActionType.Withdraw,
|
|
30900
31081
|
enabled: enabled && isHypercore(sourceChainId)
|
|
30901
31082
|
});
|
|
30902
|
-
const depositWalletAddress = (0,
|
|
31083
|
+
const depositWalletAddress = (0, import_react35.useMemo)(() => {
|
|
30903
31084
|
const wallets = depositWalletLookup.data?.data ?? [];
|
|
30904
31085
|
return wallets.find((w) => w.chain_type === sourceChainType)?.address;
|
|
30905
31086
|
}, [depositWalletLookup.data, sourceChainType]);
|
|
@@ -30990,22 +31171,22 @@ function WithdrawForm({
|
|
|
30990
31171
|
const strings = useI18n().t;
|
|
30991
31172
|
const t = strings.withdrawModal;
|
|
30992
31173
|
const tCrypto = strings.transferCrypto;
|
|
30993
|
-
const [recipientAddress, setRecipientAddress] = (0,
|
|
30994
|
-
const [amount, setAmount] = (0,
|
|
30995
|
-
const [inputUnit, setInputUnit] = (0,
|
|
30996
|
-
const [isSubmitting, setIsSubmitting] = (0,
|
|
30997
|
-
const [submitError, setSubmitError] = (0,
|
|
30998
|
-
const [detailsExpanded, setDetailsExpanded] = (0,
|
|
30999
|
-
const [glossaryOpen, setGlossaryOpen] = (0,
|
|
31000
|
-
const [isMaxed, setIsMaxed] = (0,
|
|
31001
|
-
(0,
|
|
31174
|
+
const [recipientAddress, setRecipientAddress] = (0, import_react36.useState)(recipientAddressProp || "");
|
|
31175
|
+
const [amount, setAmount] = (0, import_react36.useState)("");
|
|
31176
|
+
const [inputUnit, setInputUnit] = (0, import_react36.useState)("fiat");
|
|
31177
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react36.useState)(false);
|
|
31178
|
+
const [submitError, setSubmitError] = (0, import_react36.useState)(null);
|
|
31179
|
+
const [detailsExpanded, setDetailsExpanded] = (0, import_react36.useState)(false);
|
|
31180
|
+
const [glossaryOpen, setGlossaryOpen] = (0, import_react36.useState)(false);
|
|
31181
|
+
const [isMaxed, setIsMaxed] = (0, import_react36.useState)(false);
|
|
31182
|
+
(0, import_react36.useEffect)(() => {
|
|
31002
31183
|
setRecipientAddress(recipientAddressProp || "");
|
|
31003
31184
|
setAmount("");
|
|
31004
31185
|
setInputUnit("fiat");
|
|
31005
31186
|
setSubmitError(null);
|
|
31006
31187
|
setIsMaxed(false);
|
|
31007
31188
|
}, [recipientAddressProp]);
|
|
31008
|
-
(0,
|
|
31189
|
+
(0, import_react36.useEffect)(() => {
|
|
31009
31190
|
setIsMaxed(false);
|
|
31010
31191
|
}, [balanceData?.balanceBaseUnit]);
|
|
31011
31192
|
const trimmedAddress = recipientAddress.trim();
|
|
@@ -31023,7 +31204,7 @@ function WithdrawForm({
|
|
|
31023
31204
|
enabled: debouncedAddress.length > 5 && !!selectedChain
|
|
31024
31205
|
});
|
|
31025
31206
|
const isDebouncing = trimmedAddress !== debouncedAddress;
|
|
31026
|
-
const addressError = (0,
|
|
31207
|
+
const addressError = (0, import_react36.useMemo)(() => {
|
|
31027
31208
|
if (!trimmedAddress || trimmedAddress.length <= 5) return null;
|
|
31028
31209
|
if (isDebouncing || isVerifyingAddress) return null;
|
|
31029
31210
|
if (verifyError) return t.invalidAddress;
|
|
@@ -31067,33 +31248,33 @@ function WithdrawForm({
|
|
|
31067
31248
|
destinationTokenAddress: selectedChain?.token_address,
|
|
31068
31249
|
enabled: isAddressValid
|
|
31069
31250
|
});
|
|
31070
|
-
const exchangeRate = (0,
|
|
31251
|
+
const exchangeRate = (0, import_react36.useMemo)(() => {
|
|
31071
31252
|
if (!balanceData?.exchangeRate) return 0;
|
|
31072
31253
|
return parseFloat(balanceData.exchangeRate);
|
|
31073
31254
|
}, [balanceData]);
|
|
31074
|
-
const balanceCrypto = (0,
|
|
31255
|
+
const balanceCrypto = (0, import_react36.useMemo)(() => {
|
|
31075
31256
|
if (!balanceData?.balanceHuman) return 0;
|
|
31076
31257
|
return parseFloat(balanceData.balanceHuman);
|
|
31077
31258
|
}, [balanceData]);
|
|
31078
|
-
const balanceUsdNum = (0,
|
|
31259
|
+
const balanceUsdNum = (0, import_react36.useMemo)(() => {
|
|
31079
31260
|
if (!balanceData?.balanceUsd) return 0;
|
|
31080
31261
|
return parseFloat(balanceData.balanceUsd);
|
|
31081
31262
|
}, [balanceData]);
|
|
31082
31263
|
const tokenSymbol = sourceTokenSymbol || balanceData?.symbol || "TOKEN";
|
|
31083
31264
|
const sourceDecimals = balanceData?.decimals ?? 6;
|
|
31084
|
-
const cryptoAmountFromInput = (0,
|
|
31265
|
+
const cryptoAmountFromInput = (0, import_react36.useMemo)(() => {
|
|
31085
31266
|
const val = parseFloat(amount);
|
|
31086
31267
|
if (!val || val <= 0) return 0;
|
|
31087
31268
|
if (inputUnit === "crypto") return val;
|
|
31088
31269
|
return exchangeRate > 0 ? val / exchangeRate : 0;
|
|
31089
31270
|
}, [amount, inputUnit, exchangeRate]);
|
|
31090
|
-
const fiatAmountFromInput = (0,
|
|
31271
|
+
const fiatAmountFromInput = (0, import_react36.useMemo)(() => {
|
|
31091
31272
|
const val = parseFloat(amount);
|
|
31092
31273
|
if (!val || val <= 0) return 0;
|
|
31093
31274
|
if (inputUnit === "fiat") return val;
|
|
31094
31275
|
return val * exchangeRate;
|
|
31095
31276
|
}, [amount, inputUnit, exchangeRate]);
|
|
31096
|
-
const convertedDisplay = (0,
|
|
31277
|
+
const convertedDisplay = (0, import_react36.useMemo)(() => {
|
|
31097
31278
|
if (!amount || parseFloat(amount) <= 0) return null;
|
|
31098
31279
|
if (inputUnit === "crypto") {
|
|
31099
31280
|
return `$${fiatAmountFromInput.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
@@ -31112,7 +31293,7 @@ function WithdrawForm({
|
|
|
31112
31293
|
isMaxed,
|
|
31113
31294
|
isStablecoin
|
|
31114
31295
|
]);
|
|
31115
|
-
const balanceDisplay = (0,
|
|
31296
|
+
const balanceDisplay = (0, import_react36.useMemo)(() => {
|
|
31116
31297
|
if (isLoadingBalance || !balanceData) return null;
|
|
31117
31298
|
if (inputUnit === "crypto") {
|
|
31118
31299
|
const displayDecimals = isStablecoin ? 2 : 6;
|
|
@@ -31135,7 +31316,7 @@ function WithdrawForm({
|
|
|
31135
31316
|
tokenSymbol,
|
|
31136
31317
|
isStablecoin
|
|
31137
31318
|
]);
|
|
31138
|
-
const handleSwitchUnit = (0,
|
|
31319
|
+
const handleSwitchUnit = (0, import_react36.useCallback)(() => {
|
|
31139
31320
|
if (isMaxed && balanceData) {
|
|
31140
31321
|
if (inputUnit === "crypto") {
|
|
31141
31322
|
setAmount((Math.round(balanceUsdNum * 100) / 100).toFixed(2));
|
|
@@ -31162,7 +31343,7 @@ function WithdrawForm({
|
|
|
31162
31343
|
setInputUnit("crypto");
|
|
31163
31344
|
}
|
|
31164
31345
|
}, [amount, inputUnit, exchangeRate, sourceDecimals, isMaxed, balanceData, balanceUsdNum]);
|
|
31165
|
-
const handleMaxClick = (0,
|
|
31346
|
+
const handleMaxClick = (0, import_react36.useCallback)(() => {
|
|
31166
31347
|
if (inputUnit === "crypto") {
|
|
31167
31348
|
if (balanceCrypto <= 0) return;
|
|
31168
31349
|
setAmount(balanceData?.balanceHuman ?? "0");
|
|
@@ -31176,7 +31357,7 @@ function WithdrawForm({
|
|
|
31176
31357
|
const isBelowMinimum = minimumWithdrawAmountUsd !== null && fiatAmountFromInput > 0 && Math.round(fiatAmountFromInput * 100) / 100 < minimumWithdrawAmountUsd;
|
|
31177
31358
|
const isOverBalance = inputUnit === "crypto" ? cryptoAmountFromInput > 0 && balanceCrypto > 0 && cryptoAmountFromInput > balanceCrypto : fiatAmountFromInput > 0 && balanceUsdNum > 0 && Math.round(fiatAmountFromInput * 100) / 100 > Math.round(balanceUsdNum * 100) / 100;
|
|
31178
31359
|
const isFormValid = trimmedAddress.length > 0 && amount.trim().length > 0 && cryptoAmountFromInput > 0 && isAddressValid && !isBelowMinimum && !isOverBalance && !isBalanceBelowMinimum && !!balanceData;
|
|
31179
|
-
const handleWithdraw = (0,
|
|
31360
|
+
const handleWithdraw = (0, import_react36.useCallback)(async () => {
|
|
31180
31361
|
if (!selectedToken || !selectedChain) return;
|
|
31181
31362
|
if (!isFormValid) return;
|
|
31182
31363
|
setIsSubmitting(true);
|
|
@@ -31806,7 +31987,7 @@ function WithdrawExecutionItem({ execution, onClick }) {
|
|
|
31806
31987
|
}
|
|
31807
31988
|
|
|
31808
31989
|
// src/components/withdrawals/WithdrawConfirmingView.tsx
|
|
31809
|
-
var
|
|
31990
|
+
var import_react37 = require("react");
|
|
31810
31991
|
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
31811
31992
|
function truncateAddress4(addr) {
|
|
31812
31993
|
if (addr.length <= 12) return addr;
|
|
@@ -31822,9 +32003,9 @@ function WithdrawConfirmingView({
|
|
|
31822
32003
|
const { colors: colors2, fonts, components } = useTheme();
|
|
31823
32004
|
const { t: strings } = useI18n();
|
|
31824
32005
|
const t = strings.withdrawModal.details;
|
|
31825
|
-
const [showButton, setShowButton] = (0,
|
|
32006
|
+
const [showButton, setShowButton] = (0, import_react37.useState)(false);
|
|
31826
32007
|
const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
|
|
31827
|
-
(0,
|
|
32008
|
+
(0, import_react37.useEffect)(() => {
|
|
31828
32009
|
if (latestExecution) return;
|
|
31829
32010
|
const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
|
|
31830
32011
|
return () => clearTimeout(timer);
|
|
@@ -31974,13 +32155,13 @@ function WithdrawModal({
|
|
|
31974
32155
|
const { colors: colors2, fonts, components } = useTheme();
|
|
31975
32156
|
const t = useI18n().t.withdrawModal;
|
|
31976
32157
|
const { track, startSession, endSession, getSessionId, setUserId, subscribe } = useAnalytics();
|
|
31977
|
-
const emitEvent = (0,
|
|
32158
|
+
const emitEvent = (0, import_react38.useCallback)(
|
|
31978
32159
|
(event) => onEvent?.({ ...event, externalUserId }),
|
|
31979
32160
|
[onEvent, externalUserId]
|
|
31980
32161
|
);
|
|
31981
|
-
const onEventRef = (0,
|
|
32162
|
+
const onEventRef = (0, import_react38.useRef)(emitEvent);
|
|
31982
32163
|
onEventRef.current = emitEvent;
|
|
31983
|
-
(0,
|
|
32164
|
+
(0, import_react38.useEffect)(
|
|
31984
32165
|
() => subscribe((event) => {
|
|
31985
32166
|
if (event.properties?.flow_type !== "withdraw") return;
|
|
31986
32167
|
const selection = selectionPayload(event);
|
|
@@ -31995,14 +32176,18 @@ function WithdrawModal({
|
|
|
31995
32176
|
}),
|
|
31996
32177
|
[subscribe, getSessionId]
|
|
31997
32178
|
);
|
|
31998
|
-
const journeyActiveRef = (0,
|
|
31999
|
-
const journeySessionIdRef = (0,
|
|
32000
|
-
const
|
|
32179
|
+
const journeyActiveRef = (0, import_react38.useRef)(false);
|
|
32180
|
+
const journeySessionIdRef = (0, import_react38.useRef)(void 0);
|
|
32181
|
+
const journeyExternalUserIdRef = (0, import_react38.useRef)(void 0);
|
|
32182
|
+
const onWithdrawSuccessFor = (0, import_react38.useCallback)(
|
|
32001
32183
|
(data) => {
|
|
32002
32184
|
const execution = data.execution?.data.object;
|
|
32003
32185
|
track("flow_completed", {
|
|
32004
32186
|
flow_type: "withdraw",
|
|
32005
32187
|
amount_usd: execution?.destinationAmountUsd ?? execution?.sourceAmountUsd,
|
|
32188
|
+
// The one high-cardinality field we do send: the join key from a
|
|
32189
|
+
// funnel session back to the execution row it produced.
|
|
32190
|
+
execution_id: data.executionId ?? execution?.id,
|
|
32006
32191
|
// Flat, low-cardinality execution dimensions for PostHog breakdowns.
|
|
32007
32192
|
status: execution?.status,
|
|
32008
32193
|
source_chain_type: execution?.sourceChainType,
|
|
@@ -32017,12 +32202,13 @@ function WithdrawModal({
|
|
|
32017
32202
|
},
|
|
32018
32203
|
[onWithdrawSuccess, emitEvent, track]
|
|
32019
32204
|
);
|
|
32020
|
-
const onWithdrawErrorFor = (0,
|
|
32205
|
+
const onWithdrawErrorFor = (0, import_react38.useCallback)(
|
|
32021
32206
|
(error) => {
|
|
32022
32207
|
const execution = error.execution?.data.object;
|
|
32023
32208
|
track("flow_failed", {
|
|
32024
32209
|
flow_type: "withdraw",
|
|
32025
32210
|
error_code: error.code,
|
|
32211
|
+
execution_id: execution?.id,
|
|
32026
32212
|
failure_reason: execution?.failureReason ?? void 0,
|
|
32027
32213
|
status: execution?.status,
|
|
32028
32214
|
source_chain_type: execution?.sourceChainType,
|
|
@@ -32037,14 +32223,14 @@ function WithdrawModal({
|
|
|
32037
32223
|
},
|
|
32038
32224
|
[onWithdrawError, emitEvent, track]
|
|
32039
32225
|
);
|
|
32040
|
-
const [containerEl, setContainerEl] = (0,
|
|
32041
|
-
const containerCallbackRef = (0,
|
|
32226
|
+
const [containerEl, setContainerEl] = (0, import_react38.useState)(null);
|
|
32227
|
+
const containerCallbackRef = (0, import_react38.useCallback)((el) => {
|
|
32042
32228
|
setContainerEl(el);
|
|
32043
32229
|
}, []);
|
|
32044
|
-
const [resolvedTheme, setResolvedTheme] = (0,
|
|
32230
|
+
const [resolvedTheme, setResolvedTheme] = (0, import_react38.useState)(
|
|
32045
32231
|
theme === "auto" ? "dark" : theme
|
|
32046
32232
|
);
|
|
32047
|
-
(0,
|
|
32233
|
+
(0, import_react38.useEffect)(() => {
|
|
32048
32234
|
if (theme === "auto") {
|
|
32049
32235
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
32050
32236
|
setResolvedTheme(mq.matches ? "dark" : "light");
|
|
@@ -32059,7 +32245,7 @@ function WithdrawModal({
|
|
|
32059
32245
|
publishableKey,
|
|
32060
32246
|
open
|
|
32061
32247
|
);
|
|
32062
|
-
const destinationTokens = (0,
|
|
32248
|
+
const destinationTokens = (0, import_react38.useMemo)(() => tokensResponse?.data ?? [], [tokensResponse]);
|
|
32063
32249
|
const { data: sourceValidation, isLoading: isCheckingSourceToken } = useSourceTokenValidation({
|
|
32064
32250
|
sourceChainType,
|
|
32065
32251
|
sourceChainId,
|
|
@@ -32094,10 +32280,11 @@ function WithdrawModal({
|
|
|
32094
32280
|
const selectedChain = selectedToken && selectedChainKey ? selectedToken.chains.find(
|
|
32095
32281
|
(c) => getChainKey5(c.chain_id, c.chain_type) === selectedChainKey
|
|
32096
32282
|
) ?? null : null;
|
|
32097
|
-
const [view, setView] = (0,
|
|
32098
|
-
const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0,
|
|
32099
|
-
const
|
|
32100
|
-
const [
|
|
32283
|
+
const [view, setView] = (0, import_react38.useState)("form");
|
|
32284
|
+
const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react38.useState)();
|
|
32285
|
+
const withdrawDepositWalletIdRef = (0, import_react38.useRef)(void 0);
|
|
32286
|
+
const [selectedExecution, setSelectedExecution] = (0, import_react38.useState)(null);
|
|
32287
|
+
const [submittedTxInfo, setSubmittedTxInfo] = (0, import_react38.useState)(null);
|
|
32101
32288
|
const { executions: realtimeExecutions } = useWithdrawPolling({
|
|
32102
32289
|
userId: externalUserId,
|
|
32103
32290
|
publishableKey,
|
|
@@ -32112,7 +32299,7 @@ function WithdrawModal({
|
|
|
32112
32299
|
refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
|
|
32113
32300
|
});
|
|
32114
32301
|
const allWithdrawals = allWithdrawalsData?.data ?? [];
|
|
32115
|
-
const handleDepositWalletCreation = (0,
|
|
32302
|
+
const handleDepositWalletCreation = (0, import_react38.useCallback)(
|
|
32116
32303
|
async (params) => {
|
|
32117
32304
|
const response = await (0, import_core58.createDepositAddress)(
|
|
32118
32305
|
{
|
|
@@ -32133,12 +32320,13 @@ function WithdrawModal({
|
|
|
32133
32320
|
if (!depositWallet) {
|
|
32134
32321
|
throw new Error(`No deposit wallet available for ${sourceChainType}`);
|
|
32135
32322
|
}
|
|
32323
|
+
withdrawDepositWalletIdRef.current = depositWallet.id;
|
|
32136
32324
|
setWithdrawDepositWalletId(depositWallet.id);
|
|
32137
32325
|
return depositWallet;
|
|
32138
32326
|
},
|
|
32139
32327
|
[externalUserId, publishableKey, sourceChainType, setUserId]
|
|
32140
32328
|
);
|
|
32141
|
-
const handleWithdrawStarted = (0,
|
|
32329
|
+
const handleWithdrawStarted = (0, import_react38.useCallback)(
|
|
32142
32330
|
(txInfo) => {
|
|
32143
32331
|
const tokenData = destinationTokens.find((t2) => t2.symbol === txInfo.destinationTokenSymbol);
|
|
32144
32332
|
const chainData = tokenData?.chains.find(
|
|
@@ -32152,7 +32340,12 @@ function WithdrawModal({
|
|
|
32152
32340
|
currency: tokenData?.currency,
|
|
32153
32341
|
amount: txInfo.amount,
|
|
32154
32342
|
amount_base_unit: txInfo.amountBaseUnit,
|
|
32155
|
-
...txInfo.amountUsd ? { amount_usd: txInfo.amountUsd } : {}
|
|
32343
|
+
...txInfo.amountUsd ? { amount_usd: txInfo.amountUsd } : {},
|
|
32344
|
+
// The execution doesn't exist yet — it's created when the user's send
|
|
32345
|
+
// lands on the withdraw deposit wallet, and carries this id. So a
|
|
32346
|
+
// withdrawal confirmed but never completed still joins to whatever
|
|
32347
|
+
// did (or didn't) follow on that wallet.
|
|
32348
|
+
deposit_wallet_id: withdrawDepositWalletIdRef.current
|
|
32156
32349
|
});
|
|
32157
32350
|
emitEvent({
|
|
32158
32351
|
id: (0, import_core58.generatePrefixedKSUID)("sevt"),
|
|
@@ -32172,23 +32365,25 @@ function WithdrawModal({
|
|
|
32172
32365
|
},
|
|
32173
32366
|
[track, emitEvent, getSessionId, destinationTokens]
|
|
32174
32367
|
);
|
|
32175
|
-
const handleWithdrawSubmitted = (0,
|
|
32368
|
+
const handleWithdrawSubmitted = (0, import_react38.useCallback)((txInfo) => {
|
|
32176
32369
|
setSubmittedTxInfo(txInfo);
|
|
32177
32370
|
setView("confirming");
|
|
32178
32371
|
}, []);
|
|
32179
|
-
const resetViewTimeoutRef = (0,
|
|
32180
|
-
const finalizeJourney = (0,
|
|
32372
|
+
const resetViewTimeoutRef = (0, import_react38.useRef)(null);
|
|
32373
|
+
const finalizeJourney = (0, import_react38.useCallback)(() => {
|
|
32181
32374
|
if (!journeyActiveRef.current) return;
|
|
32182
32375
|
journeyActiveRef.current = false;
|
|
32183
32376
|
track("widget_closed", { flow_type: "withdraw" });
|
|
32184
32377
|
if (getSessionId() === journeySessionIdRef.current) endSession();
|
|
32185
32378
|
}, [track, getSessionId, endSession]);
|
|
32186
|
-
const beginJourney = (0,
|
|
32379
|
+
const beginJourney = (0, import_react38.useCallback)(() => {
|
|
32187
32380
|
journeySessionIdRef.current = startSession();
|
|
32188
32381
|
journeyActiveRef.current = true;
|
|
32382
|
+
journeyExternalUserIdRef.current = externalUserId;
|
|
32383
|
+
setUserId(null);
|
|
32189
32384
|
track("widget_opened", { flow_type: "withdraw" });
|
|
32190
|
-
}, [startSession, track]);
|
|
32191
|
-
const handleClose = (0,
|
|
32385
|
+
}, [startSession, track, setUserId, externalUserId]);
|
|
32386
|
+
const handleClose = (0, import_react38.useCallback)(() => {
|
|
32192
32387
|
finalizeJourney();
|
|
32193
32388
|
onOpenChange(false);
|
|
32194
32389
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -32196,11 +32391,12 @@ function WithdrawModal({
|
|
|
32196
32391
|
setView("form");
|
|
32197
32392
|
setSelectedExecution(null);
|
|
32198
32393
|
setSubmittedTxInfo(null);
|
|
32394
|
+
withdrawDepositWalletIdRef.current = void 0;
|
|
32199
32395
|
setWithdrawDepositWalletId(void 0);
|
|
32200
32396
|
resetViewTimeoutRef.current = null;
|
|
32201
32397
|
}, 200);
|
|
32202
32398
|
}, [onOpenChange, finalizeJourney]);
|
|
32203
|
-
(0,
|
|
32399
|
+
(0, import_react38.useLayoutEffect)(() => {
|
|
32204
32400
|
if (!open) {
|
|
32205
32401
|
finalizeJourney();
|
|
32206
32402
|
return;
|
|
@@ -32213,9 +32409,15 @@ function WithdrawModal({
|
|
|
32213
32409
|
setView("form");
|
|
32214
32410
|
setSelectedExecution(null);
|
|
32215
32411
|
setSubmittedTxInfo(null);
|
|
32412
|
+
withdrawDepositWalletIdRef.current = void 0;
|
|
32216
32413
|
setWithdrawDepositWalletId(void 0);
|
|
32217
32414
|
}, [open]);
|
|
32218
|
-
(0,
|
|
32415
|
+
(0, import_react38.useLayoutEffect)(() => {
|
|
32416
|
+
if (!open || journeyExternalUserIdRef.current === externalUserId) return;
|
|
32417
|
+
journeyExternalUserIdRef.current = externalUserId;
|
|
32418
|
+
setUserId(null);
|
|
32419
|
+
}, [open, externalUserId, setUserId]);
|
|
32420
|
+
(0, import_react38.useEffect)(
|
|
32219
32421
|
() => () => {
|
|
32220
32422
|
if (journeyActiveRef.current) {
|
|
32221
32423
|
journeyActiveRef.current = false;
|
|
@@ -32224,18 +32426,18 @@ function WithdrawModal({
|
|
|
32224
32426
|
},
|
|
32225
32427
|
[endSession, getSessionId]
|
|
32226
32428
|
);
|
|
32227
|
-
(0,
|
|
32429
|
+
(0, import_react38.useEffect)(() => {
|
|
32228
32430
|
if (!open) return;
|
|
32229
32431
|
const screen = view === "detail" ? "tracker_detail" : view;
|
|
32230
32432
|
track("screen_viewed", { flow_type: "withdraw", screen });
|
|
32231
32433
|
}, [open, view, track]);
|
|
32232
|
-
(0,
|
|
32434
|
+
(0, import_react38.useEffect)(
|
|
32233
32435
|
() => () => {
|
|
32234
32436
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
32235
32437
|
},
|
|
32236
32438
|
[]
|
|
32237
32439
|
);
|
|
32238
|
-
const trackAssetSelected = (0,
|
|
32440
|
+
const trackAssetSelected = (0, import_react38.useCallback)(
|
|
32239
32441
|
(symbol, chainKey) => {
|
|
32240
32442
|
const [chainType, chainId] = (chainKey ?? "").split(":");
|
|
32241
32443
|
const tokenData = destinationTokens.find((t2) => t2.symbol === symbol);
|
|
@@ -32253,14 +32455,14 @@ function WithdrawModal({
|
|
|
32253
32455
|
},
|
|
32254
32456
|
[destinationTokens, track]
|
|
32255
32457
|
);
|
|
32256
|
-
const handleTokenSymbolChange = (0,
|
|
32458
|
+
const handleTokenSymbolChange = (0, import_react38.useCallback)(
|
|
32257
32459
|
(symbol) => {
|
|
32258
32460
|
trackAssetSelected(symbol, selectedChainKey);
|
|
32259
32461
|
setSelectedTokenSymbol(symbol);
|
|
32260
32462
|
},
|
|
32261
32463
|
[setSelectedTokenSymbol, selectedChainKey, trackAssetSelected]
|
|
32262
32464
|
);
|
|
32263
|
-
const handleChainKeyChange = (0,
|
|
32465
|
+
const handleChainKeyChange = (0, import_react38.useCallback)(
|
|
32264
32466
|
(chainKey) => {
|
|
32265
32467
|
trackAssetSelected(selectedTokenSymbol, chainKey);
|
|
32266
32468
|
setSelectedChainKey(chainKey);
|
|
@@ -32449,16 +32651,16 @@ function WithdrawModal({
|
|
|
32449
32651
|
}
|
|
32450
32652
|
|
|
32451
32653
|
// src/components/withdrawals/WithdrawTokenSelector.tsx
|
|
32452
|
-
var
|
|
32654
|
+
var import_react39 = require("react");
|
|
32453
32655
|
var import_lucide_react45 = require("lucide-react");
|
|
32454
32656
|
var import_fuse2 = __toESM(require("fuse.js"));
|
|
32455
32657
|
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
32456
32658
|
function WithdrawTokenSelector({ tokens, onSelect, onBack }) {
|
|
32457
32659
|
const { themeClass, colors: colors2, fonts, components } = useTheme();
|
|
32458
32660
|
const t = useI18n().t.withdrawModal;
|
|
32459
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
32460
|
-
const [hoveredKey, setHoveredKey] = (0,
|
|
32461
|
-
const allOptions = (0,
|
|
32661
|
+
const [searchQuery, setSearchQuery] = (0, import_react39.useState)("");
|
|
32662
|
+
const [hoveredKey, setHoveredKey] = (0, import_react39.useState)(null);
|
|
32663
|
+
const allOptions = (0, import_react39.useMemo)(() => {
|
|
32462
32664
|
const options = [];
|
|
32463
32665
|
tokens.forEach((token) => {
|
|
32464
32666
|
token.chains.forEach((chain) => {
|
|
@@ -32467,7 +32669,7 @@ function WithdrawTokenSelector({ tokens, onSelect, onBack }) {
|
|
|
32467
32669
|
});
|
|
32468
32670
|
return options;
|
|
32469
32671
|
}, [tokens]);
|
|
32470
|
-
const fuse = (0,
|
|
32672
|
+
const fuse = (0, import_react39.useMemo)(
|
|
32471
32673
|
() => new import_fuse2.default(allOptions, {
|
|
32472
32674
|
keys: [
|
|
32473
32675
|
{ name: "token.symbol", weight: 2 },
|
|
@@ -32480,7 +32682,7 @@ function WithdrawTokenSelector({ tokens, onSelect, onBack }) {
|
|
|
32480
32682
|
}),
|
|
32481
32683
|
[allOptions]
|
|
32482
32684
|
);
|
|
32483
|
-
const filteredOptions = (0,
|
|
32685
|
+
const filteredOptions = (0, import_react39.useMemo)(() => {
|
|
32484
32686
|
if (!searchQuery.trim()) return allOptions;
|
|
32485
32687
|
const query = searchQuery.trim();
|
|
32486
32688
|
const results = fuse.search(query);
|