@unifold/ui-web 0.1.76 → 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.
Files changed (3) hide show
  1. package/dist/index.js +298 -92
  2. package/dist/index.mjs +298 -92
  3. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -39611,7 +39611,7 @@ __export(index_exports, {
39611
39611
  module.exports = __toCommonJS(index_exports);
39612
39612
 
39613
39613
  // src/unifold.tsx
39614
- var import_react49 = __toESM(require_react());
39614
+ var import_react48 = __toESM(require_react());
39615
39615
  var import_client = __toESM(require_client());
39616
39616
 
39617
39617
  // ../connect-react/dist/index.mjs
@@ -39769,7 +39769,7 @@ function generateKSUID() {
39769
39769
  function generatePrefixedKSUID(prefix) {
39770
39770
  return `${prefix}_${generateKSUID()}`;
39771
39771
  }
39772
- var SDK_VERSION = true ? "0.1.76" : "0.0.0-dev";
39772
+ var SDK_VERSION = true ? "0.1.78" : "0.0.0-dev";
39773
39773
  var CLIENT_VERSION_HEADER = "x-unifold-client-version";
39774
39774
  var CLIENT_USER_AGENT_HEADER = "x-unifold-client-user-agent";
39775
39775
  function detectRuntime() {
@@ -41595,8 +41595,8 @@ var OnrampSessionEventType = ((OnrampSessionEventType2) => {
41595
41595
  })(OnrampSessionEventType || {});
41596
41596
 
41597
41597
  // ../connect-react/dist/index.mjs
41598
- var import_react8 = __toESM(require_react(), 1);
41599
41598
  var import_react_query3 = __toESM(require_modern2(), 1);
41599
+ var import_react8 = __toESM(require_react(), 1);
41600
41600
  var React52 = __toESM(require_react(), 1);
41601
41601
  var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
41602
41602
  var import_react9 = __toESM(require_react(), 1);
@@ -41782,14 +41782,13 @@ var import_jsx_runtime90 = __toESM(require_jsx_runtime(), 1);
41782
41782
  var import_react44 = __toESM(require_react(), 1);
41783
41783
  var import_react_query26 = __toESM(require_modern2(), 1);
41784
41784
  var import_react45 = __toESM(require_react(), 1);
41785
- var import_react46 = __toESM(require_react(), 1);
41786
41785
  var import_react_query27 = __toESM(require_modern2(), 1);
41787
41786
  var import_jsx_runtime91 = __toESM(require_jsx_runtime(), 1);
41788
41787
  var import_jsx_runtime92 = __toESM(require_jsx_runtime(), 1);
41789
- var import_react47 = __toESM(require_react(), 1);
41788
+ var import_react46 = __toESM(require_react(), 1);
41790
41789
  var import_jsx_runtime93 = __toESM(require_jsx_runtime(), 1);
41791
41790
  var import_jsx_runtime94 = __toESM(require_jsx_runtime(), 1);
41792
- var import_react48 = __toESM(require_react(), 1);
41791
+ var import_react47 = __toESM(require_react(), 1);
41793
41792
  var import_jsx_runtime95 = __toESM(require_jsx_runtime(), 1);
41794
41793
  var import_jsx_runtime96 = __toESM(require_jsx_runtime(), 1);
41795
41794
  var __create2 = Object.create;
@@ -47914,7 +47913,7 @@ function generateKSUID2() {
47914
47913
  function generatePrefixedKSUID2(prefix) {
47915
47914
  return `${prefix}_${generateKSUID2()}`;
47916
47915
  }
47917
- var PACKAGE_VERSION = "0.1.76";
47916
+ var PACKAGE_VERSION = "0.1.78";
47918
47917
  var LIBRARY_NAME = "@unifold/analytics";
47919
47918
  var DEFAULT_DEDUP_MS = 500;
47920
47919
  var SESSION_PREFIX = "asess";
@@ -48004,8 +48003,12 @@ var EventTracker = class {
48004
48003
  }
48005
48004
  /**
48006
48005
  * Associate subsequent events with an internal Unifold user.id
48007
- * (`user_<ksuid>`). Pass `null` to clear. Usually called once the
48008
- * deposit-addresses response returns the id.
48006
+ * (`user_<ksuid>`). Pass `null` to clear.
48007
+ *
48008
+ * The tracker is shared across flows and outlives any one journey, so a
48009
+ * journey stamps its own user at the start — with the id if it already
48010
+ * knows one, `null` if it doesn't — rather than inheriting whatever the
48011
+ * previous journey left here.
48009
48012
  */
48010
48013
  setUserId(userId) {
48011
48014
  this.userId = userId || void 0;
@@ -48016,8 +48019,8 @@ var EventTracker = class {
48016
48019
  * {@link EventTracker.endSession} carries it.
48017
48020
  *
48018
48021
  * Does not touch `userId`: the internal `user_<ksuid>` is attached separately
48019
- * via {@link EventTracker.setUserId} once the deposit-addresses response
48020
- * returns, and persists until the host replaces it.
48022
+ * via {@link EventTracker.setUserId}, and persists until the host replaces
48023
+ * it which the SDK's modals do on every journey start.
48021
48024
  */
48022
48025
  startSession() {
48023
48026
  this.sessionId = generatePrefixedKSUID2(SESSION_PREFIX);
@@ -54362,6 +54365,9 @@ var en_default = {
54362
54365
  transactionBreakdown: "Transaction breakdown",
54363
54366
  networkFee: "Network fee",
54364
54367
  confirmOrder: "Confirm Order",
54368
+ mfaEnrollmentTitle: "Enable SMS or Authy 2FA",
54369
+ mfaEnrollmentMessage: "Please make sure you enable SMS or Authy 2FA in your Coinbase account. Press Continue after you enable it.",
54370
+ mfaEnrollmentSettingsLink: "Open Coinbase security settings",
54365
54371
  termsNoticePrefix: "By clicking on Confirm Order, you agree to our ",
54366
54372
  termsNoticeLink: "terms",
54367
54373
  termsNoticeSuffix: "."
@@ -54492,7 +54498,12 @@ var en_default = {
54492
54498
  prefix: "By continuing, you agree to Coinbase's ",
54493
54499
  separator: ", ",
54494
54500
  lastSeparator: ", and ",
54495
- suffix: ". Coinbase is the regulated provider of this fiat-to-crypto onramp."
54501
+ suffix: ".",
54502
+ agreements: {
54503
+ guest_checkout_terms: "Terms of Service",
54504
+ user_agreement: "User Agreement",
54505
+ privacy_policy: "Privacy Policy"
54506
+ }
54496
54507
  },
54497
54508
  errors: {
54498
54509
  rateLimited: "Too many attempts. Please wait a few minutes and try again.",
@@ -55151,6 +55162,9 @@ var zh_default = {
55151
55162
  transactionBreakdown: "\u4EA4\u6613\u660E\u7EC6",
55152
55163
  networkFee: "\u7F51\u7EDC\u624B\u7EED\u8D39",
55153
55164
  confirmOrder: "\u786E\u8BA4\u8BA2\u5355",
55165
+ mfaEnrollmentTitle: "\u8BF7\u542F\u7528\u77ED\u4FE1\u6216 Authy \u53CC\u91CD\u9A8C\u8BC1",
55166
+ 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",
55167
+ mfaEnrollmentSettingsLink: "\u6253\u5F00 Coinbase \u5B89\u5168\u8BBE\u7F6E",
55154
55168
  termsNoticePrefix: "\u70B9\u51FB\u201C\u786E\u8BA4\u8BA2\u5355\u201D\u5373\u8868\u793A\u60A8\u540C\u610F\u6211\u4EEC\u7684",
55155
55169
  termsNoticeLink: "\u6761\u6B3E",
55156
55170
  termsNoticeSuffix: "\u3002"
@@ -55281,7 +55295,12 @@ var zh_default = {
55281
55295
  prefix: "\u7EE7\u7EED\u5373\u8868\u793A\u60A8\u540C\u610F Coinbase \u7684",
55282
55296
  separator: "\u3001",
55283
55297
  lastSeparator: "\u548C",
55284
- suffix: "\u3002Coinbase \u662F\u672C\u6CD5\u5E01\u5151\u52A0\u5BC6\u8D27\u5E01\u5145\u503C\u670D\u52A1\u7684\u53D7\u76D1\u7BA1\u63D0\u4F9B\u65B9\u3002"
55298
+ suffix: "\u3002",
55299
+ agreements: {
55300
+ guest_checkout_terms: "\u670D\u52A1\u6761\u6B3E",
55301
+ user_agreement: "\u7528\u6237\u534F\u8BAE",
55302
+ privacy_policy: "\u9690\u79C1\u653F\u7B56"
55303
+ }
55285
55304
  },
55286
55305
  errors: {
55287
55306
  rateLimited: "\u5C1D\u8BD5\u6B21\u6570\u8FC7\u591A\u3002\u8BF7\u7A0D\u7B49\u51E0\u5206\u949F\u540E\u91CD\u8BD5\u3002",
@@ -55940,6 +55959,9 @@ var zh_TW_default = {
55940
55959
  transactionBreakdown: "\u4EA4\u6613\u660E\u7D30",
55941
55960
  networkFee: "\u7DB2\u8DEF\u624B\u7E8C\u8CBB",
55942
55961
  confirmOrder: "\u78BA\u8A8D\u8A02\u55AE",
55962
+ mfaEnrollmentTitle: "\u8ACB\u555F\u7528\u7C21\u8A0A\u6216 Authy \u96D9\u91CD\u9A57\u8B49",
55963
+ 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",
55964
+ mfaEnrollmentSettingsLink: "\u958B\u555F Coinbase \u5B89\u5168\u8A2D\u5B9A",
55943
55965
  termsNoticePrefix: "\u9EDE\u64CA\u300C\u78BA\u8A8D\u8A02\u55AE\u300D\u5373\u8868\u793A\u60A8\u540C\u610F\u6211\u5011\u7684",
55944
55966
  termsNoticeLink: "\u689D\u6B3E",
55945
55967
  termsNoticeSuffix: "\u3002"
@@ -56070,7 +56092,12 @@ var zh_TW_default = {
56070
56092
  prefix: "\u7E7C\u7E8C\u5373\u8868\u793A\u60A8\u540C\u610F Coinbase \u7684",
56071
56093
  separator: "\u3001",
56072
56094
  lastSeparator: "\u548C",
56073
- suffix: "\u3002Coinbase \u662F\u672C\u6CD5\u5E63\u514C\u52A0\u5BC6\u8CA8\u5E63\u5132\u503C\u670D\u52D9\u7684\u53D7\u76E3\u7BA1\u63D0\u4F9B\u65B9\u3002"
56095
+ suffix: "\u3002",
56096
+ agreements: {
56097
+ guest_checkout_terms: "\u670D\u52D9\u689D\u6B3E",
56098
+ user_agreement: "\u4F7F\u7528\u8005\u5354\u8B70",
56099
+ privacy_policy: "\u96B1\u79C1\u6B0A\u653F\u7B56"
56100
+ }
56074
56101
  },
56075
56102
  errors: {
56076
56103
  rateLimited: "\u5617\u8A66\u6B21\u6578\u904E\u591A\u3002\u8ACB\u7A0D\u7B49\u5E7E\u5206\u9418\u5F8C\u91CD\u8A66\u3002",
@@ -56985,6 +57012,13 @@ function useAnalytics() {
56985
57012
  );
56986
57013
  return { track, startSession, endSession, getSessionId, setUserId, subscribe };
56987
57014
  }
57015
+ function useStampInternalUserId({ internalUserId }) {
57016
+ const { setUserId } = useAnalytics();
57017
+ (0, import_react8.useEffect)(() => {
57018
+ if (!internalUserId) return;
57019
+ setUserId(internalUserId);
57020
+ }, [internalUserId, setUserId]);
57021
+ }
56988
57022
  function useDepositAddress(params) {
56989
57023
  const {
56990
57024
  userId,
@@ -56997,7 +57031,6 @@ function useDepositAddress(params) {
56997
57031
  contractCalls,
56998
57032
  enabled = true
56999
57033
  } = params;
57000
- const { setUserId } = useAnalytics();
57001
57034
  const query = (0, import_react_query3.useQuery)({
57002
57035
  queryKey: [
57003
57036
  "unifold",
@@ -57040,11 +57073,7 @@ function useDepositAddress(params) {
57040
57073
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
57041
57074
  // 1s, 2s, 4s (max 10s)
57042
57075
  });
57043
- (0, import_react8.useEffect)(() => {
57044
- if (query.data?.user_id) {
57045
- setUserId(query.data.user_id);
57046
- }
57047
- }, [query.data?.user_id, setUserId]);
57076
+ useStampInternalUserId({ internalUserId: query.data?.user_id });
57048
57077
  return query;
57049
57078
  }
57050
57079
  function useDebounce(value, delay) {
@@ -59246,6 +59275,10 @@ function BuyWithCard({
59246
59275
  wallet_address: wallet.address,
59247
59276
  subdivision_code: userIpInfo?.subdivisionCode || void 0,
59248
59277
  external_id: externalId,
59278
+ // The rail this quote was priced for, so the provider opens on it. Most
59279
+ // are `card`, which is also the server default, but a local rail (e.g.
59280
+ // `upi` in India) is the whole reason its provider was quoted.
59281
+ payment_method_type: selectedProvider.payment_method_type,
59249
59282
  // Exactly one of source_amount / destination_amount (mutually exclusive):
59250
59283
  // destination mode starts the session by the fixed crypto amount (fees on
59251
59284
  // top); otherwise by the entered fiat amount.
@@ -59263,7 +59296,11 @@ function BuyWithCard({
59263
59296
  method: "card",
59264
59297
  flow_type: "deposit",
59265
59298
  provider: selectedProvider.service_provider,
59266
- amount_usd: amount
59299
+ amount_usd: amount,
59300
+ // The execution only exists once the provider's payout lands on this
59301
+ // wallet, and it carries this id — so it's the join key for a purchase
59302
+ // that starts here and never reaches flow_completed.
59303
+ deposit_wallet_id: depositWalletId
59267
59304
  });
59268
59305
  onEvent?.({
59269
59306
  id: generatePrefixedKSUID("sevt"),
@@ -60700,6 +60737,8 @@ var BuyWithWalletPay = React82.forwardRef(
60700
60737
  const [limitUpgradeError, setLimitUpgradeError] = (0, import_react16.useState)(null);
60701
60738
  const [upgradeSubmitting, setUpgradeSubmitting] = (0, import_react16.useState)(false);
60702
60739
  const upgradeFlowAbortRef = (0, import_react16.useRef)(null);
60740
+ const applyLimitRoutingRef = (0, import_react16.useRef)(() => {
60741
+ });
60703
60742
  const [amount, setAmount] = (0, import_react16.useState)(amountUsd ?? "");
60704
60743
  const [preparedOrder, setPreparedOrder] = (0, import_react16.useState)(null);
60705
60744
  const sessionAbortRef = (0, import_react16.useRef)(null);
@@ -60834,6 +60873,14 @@ var BuyWithWalletPay = React82.forwardRef(
60834
60873
  },
60835
60874
  [email, normalizedPhone, userId]
60836
60875
  );
60876
+ const { action: initialAction, refetchWalletPayLimits } = useWalletPayInitialScreen({
60877
+ userId,
60878
+ publishableKey,
60879
+ normalizedPhone,
60880
+ userEmail,
60881
+ sessionPhoneVerified: verificationSession?.phone?.status === "verified",
60882
+ isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
60883
+ });
60837
60884
  const createSessionAndSendOtp = (0, import_react16.useCallback)(async () => {
60838
60885
  setView("submitting_session");
60839
60886
  setErrorMessage("");
@@ -60843,7 +60890,12 @@ var BuyWithWalletPay = React82.forwardRef(
60843
60890
  email,
60844
60891
  phone: normalizedPhone,
60845
60892
  terms_accepted: true,
60846
- email_already_verified: true
60893
+ // TODO: when the API honors `false`, this will trigger email OTP.
60894
+ // Today `false` still skips email (we don't verify it) and JWT ev
60895
+ // is null. Don't send `true` — that was a fake attest.
60896
+ email_already_verified: false
60897
+ // Coinbase stays Redis-only + JWT until bank-transfer identity
60898
+ // is live. Do not persist from this path yet.
60847
60899
  },
60848
60900
  publishableKey
60849
60901
  );
@@ -60853,6 +60905,34 @@ var BuyWithWalletPay = React82.forwardRef(
60853
60905
  }
60854
60906
  setClientSecret(session.client_secret);
60855
60907
  storeWalletPaySession();
60908
+ if (session.status === "verified") {
60909
+ const tokenRes = await exchangeOnrampVerificationToken(
60910
+ session.id,
60911
+ session.client_secret,
60912
+ publishableKey
60913
+ );
60914
+ setOnrampToken(tokenRes);
60915
+ storeWalletPaySession({
60916
+ emailVerifiedAt: session.email.verified_at,
60917
+ phoneVerifiedAt: session.phone.verified_at,
60918
+ onrampToken: tokenRes.token,
60919
+ onrampTokenExpiresAtMs: Date.now() + tokenRes.expires_in * 1e3
60920
+ });
60921
+ if (amountUsd) setAmount(amountUsd);
60922
+ try {
60923
+ const result = await refetchWalletPayLimits();
60924
+ if (result.data) {
60925
+ const nextView = getViewForLimitStatus(result.data);
60926
+ if (nextView) {
60927
+ applyLimitRoutingRef.current(nextView, result.data.upgrade_status);
60928
+ return;
60929
+ }
60930
+ }
60931
+ } catch {
60932
+ }
60933
+ setView("amount");
60934
+ return;
60935
+ }
60856
60936
  await sendOnrampVerificationOtp(session.id, "phone", session.client_secret, publishableKey);
60857
60937
  setResendCooldown(30);
60858
60938
  setView("phone_otp");
@@ -60861,19 +60941,19 @@ var BuyWithWalletPay = React82.forwardRef(
60861
60941
  setErrorMessage(prettifyVerificationError(raw));
60862
60942
  setView("phone_input");
60863
60943
  }
60864
- }, [email, normalizedPhone, publishableKey, storeWalletPaySession]);
60944
+ }, [
60945
+ email,
60946
+ normalizedPhone,
60947
+ publishableKey,
60948
+ storeWalletPaySession,
60949
+ userId,
60950
+ amountUsd,
60951
+ refetchWalletPayLimits
60952
+ ]);
60865
60953
  const clearUpgradeFields = (0, import_react16.useCallback)(() => {
60866
60954
  setSsnLast4("");
60867
60955
  setDobInput("");
60868
60956
  }, []);
60869
- const { action: initialAction, refetchWalletPayLimits } = useWalletPayInitialScreen({
60870
- userId,
60871
- publishableKey,
60872
- normalizedPhone,
60873
- userEmail,
60874
- sessionPhoneVerified: verificationSession?.phone?.status === "verified",
60875
- isWaiting: defaultTokenLoading || legalAgreementsLoading || userIpInfoLoading
60876
- });
60877
60957
  const pollLimitUpgradeStatus = (0, import_react16.useCallback)(
60878
60958
  async (signal) => {
60879
60959
  const POLL_INTERVAL_MS5 = 1500;
@@ -60984,6 +61064,7 @@ var BuyWithWalletPay = React82.forwardRef(
60984
61064
  },
60985
61065
  [startUpgradePolling]
60986
61066
  );
61067
+ applyLimitRoutingRef.current = applyLimitRouting;
60987
61068
  const hasInitializedRef = (0, import_react16.useRef)(false);
60988
61069
  (0, import_react16.useEffect)(() => {
60989
61070
  if (hasInitializedRef.current) return;
@@ -61213,7 +61294,10 @@ var BuyWithWalletPay = React82.forwardRef(
61213
61294
  track("flow_started", {
61214
61295
  method,
61215
61296
  flow_type: "deposit",
61216
- amount_usd: walletPayAmountUsd
61297
+ amount_usd: walletPayAmountUsd,
61298
+ // No execution yet — one appears when the payout lands on this
61299
+ // wallet, carrying the same id.
61300
+ deposit_wallet_id: depositWalletId
61217
61301
  });
61218
61302
  onEvent?.({
61219
61303
  id: generatePrefixedKSUID("sevt"),
@@ -61263,6 +61347,7 @@ var BuyWithWalletPay = React82.forwardRef(
61263
61347
  defaultTokenLoading,
61264
61348
  defaultTokenError,
61265
61349
  depositWallet?.address,
61350
+ depositWalletId,
61266
61351
  userEmail,
61267
61352
  publishableKey,
61268
61353
  onEvent,
@@ -62237,7 +62322,7 @@ var FALLBACK_AGREEMENTS = [
62237
62322
  {
62238
62323
  key: "guest_checkout_terms",
62239
62324
  name: "Guest Checkout Terms of Service",
62240
- url: "https://www.coinbase.com/legal/cb-pay/onramp-guest-checkout-terms"
62325
+ url: "https://www.coinbase.com/legal/guest-checkout/us"
62241
62326
  },
62242
62327
  {
62243
62328
  key: "user_agreement",
@@ -62257,22 +62342,24 @@ function LegalDisclaimer({ legalAgreements, loading }) {
62257
62342
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
62258
62343
  "div",
62259
62344
  {
62260
- className: "uf-mt-3 uf-mb-3 uf-px-1 uf-space-y-1.5 uf-animate-pulse",
62345
+ className: "uf-mt-3 uf-mb-3 uf-px-1 uf-space-y-1.5 uf-animate-pulse uf-opacity-50",
62261
62346
  "aria-hidden": true,
62262
62347
  "aria-busy": "true",
62263
62348
  children: [
62264
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "uf-h-2.5 uf-rounded uf-w-full", style: { backgroundColor: colors2.card } }),
62265
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "uf-h-2.5 uf-rounded uf-w-11/12", style: { backgroundColor: colors2.card } }),
62266
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "uf-h-2.5 uf-rounded uf-w-3/4", style: { backgroundColor: colors2.card } })
62349
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "uf-h-2 uf-rounded uf-w-full", style: { backgroundColor: colors2.card } }),
62350
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "uf-h-2 uf-rounded uf-w-11/12", style: { backgroundColor: colors2.card } }),
62351
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "uf-h-2 uf-rounded uf-w-3/4", style: { backgroundColor: colors2.card } })
62267
62352
  ]
62268
62353
  }
62269
62354
  );
62270
62355
  }
62271
62356
  const agreements = legalAgreements?.agreements ?? FALLBACK_AGREEMENTS;
62357
+ const shortLabels = t.agreements;
62358
+ const lastSeparator = t.lastSeparator.replace(/\s+$/, "\xA0");
62272
62359
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
62273
62360
  "p",
62274
62361
  {
62275
- className: "uf-text-[11px] uf-leading-relaxed uf-mt-3 uf-mb-3 uf-px-1",
62362
+ className: "uf-text-[10px] uf-leading-relaxed uf-mt-3 uf-mb-3 uf-opacity-60 uf-text-center",
62276
62363
  style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
62277
62364
  children: [
62278
62365
  t.prefix,
@@ -62283,12 +62370,12 @@ function LegalDisclaimer({ legalAgreements, loading }) {
62283
62370
  href: a.url,
62284
62371
  target: "_blank",
62285
62372
  rel: "noopener noreferrer",
62286
- className: "uf-underline",
62287
- style: { color: colors2.foreground },
62288
- children: a.name
62373
+ className: "uf-no-underline",
62374
+ style: { color: "inherit", textDecoration: "none", whiteSpace: "nowrap" },
62375
+ children: shortLabels[a.key] ?? a.name
62289
62376
  }
62290
62377
  ),
62291
- idx < arr.length - 2 ? t.separator : idx === arr.length - 2 ? t.lastSeparator : ""
62378
+ idx < arr.length - 2 ? t.separator : idx === arr.length - 2 ? lastSeparator : ""
62292
62379
  ] }, a.key)),
62293
62380
  t.suffix
62294
62381
  ]
@@ -62931,6 +63018,7 @@ function PayWithCashApp({
62931
63018
  destinationChainType,
62932
63019
  destinationChainId,
62933
63020
  destinationTokenAddress,
63021
+ contractCalls,
62934
63022
  cashAppIconUrl,
62935
63023
  view: controlledView,
62936
63024
  onViewChange,
@@ -63023,7 +63111,8 @@ function PayWithCashApp({
63023
63111
  destination_token_address: destinationTokenAddress,
63024
63112
  recipient_address: recipientAddress,
63025
63113
  source_amount: amount,
63026
- external_id: externalId
63114
+ external_id: externalId,
63115
+ ...contractCalls?.length ? { contract_calls: contractCalls } : {}
63027
63116
  },
63028
63117
  publishableKey
63029
63118
  );
@@ -63036,7 +63125,10 @@ function PayWithCashApp({
63036
63125
  track("flow_started", {
63037
63126
  method: "cashapp",
63038
63127
  flow_type: "deposit",
63039
- amount_usd: amount
63128
+ amount_usd: amount,
63129
+ // No execution yet — one appears when the payout lands on this
63130
+ // wallet, carrying the same id.
63131
+ deposit_wallet_id: depositWalletId
63040
63132
  });
63041
63133
  onEvent?.({
63042
63134
  id: generatePrefixedKSUID("sevt"),
@@ -63061,6 +63153,8 @@ function PayWithCashApp({
63061
63153
  destinationChainType,
63062
63154
  destinationChainId,
63063
63155
  destinationTokenAddress,
63156
+ contractCalls,
63157
+ depositWalletId,
63064
63158
  onEvent,
63065
63159
  onDepositError,
63066
63160
  track,
@@ -63662,7 +63756,10 @@ function BankTransfer({
63662
63756
  method: "bank_transfer",
63663
63757
  flow_type: "deposit",
63664
63758
  provider: request.service_provider,
63665
- amount_usd: request.source_amount
63759
+ amount_usd: request.source_amount,
63760
+ // No execution yet — one appears when the provider's payout lands on
63761
+ // this wallet, carrying the same id.
63762
+ deposit_wallet_id: pollingWalletId
63666
63763
  });
63667
63764
  onEvent?.({
63668
63765
  id: generatePrefixedKSUID("sevt"),
@@ -69743,7 +69840,11 @@ function PayWithStripeLink({
69743
69840
  if (checkoutResult.successful) {
69744
69841
  handledTerminalSessionRef.current = null;
69745
69842
  executionReconciledSessionRef.current = null;
69746
- track("flow_started", { method: "stripe_link", flow_type: "deposit" });
69843
+ track("flow_started", {
69844
+ method: "stripe_link",
69845
+ flow_type: "deposit",
69846
+ deposit_wallet_id: depositWalletId
69847
+ });
69747
69848
  setConfirmedSessionId(activeSessionId);
69748
69849
  setSessionStatus(STRIPE_SESSION_STATUS.FULFILLMENT_PROCESSING);
69749
69850
  if (selectedTokenSingleUseRef.current) clearSelectedPaymentToken();
@@ -71240,7 +71341,14 @@ function PayWithStripeLink({
71240
71341
  ]
71241
71342
  }
71242
71343
  ),
71243
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { ref: authMountRef, className: "uf-w-full uf-min-h-[200px]" })
71344
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
71345
+ "div",
71346
+ {
71347
+ ref: authMountRef,
71348
+ className: "uf-w-full uf-min-h-[200px]",
71349
+ style: { colorScheme: "only light" }
71350
+ }
71351
+ )
71244
71352
  ]
71245
71353
  }
71246
71354
  );
@@ -72503,6 +72611,9 @@ function CoinbaseConnect({
72503
72611
  flow_type: "deposit",
72504
72612
  method: "exchange_connect",
72505
72613
  provider: IntegrationProvider.COINBASE,
72614
+ // No execution yet — one appears when the exchange's transfer lands on
72615
+ // this wallet, carrying the same id.
72616
+ deposit_wallet_id: transferDepositWalletId,
72506
72617
  amount_usd: sendAmount || void 0,
72507
72618
  currency: selectedAsset?.currency.toLowerCase().replace(/[^a-z0-9]+/g, "_"),
72508
72619
  chain: sourceChain?.chain_id,
@@ -72510,6 +72621,34 @@ function CoinbaseConnect({
72510
72621
  network: sourceChain?.network
72511
72622
  });
72512
72623
  };
72624
+ const applyConfirmResult = (result) => {
72625
+ if (result.status === "mfa_required") {
72626
+ track("verification_started", {
72627
+ flow_type: "deposit",
72628
+ method: "exchange_connect",
72629
+ provider: IntegrationProvider.COINBASE,
72630
+ verification_type: "mfa",
72631
+ verification_status: result.status
72632
+ });
72633
+ transitionTo("mfa");
72634
+ setMfaCode("");
72635
+ setMfaError(false);
72636
+ } else if (result.status === "mfa_enrollment_required") {
72637
+ transitionTo("mfa_enrollment");
72638
+ } else if (result.status === "completed") {
72639
+ trackTransferStarted();
72640
+ setConfirmResult(result);
72641
+ transitionTo("success");
72642
+ onTransferSuccess?.(result);
72643
+ } else {
72644
+ setErrorMessage(result.message || t.errors.transferFailed);
72645
+ transitionTo("error");
72646
+ onTransferError?.({
72647
+ message: result.message || t.errors.transferFailed,
72648
+ code: result.status
72649
+ });
72650
+ }
72651
+ };
72513
72652
  const handleConfirmTransfer = async () => {
72514
72653
  if (!transferIntent || !accessToken) return;
72515
72654
  setIsLoading(true);
@@ -72544,30 +72683,7 @@ function CoinbaseConnect({
72544
72683
  });
72545
72684
  throw err;
72546
72685
  });
72547
- if (result.status === "mfa_required") {
72548
- track("verification_started", {
72549
- flow_type: "deposit",
72550
- method: "exchange_connect",
72551
- provider: IntegrationProvider.COINBASE,
72552
- verification_type: "mfa",
72553
- verification_status: result.status
72554
- });
72555
- transitionTo("mfa");
72556
- setMfaCode("");
72557
- setMfaError(false);
72558
- } else if (result.status === "completed") {
72559
- trackTransferStarted();
72560
- setConfirmResult(result);
72561
- transitionTo("success");
72562
- onTransferSuccess?.(result);
72563
- } else {
72564
- setErrorMessage(result.message || t.errors.transferFailed);
72565
- transitionTo("error");
72566
- onTransferError?.({
72567
- message: result.message || t.errors.transferFailed,
72568
- code: result.status
72569
- });
72570
- }
72686
+ applyConfirmResult(result);
72571
72687
  } catch (err) {
72572
72688
  const message = err instanceof Error ? err.message : t.errors.transferFailed;
72573
72689
  setErrorMessage(message);
@@ -72724,6 +72840,9 @@ function CoinbaseConnect({
72724
72840
  setShowTransferDetails(false);
72725
72841
  transitionTo("enter_amount");
72726
72842
  break;
72843
+ case "mfa_enrollment":
72844
+ transitionTo("transfer_confirm");
72845
+ break;
72727
72846
  case "mfa":
72728
72847
  transitionTo("transfer_confirm");
72729
72848
  break;
@@ -74280,6 +74399,55 @@ function CoinbaseConnect({
74280
74399
  ] })
74281
74400
  ] });
74282
74401
  }
74402
+ if (view === "mfa_enrollment") {
74403
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
74404
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(DepositHeader, { title: t.title, showBack: true, onBack: handleBack, onClose }),
74405
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
74406
+ "div",
74407
+ {
74408
+ className: "uf-flex uf-flex-col uf-items-center uf-px-4 uf-pb-4",
74409
+ style: viewTransitionStyle,
74410
+ children: [
74411
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
74412
+ DepositErrorState,
74413
+ {
74414
+ title: t.transfer.mfaEnrollmentTitle,
74415
+ message: t.transfer.mfaEnrollmentMessage
74416
+ }
74417
+ ),
74418
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
74419
+ "a",
74420
+ {
74421
+ href: "https://www.coinbase.com/settings/security",
74422
+ target: "_blank",
74423
+ rel: "noopener noreferrer",
74424
+ className: "uf-text-sm uf-underline uf-mb-8 uf-inline-flex uf-items-center uf-gap-1",
74425
+ style: { color: colors2.primary, fontFamily: fonts.medium },
74426
+ children: [
74427
+ t.transfer.mfaEnrollmentSettingsLink,
74428
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(ExternalLink, { className: "uf-w-3.5 uf-h-3.5" })
74429
+ ]
74430
+ }
74431
+ ),
74432
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
74433
+ "button",
74434
+ {
74435
+ onClick: handleConfirmTransfer,
74436
+ disabled: isLoading,
74437
+ 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",
74438
+ style: {
74439
+ backgroundColor: colors2.primary,
74440
+ color: "#fff",
74441
+ fontFamily: fonts.medium
74442
+ },
74443
+ children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin" }) : t.continue
74444
+ }
74445
+ )
74446
+ ]
74447
+ }
74448
+ )
74449
+ ] });
74450
+ }
74283
74451
  if (view === "mfa") {
74284
74452
  return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
74285
74453
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(DepositHeader, { title: t.title, showBack: true, onBack: handleBack, onClose }),
@@ -80207,7 +80375,11 @@ function WalletConnect({
80207
80375
  chain: String(token.chain_id),
80208
80376
  network: token.network,
80209
80377
  token: token.symbol ?? token.token_address,
80210
- currency: token.currency
80378
+ currency: token.currency,
80379
+ // No execution exists yet — it's created when this send lands on the
80380
+ // wallet. The wallet id is what that execution will carry, so it's
80381
+ // how a send that never completes is matched to what followed.
80382
+ deposit_wallet_id: activeDepositWallet?.id
80211
80383
  });
80212
80384
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
80213
80385
  setHasSignedTransaction(true);
@@ -80794,7 +80966,7 @@ function DepositModal({
80794
80966
  const applePaySubTitle = applePaySubTitleProp ?? t.applePayMenu.subtitle;
80795
80967
  const googlePayTitle = googlePayTitleProp ?? t.googlePayMenu.title;
80796
80968
  const googlePaySubTitle = googlePaySubTitleProp ?? t.googlePayMenu.subtitle;
80797
- const { track, startSession, endSession, getSessionId, subscribe } = useAnalytics();
80969
+ const { track, startSession, endSession, getSessionId, setUserId, subscribe } = useAnalytics();
80798
80970
  const normalizedPrefilledAmountUsd = (0, import_react3.useMemo)(
80799
80971
  () => normalizePrefilledUsdAmount(prefilledAmountUsd),
80800
80972
  [prefilledAmountUsd]
@@ -80802,6 +80974,7 @@ function DepositModal({
80802
80974
  const analyticsMethod = (method) => method === "transfer" ? "transfer_crypto" : method;
80803
80975
  const journeyActiveRef = (0, import_react3.useRef)(false);
80804
80976
  const journeySessionIdRef = (0, import_react3.useRef)(void 0);
80977
+ const journeyExternalUserIdRef = (0, import_react3.useRef)(void 0);
80805
80978
  const externalUserId = userId || void 0;
80806
80979
  const emitEvent = (0, import_react3.useCallback)(
80807
80980
  (event) => onEvent?.({ ...event, externalUserId }),
@@ -80829,6 +81002,9 @@ function DepositModal({
80829
81002
  method: analyticsMethod(method),
80830
81003
  flow_type: "deposit",
80831
81004
  amount_usd: execution?.destinationAmountUsd ?? execution?.sourceAmountUsd,
81005
+ // The one high-cardinality field we do send: the join key from a
81006
+ // funnel session back to the execution row it produced.
81007
+ execution_id: data.executionId ?? execution?.id,
80832
81008
  // Flat, low-cardinality execution dimensions for PostHog breakdowns
80833
81009
  // (precise/opaque fields like base units, addresses, tx hashes live in
80834
81010
  // the onEvent DirectExecution instead).
@@ -80856,6 +81032,7 @@ function DepositModal({
80856
81032
  method: analyticsMethod(method),
80857
81033
  flow_type: "deposit",
80858
81034
  error_code: error.code,
81035
+ execution_id: execution?.id,
80859
81036
  failure_reason: execution?.failureReason ?? void 0,
80860
81037
  status: execution?.status,
80861
81038
  source_chain_type: execution?.sourceChainType,
@@ -81284,8 +81461,10 @@ function DepositModal({
81284
81461
  const beginJourney = (0, import_react3.useCallback)(() => {
81285
81462
  journeySessionIdRef.current = startSession();
81286
81463
  journeyActiveRef.current = true;
81464
+ journeyExternalUserIdRef.current = userId;
81465
+ setUserId(null);
81287
81466
  track("widget_opened", { flow_type: "deposit" });
81288
- }, [startSession, track]);
81467
+ }, [startSession, track, setUserId, userId]);
81289
81468
  const handleClose = () => {
81290
81469
  finalizeJourney();
81291
81470
  onOpenChange(false);
@@ -81310,6 +81489,11 @@ function DepositModal({
81310
81489
  }
81311
81490
  beginJourney();
81312
81491
  }, [open]);
81492
+ (0, import_react3.useLayoutEffect)(() => {
81493
+ if (!open || journeyExternalUserIdRef.current === userId) return;
81494
+ journeyExternalUserIdRef.current = userId;
81495
+ setUserId(null);
81496
+ }, [open, userId, setUserId]);
81313
81497
  (0, import_react3.useLayoutEffect)(() => {
81314
81498
  if (!open) return;
81315
81499
  if (resetViewTimeoutRef.current) {
@@ -82221,6 +82405,7 @@ function DepositModal({
82221
82405
  destinationChainType,
82222
82406
  destinationChainId,
82223
82407
  destinationTokenAddress,
82408
+ contractCalls,
82224
82409
  cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
82225
82410
  view: cashAppView,
82226
82411
  onViewChange: setCashAppView,
@@ -82556,6 +82741,9 @@ function CheckoutModal({
82556
82741
  flowCompletedRef.current = true;
82557
82742
  track("flow_completed", {
82558
82743
  flow_type: "checkout",
82744
+ // Checkout has no direct execution; the intent is what a funnel
82745
+ // session joins back to.
82746
+ payment_intent_id: data.paymentIntentId,
82559
82747
  ...method ? { method: method === "transfer" ? "transfer_crypto" : method } : {}
82560
82748
  });
82561
82749
  }
@@ -82776,7 +82964,7 @@ function CheckoutModal({
82776
82964
  journeySessionIdRef.current = startSession();
82777
82965
  journeyActiveRef.current = true;
82778
82966
  flowCompletedRef.current = false;
82779
- setUserId(null);
82967
+ setUserId(paymentIntentUserId ?? null);
82780
82968
  track("widget_opened", { flow_type: "checkout" });
82781
82969
  if (resetViewTimeoutRef.current) {
82782
82970
  clearTimeout(resetViewTimeoutRef.current);
@@ -83361,7 +83549,7 @@ function useAddressBalance(params) {
83361
83549
  }
83362
83550
  function useExecutions(userId, publishableKey, options2) {
83363
83551
  const actionType = options2?.actionType ?? ActionType.Deposit;
83364
- return (0, import_react_query25.useQuery)({
83552
+ const query = (0, import_react_query25.useQuery)({
83365
83553
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
83366
83554
  queryFn: () => queryExecutions(userId, publishableKey, actionType),
83367
83555
  enabled: (options2?.enabled ?? true) && !!userId,
@@ -83370,6 +83558,8 @@ function useExecutions(userId, publishableKey, options2) {
83370
83558
  gcTime: 1e3 * 60 * 5,
83371
83559
  refetchOnWindowFocus: false
83372
83560
  });
83561
+ useStampInternalUserId({ internalUserId: query.data?.data[0]?.user_id });
83562
+ return query;
83373
83563
  }
83374
83564
  var POLL_INTERVAL_MS4 = 2500;
83375
83565
  var POLL_ENDPOINT_INTERVAL_MS2 = 5e3;
@@ -83744,7 +83934,6 @@ function useGetDepositAddress(params) {
83744
83934
  actionType,
83745
83935
  enabled = true
83746
83936
  } = params;
83747
- const { setUserId } = useAnalytics();
83748
83937
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
83749
83938
  const query = (0, import_react_query27.useQuery)({
83750
83939
  queryKey: [
@@ -83776,11 +83965,7 @@ function useGetDepositAddress(params) {
83776
83965
  refetchOnWindowFocus: false,
83777
83966
  retry: 1
83778
83967
  });
83779
- (0, import_react46.useEffect)(() => {
83780
- if (query.data?.user_id) {
83781
- setUserId(query.data.user_id);
83782
- }
83783
- }, [query.data?.user_id, setUserId]);
83968
+ useStampInternalUserId({ internalUserId: query.data?.user_id });
83784
83969
  return query;
83785
83970
  }
83786
83971
  var isHypercore = (chainId) => chainId === HYPERCORE_CHAIN_ID;
@@ -84730,9 +84915,9 @@ function WithdrawConfirmingView({
84730
84915
  const { colors: colors2, fonts, components } = useTheme();
84731
84916
  const { t: strings } = useI18n();
84732
84917
  const t = strings.withdrawModal.details;
84733
- const [showButton, setShowButton] = (0, import_react47.useState)(false);
84918
+ const [showButton, setShowButton] = (0, import_react46.useState)(false);
84734
84919
  const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
84735
- (0, import_react47.useEffect)(() => {
84920
+ (0, import_react46.useEffect)(() => {
84736
84921
  if (latestExecution) return;
84737
84922
  const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
84738
84923
  return () => clearTimeout(timer);
@@ -84901,12 +85086,16 @@ function WithdrawModal({
84901
85086
  );
84902
85087
  const journeyActiveRef = (0, import_react42.useRef)(false);
84903
85088
  const journeySessionIdRef = (0, import_react42.useRef)(void 0);
85089
+ const journeyExternalUserIdRef = (0, import_react42.useRef)(void 0);
84904
85090
  const onWithdrawSuccessFor = (0, import_react42.useCallback)(
84905
85091
  (data) => {
84906
85092
  const execution = data.execution?.data.object;
84907
85093
  track("flow_completed", {
84908
85094
  flow_type: "withdraw",
84909
85095
  amount_usd: execution?.destinationAmountUsd ?? execution?.sourceAmountUsd,
85096
+ // The one high-cardinality field we do send: the join key from a
85097
+ // funnel session back to the execution row it produced.
85098
+ execution_id: data.executionId ?? execution?.id,
84910
85099
  // Flat, low-cardinality execution dimensions for PostHog breakdowns.
84911
85100
  status: execution?.status,
84912
85101
  source_chain_type: execution?.sourceChainType,
@@ -84927,6 +85116,7 @@ function WithdrawModal({
84927
85116
  track("flow_failed", {
84928
85117
  flow_type: "withdraw",
84929
85118
  error_code: error.code,
85119
+ execution_id: execution?.id,
84930
85120
  failure_reason: execution?.failureReason ?? void 0,
84931
85121
  status: execution?.status,
84932
85122
  source_chain_type: execution?.sourceChainType,
@@ -85000,6 +85190,7 @@ function WithdrawModal({
85000
85190
  ) ?? null : null;
85001
85191
  const [view, setView] = (0, import_react42.useState)("form");
85002
85192
  const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react42.useState)();
85193
+ const withdrawDepositWalletIdRef = (0, import_react42.useRef)(void 0);
85003
85194
  const [selectedExecution, setSelectedExecution] = (0, import_react42.useState)(null);
85004
85195
  const [submittedTxInfo, setSubmittedTxInfo] = (0, import_react42.useState)(null);
85005
85196
  const { executions: realtimeExecutions } = useWithdrawPolling({
@@ -85037,6 +85228,7 @@ function WithdrawModal({
85037
85228
  if (!depositWallet) {
85038
85229
  throw new Error(`No deposit wallet available for ${sourceChainType}`);
85039
85230
  }
85231
+ withdrawDepositWalletIdRef.current = depositWallet.id;
85040
85232
  setWithdrawDepositWalletId(depositWallet.id);
85041
85233
  return depositWallet;
85042
85234
  },
@@ -85056,7 +85248,12 @@ function WithdrawModal({
85056
85248
  currency: tokenData?.currency,
85057
85249
  amount: txInfo.amount,
85058
85250
  amount_base_unit: txInfo.amountBaseUnit,
85059
- ...txInfo.amountUsd ? { amount_usd: txInfo.amountUsd } : {}
85251
+ ...txInfo.amountUsd ? { amount_usd: txInfo.amountUsd } : {},
85252
+ // The execution doesn't exist yet — it's created when the user's send
85253
+ // lands on the withdraw deposit wallet, and carries this id. So a
85254
+ // withdrawal confirmed but never completed still joins to whatever
85255
+ // did (or didn't) follow on that wallet.
85256
+ deposit_wallet_id: withdrawDepositWalletIdRef.current
85060
85257
  });
85061
85258
  emitEvent({
85062
85259
  id: generatePrefixedKSUID("sevt"),
@@ -85090,8 +85287,10 @@ function WithdrawModal({
85090
85287
  const beginJourney = (0, import_react42.useCallback)(() => {
85091
85288
  journeySessionIdRef.current = startSession();
85092
85289
  journeyActiveRef.current = true;
85290
+ journeyExternalUserIdRef.current = externalUserId;
85291
+ setUserId(null);
85093
85292
  track("widget_opened", { flow_type: "withdraw" });
85094
- }, [startSession, track]);
85293
+ }, [startSession, track, setUserId, externalUserId]);
85095
85294
  const handleClose = (0, import_react42.useCallback)(() => {
85096
85295
  finalizeJourney();
85097
85296
  onOpenChange(false);
@@ -85100,6 +85299,7 @@ function WithdrawModal({
85100
85299
  setView("form");
85101
85300
  setSelectedExecution(null);
85102
85301
  setSubmittedTxInfo(null);
85302
+ withdrawDepositWalletIdRef.current = void 0;
85103
85303
  setWithdrawDepositWalletId(void 0);
85104
85304
  resetViewTimeoutRef.current = null;
85105
85305
  }, 200);
@@ -85117,8 +85317,14 @@ function WithdrawModal({
85117
85317
  setView("form");
85118
85318
  setSelectedExecution(null);
85119
85319
  setSubmittedTxInfo(null);
85320
+ withdrawDepositWalletIdRef.current = void 0;
85120
85321
  setWithdrawDepositWalletId(void 0);
85121
85322
  }, [open]);
85323
+ (0, import_react42.useLayoutEffect)(() => {
85324
+ if (!open || journeyExternalUserIdRef.current === externalUserId) return;
85325
+ journeyExternalUserIdRef.current = externalUserId;
85326
+ setUserId(null);
85327
+ }, [open, externalUserId, setUserId]);
85122
85328
  (0, import_react42.useEffect)(
85123
85329
  () => () => {
85124
85330
  if (journeyActiveRef.current) {
@@ -85804,9 +86010,9 @@ function useUnifold2() {
85804
86010
  }
85805
86011
 
85806
86012
  // src/unifold.tsx
85807
- var UnifoldBridge = (0, import_react49.forwardRef)((_, ref) => {
86013
+ var UnifoldBridge = (0, import_react48.forwardRef)((_, ref) => {
85808
86014
  const { beginDeposit, closeDeposit, beginWithdraw, closeWithdraw } = useUnifold2();
85809
- (0, import_react49.useImperativeHandle)(ref, () => ({ beginDeposit, closeDeposit, beginWithdraw, closeWithdraw }), [
86015
+ (0, import_react48.useImperativeHandle)(ref, () => ({ beginDeposit, closeDeposit, beginWithdraw, closeWithdraw }), [
85810
86016
  beginDeposit,
85811
86017
  closeDeposit,
85812
86018
  beginWithdraw,
@@ -85815,7 +86021,7 @@ var UnifoldBridge = (0, import_react49.forwardRef)((_, ref) => {
85815
86021
  return null;
85816
86022
  });
85817
86023
  UnifoldBridge.displayName = "UnifoldBridge";
85818
- var RenderErrorBoundary = class extends import_react49.Component {
86024
+ var RenderErrorBoundary = class extends import_react48.Component {
85819
86025
  constructor() {
85820
86026
  super(...arguments);
85821
86027
  this.state = { hasError: false };
@@ -85887,13 +86093,13 @@ function createUnifold(publishableKey, config) {
85887
86093
  };
85888
86094
  try {
85889
86095
  root.render(
85890
- import_react49.default.createElement(
86096
+ import_react48.default.createElement(
85891
86097
  RenderErrorBoundary,
85892
86098
  { onError: handleRenderError },
85893
- import_react49.default.createElement(
86099
+ import_react48.default.createElement(
85894
86100
  UnifoldProvider2,
85895
86101
  { publishableKey, config },
85896
- import_react49.default.createElement(UnifoldBridge, { ref: refCallback })
86102
+ import_react48.default.createElement(UnifoldBridge, { ref: refCallback })
85897
86103
  )
85898
86104
  )
85899
86105
  );