@unifold/ui-react 0.1.77 → 0.1.79
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 +634 -450
- package/dist/index.mjs +339 -155
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -420,6 +420,9 @@ var en_default = {
|
|
|
420
420
|
transactionBreakdown: "Transaction breakdown",
|
|
421
421
|
networkFee: "Network fee",
|
|
422
422
|
confirmOrder: "Confirm Order",
|
|
423
|
+
mfaEnrollmentTitle: "Enable SMS or Authy 2FA",
|
|
424
|
+
mfaEnrollmentMessage: "Please make sure you enable SMS or Authy 2FA in your Coinbase account. Press Continue after you enable it.",
|
|
425
|
+
mfaEnrollmentSettingsLink: "Open Coinbase security settings",
|
|
423
426
|
termsNoticePrefix: "By clicking on Confirm Order, you agree to our ",
|
|
424
427
|
termsNoticeLink: "terms",
|
|
425
428
|
termsNoticeSuffix: "."
|
|
@@ -550,7 +553,12 @@ var en_default = {
|
|
|
550
553
|
prefix: "By continuing, you agree to Coinbase's ",
|
|
551
554
|
separator: ", ",
|
|
552
555
|
lastSeparator: ", and ",
|
|
553
|
-
suffix: ".
|
|
556
|
+
suffix: ".",
|
|
557
|
+
agreements: {
|
|
558
|
+
guest_checkout_terms: "Terms of Service",
|
|
559
|
+
user_agreement: "User Agreement",
|
|
560
|
+
privacy_policy: "Privacy Policy"
|
|
561
|
+
}
|
|
554
562
|
},
|
|
555
563
|
errors: {
|
|
556
564
|
rateLimited: "Too many attempts. Please wait a few minutes and try again.",
|
|
@@ -1211,6 +1219,9 @@ var zh_default = {
|
|
|
1211
1219
|
transactionBreakdown: "\u4EA4\u6613\u660E\u7EC6",
|
|
1212
1220
|
networkFee: "\u7F51\u7EDC\u624B\u7EED\u8D39",
|
|
1213
1221
|
confirmOrder: "\u786E\u8BA4\u8BA2\u5355",
|
|
1222
|
+
mfaEnrollmentTitle: "\u8BF7\u542F\u7528\u77ED\u4FE1\u6216 Authy \u53CC\u91CD\u9A8C\u8BC1",
|
|
1223
|
+
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",
|
|
1224
|
+
mfaEnrollmentSettingsLink: "\u6253\u5F00 Coinbase \u5B89\u5168\u8BBE\u7F6E",
|
|
1214
1225
|
termsNoticePrefix: "\u70B9\u51FB\u201C\u786E\u8BA4\u8BA2\u5355\u201D\u5373\u8868\u793A\u60A8\u540C\u610F\u6211\u4EEC\u7684",
|
|
1215
1226
|
termsNoticeLink: "\u6761\u6B3E",
|
|
1216
1227
|
termsNoticeSuffix: "\u3002"
|
|
@@ -1341,7 +1352,12 @@ var zh_default = {
|
|
|
1341
1352
|
prefix: "\u7EE7\u7EED\u5373\u8868\u793A\u60A8\u540C\u610F Coinbase \u7684",
|
|
1342
1353
|
separator: "\u3001",
|
|
1343
1354
|
lastSeparator: "\u548C",
|
|
1344
|
-
suffix: "\
|
|
1355
|
+
suffix: "\u3002",
|
|
1356
|
+
agreements: {
|
|
1357
|
+
guest_checkout_terms: "\u670D\u52A1\u6761\u6B3E",
|
|
1358
|
+
user_agreement: "\u7528\u6237\u534F\u8BAE",
|
|
1359
|
+
privacy_policy: "\u9690\u79C1\u653F\u7B56"
|
|
1360
|
+
}
|
|
1345
1361
|
},
|
|
1346
1362
|
errors: {
|
|
1347
1363
|
rateLimited: "\u5C1D\u8BD5\u6B21\u6570\u8FC7\u591A\u3002\u8BF7\u7A0D\u7B49\u51E0\u5206\u949F\u540E\u91CD\u8BD5\u3002",
|
|
@@ -2002,6 +2018,9 @@ var zh_TW_default = {
|
|
|
2002
2018
|
transactionBreakdown: "\u4EA4\u6613\u660E\u7D30",
|
|
2003
2019
|
networkFee: "\u7DB2\u8DEF\u624B\u7E8C\u8CBB",
|
|
2004
2020
|
confirmOrder: "\u78BA\u8A8D\u8A02\u55AE",
|
|
2021
|
+
mfaEnrollmentTitle: "\u8ACB\u555F\u7528\u7C21\u8A0A\u6216 Authy \u96D9\u91CD\u9A57\u8B49",
|
|
2022
|
+
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",
|
|
2023
|
+
mfaEnrollmentSettingsLink: "\u958B\u555F Coinbase \u5B89\u5168\u8A2D\u5B9A",
|
|
2005
2024
|
termsNoticePrefix: "\u9EDE\u64CA\u300C\u78BA\u8A8D\u8A02\u55AE\u300D\u5373\u8868\u793A\u60A8\u540C\u610F\u6211\u5011\u7684",
|
|
2006
2025
|
termsNoticeLink: "\u689D\u6B3E",
|
|
2007
2026
|
termsNoticeSuffix: "\u3002"
|
|
@@ -2132,7 +2151,12 @@ var zh_TW_default = {
|
|
|
2132
2151
|
prefix: "\u7E7C\u7E8C\u5373\u8868\u793A\u60A8\u540C\u610F Coinbase \u7684",
|
|
2133
2152
|
separator: "\u3001",
|
|
2134
2153
|
lastSeparator: "\u548C",
|
|
2135
|
-
suffix: "\
|
|
2154
|
+
suffix: "\u3002",
|
|
2155
|
+
agreements: {
|
|
2156
|
+
guest_checkout_terms: "\u670D\u52D9\u689D\u6B3E",
|
|
2157
|
+
user_agreement: "\u4F7F\u7528\u8005\u5354\u8B70",
|
|
2158
|
+
privacy_policy: "\u96B1\u79C1\u6B0A\u653F\u7B56"
|
|
2159
|
+
}
|
|
2136
2160
|
},
|
|
2137
2161
|
errors: {
|
|
2138
2162
|
rateLimited: "\u5617\u8A66\u6B21\u6578\u904E\u591A\u3002\u8ACB\u7A0D\u7B49\u5E7E\u5206\u9418\u5F8C\u91CD\u8A66\u3002",
|
|
@@ -3071,13 +3095,15 @@ import {
|
|
|
3071
3095
|
} from "@unifold/core";
|
|
3072
3096
|
|
|
3073
3097
|
// src/hooks/use-deposit-address.ts
|
|
3074
|
-
import { useEffect as useEffect3 } from "react";
|
|
3075
3098
|
import { useQuery } from "@tanstack/react-query";
|
|
3076
3099
|
import {
|
|
3077
3100
|
createDepositAddress,
|
|
3078
3101
|
isDepositAddressValidationError
|
|
3079
3102
|
} from "@unifold/core";
|
|
3080
3103
|
|
|
3104
|
+
// src/hooks/use-internal-user-id.ts
|
|
3105
|
+
import { useEffect as useEffect3 } from "react";
|
|
3106
|
+
|
|
3081
3107
|
// src/context/AnalyticsContext.tsx
|
|
3082
3108
|
import * as React5 from "react";
|
|
3083
3109
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
@@ -3109,6 +3135,15 @@ function useAnalytics() {
|
|
|
3109
3135
|
return { track, startSession, endSession, getSessionId, setUserId, subscribe };
|
|
3110
3136
|
}
|
|
3111
3137
|
|
|
3138
|
+
// src/hooks/use-internal-user-id.ts
|
|
3139
|
+
function useStampInternalUserId({ internalUserId }) {
|
|
3140
|
+
const { setUserId } = useAnalytics();
|
|
3141
|
+
useEffect3(() => {
|
|
3142
|
+
if (!internalUserId) return;
|
|
3143
|
+
setUserId(internalUserId);
|
|
3144
|
+
}, [internalUserId, setUserId]);
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3112
3147
|
// src/hooks/use-deposit-address.ts
|
|
3113
3148
|
function useDepositAddress(params) {
|
|
3114
3149
|
const {
|
|
@@ -3122,7 +3157,6 @@ function useDepositAddress(params) {
|
|
|
3122
3157
|
contractCalls,
|
|
3123
3158
|
enabled = true
|
|
3124
3159
|
} = params;
|
|
3125
|
-
const { setUserId } = useAnalytics();
|
|
3126
3160
|
const query = useQuery({
|
|
3127
3161
|
queryKey: [
|
|
3128
3162
|
"unifold",
|
|
@@ -3165,11 +3199,7 @@ function useDepositAddress(params) {
|
|
|
3165
3199
|
retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
|
|
3166
3200
|
// 1s, 2s, 4s (max 10s)
|
|
3167
3201
|
});
|
|
3168
|
-
|
|
3169
|
-
if (query.data?.user_id) {
|
|
3170
|
-
setUserId(query.data.user_id);
|
|
3171
|
-
}
|
|
3172
|
-
}, [query.data?.user_id, setUserId]);
|
|
3202
|
+
useStampInternalUserId({ internalUserId: query.data?.user_id });
|
|
3173
3203
|
return query;
|
|
3174
3204
|
}
|
|
3175
3205
|
|
|
@@ -5475,7 +5505,11 @@ function BuyWithCard({
|
|
|
5475
5505
|
method: "card",
|
|
5476
5506
|
flow_type: "deposit",
|
|
5477
5507
|
provider: selectedProvider.service_provider,
|
|
5478
|
-
amount_usd: amount
|
|
5508
|
+
amount_usd: amount,
|
|
5509
|
+
// The execution only exists once the provider's payout lands on this
|
|
5510
|
+
// wallet, and it carries this id — so it's the join key for a purchase
|
|
5511
|
+
// that starts here and never reaches flow_completed.
|
|
5512
|
+
deposit_wallet_id: depositWalletId
|
|
5479
5513
|
});
|
|
5480
5514
|
onEvent?.({
|
|
5481
5515
|
id: generatePrefixedKSUID2("sevt"),
|
|
@@ -6987,6 +7021,8 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
6987
7021
|
const [limitUpgradeError, setLimitUpgradeError] = useState15(null);
|
|
6988
7022
|
const [upgradeSubmitting, setUpgradeSubmitting] = useState15(false);
|
|
6989
7023
|
const upgradeFlowAbortRef = useRef6(null);
|
|
7024
|
+
const applyLimitRoutingRef = useRef6(() => {
|
|
7025
|
+
});
|
|
6990
7026
|
const [amount, setAmount] = useState15(amountUsd ?? "");
|
|
6991
7027
|
const [preparedOrder, setPreparedOrder] = useState15(null);
|
|
6992
7028
|
const sessionAbortRef = useRef6(null);
|
|
@@ -7121,6 +7157,14 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7121
7157
|
},
|
|
7122
7158
|
[email, normalizedPhone, userId]
|
|
7123
7159
|
);
|
|
7160
|
+
const { action: initialAction, refetchWalletPayLimits } = useWalletPayInitialScreen({
|
|
7161
|
+
userId,
|
|
7162
|
+
publishableKey,
|
|
7163
|
+
normalizedPhone,
|
|
7164
|
+
userEmail,
|
|
7165
|
+
sessionPhoneVerified: verificationSession?.phone?.status === "verified",
|
|
7166
|
+
isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
|
|
7167
|
+
});
|
|
7124
7168
|
const createSessionAndSendOtp = useCallback4(async () => {
|
|
7125
7169
|
setView("submitting_session");
|
|
7126
7170
|
setErrorMessage("");
|
|
@@ -7130,7 +7174,12 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7130
7174
|
email,
|
|
7131
7175
|
phone: normalizedPhone,
|
|
7132
7176
|
terms_accepted: true,
|
|
7133
|
-
|
|
7177
|
+
// TODO: when the API honors `false`, this will trigger email OTP.
|
|
7178
|
+
// Today `false` still skips email (we don't verify it) and JWT ev
|
|
7179
|
+
// is null. Don't send `true` — that was a fake attest.
|
|
7180
|
+
email_already_verified: false
|
|
7181
|
+
// Coinbase stays Redis-only + JWT until bank-transfer identity
|
|
7182
|
+
// is live. Do not persist from this path yet.
|
|
7134
7183
|
},
|
|
7135
7184
|
publishableKey
|
|
7136
7185
|
);
|
|
@@ -7140,6 +7189,34 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7140
7189
|
}
|
|
7141
7190
|
setClientSecret(session.client_secret);
|
|
7142
7191
|
storeWalletPaySession();
|
|
7192
|
+
if (session.status === "verified") {
|
|
7193
|
+
const tokenRes = await exchangeOnrampVerificationToken(
|
|
7194
|
+
session.id,
|
|
7195
|
+
session.client_secret,
|
|
7196
|
+
publishableKey
|
|
7197
|
+
);
|
|
7198
|
+
setOnrampToken(tokenRes);
|
|
7199
|
+
storeWalletPaySession({
|
|
7200
|
+
emailVerifiedAt: session.email.verified_at,
|
|
7201
|
+
phoneVerifiedAt: session.phone.verified_at,
|
|
7202
|
+
onrampToken: tokenRes.token,
|
|
7203
|
+
onrampTokenExpiresAtMs: Date.now() + tokenRes.expires_in * 1e3
|
|
7204
|
+
});
|
|
7205
|
+
if (amountUsd) setAmount(amountUsd);
|
|
7206
|
+
try {
|
|
7207
|
+
const result = await refetchWalletPayLimits();
|
|
7208
|
+
if (result.data) {
|
|
7209
|
+
const nextView = getViewForLimitStatus(result.data);
|
|
7210
|
+
if (nextView) {
|
|
7211
|
+
applyLimitRoutingRef.current(nextView, result.data.upgrade_status);
|
|
7212
|
+
return;
|
|
7213
|
+
}
|
|
7214
|
+
}
|
|
7215
|
+
} catch {
|
|
7216
|
+
}
|
|
7217
|
+
setView("amount");
|
|
7218
|
+
return;
|
|
7219
|
+
}
|
|
7143
7220
|
await sendOnrampVerificationOtp(session.id, "phone", session.client_secret, publishableKey);
|
|
7144
7221
|
setResendCooldown(30);
|
|
7145
7222
|
setView("phone_otp");
|
|
@@ -7148,19 +7225,19 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7148
7225
|
setErrorMessage(prettifyVerificationError(raw));
|
|
7149
7226
|
setView("phone_input");
|
|
7150
7227
|
}
|
|
7151
|
-
}, [
|
|
7228
|
+
}, [
|
|
7229
|
+
email,
|
|
7230
|
+
normalizedPhone,
|
|
7231
|
+
publishableKey,
|
|
7232
|
+
storeWalletPaySession,
|
|
7233
|
+
userId,
|
|
7234
|
+
amountUsd,
|
|
7235
|
+
refetchWalletPayLimits
|
|
7236
|
+
]);
|
|
7152
7237
|
const clearUpgradeFields = useCallback4(() => {
|
|
7153
7238
|
setSsnLast4("");
|
|
7154
7239
|
setDobInput("");
|
|
7155
7240
|
}, []);
|
|
7156
|
-
const { action: initialAction, refetchWalletPayLimits } = useWalletPayInitialScreen({
|
|
7157
|
-
userId,
|
|
7158
|
-
publishableKey,
|
|
7159
|
-
normalizedPhone,
|
|
7160
|
-
userEmail,
|
|
7161
|
-
sessionPhoneVerified: verificationSession?.phone?.status === "verified",
|
|
7162
|
-
isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
|
|
7163
|
-
});
|
|
7164
7241
|
const pollLimitUpgradeStatus = useCallback4(
|
|
7165
7242
|
async (signal) => {
|
|
7166
7243
|
const POLL_INTERVAL_MS5 = 1500;
|
|
@@ -7271,6 +7348,7 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7271
7348
|
},
|
|
7272
7349
|
[startUpgradePolling]
|
|
7273
7350
|
);
|
|
7351
|
+
applyLimitRoutingRef.current = applyLimitRouting;
|
|
7274
7352
|
const hasInitializedRef = useRef6(false);
|
|
7275
7353
|
useEffect12(() => {
|
|
7276
7354
|
if (hasInitializedRef.current) return;
|
|
@@ -7500,7 +7578,10 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7500
7578
|
track("flow_started", {
|
|
7501
7579
|
method,
|
|
7502
7580
|
flow_type: "deposit",
|
|
7503
|
-
amount_usd: walletPayAmountUsd
|
|
7581
|
+
amount_usd: walletPayAmountUsd,
|
|
7582
|
+
// No execution yet — one appears when the payout lands on this
|
|
7583
|
+
// wallet, carrying the same id.
|
|
7584
|
+
deposit_wallet_id: depositWalletId
|
|
7504
7585
|
});
|
|
7505
7586
|
onEvent?.({
|
|
7506
7587
|
id: generatePrefixedKSUID3("sevt"),
|
|
@@ -7550,6 +7631,7 @@ var BuyWithWalletPay = React8.forwardRef(
|
|
|
7550
7631
|
defaultTokenLoading,
|
|
7551
7632
|
defaultTokenError,
|
|
7552
7633
|
depositWallet?.address,
|
|
7634
|
+
depositWalletId,
|
|
7553
7635
|
userEmail,
|
|
7554
7636
|
publishableKey,
|
|
7555
7637
|
onEvent,
|
|
@@ -8524,7 +8606,7 @@ var FALLBACK_AGREEMENTS = [
|
|
|
8524
8606
|
{
|
|
8525
8607
|
key: "guest_checkout_terms",
|
|
8526
8608
|
name: "Guest Checkout Terms of Service",
|
|
8527
|
-
url: "https://www.coinbase.com/legal/
|
|
8609
|
+
url: "https://www.coinbase.com/legal/guest-checkout/us"
|
|
8528
8610
|
},
|
|
8529
8611
|
{
|
|
8530
8612
|
key: "user_agreement",
|
|
@@ -8544,22 +8626,24 @@ function LegalDisclaimer({ legalAgreements, loading }) {
|
|
|
8544
8626
|
return /* @__PURE__ */ jsxs14(
|
|
8545
8627
|
"div",
|
|
8546
8628
|
{
|
|
8547
|
-
className: "uf-mt-3 uf-mb-3 uf-px-1 uf-space-y-1.5 uf-animate-pulse",
|
|
8629
|
+
className: "uf-mt-3 uf-mb-3 uf-px-1 uf-space-y-1.5 uf-animate-pulse uf-opacity-50",
|
|
8548
8630
|
"aria-hidden": true,
|
|
8549
8631
|
"aria-busy": "true",
|
|
8550
8632
|
children: [
|
|
8551
|
-
/* @__PURE__ */ jsx18("div", { className: "uf-h-2
|
|
8552
|
-
/* @__PURE__ */ jsx18("div", { className: "uf-h-2
|
|
8553
|
-
/* @__PURE__ */ jsx18("div", { className: "uf-h-2
|
|
8633
|
+
/* @__PURE__ */ jsx18("div", { className: "uf-h-2 uf-rounded uf-w-full", style: { backgroundColor: colors2.card } }),
|
|
8634
|
+
/* @__PURE__ */ jsx18("div", { className: "uf-h-2 uf-rounded uf-w-11/12", style: { backgroundColor: colors2.card } }),
|
|
8635
|
+
/* @__PURE__ */ jsx18("div", { className: "uf-h-2 uf-rounded uf-w-3/4", style: { backgroundColor: colors2.card } })
|
|
8554
8636
|
]
|
|
8555
8637
|
}
|
|
8556
8638
|
);
|
|
8557
8639
|
}
|
|
8558
8640
|
const agreements = legalAgreements?.agreements ?? FALLBACK_AGREEMENTS;
|
|
8641
|
+
const shortLabels = t.agreements;
|
|
8642
|
+
const lastSeparator = t.lastSeparator.replace(/\s+$/, "\xA0");
|
|
8559
8643
|
return /* @__PURE__ */ jsxs14(
|
|
8560
8644
|
"p",
|
|
8561
8645
|
{
|
|
8562
|
-
className: "uf-text-[
|
|
8646
|
+
className: "uf-text-[10px] uf-leading-relaxed uf-mt-3 uf-mb-3 uf-opacity-60 uf-text-center",
|
|
8563
8647
|
style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
|
|
8564
8648
|
children: [
|
|
8565
8649
|
t.prefix,
|
|
@@ -8570,12 +8654,12 @@ function LegalDisclaimer({ legalAgreements, loading }) {
|
|
|
8570
8654
|
href: a.url,
|
|
8571
8655
|
target: "_blank",
|
|
8572
8656
|
rel: "noopener noreferrer",
|
|
8573
|
-
className: "uf-underline",
|
|
8574
|
-
style: { color:
|
|
8575
|
-
children: a.name
|
|
8657
|
+
className: "uf-no-underline",
|
|
8658
|
+
style: { color: "inherit", textDecoration: "none", whiteSpace: "nowrap" },
|
|
8659
|
+
children: shortLabels[a.key] ?? a.name
|
|
8576
8660
|
}
|
|
8577
8661
|
),
|
|
8578
|
-
idx < arr.length - 2 ? t.separator : idx === arr.length - 2 ?
|
|
8662
|
+
idx < arr.length - 2 ? t.separator : idx === arr.length - 2 ? lastSeparator : ""
|
|
8579
8663
|
] }, a.key)),
|
|
8580
8664
|
t.suffix
|
|
8581
8665
|
]
|
|
@@ -9231,22 +9315,6 @@ import {
|
|
|
9231
9315
|
generatePrefixedKSUID as generatePrefixedKSUID5,
|
|
9232
9316
|
DepositEventType as DepositEventType4
|
|
9233
9317
|
} from "@unifold/core";
|
|
9234
|
-
|
|
9235
|
-
// src/hooks/use-cashapp-limits.ts
|
|
9236
|
-
import { useQuery as useQuery9 } from "@tanstack/react-query";
|
|
9237
|
-
import { getCashAppLimits } from "@unifold/core";
|
|
9238
|
-
function useCashAppLimits({ publishableKey, currency = "usd" }) {
|
|
9239
|
-
return useQuery9({
|
|
9240
|
-
queryKey: ["unifold", "cashAppLimits", currency, publishableKey],
|
|
9241
|
-
queryFn: () => getCashAppLimits(currency, publishableKey),
|
|
9242
|
-
enabled: !!publishableKey,
|
|
9243
|
-
staleTime: 2 * 60 * 6e4,
|
|
9244
|
-
gcTime: 4 * 60 * 6e4,
|
|
9245
|
-
retry: 2
|
|
9246
|
-
});
|
|
9247
|
-
}
|
|
9248
|
-
|
|
9249
|
-
// src/components/deposits/PayWithCashApp.tsx
|
|
9250
9318
|
import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
9251
9319
|
var POLL_INTERVAL_MS3 = 5e3;
|
|
9252
9320
|
var FALLBACK_MIN_USD = 5;
|
|
@@ -9259,6 +9327,7 @@ function PayWithCashApp({
|
|
|
9259
9327
|
destinationChainType,
|
|
9260
9328
|
destinationChainId,
|
|
9261
9329
|
destinationTokenAddress,
|
|
9330
|
+
contractCalls,
|
|
9262
9331
|
cashAppIconUrl,
|
|
9263
9332
|
view: controlledView,
|
|
9264
9333
|
onViewChange,
|
|
@@ -9282,9 +9351,11 @@ function PayWithCashApp({
|
|
|
9282
9351
|
const b = parseInt(bg.slice(4, 6), 16);
|
|
9283
9352
|
return (r * 299 + g * 587 + b * 114) / 1e3 < 128;
|
|
9284
9353
|
})();
|
|
9285
|
-
const { data:
|
|
9286
|
-
|
|
9287
|
-
|
|
9354
|
+
const { data: fiatCurrencies, isLoading: limitsLoading } = useFiatCurrencies({
|
|
9355
|
+
publishableKey
|
|
9356
|
+
});
|
|
9357
|
+
const minUsd = fiatCurrencies?.data.find((entry) => entry.currency_code.toLowerCase() === "usd")?.minimum_amount ?? FALLBACK_MIN_USD;
|
|
9358
|
+
const quickAmounts = SUGGESTED_AMOUNTS.filter((value) => value >= minUsd);
|
|
9288
9359
|
const [amount, setAmount] = useState18(() => sanitizePrefilledUsd(prefilledAmountUsd));
|
|
9289
9360
|
const [loading, setLoading] = useState18(false);
|
|
9290
9361
|
const [session, setSession] = useState18(null);
|
|
@@ -9339,6 +9410,8 @@ function PayWithCashApp({
|
|
|
9339
9410
|
setError(strings.depositModal.cashAppErrors.missingFields);
|
|
9340
9411
|
return;
|
|
9341
9412
|
}
|
|
9413
|
+
const amountNum2 = parseFloat(amount);
|
|
9414
|
+
if (isNaN(amountNum2) || amountNum2 < minUsd) return;
|
|
9342
9415
|
setLoading(true);
|
|
9343
9416
|
setError(null);
|
|
9344
9417
|
try {
|
|
@@ -9351,7 +9424,8 @@ function PayWithCashApp({
|
|
|
9351
9424
|
destination_token_address: destinationTokenAddress,
|
|
9352
9425
|
recipient_address: recipientAddress,
|
|
9353
9426
|
source_amount: amount,
|
|
9354
|
-
external_id: externalId
|
|
9427
|
+
external_id: externalId,
|
|
9428
|
+
...contractCalls?.length ? { contract_calls: contractCalls } : {}
|
|
9355
9429
|
},
|
|
9356
9430
|
publishableKey
|
|
9357
9431
|
);
|
|
@@ -9364,7 +9438,10 @@ function PayWithCashApp({
|
|
|
9364
9438
|
track("flow_started", {
|
|
9365
9439
|
method: "cashapp",
|
|
9366
9440
|
flow_type: "deposit",
|
|
9367
|
-
amount_usd: amount
|
|
9441
|
+
amount_usd: amount,
|
|
9442
|
+
// No execution yet — one appears when the payout lands on this
|
|
9443
|
+
// wallet, carrying the same id.
|
|
9444
|
+
deposit_wallet_id: depositWalletId
|
|
9368
9445
|
});
|
|
9369
9446
|
onEvent?.({
|
|
9370
9447
|
id: generatePrefixedKSUID5("sevt"),
|
|
@@ -9383,12 +9460,15 @@ function PayWithCashApp({
|
|
|
9383
9460
|
}
|
|
9384
9461
|
}, [
|
|
9385
9462
|
amount,
|
|
9463
|
+
minUsd,
|
|
9386
9464
|
userId,
|
|
9387
9465
|
publishableKey,
|
|
9388
9466
|
recipientAddress,
|
|
9389
9467
|
destinationChainType,
|
|
9390
9468
|
destinationChainId,
|
|
9391
9469
|
destinationTokenAddress,
|
|
9470
|
+
contractCalls,
|
|
9471
|
+
depositWalletId,
|
|
9392
9472
|
onEvent,
|
|
9393
9473
|
onDepositError,
|
|
9394
9474
|
track,
|
|
@@ -9484,8 +9564,7 @@ function PayWithCashApp({
|
|
|
9484
9564
|
const amountNum = parseFloat(amount);
|
|
9485
9565
|
const hasInput = !isNaN(amountNum) && amountNum > 0;
|
|
9486
9566
|
const belowMin = hasInput && amountNum < minUsd;
|
|
9487
|
-
const
|
|
9488
|
-
const isValidAmount = hasInput && !belowMin && !aboveMax;
|
|
9567
|
+
const isValidAmount = hasInput && !belowMin;
|
|
9489
9568
|
if (view === "amount") {
|
|
9490
9569
|
return /* @__PURE__ */ jsxs16(
|
|
9491
9570
|
"div",
|
|
@@ -9514,7 +9593,7 @@ function PayWithCashApp({
|
|
|
9514
9593
|
}
|
|
9515
9594
|
}
|
|
9516
9595
|
) }) }),
|
|
9517
|
-
/* @__PURE__ */ jsx20("div", { className: "uf-flex uf-gap-3 uf-justify-center", children:
|
|
9596
|
+
/* @__PURE__ */ jsx20("div", { className: "uf-flex uf-gap-3 uf-justify-center", children: quickAmounts.map((quickAmount) => {
|
|
9518
9597
|
const isSelected = parseFloat(amount) === quickAmount;
|
|
9519
9598
|
return /* @__PURE__ */ jsxs16(
|
|
9520
9599
|
"button",
|
|
@@ -9540,23 +9619,17 @@ function PayWithCashApp({
|
|
|
9540
9619
|
quickAmount
|
|
9541
9620
|
);
|
|
9542
9621
|
}) }),
|
|
9543
|
-
|
|
9622
|
+
!limitsLoading && minUsd > 0 && /* @__PURE__ */ jsx20(
|
|
9544
9623
|
"div",
|
|
9545
9624
|
{
|
|
9546
|
-
className: "uf-text-
|
|
9547
|
-
style: { color: colors2.
|
|
9548
|
-
children: interpolate(strings.common.
|
|
9549
|
-
|
|
9550
|
-
) : amount && maxUsd !== null && amountNum > maxUsd && !error ? /* @__PURE__ */ jsx20(
|
|
9551
|
-
"div",
|
|
9552
|
-
{
|
|
9553
|
-
className: "uf-text-sm uf-text-center uf-mt-3 uf-px-2",
|
|
9554
|
-
style: { color: colors2.error, fontFamily: fonts.regular },
|
|
9555
|
-
children: interpolate(strings.common.maximumAmount, {
|
|
9556
|
-
amount: `$${maxUsd.toLocaleString()}`
|
|
9625
|
+
className: "uf-text-center uf-text-xs uf-mt-4",
|
|
9626
|
+
style: { color: colors2.warning, fontFamily: fonts.regular },
|
|
9627
|
+
children: interpolate(strings.common.minimumDeposit, {
|
|
9628
|
+
amount: `$${minUsd.toFixed(2)}`
|
|
9557
9629
|
})
|
|
9558
9630
|
}
|
|
9559
|
-
)
|
|
9631
|
+
),
|
|
9632
|
+
error ? /* @__PURE__ */ jsx20(
|
|
9560
9633
|
"div",
|
|
9561
9634
|
{
|
|
9562
9635
|
className: "uf-text-sm uf-text-center uf-mt-3 uf-px-2",
|
|
@@ -9565,7 +9638,7 @@ function PayWithCashApp({
|
|
|
9565
9638
|
}
|
|
9566
9639
|
) : null
|
|
9567
9640
|
] }),
|
|
9568
|
-
/* @__PURE__ */ jsx20("div", { className: "uf-px-1", children: /* @__PURE__ */ jsx20(
|
|
9641
|
+
/* @__PURE__ */ jsx20("div", { className: "uf-px-1 uf-mt-5", children: /* @__PURE__ */ jsx20(
|
|
9569
9642
|
"button",
|
|
9570
9643
|
{
|
|
9571
9644
|
onClick: handleCreateSession,
|
|
@@ -9794,7 +9867,7 @@ import {
|
|
|
9794
9867
|
} from "@unifold/core";
|
|
9795
9868
|
|
|
9796
9869
|
// src/hooks/use-bank-transfer-providers.ts
|
|
9797
|
-
import { useQuery as
|
|
9870
|
+
import { useQuery as useQuery9 } from "@tanstack/react-query";
|
|
9798
9871
|
import { getBankTransferProviders } from "@unifold/core";
|
|
9799
9872
|
function useBankTransferProviders({
|
|
9800
9873
|
publishableKey,
|
|
@@ -9802,7 +9875,7 @@ function useBankTransferProviders({
|
|
|
9802
9875
|
countryCode
|
|
9803
9876
|
}) {
|
|
9804
9877
|
const normalizedCountry = countryCode?.toUpperCase();
|
|
9805
|
-
const { data: providers, isLoading } =
|
|
9878
|
+
const { data: providers, isLoading } = useQuery9({
|
|
9806
9879
|
queryKey: ["unifold", "bankTransferProviders", publishableKey, normalizedCountry ?? null],
|
|
9807
9880
|
queryFn: () => getBankTransferProviders(publishableKey, { countryCode: normalizedCountry }),
|
|
9808
9881
|
enabled,
|
|
@@ -10009,7 +10082,10 @@ function BankTransfer({
|
|
|
10009
10082
|
method: "bank_transfer",
|
|
10010
10083
|
flow_type: "deposit",
|
|
10011
10084
|
provider: request.service_provider,
|
|
10012
|
-
amount_usd: request.source_amount
|
|
10085
|
+
amount_usd: request.source_amount,
|
|
10086
|
+
// No execution yet — one appears when the provider's payout lands on
|
|
10087
|
+
// this wallet, carrying the same id.
|
|
10088
|
+
deposit_wallet_id: pollingWalletId
|
|
10013
10089
|
});
|
|
10014
10090
|
onEvent?.({
|
|
10015
10091
|
id: generatePrefixedKSUID6("sevt"),
|
|
@@ -16274,7 +16350,11 @@ function PayWithStripeLink({
|
|
|
16274
16350
|
if (checkoutResult.successful) {
|
|
16275
16351
|
handledTerminalSessionRef.current = null;
|
|
16276
16352
|
executionReconciledSessionRef.current = null;
|
|
16277
|
-
track("flow_started", {
|
|
16353
|
+
track("flow_started", {
|
|
16354
|
+
method: "stripe_link",
|
|
16355
|
+
flow_type: "deposit",
|
|
16356
|
+
deposit_wallet_id: depositWalletId
|
|
16357
|
+
});
|
|
16278
16358
|
setConfirmedSessionId(activeSessionId);
|
|
16279
16359
|
setSessionStatus(STRIPE_SESSION_STATUS.FULFILLMENT_PROCESSING);
|
|
16280
16360
|
if (selectedTokenSingleUseRef.current) clearSelectedPaymentToken();
|
|
@@ -17771,7 +17851,14 @@ function PayWithStripeLink({
|
|
|
17771
17851
|
]
|
|
17772
17852
|
}
|
|
17773
17853
|
),
|
|
17774
|
-
/* @__PURE__ */ jsx50(
|
|
17854
|
+
/* @__PURE__ */ jsx50(
|
|
17855
|
+
"div",
|
|
17856
|
+
{
|
|
17857
|
+
ref: authMountRef,
|
|
17858
|
+
className: "uf-w-full uf-min-h-[200px]",
|
|
17859
|
+
style: { colorScheme: "only light" }
|
|
17860
|
+
}
|
|
17861
|
+
)
|
|
17775
17862
|
]
|
|
17776
17863
|
}
|
|
17777
17864
|
);
|
|
@@ -18351,7 +18438,7 @@ import {
|
|
|
18351
18438
|
} from "@unifold/core";
|
|
18352
18439
|
|
|
18353
18440
|
// src/hooks/use-project-config.ts
|
|
18354
|
-
import { useQuery as
|
|
18441
|
+
import { useQuery as useQuery10, keepPreviousData } from "@tanstack/react-query";
|
|
18355
18442
|
import { getProjectConfig } from "@unifold/core";
|
|
18356
18443
|
function useProjectConfig({
|
|
18357
18444
|
publishableKey,
|
|
@@ -18363,7 +18450,7 @@ function useProjectConfig({
|
|
|
18363
18450
|
data: projectConfig,
|
|
18364
18451
|
isLoading,
|
|
18365
18452
|
error
|
|
18366
|
-
} =
|
|
18453
|
+
} = useQuery10({
|
|
18367
18454
|
// Country is part of the key so a region change refetches the region-aware
|
|
18368
18455
|
// config. Omitted when undefined so callers that don't pass a country keep
|
|
18369
18456
|
// sharing the base cache entry.
|
|
@@ -18382,7 +18469,7 @@ function useProjectConfig({
|
|
|
18382
18469
|
}
|
|
18383
18470
|
|
|
18384
18471
|
// src/hooks/use-integration-transfer-default-token.ts
|
|
18385
|
-
import { useQuery as
|
|
18472
|
+
import { useQuery as useQuery11 } from "@tanstack/react-query";
|
|
18386
18473
|
import {
|
|
18387
18474
|
getIntegrationTransferDefaultToken
|
|
18388
18475
|
} from "@unifold/core";
|
|
@@ -18391,7 +18478,7 @@ function useIntegrationTransferDefaultToken({
|
|
|
18391
18478
|
publishableKey,
|
|
18392
18479
|
enabled = true
|
|
18393
18480
|
}) {
|
|
18394
|
-
return
|
|
18481
|
+
return useQuery11({
|
|
18395
18482
|
queryKey: [
|
|
18396
18483
|
"unifold",
|
|
18397
18484
|
"integrationTransferDefaultToken",
|
|
@@ -19079,6 +19166,9 @@ function CoinbaseConnect({
|
|
|
19079
19166
|
flow_type: "deposit",
|
|
19080
19167
|
method: "exchange_connect",
|
|
19081
19168
|
provider: IntegrationProvider.COINBASE,
|
|
19169
|
+
// No execution yet — one appears when the exchange's transfer lands on
|
|
19170
|
+
// this wallet, carrying the same id.
|
|
19171
|
+
deposit_wallet_id: transferDepositWalletId,
|
|
19082
19172
|
amount_usd: sendAmount || void 0,
|
|
19083
19173
|
currency: selectedAsset?.currency.toLowerCase().replace(/[^a-z0-9]+/g, "_"),
|
|
19084
19174
|
chain: sourceChain?.chain_id,
|
|
@@ -19086,6 +19176,34 @@ function CoinbaseConnect({
|
|
|
19086
19176
|
network: sourceChain?.network
|
|
19087
19177
|
});
|
|
19088
19178
|
};
|
|
19179
|
+
const applyConfirmResult = (result) => {
|
|
19180
|
+
if (result.status === "mfa_required") {
|
|
19181
|
+
track("verification_started", {
|
|
19182
|
+
flow_type: "deposit",
|
|
19183
|
+
method: "exchange_connect",
|
|
19184
|
+
provider: IntegrationProvider.COINBASE,
|
|
19185
|
+
verification_type: "mfa",
|
|
19186
|
+
verification_status: result.status
|
|
19187
|
+
});
|
|
19188
|
+
transitionTo("mfa");
|
|
19189
|
+
setMfaCode("");
|
|
19190
|
+
setMfaError(false);
|
|
19191
|
+
} else if (result.status === "mfa_enrollment_required") {
|
|
19192
|
+
transitionTo("mfa_enrollment");
|
|
19193
|
+
} else if (result.status === "completed") {
|
|
19194
|
+
trackTransferStarted();
|
|
19195
|
+
setConfirmResult(result);
|
|
19196
|
+
transitionTo("success");
|
|
19197
|
+
onTransferSuccess?.(result);
|
|
19198
|
+
} else {
|
|
19199
|
+
setErrorMessage(result.message || t.errors.transferFailed);
|
|
19200
|
+
transitionTo("error");
|
|
19201
|
+
onTransferError?.({
|
|
19202
|
+
message: result.message || t.errors.transferFailed,
|
|
19203
|
+
code: result.status
|
|
19204
|
+
});
|
|
19205
|
+
}
|
|
19206
|
+
};
|
|
19089
19207
|
const handleConfirmTransfer = async () => {
|
|
19090
19208
|
if (!transferIntent || !accessToken) return;
|
|
19091
19209
|
setIsLoading(true);
|
|
@@ -19120,30 +19238,7 @@ function CoinbaseConnect({
|
|
|
19120
19238
|
});
|
|
19121
19239
|
throw err;
|
|
19122
19240
|
});
|
|
19123
|
-
|
|
19124
|
-
track("verification_started", {
|
|
19125
|
-
flow_type: "deposit",
|
|
19126
|
-
method: "exchange_connect",
|
|
19127
|
-
provider: IntegrationProvider.COINBASE,
|
|
19128
|
-
verification_type: "mfa",
|
|
19129
|
-
verification_status: result.status
|
|
19130
|
-
});
|
|
19131
|
-
transitionTo("mfa");
|
|
19132
|
-
setMfaCode("");
|
|
19133
|
-
setMfaError(false);
|
|
19134
|
-
} else if (result.status === "completed") {
|
|
19135
|
-
trackTransferStarted();
|
|
19136
|
-
setConfirmResult(result);
|
|
19137
|
-
transitionTo("success");
|
|
19138
|
-
onTransferSuccess?.(result);
|
|
19139
|
-
} else {
|
|
19140
|
-
setErrorMessage(result.message || t.errors.transferFailed);
|
|
19141
|
-
transitionTo("error");
|
|
19142
|
-
onTransferError?.({
|
|
19143
|
-
message: result.message || t.errors.transferFailed,
|
|
19144
|
-
code: result.status
|
|
19145
|
-
});
|
|
19146
|
-
}
|
|
19241
|
+
applyConfirmResult(result);
|
|
19147
19242
|
} catch (err) {
|
|
19148
19243
|
const message = err instanceof Error ? err.message : t.errors.transferFailed;
|
|
19149
19244
|
setErrorMessage(message);
|
|
@@ -19300,6 +19395,9 @@ function CoinbaseConnect({
|
|
|
19300
19395
|
setShowTransferDetails(false);
|
|
19301
19396
|
transitionTo("enter_amount");
|
|
19302
19397
|
break;
|
|
19398
|
+
case "mfa_enrollment":
|
|
19399
|
+
transitionTo("transfer_confirm");
|
|
19400
|
+
break;
|
|
19303
19401
|
case "mfa":
|
|
19304
19402
|
transitionTo("transfer_confirm");
|
|
19305
19403
|
break;
|
|
@@ -20856,6 +20954,55 @@ function CoinbaseConnect({
|
|
|
20856
20954
|
] })
|
|
20857
20955
|
] });
|
|
20858
20956
|
}
|
|
20957
|
+
if (view === "mfa_enrollment") {
|
|
20958
|
+
return /* @__PURE__ */ jsxs46(Fragment9, { children: [
|
|
20959
|
+
/* @__PURE__ */ jsx51(DepositHeader, { title: t.title, showBack: true, onBack: handleBack, onClose }),
|
|
20960
|
+
/* @__PURE__ */ jsxs46(
|
|
20961
|
+
"div",
|
|
20962
|
+
{
|
|
20963
|
+
className: "uf-flex uf-flex-col uf-items-center uf-px-4 uf-pb-4",
|
|
20964
|
+
style: viewTransitionStyle,
|
|
20965
|
+
children: [
|
|
20966
|
+
/* @__PURE__ */ jsx51(
|
|
20967
|
+
DepositErrorState,
|
|
20968
|
+
{
|
|
20969
|
+
title: t.transfer.mfaEnrollmentTitle,
|
|
20970
|
+
message: t.transfer.mfaEnrollmentMessage
|
|
20971
|
+
}
|
|
20972
|
+
),
|
|
20973
|
+
/* @__PURE__ */ jsxs46(
|
|
20974
|
+
"a",
|
|
20975
|
+
{
|
|
20976
|
+
href: "https://www.coinbase.com/settings/security",
|
|
20977
|
+
target: "_blank",
|
|
20978
|
+
rel: "noopener noreferrer",
|
|
20979
|
+
className: "uf-text-sm uf-underline uf-mb-8 uf-inline-flex uf-items-center uf-gap-1",
|
|
20980
|
+
style: { color: colors2.primary, fontFamily: fonts.medium },
|
|
20981
|
+
children: [
|
|
20982
|
+
t.transfer.mfaEnrollmentSettingsLink,
|
|
20983
|
+
/* @__PURE__ */ jsx51(ExternalLink4, { className: "uf-w-3.5 uf-h-3.5" })
|
|
20984
|
+
]
|
|
20985
|
+
}
|
|
20986
|
+
),
|
|
20987
|
+
/* @__PURE__ */ jsx51(
|
|
20988
|
+
"button",
|
|
20989
|
+
{
|
|
20990
|
+
onClick: handleConfirmTransfer,
|
|
20991
|
+
disabled: isLoading,
|
|
20992
|
+
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",
|
|
20993
|
+
style: {
|
|
20994
|
+
backgroundColor: colors2.primary,
|
|
20995
|
+
color: "#fff",
|
|
20996
|
+
fontFamily: fonts.medium
|
|
20997
|
+
},
|
|
20998
|
+
children: isLoading ? /* @__PURE__ */ jsx51(Loader27, { className: "uf-w-4 uf-h-4 uf-animate-spin" }) : t.continue
|
|
20999
|
+
}
|
|
21000
|
+
)
|
|
21001
|
+
]
|
|
21002
|
+
}
|
|
21003
|
+
)
|
|
21004
|
+
] });
|
|
21005
|
+
}
|
|
20859
21006
|
if (view === "mfa") {
|
|
20860
21007
|
return /* @__PURE__ */ jsxs46(Fragment9, { children: [
|
|
20861
21008
|
/* @__PURE__ */ jsx51(DepositHeader, { title: t.title, showBack: true, onBack: handleBack, onClose }),
|
|
@@ -21141,13 +21288,13 @@ function resolveDepositMenuLayout(layout, displayMode) {
|
|
|
21141
21288
|
}
|
|
21142
21289
|
|
|
21143
21290
|
// src/hooks/use-exchanges.ts
|
|
21144
|
-
import { useQuery as
|
|
21291
|
+
import { useQuery as useQuery12 } from "@tanstack/react-query";
|
|
21145
21292
|
import { getExchanges } from "@unifold/core";
|
|
21146
21293
|
function useExchanges({
|
|
21147
21294
|
publishableKey,
|
|
21148
21295
|
enabled = true
|
|
21149
21296
|
}) {
|
|
21150
|
-
const { data: exchanges = [], isLoading } =
|
|
21297
|
+
const { data: exchanges = [], isLoading } = useQuery12({
|
|
21151
21298
|
queryKey: ["unifold", "exchanges", publishableKey],
|
|
21152
21299
|
queryFn: () => getExchanges(void 0, publishableKey).then((res) => res.data),
|
|
21153
21300
|
enabled,
|
|
@@ -21159,7 +21306,7 @@ function useExchanges({
|
|
|
21159
21306
|
}
|
|
21160
21307
|
|
|
21161
21308
|
// src/hooks/use-public-incident.ts
|
|
21162
|
-
import { useQuery as
|
|
21309
|
+
import { useQuery as useQuery13 } from "@tanstack/react-query";
|
|
21163
21310
|
import { getPublicIncident } from "@unifold/core";
|
|
21164
21311
|
function usePublicIncident({
|
|
21165
21312
|
publishableKey,
|
|
@@ -21169,7 +21316,7 @@ function usePublicIncident({
|
|
|
21169
21316
|
data: incident,
|
|
21170
21317
|
isLoading,
|
|
21171
21318
|
error
|
|
21172
|
-
} =
|
|
21319
|
+
} = useQuery13({
|
|
21173
21320
|
queryKey: ["unifold", "publicIncident", publishableKey],
|
|
21174
21321
|
queryFn: () => getPublicIncident(publishableKey),
|
|
21175
21322
|
enabled,
|
|
@@ -21181,7 +21328,7 @@ function usePublicIncident({
|
|
|
21181
21328
|
}
|
|
21182
21329
|
|
|
21183
21330
|
// src/hooks/use-wallet-pay-providers.ts
|
|
21184
|
-
import { useQuery as
|
|
21331
|
+
import { useQuery as useQuery14 } from "@tanstack/react-query";
|
|
21185
21332
|
import {
|
|
21186
21333
|
getWalletPayProviders
|
|
21187
21334
|
} from "@unifold/core";
|
|
@@ -21190,7 +21337,7 @@ function useWalletPayProviders({
|
|
|
21190
21337
|
publishableKey,
|
|
21191
21338
|
enabled = true
|
|
21192
21339
|
}) {
|
|
21193
|
-
const { data: providers, isLoading } =
|
|
21340
|
+
const { data: providers, isLoading } = useQuery14({
|
|
21194
21341
|
queryKey: ["unifold", "walletPayProviders", method, publishableKey],
|
|
21195
21342
|
queryFn: () => getWalletPayProviders(method, publishableKey),
|
|
21196
21343
|
enabled,
|
|
@@ -21483,7 +21630,7 @@ function useAllowedCountry(publishableKey) {
|
|
|
21483
21630
|
}
|
|
21484
21631
|
|
|
21485
21632
|
// src/hooks/use-address-validation.ts
|
|
21486
|
-
import { useQuery as
|
|
21633
|
+
import { useQuery as useQuery15 } from "@tanstack/react-query";
|
|
21487
21634
|
import {
|
|
21488
21635
|
verifyRecipientAddress
|
|
21489
21636
|
} from "@unifold/core";
|
|
@@ -21497,7 +21644,7 @@ function useAddressValidation({
|
|
|
21497
21644
|
refetchOnMount = false
|
|
21498
21645
|
}) {
|
|
21499
21646
|
const shouldValidate = enabled && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
21500
|
-
const { data, isLoading, error } =
|
|
21647
|
+
const { data, isLoading, error } = useQuery15({
|
|
21501
21648
|
queryKey: [
|
|
21502
21649
|
"unifold",
|
|
21503
21650
|
"addressValidation",
|
|
@@ -22960,7 +23107,7 @@ import {
|
|
|
22960
23107
|
} from "@unifold/core";
|
|
22961
23108
|
|
|
22962
23109
|
// src/hooks/use-hypercore-activation.ts
|
|
22963
|
-
import { useQuery as
|
|
23110
|
+
import { useQuery as useQuery16 } from "@tanstack/react-query";
|
|
22964
23111
|
import { checkHypercoreActivation } from "@unifold/core";
|
|
22965
23112
|
|
|
22966
23113
|
// src/lib/constants.ts
|
|
@@ -22979,7 +23126,7 @@ function useHypercoreActivation(params) {
|
|
|
22979
23126
|
const recipient = recipientAddress?.trim() ?? "";
|
|
22980
23127
|
const source = sourceAddress?.trim() ?? "";
|
|
22981
23128
|
const hasAddresses = !!recipient && !!source;
|
|
22982
|
-
const { data, isLoading } =
|
|
23129
|
+
const { data, isLoading } = useQuery16({
|
|
22983
23130
|
queryKey: ["unifold", "hypercoreActivation", source, recipient, publishableKey],
|
|
22984
23131
|
queryFn: () => checkHypercoreActivation(
|
|
22985
23132
|
{
|
|
@@ -24793,7 +24940,7 @@ async function sendHypercoreEvmTransfer(params) {
|
|
|
24793
24940
|
}
|
|
24794
24941
|
|
|
24795
24942
|
// src/hooks/use-deposit-quote.ts
|
|
24796
|
-
import { useQuery as
|
|
24943
|
+
import { useQuery as useQuery17 } from "@tanstack/react-query";
|
|
24797
24944
|
import { getDepositQuote } from "@unifold/core";
|
|
24798
24945
|
function useDepositQuote(params) {
|
|
24799
24946
|
const {
|
|
@@ -24820,7 +24967,7 @@ function useDepositQuote(params) {
|
|
|
24820
24967
|
...adjustForSlippage ? { adjust_for_slippage: true } : {},
|
|
24821
24968
|
...stablecoinParity ? { stablecoin_parity: true } : {}
|
|
24822
24969
|
};
|
|
24823
|
-
return
|
|
24970
|
+
return useQuery17({
|
|
24824
24971
|
queryKey: [
|
|
24825
24972
|
"unifold",
|
|
24826
24973
|
"depositQuote",
|
|
@@ -24848,13 +24995,13 @@ function useDepositQuote(params) {
|
|
|
24848
24995
|
}
|
|
24849
24996
|
|
|
24850
24997
|
// src/hooks/use-external-wallets.ts
|
|
24851
|
-
import { useQuery as
|
|
24998
|
+
import { useQuery as useQuery18 } from "@tanstack/react-query";
|
|
24852
24999
|
import { getExternalWallets } from "@unifold/core";
|
|
24853
25000
|
function useExternalWallets({
|
|
24854
25001
|
publishableKey,
|
|
24855
25002
|
enabled = true
|
|
24856
25003
|
}) {
|
|
24857
|
-
const { data: wallets = [], isLoading } =
|
|
25004
|
+
const { data: wallets = [], isLoading } = useQuery18({
|
|
24858
25005
|
queryKey: ["unifold", "external-wallets", publishableKey],
|
|
24859
25006
|
queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
|
|
24860
25007
|
enabled: enabled && !!publishableKey,
|
|
@@ -27015,7 +27162,11 @@ function WalletConnect({
|
|
|
27015
27162
|
chain: String(token.chain_id),
|
|
27016
27163
|
network: token.network,
|
|
27017
27164
|
token: token.symbol ?? token.token_address,
|
|
27018
|
-
currency: token.currency
|
|
27165
|
+
currency: token.currency,
|
|
27166
|
+
// No execution exists yet — it's created when this send lands on the
|
|
27167
|
+
// wallet. The wallet id is what that execution will carry, so it's
|
|
27168
|
+
// how a send that never completes is matched to what followed.
|
|
27169
|
+
deposit_wallet_id: activeDepositWallet?.id
|
|
27019
27170
|
});
|
|
27020
27171
|
setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
|
|
27021
27172
|
setHasSignedTransaction(true);
|
|
@@ -27605,7 +27756,7 @@ function DepositModal({
|
|
|
27605
27756
|
const applePaySubTitle = applePaySubTitleProp ?? t.applePayMenu.subtitle;
|
|
27606
27757
|
const googlePayTitle = googlePayTitleProp ?? t.googlePayMenu.title;
|
|
27607
27758
|
const googlePaySubTitle = googlePaySubTitleProp ?? t.googlePayMenu.subtitle;
|
|
27608
|
-
const { track, startSession, endSession, getSessionId, subscribe } = useAnalytics();
|
|
27759
|
+
const { track, startSession, endSession, getSessionId, setUserId, subscribe } = useAnalytics();
|
|
27609
27760
|
const normalizedPrefilledAmountUsd = useMemo17(
|
|
27610
27761
|
() => normalizePrefilledUsdAmount(prefilledAmountUsd),
|
|
27611
27762
|
[prefilledAmountUsd]
|
|
@@ -27613,6 +27764,7 @@ function DepositModal({
|
|
|
27613
27764
|
const analyticsMethod = (method) => method === "transfer" ? "transfer_crypto" : method;
|
|
27614
27765
|
const journeyActiveRef = useRef16(false);
|
|
27615
27766
|
const journeySessionIdRef = useRef16(void 0);
|
|
27767
|
+
const journeyExternalUserIdRef = useRef16(void 0);
|
|
27616
27768
|
const externalUserId = userId || void 0;
|
|
27617
27769
|
const emitEvent = useCallback14(
|
|
27618
27770
|
(event) => onEvent?.({ ...event, externalUserId }),
|
|
@@ -27640,6 +27792,9 @@ function DepositModal({
|
|
|
27640
27792
|
method: analyticsMethod(method),
|
|
27641
27793
|
flow_type: "deposit",
|
|
27642
27794
|
amount_usd: execution?.destinationAmountUsd ?? execution?.sourceAmountUsd,
|
|
27795
|
+
// The one high-cardinality field we do send: the join key from a
|
|
27796
|
+
// funnel session back to the execution row it produced.
|
|
27797
|
+
execution_id: data.executionId ?? execution?.id,
|
|
27643
27798
|
// Flat, low-cardinality execution dimensions for PostHog breakdowns
|
|
27644
27799
|
// (precise/opaque fields like base units, addresses, tx hashes live in
|
|
27645
27800
|
// the onEvent DirectExecution instead).
|
|
@@ -27667,6 +27822,7 @@ function DepositModal({
|
|
|
27667
27822
|
method: analyticsMethod(method),
|
|
27668
27823
|
flow_type: "deposit",
|
|
27669
27824
|
error_code: error.code,
|
|
27825
|
+
execution_id: execution?.id,
|
|
27670
27826
|
failure_reason: execution?.failureReason ?? void 0,
|
|
27671
27827
|
status: execution?.status,
|
|
27672
27828
|
source_chain_type: execution?.sourceChainType,
|
|
@@ -28095,8 +28251,10 @@ function DepositModal({
|
|
|
28095
28251
|
const beginJourney = useCallback14(() => {
|
|
28096
28252
|
journeySessionIdRef.current = startSession();
|
|
28097
28253
|
journeyActiveRef.current = true;
|
|
28254
|
+
journeyExternalUserIdRef.current = userId;
|
|
28255
|
+
setUserId(null);
|
|
28098
28256
|
track("widget_opened", { flow_type: "deposit" });
|
|
28099
|
-
}, [startSession, track]);
|
|
28257
|
+
}, [startSession, track, setUserId, userId]);
|
|
28100
28258
|
const handleClose = () => {
|
|
28101
28259
|
finalizeJourney();
|
|
28102
28260
|
onOpenChange(false);
|
|
@@ -28121,6 +28279,11 @@ function DepositModal({
|
|
|
28121
28279
|
}
|
|
28122
28280
|
beginJourney();
|
|
28123
28281
|
}, [open]);
|
|
28282
|
+
useLayoutEffect2(() => {
|
|
28283
|
+
if (!open || journeyExternalUserIdRef.current === userId) return;
|
|
28284
|
+
journeyExternalUserIdRef.current = userId;
|
|
28285
|
+
setUserId(null);
|
|
28286
|
+
}, [open, userId, setUserId]);
|
|
28124
28287
|
useLayoutEffect2(() => {
|
|
28125
28288
|
if (!open) return;
|
|
28126
28289
|
if (resetViewTimeoutRef.current) {
|
|
@@ -29032,6 +29195,7 @@ function DepositModal({
|
|
|
29032
29195
|
destinationChainType,
|
|
29033
29196
|
destinationChainId,
|
|
29034
29197
|
destinationTokenAddress,
|
|
29198
|
+
contractCalls,
|
|
29035
29199
|
cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
|
|
29036
29200
|
view: cashAppView,
|
|
29037
29201
|
onViewChange: setCashAppView,
|
|
@@ -29216,12 +29380,12 @@ function useForwardCheckoutEvents(onEvent, journeySessionId) {
|
|
|
29216
29380
|
}
|
|
29217
29381
|
|
|
29218
29382
|
// src/hooks/use-payment-intent.ts
|
|
29219
|
-
import { useQuery as
|
|
29383
|
+
import { useQuery as useQuery19 } from "@tanstack/react-query";
|
|
29220
29384
|
import { retrievePaymentIntent } from "@unifold/core";
|
|
29221
29385
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["succeeded", "expired", "refunded", "canceled"]);
|
|
29222
29386
|
function usePaymentIntent(params) {
|
|
29223
29387
|
const { clientSecret, publishableKey, enabled = true, pollingInterval = 3e3 } = params;
|
|
29224
|
-
return
|
|
29388
|
+
return useQuery19({
|
|
29225
29389
|
queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
|
|
29226
29390
|
queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
|
|
29227
29391
|
enabled: enabled && !!clientSecret && !!publishableKey,
|
|
@@ -29395,6 +29559,9 @@ function CheckoutModal({
|
|
|
29395
29559
|
flowCompletedRef.current = true;
|
|
29396
29560
|
track("flow_completed", {
|
|
29397
29561
|
flow_type: "checkout",
|
|
29562
|
+
// Checkout has no direct execution; the intent is what a funnel
|
|
29563
|
+
// session joins back to.
|
|
29564
|
+
payment_intent_id: data.paymentIntentId,
|
|
29398
29565
|
...method ? { method: method === "transfer" ? "transfer_crypto" : method } : {}
|
|
29399
29566
|
});
|
|
29400
29567
|
}
|
|
@@ -29615,7 +29782,7 @@ function CheckoutModal({
|
|
|
29615
29782
|
journeySessionIdRef.current = startSession();
|
|
29616
29783
|
journeyActiveRef.current = true;
|
|
29617
29784
|
flowCompletedRef.current = false;
|
|
29618
|
-
setUserId(null);
|
|
29785
|
+
setUserId(paymentIntentUserId ?? null);
|
|
29619
29786
|
track("widget_opened", { flow_type: "checkout" });
|
|
29620
29787
|
if (resetViewTimeoutRef.current) {
|
|
29621
29788
|
clearTimeout(resetViewTimeoutRef.current);
|
|
@@ -30056,16 +30223,16 @@ function CheckoutModal({
|
|
|
30056
30223
|
}
|
|
30057
30224
|
|
|
30058
30225
|
// src/components/withdrawals/WithdrawModal.tsx
|
|
30059
|
-
import { useState as useState49, useEffect as
|
|
30226
|
+
import { useState as useState49, useEffect as useEffect47, useLayoutEffect as useLayoutEffect4, useCallback as useCallback17, useMemo as useMemo21, useRef as useRef20 } from "react";
|
|
30060
30227
|
import { AlertTriangle as AlertTriangle8, ChevronRight as ChevronRight22, Clock as Clock6 } from "lucide-react";
|
|
30061
30228
|
|
|
30062
30229
|
// src/hooks/use-supported-destination-tokens.ts
|
|
30063
|
-
import { useQuery as
|
|
30230
|
+
import { useQuery as useQuery20 } from "@tanstack/react-query";
|
|
30064
30231
|
import {
|
|
30065
30232
|
getSupportedDestinationTokens
|
|
30066
30233
|
} from "@unifold/core";
|
|
30067
30234
|
function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
30068
|
-
return
|
|
30235
|
+
return useQuery20({
|
|
30069
30236
|
queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
|
|
30070
30237
|
queryFn: () => getSupportedDestinationTokens(publishableKey),
|
|
30071
30238
|
staleTime: 1e3 * 60 * 5,
|
|
@@ -30097,7 +30264,7 @@ function useDefaultDestinationToken({
|
|
|
30097
30264
|
}
|
|
30098
30265
|
|
|
30099
30266
|
// src/hooks/use-source-token-validation.ts
|
|
30100
|
-
import { useQuery as
|
|
30267
|
+
import { useQuery as useQuery21 } from "@tanstack/react-query";
|
|
30101
30268
|
import { getSupportedDepositTokens as getSupportedDepositTokens3 } from "@unifold/core";
|
|
30102
30269
|
function useSourceTokenValidation(params) {
|
|
30103
30270
|
const {
|
|
@@ -30109,7 +30276,7 @@ function useSourceTokenValidation(params) {
|
|
|
30109
30276
|
enabled = true
|
|
30110
30277
|
} = params;
|
|
30111
30278
|
const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
|
|
30112
|
-
return
|
|
30279
|
+
return useQuery21({
|
|
30113
30280
|
queryKey: [
|
|
30114
30281
|
"unifold",
|
|
30115
30282
|
"sourceTokenValidation",
|
|
@@ -30159,12 +30326,12 @@ function useSourceTokenValidation(params) {
|
|
|
30159
30326
|
}
|
|
30160
30327
|
|
|
30161
30328
|
// src/hooks/use-address-balance.ts
|
|
30162
|
-
import { useQuery as
|
|
30329
|
+
import { useQuery as useQuery22 } from "@tanstack/react-query";
|
|
30163
30330
|
import { getAddressBalance as getAddressBalance2 } from "@unifold/core";
|
|
30164
30331
|
function useAddressBalance(params) {
|
|
30165
30332
|
const { address, chainType, chainId, tokenAddress, publishableKey, enabled = true } = params;
|
|
30166
30333
|
const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
|
|
30167
|
-
return
|
|
30334
|
+
return useQuery22({
|
|
30168
30335
|
queryKey: [
|
|
30169
30336
|
"unifold",
|
|
30170
30337
|
"addressBalance",
|
|
@@ -30220,11 +30387,11 @@ function useAddressBalance(params) {
|
|
|
30220
30387
|
}
|
|
30221
30388
|
|
|
30222
30389
|
// src/hooks/use-executions.ts
|
|
30223
|
-
import { useQuery as
|
|
30390
|
+
import { useQuery as useQuery23 } from "@tanstack/react-query";
|
|
30224
30391
|
import { queryExecutions as queryExecutions4, ActionType as ActionType4 } from "@unifold/core";
|
|
30225
30392
|
function useExecutions(userId, publishableKey, options) {
|
|
30226
30393
|
const actionType = options?.actionType ?? ActionType4.Deposit;
|
|
30227
|
-
|
|
30394
|
+
const query = useQuery23({
|
|
30228
30395
|
queryKey: ["unifold", "executions", actionType, userId, publishableKey],
|
|
30229
30396
|
queryFn: () => queryExecutions4(userId, publishableKey, actionType),
|
|
30230
30397
|
enabled: (options?.enabled ?? true) && !!userId,
|
|
@@ -30233,6 +30400,8 @@ function useExecutions(userId, publishableKey, options) {
|
|
|
30233
30400
|
gcTime: 1e3 * 60 * 5,
|
|
30234
30401
|
refetchOnWindowFocus: false
|
|
30235
30402
|
});
|
|
30403
|
+
useStampInternalUserId({ internalUserId: query.data?.data[0]?.user_id });
|
|
30404
|
+
return query;
|
|
30236
30405
|
}
|
|
30237
30406
|
|
|
30238
30407
|
// src/hooks/use-withdraw-polling.ts
|
|
@@ -30574,7 +30743,7 @@ function WithdrawDoubleInput({
|
|
|
30574
30743
|
}
|
|
30575
30744
|
|
|
30576
30745
|
// src/components/withdrawals/WithdrawForm.tsx
|
|
30577
|
-
import { useState as useState47, useCallback as useCallback16, useMemo as useMemo20, useEffect as
|
|
30746
|
+
import { useState as useState47, useCallback as useCallback16, useMemo as useMemo20, useEffect as useEffect45 } from "react";
|
|
30578
30747
|
import {
|
|
30579
30748
|
AlertTriangle as AlertTriangle7,
|
|
30580
30749
|
ArrowUpDown,
|
|
@@ -30592,7 +30761,7 @@ import {
|
|
|
30592
30761
|
} from "@unifold/core";
|
|
30593
30762
|
|
|
30594
30763
|
// src/hooks/use-verify-recipient-address.ts
|
|
30595
|
-
import { useQuery as
|
|
30764
|
+
import { useQuery as useQuery24 } from "@tanstack/react-query";
|
|
30596
30765
|
import { verifyRecipientAddress as verifyRecipientAddress2 } from "@unifold/core";
|
|
30597
30766
|
function useVerifyRecipientAddress(params) {
|
|
30598
30767
|
const {
|
|
@@ -30605,7 +30774,7 @@ function useVerifyRecipientAddress(params) {
|
|
|
30605
30774
|
} = params;
|
|
30606
30775
|
const trimmedAddress = recipientAddress?.trim() || "";
|
|
30607
30776
|
const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
|
|
30608
|
-
return
|
|
30777
|
+
return useQuery24({
|
|
30609
30778
|
queryKey: [
|
|
30610
30779
|
"unifold",
|
|
30611
30780
|
"verifyRecipientAddress",
|
|
@@ -30857,8 +31026,7 @@ import { useMemo as useMemo19 } from "react";
|
|
|
30857
31026
|
import { ActionType as ActionType6 } from "@unifold/core";
|
|
30858
31027
|
|
|
30859
31028
|
// src/hooks/use-get-deposit-address.ts
|
|
30860
|
-
import {
|
|
30861
|
-
import { useQuery as useQuery26 } from "@tanstack/react-query";
|
|
31029
|
+
import { useQuery as useQuery25 } from "@tanstack/react-query";
|
|
30862
31030
|
import { getDepositAddress } from "@unifold/core";
|
|
30863
31031
|
function useGetDepositAddress(params) {
|
|
30864
31032
|
const {
|
|
@@ -30871,9 +31039,8 @@ function useGetDepositAddress(params) {
|
|
|
30871
31039
|
actionType,
|
|
30872
31040
|
enabled = true
|
|
30873
31041
|
} = params;
|
|
30874
|
-
const { setUserId } = useAnalytics();
|
|
30875
31042
|
const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
|
|
30876
|
-
const query =
|
|
31043
|
+
const query = useQuery25({
|
|
30877
31044
|
queryKey: [
|
|
30878
31045
|
"unifold",
|
|
30879
31046
|
"getDepositAddress",
|
|
@@ -30903,11 +31070,7 @@ function useGetDepositAddress(params) {
|
|
|
30903
31070
|
refetchOnWindowFocus: false,
|
|
30904
31071
|
retry: 1
|
|
30905
31072
|
});
|
|
30906
|
-
|
|
30907
|
-
if (query.data?.user_id) {
|
|
30908
|
-
setUserId(query.data.user_id);
|
|
30909
|
-
}
|
|
30910
|
-
}, [query.data?.user_id, setUserId]);
|
|
31073
|
+
useStampInternalUserId({ internalUserId: query.data?.user_id });
|
|
30911
31074
|
return query;
|
|
30912
31075
|
}
|
|
30913
31076
|
|
|
@@ -31047,14 +31210,14 @@ function WithdrawForm({
|
|
|
31047
31210
|
const [detailsExpanded, setDetailsExpanded] = useState47(false);
|
|
31048
31211
|
const [glossaryOpen, setGlossaryOpen] = useState47(false);
|
|
31049
31212
|
const [isMaxed, setIsMaxed] = useState47(false);
|
|
31050
|
-
|
|
31213
|
+
useEffect45(() => {
|
|
31051
31214
|
setRecipientAddress(recipientAddressProp || "");
|
|
31052
31215
|
setAmount("");
|
|
31053
31216
|
setInputUnit("fiat");
|
|
31054
31217
|
setSubmitError(null);
|
|
31055
31218
|
setIsMaxed(false);
|
|
31056
31219
|
}, [recipientAddressProp]);
|
|
31057
|
-
|
|
31220
|
+
useEffect45(() => {
|
|
31058
31221
|
setIsMaxed(false);
|
|
31059
31222
|
}, [balanceData?.balanceBaseUnit]);
|
|
31060
31223
|
const trimmedAddress = recipientAddress.trim();
|
|
@@ -31855,7 +32018,7 @@ function WithdrawExecutionItem({ execution, onClick }) {
|
|
|
31855
32018
|
}
|
|
31856
32019
|
|
|
31857
32020
|
// src/components/withdrawals/WithdrawConfirmingView.tsx
|
|
31858
|
-
import { useState as useState48, useEffect as
|
|
32021
|
+
import { useState as useState48, useEffect as useEffect46 } from "react";
|
|
31859
32022
|
import { Fragment as Fragment19, jsx as jsx76, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
31860
32023
|
function truncateAddress4(addr) {
|
|
31861
32024
|
if (addr.length <= 12) return addr;
|
|
@@ -31873,7 +32036,7 @@ function WithdrawConfirmingView({
|
|
|
31873
32036
|
const t = strings.withdrawModal.details;
|
|
31874
32037
|
const [showButton, setShowButton] = useState48(false);
|
|
31875
32038
|
const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
|
|
31876
|
-
|
|
32039
|
+
useEffect46(() => {
|
|
31877
32040
|
if (latestExecution) return;
|
|
31878
32041
|
const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
|
|
31879
32042
|
return () => clearTimeout(timer);
|
|
@@ -32035,7 +32198,7 @@ function WithdrawModal({
|
|
|
32035
32198
|
);
|
|
32036
32199
|
const onEventRef = useRef20(emitEvent);
|
|
32037
32200
|
onEventRef.current = emitEvent;
|
|
32038
|
-
|
|
32201
|
+
useEffect47(
|
|
32039
32202
|
() => subscribe((event) => {
|
|
32040
32203
|
if (event.properties?.flow_type !== "withdraw") return;
|
|
32041
32204
|
const selection = selectionPayload(event);
|
|
@@ -32052,12 +32215,16 @@ function WithdrawModal({
|
|
|
32052
32215
|
);
|
|
32053
32216
|
const journeyActiveRef = useRef20(false);
|
|
32054
32217
|
const journeySessionIdRef = useRef20(void 0);
|
|
32218
|
+
const journeyExternalUserIdRef = useRef20(void 0);
|
|
32055
32219
|
const onWithdrawSuccessFor = useCallback17(
|
|
32056
32220
|
(data) => {
|
|
32057
32221
|
const execution = data.execution?.data.object;
|
|
32058
32222
|
track("flow_completed", {
|
|
32059
32223
|
flow_type: "withdraw",
|
|
32060
32224
|
amount_usd: execution?.destinationAmountUsd ?? execution?.sourceAmountUsd,
|
|
32225
|
+
// The one high-cardinality field we do send: the join key from a
|
|
32226
|
+
// funnel session back to the execution row it produced.
|
|
32227
|
+
execution_id: data.executionId ?? execution?.id,
|
|
32061
32228
|
// Flat, low-cardinality execution dimensions for PostHog breakdowns.
|
|
32062
32229
|
status: execution?.status,
|
|
32063
32230
|
source_chain_type: execution?.sourceChainType,
|
|
@@ -32078,6 +32245,7 @@ function WithdrawModal({
|
|
|
32078
32245
|
track("flow_failed", {
|
|
32079
32246
|
flow_type: "withdraw",
|
|
32080
32247
|
error_code: error.code,
|
|
32248
|
+
execution_id: execution?.id,
|
|
32081
32249
|
failure_reason: execution?.failureReason ?? void 0,
|
|
32082
32250
|
status: execution?.status,
|
|
32083
32251
|
source_chain_type: execution?.sourceChainType,
|
|
@@ -32099,7 +32267,7 @@ function WithdrawModal({
|
|
|
32099
32267
|
const [resolvedTheme, setResolvedTheme] = useState49(
|
|
32100
32268
|
theme === "auto" ? "dark" : theme
|
|
32101
32269
|
);
|
|
32102
|
-
|
|
32270
|
+
useEffect47(() => {
|
|
32103
32271
|
if (theme === "auto") {
|
|
32104
32272
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
32105
32273
|
setResolvedTheme(mq.matches ? "dark" : "light");
|
|
@@ -32151,6 +32319,7 @@ function WithdrawModal({
|
|
|
32151
32319
|
) ?? null : null;
|
|
32152
32320
|
const [view, setView] = useState49("form");
|
|
32153
32321
|
const [withdrawDepositWalletId, setWithdrawDepositWalletId] = useState49();
|
|
32322
|
+
const withdrawDepositWalletIdRef = useRef20(void 0);
|
|
32154
32323
|
const [selectedExecution, setSelectedExecution] = useState49(null);
|
|
32155
32324
|
const [submittedTxInfo, setSubmittedTxInfo] = useState49(null);
|
|
32156
32325
|
const { executions: realtimeExecutions } = useWithdrawPolling({
|
|
@@ -32188,6 +32357,7 @@ function WithdrawModal({
|
|
|
32188
32357
|
if (!depositWallet) {
|
|
32189
32358
|
throw new Error(`No deposit wallet available for ${sourceChainType}`);
|
|
32190
32359
|
}
|
|
32360
|
+
withdrawDepositWalletIdRef.current = depositWallet.id;
|
|
32191
32361
|
setWithdrawDepositWalletId(depositWallet.id);
|
|
32192
32362
|
return depositWallet;
|
|
32193
32363
|
},
|
|
@@ -32207,7 +32377,12 @@ function WithdrawModal({
|
|
|
32207
32377
|
currency: tokenData?.currency,
|
|
32208
32378
|
amount: txInfo.amount,
|
|
32209
32379
|
amount_base_unit: txInfo.amountBaseUnit,
|
|
32210
|
-
...txInfo.amountUsd ? { amount_usd: txInfo.amountUsd } : {}
|
|
32380
|
+
...txInfo.amountUsd ? { amount_usd: txInfo.amountUsd } : {},
|
|
32381
|
+
// The execution doesn't exist yet — it's created when the user's send
|
|
32382
|
+
// lands on the withdraw deposit wallet, and carries this id. So a
|
|
32383
|
+
// withdrawal confirmed but never completed still joins to whatever
|
|
32384
|
+
// did (or didn't) follow on that wallet.
|
|
32385
|
+
deposit_wallet_id: withdrawDepositWalletIdRef.current
|
|
32211
32386
|
});
|
|
32212
32387
|
emitEvent({
|
|
32213
32388
|
id: generatePrefixedKSUID12("sevt"),
|
|
@@ -32241,8 +32416,10 @@ function WithdrawModal({
|
|
|
32241
32416
|
const beginJourney = useCallback17(() => {
|
|
32242
32417
|
journeySessionIdRef.current = startSession();
|
|
32243
32418
|
journeyActiveRef.current = true;
|
|
32419
|
+
journeyExternalUserIdRef.current = externalUserId;
|
|
32420
|
+
setUserId(null);
|
|
32244
32421
|
track("widget_opened", { flow_type: "withdraw" });
|
|
32245
|
-
}, [startSession, track]);
|
|
32422
|
+
}, [startSession, track, setUserId, externalUserId]);
|
|
32246
32423
|
const handleClose = useCallback17(() => {
|
|
32247
32424
|
finalizeJourney();
|
|
32248
32425
|
onOpenChange(false);
|
|
@@ -32251,6 +32428,7 @@ function WithdrawModal({
|
|
|
32251
32428
|
setView("form");
|
|
32252
32429
|
setSelectedExecution(null);
|
|
32253
32430
|
setSubmittedTxInfo(null);
|
|
32431
|
+
withdrawDepositWalletIdRef.current = void 0;
|
|
32254
32432
|
setWithdrawDepositWalletId(void 0);
|
|
32255
32433
|
resetViewTimeoutRef.current = null;
|
|
32256
32434
|
}, 200);
|
|
@@ -32268,9 +32446,15 @@ function WithdrawModal({
|
|
|
32268
32446
|
setView("form");
|
|
32269
32447
|
setSelectedExecution(null);
|
|
32270
32448
|
setSubmittedTxInfo(null);
|
|
32449
|
+
withdrawDepositWalletIdRef.current = void 0;
|
|
32271
32450
|
setWithdrawDepositWalletId(void 0);
|
|
32272
32451
|
}, [open]);
|
|
32273
|
-
|
|
32452
|
+
useLayoutEffect4(() => {
|
|
32453
|
+
if (!open || journeyExternalUserIdRef.current === externalUserId) return;
|
|
32454
|
+
journeyExternalUserIdRef.current = externalUserId;
|
|
32455
|
+
setUserId(null);
|
|
32456
|
+
}, [open, externalUserId, setUserId]);
|
|
32457
|
+
useEffect47(
|
|
32274
32458
|
() => () => {
|
|
32275
32459
|
if (journeyActiveRef.current) {
|
|
32276
32460
|
journeyActiveRef.current = false;
|
|
@@ -32279,12 +32463,12 @@ function WithdrawModal({
|
|
|
32279
32463
|
},
|
|
32280
32464
|
[endSession, getSessionId]
|
|
32281
32465
|
);
|
|
32282
|
-
|
|
32466
|
+
useEffect47(() => {
|
|
32283
32467
|
if (!open) return;
|
|
32284
32468
|
const screen = view === "detail" ? "tracker_detail" : view;
|
|
32285
32469
|
track("screen_viewed", { flow_type: "withdraw", screen });
|
|
32286
32470
|
}, [open, view, track]);
|
|
32287
|
-
|
|
32471
|
+
useEffect47(
|
|
32288
32472
|
() => () => {
|
|
32289
32473
|
if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
|
|
32290
32474
|
},
|