@rhinestone/deposit-modal 0.13.0 → 0.14.1

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 (57) hide show
  1. package/README.md +47 -12
  2. package/bridge-transcript.json +653 -0
  3. package/dist/ClaimModal-GDFENSLV.mjs +13 -0
  4. package/dist/ClaimModal-L3FUBI5U.cjs +13 -0
  5. package/dist/{DepositModalReown-3H75G3XQ.mjs → DepositModalReown-2EVV64OA.mjs} +30 -27
  6. package/dist/{DepositModalReown-YNNHLAV2.cjs → DepositModalReown-GAD45GIC.cjs} +77 -74
  7. package/dist/WithdrawModal-FAQH35NG.cjs +12 -0
  8. package/dist/WithdrawModal-IKUHF5CF.mjs +12 -0
  9. package/dist/{chunk-RAADLTSW.cjs → chunk-4J5ADVIN.cjs} +184 -139
  10. package/dist/{chunk-DSIZNRWA.mjs → chunk-5Q5CSVKF.mjs} +1049 -388
  11. package/dist/{chunk-HOGZKHHY.cjs → chunk-62UCV2LG.cjs} +3 -3
  12. package/dist/{chunk-CVGNCUVU.cjs → chunk-7AZFT2MV.cjs} +22 -13
  13. package/dist/{chunk-7N77GIP4.cjs → chunk-A6JPBMYY.cjs} +465 -171
  14. package/dist/{chunk-GACIGCSN.cjs → chunk-AQVJUXSG.cjs} +1 -1
  15. package/dist/{chunk-LTMMETAB.mjs → chunk-GZ4GQ5MC.mjs} +404 -110
  16. package/dist/{chunk-ZMT4ATHR.cjs → chunk-HAQOFI3D.cjs} +594 -41
  17. package/dist/{chunk-FZ5FZFIG.mjs → chunk-LMG46EP2.mjs} +1 -1
  18. package/dist/{chunk-2G2EIN4A.cjs → chunk-NQMC5VKQ.cjs} +1343 -682
  19. package/dist/{chunk-OLCD75JK.mjs → chunk-QACOOLOE.mjs} +451 -131
  20. package/dist/{chunk-XYJFEN5D.mjs → chunk-R5UQ3TN4.mjs} +1 -1
  21. package/dist/{chunk-EOMT5LKX.mjs → chunk-UX35GYLM.mjs} +556 -3
  22. package/dist/{chunk-YREVFB64.mjs → chunk-VALXN5IO.mjs} +16 -7
  23. package/dist/{chunk-COCBCQQC.mjs → chunk-XCTRKCNM.mjs} +51 -6
  24. package/dist/{chunk-5NUIKYSF.cjs → chunk-YP7QVKQ6.cjs} +458 -138
  25. package/dist/claim.cjs +6 -6
  26. package/dist/claim.d.cts +3 -3
  27. package/dist/claim.d.ts +3 -3
  28. package/dist/claim.mjs +5 -5
  29. package/dist/constants.cjs +2 -2
  30. package/dist/constants.d.cts +1 -1
  31. package/dist/constants.d.ts +1 -1
  32. package/dist/constants.mjs +1 -1
  33. package/dist/deposit.cjs +6 -6
  34. package/dist/deposit.d.cts +2 -2
  35. package/dist/deposit.d.ts +2 -2
  36. package/dist/deposit.mjs +5 -5
  37. package/dist/embed.cjs +310 -102
  38. package/dist/embed.d.cts +7 -1
  39. package/dist/embed.d.ts +7 -1
  40. package/dist/embed.mjs +285 -77
  41. package/dist/index.cjs +9 -9
  42. package/dist/index.d.cts +1 -1
  43. package/dist/index.d.ts +1 -1
  44. package/dist/index.mjs +8 -8
  45. package/dist/types-Bho4OA03.d.ts +982 -0
  46. package/dist/types-DP_3KwlD.d.cts +982 -0
  47. package/dist/withdraw.cjs +5 -5
  48. package/dist/withdraw.d.cts +3 -3
  49. package/dist/withdraw.d.ts +3 -3
  50. package/dist/withdraw.mjs +4 -4
  51. package/package.json +29 -7
  52. package/dist/ClaimModal-CREZO27I.mjs +0 -11
  53. package/dist/ClaimModal-JRIA32U2.cjs +0 -11
  54. package/dist/WithdrawModal-NVRX44IZ.mjs +0 -10
  55. package/dist/WithdrawModal-YYSBPCJJ.cjs +0 -10
  56. package/dist/types-B89I8_8H.d.ts +0 -638
  57. package/dist/types-nnDR4tqA.d.cts +0 -638
@@ -2,6 +2,7 @@ import {
2
2
  ProcessingStep,
3
3
  SetupError,
4
4
  Tooltip,
5
+ analyticsTargetProperties,
5
6
  computeCacheKey,
6
7
  computeIsCacheable,
7
8
  computeRequestKey,
@@ -18,12 +19,13 @@ import {
18
19
  runAccountSetupDeduped,
19
20
  txRefsMatch,
20
21
  warnRemovedProps
21
- } from "./chunk-COCBCQQC.mjs";
22
+ } from "./chunk-XCTRKCNM.mjs";
22
23
  import {
23
24
  ListRow
24
- } from "./chunk-XYJFEN5D.mjs";
25
+ } from "./chunk-R5UQ3TN4.mjs";
25
26
  import {
26
27
  AlertTriangleIcon,
28
+ AnalyticsSession,
27
29
  AppleIcon,
28
30
  ArrowUpRightIcon,
29
31
  BankIcon,
@@ -79,13 +81,14 @@ import {
79
81
  useCatalogChain,
80
82
  useChainCatalog,
81
83
  useChainName,
84
+ useDepositAnalyticsEmitter,
82
85
  useDepositChainIds,
83
86
  useExplorerTxUrl,
84
87
  useIsDepositChain,
85
88
  useLatestRef,
86
89
  useRpcUrls,
87
90
  useStableRpcUrls
88
- } from "./chunk-EOMT5LKX.mjs";
91
+ } from "./chunk-UX35GYLM.mjs";
89
92
  import {
90
93
  MULTICALL3_ADDRESS,
91
94
  POLYMARKET_COLLATERAL_OFFRAMP_ADDRESS,
@@ -103,6 +106,7 @@ import {
103
106
  HYPERCORE_MIN_DEPOSIT_USD,
104
107
  HYPERCORE_SPOT_CAIP2,
105
108
  NATIVE_TOKEN_ADDRESS,
109
+ SOLANA_MAINNET_CAIP2,
106
110
  SOLANA_TOKENS,
107
111
  SUPPORTED_CHAIN_IDS,
108
112
  cdnIconUrl,
@@ -125,12 +129,41 @@ import {
125
129
  isVirtualDestination,
126
130
  parseEvmChainId,
127
131
  publishShortlistTokens,
128
- targetChainToChainId
132
+ targetChainToChainId,
133
+ toEvmCaip2
129
134
  } from "./chunk-VUATPOWJ.mjs";
130
135
 
136
+ // src/core/reown-dependencies.ts
137
+ var dependencies;
138
+ var dependenciesPromise;
139
+ function loadReownDependencies() {
140
+ dependenciesPromise ?? (dependenciesPromise = Promise.all([
141
+ import("@reown/appkit/react"),
142
+ import("@reown/appkit/networks"),
143
+ import("@reown/appkit-adapter-wagmi"),
144
+ import("@reown/appkit-adapter-solana"),
145
+ import("@reown/appkit-adapter-solana/react")
146
+ ]).then((modules) => dependencies = modules).catch((cause) => {
147
+ const error = new Error(
148
+ "[rhinestone] reownAppId requires @reown/appkit, @reown/appkit-adapter-wagmi, @reown/appkit-adapter-solana, @solana/web3.js, and @solana/spl-token."
149
+ );
150
+ error.cause = cause;
151
+ throw error;
152
+ }));
153
+ return dependenciesPromise;
154
+ }
155
+ function getReownDependencies() {
156
+ if (!dependencies) {
157
+ throw new Error(
158
+ "[rhinestone] Reown dependencies were accessed before initialization."
159
+ );
160
+ }
161
+ return dependencies;
162
+ }
163
+
131
164
  // src/DepositModal.tsx
132
165
  import {
133
- useMemo as useMemo9,
166
+ useMemo as useMemo10,
134
167
  useEffect as useEffect13,
135
168
  useRef as useRef9,
136
169
  useState as useState15,
@@ -143,7 +176,7 @@ import {
143
176
  import {
144
177
  useState as useState13,
145
178
  useCallback as useCallback7,
146
- useMemo as useMemo7,
179
+ useMemo as useMemo8,
147
180
  useEffect as useEffect12,
148
181
  useLayoutEffect as useLayoutEffect2,
149
182
  useRef as useRef8
@@ -1882,7 +1915,8 @@ function ConfirmStep({
1882
1915
  targetChain,
1883
1916
  targetToken,
1884
1917
  directTransfer: false,
1885
- sourceTxHashPending: true
1918
+ sourceTxHashPending: true,
1919
+ depositId: submitted.depositId
1886
1920
  }
1887
1921
  );
1888
1922
  } catch (err) {
@@ -2290,7 +2324,7 @@ function DepositNotification({
2290
2324
  );
2291
2325
  const pollIntervalRef = useRef4(INITIAL_POLL_INTERVAL);
2292
2326
  const pollTimeoutRef = useRef4(null);
2293
- const completedRef = useRef4(directTransfer ?? false);
2327
+ const completedRef = useRef4(false);
2294
2328
  const depositContextRef = useLatestRef({
2295
2329
  amount,
2296
2330
  sourceChain,
@@ -2513,6 +2547,30 @@ function DepositNotification({
2513
2547
  );
2514
2548
  }
2515
2549
 
2550
+ // src/core/deposit-source-identity.ts
2551
+ var SOLANA_NATIVE_MINT = "11111111111111111111111111111111";
2552
+ var EVM_ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
2553
+ function sourceChainToCaip2(chain) {
2554
+ if (chain === "solana") return SOLANA_MAINNET_CAIP2;
2555
+ if (chain === "hypercore") return HYPERCORE_SPOT_CAIP2;
2556
+ return toEvmCaip2(chain);
2557
+ }
2558
+ function findAddress(tokens, symbol) {
2559
+ return tokens?.find((t) => t.symbol.toLowerCase() === symbol.toLowerCase())?.address;
2560
+ }
2561
+ function resolveSourceTokenIdentity(input) {
2562
+ const { chain, symbol, shortlist, catalogTokens } = input;
2563
+ if (!symbol) return void 0;
2564
+ const shortlistTokens = shortlist?.[String(chain)];
2565
+ const raw = shortlistTokens !== void 0 ? findAddress(shortlistTokens, symbol) : chain === "hypercore" || !Array.isArray(catalogTokens) ? void 0 : findAddress(catalogTokens, symbol);
2566
+ if (!raw) return void 0;
2567
+ if (chain === "solana") {
2568
+ const isNative = raw.toLowerCase() === "native" || raw.toLowerCase() === EVM_ZERO_ADDRESS;
2569
+ return isNative ? SOLANA_NATIVE_MINT : raw;
2570
+ }
2571
+ return raw.toLowerCase();
2572
+ }
2573
+
2516
2574
  // src/components/steps/DepositAddressStep.tsx
2517
2575
  import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
2518
2576
  var QRCode = lazy(
@@ -2647,18 +2705,22 @@ function DepositAddressStep({
2647
2705
  onDepositSubmitted,
2648
2706
  onDepositComplete,
2649
2707
  onDepositFailed,
2708
+ onAddressShown,
2650
2709
  onCopyAddress,
2651
2710
  onReviewDeposit,
2652
2711
  onError
2653
2712
  }) {
2654
2713
  const hasSolana = Boolean(solanaDepositAddress);
2655
2714
  const [topTokens, setTopTokens] = useState7(null);
2715
+ const [topTokensSettled, setTopTokensSettled] = useState7(false);
2656
2716
  useEffect7(() => {
2657
2717
  let active = true;
2658
2718
  setTopTokens(null);
2719
+ setTopTokensSettled(false);
2659
2720
  service.getTopTokens().then((t) => {
2660
2721
  if (!active) return;
2661
2722
  setTopTokens(t);
2723
+ setTopTokensSettled(true);
2662
2724
  if (t) publishShortlistTokens(t);
2663
2725
  });
2664
2726
  return () => {
@@ -2693,11 +2755,11 @@ function DepositAddressStep({
2693
2755
  const pendingChainRef = useRef5(initialSource?.chainId);
2694
2756
  useEffect7(() => {
2695
2757
  if (chainOptions.length === 0) return;
2696
- const pendingChain = pendingChainRef.current;
2697
- if (pendingChain !== void 0) {
2698
- if (chainOptions.includes(pendingChain)) {
2758
+ const pendingChain2 = pendingChainRef.current;
2759
+ if (pendingChain2 !== void 0) {
2760
+ if (chainOptions.includes(pendingChain2)) {
2699
2761
  pendingChainRef.current = void 0;
2700
- setSourceChainId(pendingChain);
2762
+ setSourceChainId(pendingChain2);
2701
2763
  return;
2702
2764
  }
2703
2765
  if (catalogLoading || topTokens === null) return;
@@ -2744,6 +2806,32 @@ function DepositAddressStep({
2744
2806
  const baselineTxHashRef = useRef5(void 0);
2745
2807
  const notificationIdRef = useRef5(0);
2746
2808
  const displayAddress = isSolana && solanaDepositAddress ? solanaDepositAddress : smartAccount;
2809
+ const sourceTokenIdentity = useMemo3(
2810
+ () => resolveSourceTokenIdentity({
2811
+ chain: sourceChainId,
2812
+ symbol: sourceTokenSymbol,
2813
+ shortlist: topTokens,
2814
+ catalogTokens: catalogFor(sourceChainId)?.supportedTokens
2815
+ }),
2816
+ [sourceChainId, sourceTokenSymbol, topTokens, catalogFor]
2817
+ );
2818
+ const pendingChain = pendingChainRef.current;
2819
+ const sourceSelectionSettled = !catalogLoading && topTokensSettled && chainOptions.length > 0 && (pendingChain === void 0 || pendingChain === sourceChainId) && (chainChosenByUser.current ? chainOptions.includes(sourceChainId) : sourceChainId === preferredChainId(chainOptions));
2820
+ useEffect7(() => {
2821
+ if (!sourceTokenIdentity) return;
2822
+ if (!sourceSelectionSettled) return;
2823
+ onAddressShown?.({
2824
+ address: displayAddress,
2825
+ sourceChainCaip2: sourceChainToCaip2(sourceChainId),
2826
+ sourceTokenIdentity
2827
+ });
2828
+ }, [
2829
+ displayAddress,
2830
+ onAddressShown,
2831
+ sourceChainId,
2832
+ sourceTokenIdentity,
2833
+ sourceSelectionSettled
2834
+ ]);
2747
2835
  useEffect7(() => {
2748
2836
  if (!chainDropdownOpen && !tokenDropdownOpen) return;
2749
2837
  function handlePointerDown(event) {
@@ -2763,10 +2851,10 @@ function DepositAddressStep({
2763
2851
  };
2764
2852
  }, [chainDropdownOpen, tokenDropdownOpen]);
2765
2853
  const handleCopy = useCallback2(async () => {
2766
- onCopyAddress?.();
2767
2854
  try {
2768
2855
  await navigator.clipboard.writeText(displayAddress);
2769
2856
  setCopied(true);
2857
+ onCopyAddress?.(true);
2770
2858
  setTimeout(() => setCopied(false), 2e3);
2771
2859
  } catch {
2772
2860
  const textarea = document.createElement("textarea");
@@ -2775,10 +2863,13 @@ function DepositAddressStep({
2775
2863
  textarea.style.opacity = "0";
2776
2864
  document.body.appendChild(textarea);
2777
2865
  textarea.select();
2778
- document.execCommand("copy");
2866
+ const copiedWithFallback = document.execCommand("copy");
2779
2867
  document.body.removeChild(textarea);
2780
- setCopied(true);
2781
- setTimeout(() => setCopied(false), 2e3);
2868
+ if (copiedWithFallback) {
2869
+ setCopied(true);
2870
+ setTimeout(() => setCopied(false), 2e3);
2871
+ }
2872
+ onCopyAddress?.(copiedWithFallback);
2782
2873
  }
2783
2874
  }, [displayAddress, onCopyAddress]);
2784
2875
  const handleSelectChain = useCallback2(
@@ -3329,6 +3420,10 @@ function SwappedProviderStep({
3329
3420
  onClose,
3330
3421
  onGoBack,
3331
3422
  onError,
3423
+ onAttemptConsumed,
3424
+ onProviderHandoff,
3425
+ onRetry,
3426
+ onCancelled,
3332
3427
  onImmersiveChange,
3333
3428
  openExternally
3334
3429
  }) {
@@ -3344,6 +3439,7 @@ function SwappedProviderStep({
3344
3439
  const [opening, setOpening] = useState8(false);
3345
3440
  const iframeRef = useRef6(null);
3346
3441
  const openedUrlRef = useRef6(null);
3442
+ const assignedIframeUrlRef = useRef6(null);
3347
3443
  const completeFiredRef = useRef6(false);
3348
3444
  const failedFiredRef = useRef6(false);
3349
3445
  const completeTimeoutRef = useRef6(null);
@@ -3364,6 +3460,8 @@ function SwappedProviderStep({
3364
3460
  onSwappedFailedRef.current = onSwappedFailed;
3365
3461
  const onErrorRef = useRef6(onError);
3366
3462
  onErrorRef.current = onError;
3463
+ const onProviderHandoffRef = useRef6(onProviderHandoff);
3464
+ onProviderHandoffRef.current = onProviderHandoff;
3367
3465
  const onGoBackRef = useRef6(onGoBack);
3368
3466
  onGoBackRef.current = onGoBack;
3369
3467
  const onImmersiveChangeRef = useRef6(onImmersiveChange);
@@ -3382,6 +3480,7 @@ function SwappedProviderStep({
3382
3480
  setHandoffOpened(false);
3383
3481
  setOpening(false);
3384
3482
  openedUrlRef.current = null;
3483
+ assignedIframeUrlRef.current = null;
3385
3484
  if (completeTimeoutRef.current !== null) {
3386
3485
  clearTimeout(completeTimeoutRef.current);
3387
3486
  completeTimeoutRef.current = null;
@@ -3402,6 +3501,7 @@ function SwappedProviderStep({
3402
3501
  }
3403
3502
  setWidgetUrl(res.url);
3404
3503
  expectedExternalCustomerIdRef.current = res.externalCustomerId;
3504
+ onAttemptConsumed?.(res.externalCustomerId);
3405
3505
  const sep = res.externalCustomerId.indexOf(":");
3406
3506
  expectedOrderUuidRef.current = sep >= 0 ? res.externalCustomerId.slice(sep + 1) : null;
3407
3507
  }).catch((err) => {
@@ -3421,13 +3521,20 @@ function SwappedProviderStep({
3421
3521
  useEffect8(() => {
3422
3522
  if (openExternally || !widgetUrl || iframeLoaded || loadError) return;
3423
3523
  const timer = setTimeout(() => {
3424
- setLoadError("Iframe took too long to load.");
3524
+ const message = "Iframe took too long to load.";
3525
+ setLoadError(message);
3526
+ onErrorRef.current?.(message, "SWAPPED_IFRAME_TIMEOUT");
3425
3527
  }, IFRAME_LOAD_TIMEOUT_MS);
3426
3528
  return () => clearTimeout(timer);
3427
3529
  }, [openExternally, widgetUrl, iframeLoaded, loadError]);
3428
3530
  useEffect8(() => {
3429
3531
  if (openExternally) return;
3430
- setIframeSrc(widgetUrl && !loadError ? widgetUrl : null);
3532
+ const nextSrc = widgetUrl && !loadError ? widgetUrl : null;
3533
+ setIframeSrc(nextSrc);
3534
+ if (nextSrc && assignedIframeUrlRef.current !== nextSrc) {
3535
+ assignedIframeUrlRef.current = nextSrc;
3536
+ onProviderHandoffRef.current?.();
3537
+ }
3431
3538
  }, [openExternally, widgetUrl, loadError, retryToken]);
3432
3539
  const openPaymentPage = async (url) => {
3433
3540
  if (!openExternally) return;
@@ -3436,6 +3543,7 @@ function SwappedProviderStep({
3436
3543
  try {
3437
3544
  await openExternally(url);
3438
3545
  setHandoffOpened(true);
3546
+ onProviderHandoff?.();
3439
3547
  } catch (error) {
3440
3548
  openedUrlRef.current = null;
3441
3549
  setLoadError(OPEN_FAILED_MESSAGE);
@@ -3592,6 +3700,9 @@ function SwappedProviderStep({
3592
3700
  }
3593
3701
  return null;
3594
3702
  }, [latestEvent, orderState, bannerForStatus]);
3703
+ useEffect8(() => {
3704
+ if (orderState?.status === "order_cancelled") onCancelled?.();
3705
+ }, [onCancelled, orderState?.status]);
3595
3706
  useEffect8(() => {
3596
3707
  if (completeFiredRef.current || failedFiredRef.current) return;
3597
3708
  const t = latestEvent?.type;
@@ -3633,6 +3744,7 @@ function SwappedProviderStep({
3633
3744
  }, [immersive]);
3634
3745
  useEffect8(() => () => onImmersiveChangeRef.current?.(false), []);
3635
3746
  const handleRetry = () => {
3747
+ onRetry?.();
3636
3748
  setIframeSrc(null);
3637
3749
  setWidgetUrl(null);
3638
3750
  setIframeLoaded(false);
@@ -3802,6 +3914,10 @@ function FiatOnrampStep({
3802
3914
  onClose,
3803
3915
  onGoBack,
3804
3916
  onError,
3917
+ onAttemptConsumed,
3918
+ onProviderHandoff,
3919
+ onRetry,
3920
+ onCancelled,
3805
3921
  onImmersiveChange,
3806
3922
  openExternally
3807
3923
  }) {
@@ -3846,6 +3962,10 @@ function FiatOnrampStep({
3846
3962
  onClose,
3847
3963
  onGoBack,
3848
3964
  onError,
3965
+ onAttemptConsumed,
3966
+ onProviderHandoff,
3967
+ onRetry,
3968
+ onCancelled,
3849
3969
  onImmersiveChange,
3850
3970
  openExternally
3851
3971
  }
@@ -3895,6 +4015,10 @@ function ExchangeConnectStep({
3895
4015
  onClose,
3896
4016
  onGoBack,
3897
4017
  onError,
4018
+ onAttemptConsumed,
4019
+ onProviderHandoff,
4020
+ onRetry,
4021
+ onCancelled,
3898
4022
  onImmersiveChange,
3899
4023
  openExternally
3900
4024
  }) {
@@ -3922,6 +4046,10 @@ function ExchangeConnectStep({
3922
4046
  onClose,
3923
4047
  onGoBack,
3924
4048
  onError,
4049
+ onAttemptConsumed,
4050
+ onProviderHandoff,
4051
+ onRetry,
4052
+ onCancelled,
3925
4053
  onImmersiveChange,
3926
4054
  openExternally
3927
4055
  }
@@ -4580,40 +4708,41 @@ import { useState as useState12 } from "react";
4580
4708
  import { parseUnits as parseUnits5 } from "viem";
4581
4709
 
4582
4710
  // src/core/solana.ts
4583
- import {
4584
- Connection,
4585
- PublicKey,
4586
- SystemProgram,
4587
- Transaction
4588
- } from "@solana/web3.js";
4589
- import {
4590
- getAssociatedTokenAddress,
4591
- createAssociatedTokenAccountInstruction,
4592
- createTransferInstruction
4593
- } from "@solana/spl-token";
4594
4711
  var DEFAULT_SOLANA_RPC_URL = "https://api.mainnet.solana.com";
4595
4712
  var cachedConnections = /* @__PURE__ */ new Map();
4713
+ var dependenciesPromise2;
4714
+ function loadSolanaDependencies() {
4715
+ dependenciesPromise2 ?? (dependenciesPromise2 = Promise.all([
4716
+ import("@solana/web3.js"),
4717
+ import("@solana/spl-token")
4718
+ ]));
4719
+ return dependenciesPromise2;
4720
+ }
4596
4721
  function getSolanaRpcUrl(rpcUrls) {
4597
4722
  return rpcUrlFor(rpcUrls, "solana") ?? DEFAULT_SOLANA_RPC_URL;
4598
4723
  }
4599
4724
  function hasConfiguredSolanaRpcUrl(rpcUrls) {
4600
4725
  return rpcUrlFor(rpcUrls, "solana") !== void 0;
4601
4726
  }
4602
- function getSolanaConnection(rpcUrls) {
4727
+ async function getSolanaConnection(rpcUrls) {
4603
4728
  const rpcUrl = getSolanaRpcUrl(rpcUrls);
4604
4729
  const cached = cachedConnections.get(rpcUrl);
4605
4730
  if (cached) {
4606
4731
  return cached;
4607
4732
  }
4608
- const next = new Connection(rpcUrl, "confirmed");
4733
+ const [web3] = await loadSolanaDependencies();
4734
+ const initialized = cachedConnections.get(rpcUrl);
4735
+ if (initialized) return initialized;
4736
+ const next = new web3.Connection(rpcUrl, "confirmed");
4609
4737
  cachedConnections.set(rpcUrl, next);
4610
4738
  return next;
4611
4739
  }
4612
4740
  async function buildSolTransferTransaction(connection, from, to, lamports) {
4613
- const fromPubkey = new PublicKey(from);
4614
- const toPubkey = new PublicKey(to);
4615
- const tx = new Transaction().add(
4616
- SystemProgram.transfer({
4741
+ const [web3] = await loadSolanaDependencies();
4742
+ const fromPubkey = new web3.PublicKey(from);
4743
+ const toPubkey = new web3.PublicKey(to);
4744
+ const tx = new web3.Transaction().add(
4745
+ web3.SystemProgram.transfer({
4617
4746
  fromPubkey,
4618
4747
  toPubkey,
4619
4748
  lamports
@@ -4626,16 +4755,24 @@ async function buildSolTransferTransaction(connection, from, to, lamports) {
4626
4755
  return tx;
4627
4756
  }
4628
4757
  async function buildSplTransferTransaction(connection, from, to, mint, amount) {
4629
- const fromPubkey = new PublicKey(from);
4630
- const toPubkey = new PublicKey(to);
4631
- const mintPubkey = new PublicKey(mint);
4632
- const fromAta = await getAssociatedTokenAddress(mintPubkey, fromPubkey);
4633
- const toAta = await getAssociatedTokenAddress(mintPubkey, toPubkey, true);
4634
- const tx = new Transaction();
4758
+ const [web3, splToken] = await loadSolanaDependencies();
4759
+ const fromPubkey = new web3.PublicKey(from);
4760
+ const toPubkey = new web3.PublicKey(to);
4761
+ const mintPubkey = new web3.PublicKey(mint);
4762
+ const fromAta = await splToken.getAssociatedTokenAddress(
4763
+ mintPubkey,
4764
+ fromPubkey
4765
+ );
4766
+ const toAta = await splToken.getAssociatedTokenAddress(
4767
+ mintPubkey,
4768
+ toPubkey,
4769
+ true
4770
+ );
4771
+ const tx = new web3.Transaction();
4635
4772
  const toAtaInfo = await connection.getAccountInfo(toAta);
4636
4773
  if (!toAtaInfo) {
4637
4774
  tx.add(
4638
- createAssociatedTokenAccountInstruction(
4775
+ splToken.createAssociatedTokenAccountInstruction(
4639
4776
  fromPubkey,
4640
4777
  toAta,
4641
4778
  toPubkey,
@@ -4643,7 +4780,9 @@ async function buildSplTransferTransaction(connection, from, to, mint, amount) {
4643
4780
  )
4644
4781
  );
4645
4782
  }
4646
- tx.add(createTransferInstruction(fromAta, toAta, fromPubkey, amount));
4783
+ tx.add(
4784
+ splToken.createTransferInstruction(fromAta, toAta, fromPubkey, amount)
4785
+ );
4647
4786
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
4648
4787
  tx.recentBlockhash = blockhash;
4649
4788
  tx.lastValidBlockHeight = lastValidBlockHeight;
@@ -4767,7 +4906,7 @@ function SolanaConfirmStep({
4767
4906
  "Deposit account is not registered yet. Please restart setup and try again."
4768
4907
  );
4769
4908
  }
4770
- const connection = hasConfiguredSolanaRpcUrl(rpcUrls) ? getSolanaConnection(rpcUrls) : solanaConnection ?? getSolanaConnection(rpcUrls);
4909
+ const connection = await (hasConfiguredSolanaRpcUrl(rpcUrls) ? getSolanaConnection(rpcUrls) : solanaConnection ?? getSolanaConnection(rpcUrls));
4771
4910
  const amountUnits = parseUnits5(sourceAmount, token.decimals);
4772
4911
  debugLog(debug, "solana-confirm", "tx:build:start", {
4773
4912
  token: token.symbol,
@@ -5659,8 +5798,297 @@ function bootRetryPlan(params) {
5659
5798
  };
5660
5799
  }
5661
5800
 
5801
+ // src/core/deposit-analytics.tsx
5802
+ import {
5803
+ createContext,
5804
+ useContext,
5805
+ useMemo as useMemo7
5806
+ } from "react";
5807
+ import { jsx as jsx27 } from "react/jsx-runtime";
5808
+ function fundingMethodForFlowMode(mode) {
5809
+ switch (mode) {
5810
+ case "wallet":
5811
+ case "solana-wallet":
5812
+ return "wallet";
5813
+ case "deposit-address":
5814
+ return "transfer";
5815
+ case "fiat-onramp":
5816
+ return "fiat_onramp";
5817
+ case "exchange-connect":
5818
+ return "exchange_connect";
5819
+ case "dapp-import":
5820
+ return "asset_migration";
5821
+ default:
5822
+ return null;
5823
+ }
5824
+ }
5825
+ function analyticsStepForFlowStep(method, step) {
5826
+ if (!method) {
5827
+ return step === "setup" ? "account_setup" : "funding_method_home";
5828
+ }
5829
+ switch (step) {
5830
+ case "connect":
5831
+ return method === "wallet" ? "wallet_connect" : "funding_method_home";
5832
+ case "setup":
5833
+ return "account_setup";
5834
+ case "select-asset":
5835
+ return "wallet_source_asset";
5836
+ case "solana-token-select":
5837
+ return "wallet_source_token";
5838
+ case "amount":
5839
+ case "solana-amount":
5840
+ return method === "asset_migration" ? "migration_amount" : "wallet_amount";
5841
+ case "confirm":
5842
+ case "solana-confirm":
5843
+ return method === "asset_migration" ? "migration_review" : "wallet_review";
5844
+ case "processing":
5845
+ return method === "asset_migration" ? "migration_processing" : method === "transfer" ? "transfer_tracking" : method === "fiat_onramp" ? "fiat_receipt" : method === "exchange_connect" ? "exchange_receipt" : "wallet_processing";
5846
+ case "deposit-address":
5847
+ return "transfer_address_shown";
5848
+ case "qr-amount":
5849
+ return "transfer_fee_amount";
5850
+ case "qr-review":
5851
+ return "transfer_fee_review";
5852
+ case "fiat-onramp":
5853
+ return "fiat_provider_handoff";
5854
+ case "exchange-select":
5855
+ return "exchange_selection";
5856
+ case "exchange-connect":
5857
+ return "exchange_provider_handoff";
5858
+ case "dapp-import-resolving":
5859
+ return "migration_boot_resolve";
5860
+ case "dapp-import-select":
5861
+ return "migration_provider_selection";
5862
+ case "dapp-import-asset-select":
5863
+ return "migration_asset_selection";
5864
+ default:
5865
+ return "funding_method_home";
5866
+ }
5867
+ }
5868
+ function failureReasonForCode(code, cause) {
5869
+ const normalized = `${code ?? ""} ${cause ?? ""}`.toLowerCase();
5870
+ if (normalized.includes("uncertain")) return "submission_uncertain";
5871
+ if (normalized.includes("reject") && (normalized.includes("sign") || normalized.includes("permit"))) {
5872
+ return "wallet_signature_rejected";
5873
+ }
5874
+ if (normalized.includes("permit")) {
5875
+ return "wallet_permit_preparation_unavailable";
5876
+ }
5877
+ if (normalized.includes("clipboard")) return "transfer_clipboard_failed";
5878
+ if (normalized.includes("switch") && normalized.includes("reject")) {
5879
+ return "wallet_chain_switch_rejected";
5880
+ }
5881
+ if (normalized.includes("reject")) return "submission_rejected";
5882
+ if (normalized.includes("switch")) return "wallet_chain_switch_failed";
5883
+ if (normalized.includes("quote")) return "quote_unavailable";
5884
+ if (normalized.includes("price")) return "quote_source_price_unavailable";
5885
+ if (normalized.includes("iframe_timeout")) return "swapped_iframe_timeout";
5886
+ if (normalized.includes("connect_exchanges") || normalized.includes("exchange_list")) {
5887
+ return "exchange_list_failed";
5888
+ }
5889
+ if (normalized.includes("browser")) return "swapped_browser_open_failed";
5890
+ if (normalized.includes("swapped") || normalized.includes("onramp")) {
5891
+ return "swapped_mint_failed";
5892
+ }
5893
+ if (normalized.includes("solana") || normalized.includes("transfer")) {
5894
+ return "submission_failed";
5895
+ }
5896
+ return "submission_failed";
5897
+ }
5898
+ function correlatorKey(correlator) {
5899
+ return `${correlator.type}:${correlator.value}`;
5900
+ }
5901
+ function createDepositAnalyticsController(emit) {
5902
+ let method = null;
5903
+ let step = null;
5904
+ let afterHandoff = false;
5905
+ let opened = false;
5906
+ let closed = false;
5907
+ const dedupe = /* @__PURE__ */ new Set();
5908
+ const emitOnce = (key, ...args) => {
5909
+ if (dedupe.has(key)) return;
5910
+ dedupe.add(key);
5911
+ emit(...args);
5912
+ };
5913
+ const controller = {
5914
+ emit,
5915
+ openSession() {
5916
+ if (opened) return;
5917
+ opened = true;
5918
+ emit({ type: "deposit_modal_open" }, null);
5919
+ },
5920
+ selectMethod(...args) {
5921
+ const [nextMethod, entrySource, identifiers] = args;
5922
+ controller.openSession();
5923
+ if (method && method !== nextMethod && !afterHandoff) {
5924
+ controller.abandon("method_replacement");
5925
+ }
5926
+ method = nextMethod;
5927
+ step = null;
5928
+ afterHandoff = false;
5929
+ emitOnce(
5930
+ `method:${nextMethod}:${entrySource}:${JSON.stringify(identifiers ?? {})}`,
5931
+ ...[
5932
+ {
5933
+ type: "deposit_modal_method_selected",
5934
+ entry_source: entrySource,
5935
+ ...identifiers ? { identifiers } : {}
5936
+ },
5937
+ nextMethod
5938
+ ]
5939
+ );
5940
+ },
5941
+ openStep(nextStep) {
5942
+ controller.openSession();
5943
+ if (step === nextStep) return;
5944
+ step = nextStep;
5945
+ emitOnce(
5946
+ `step-open:${method ?? "none"}:${nextStep}`,
5947
+ { type: "deposit_modal_step_open", step: nextStep },
5948
+ method
5949
+ );
5950
+ },
5951
+ completeStep(completedStep = step ?? void 0) {
5952
+ if (!completedStep) return;
5953
+ emitOnce(
5954
+ `step-complete:${method ?? "none"}:${completedStep}`,
5955
+ { type: "deposit_modal_step_complete", step: completedStep },
5956
+ method
5957
+ );
5958
+ },
5959
+ friction(reason, eventStep = step ?? void 0) {
5960
+ if (!eventStep) return;
5961
+ emitOnce(
5962
+ `friction:${method}:${eventStep}:${reason}`,
5963
+ {
5964
+ type: "deposit_modal_friction",
5965
+ step: eventStep,
5966
+ reason
5967
+ },
5968
+ method
5969
+ );
5970
+ },
5971
+ failure(reason, retryable, eventStep = step ?? void 0) {
5972
+ if (!eventStep) return;
5973
+ emitOnce(
5974
+ `failure:${method}:${eventStep}:${reason}`,
5975
+ {
5976
+ type: "deposit_modal_failure",
5977
+ step: eventStep,
5978
+ reason,
5979
+ retryable
5980
+ },
5981
+ method
5982
+ );
5983
+ },
5984
+ retry(reason, eventStep = step ?? void 0) {
5985
+ if (!eventStep) return;
5986
+ emit({ type: "deposit_modal_retry", step: eventStep, reason }, method);
5987
+ for (const key of [...dedupe]) {
5988
+ if (key.includes(`:${method}:${eventStep}:`)) dedupe.delete(key);
5989
+ }
5990
+ },
5991
+ handoff(...args) {
5992
+ const [handoffMethod, correlator, eventStep = step ?? void 0, identifiers] = args;
5993
+ if (!eventStep) return;
5994
+ if (step !== eventStep) controller.openStep(eventStep);
5995
+ afterHandoff = true;
5996
+ emitOnce(
5997
+ `handoff:${correlatorKey(correlator)}:${JSON.stringify(identifiers ?? {})}`,
5998
+ ...[
5999
+ {
6000
+ type: "deposit_modal_handoff",
6001
+ step: eventStep,
6002
+ correlator,
6003
+ ...identifiers ? { identifiers } : {}
6004
+ },
6005
+ handoffMethod
6006
+ ]
6007
+ );
6008
+ },
6009
+ observeCorrelator(correlator, eventStep = step ?? void 0) {
6010
+ if (!eventStep) return;
6011
+ const key = `correlator:${correlatorKey(correlator)}`;
6012
+ if (dedupe.has(key)) return;
6013
+ if (step !== eventStep) controller.openStep(eventStep);
6014
+ emitOnce(
6015
+ key,
6016
+ {
6017
+ type: "deposit_modal_correlator_observed",
6018
+ step: eventStep,
6019
+ correlator
6020
+ },
6021
+ method
6022
+ );
6023
+ },
6024
+ outcome(outcome) {
6025
+ if (!step) return;
6026
+ emitOnce(
6027
+ `outcome:${method}:${outcome}`,
6028
+ { type: "deposit_modal_ui_outcome", step, outcome },
6029
+ method
6030
+ );
6031
+ },
6032
+ abandon(reason) {
6033
+ if (!method || !step || afterHandoff) return;
6034
+ emitOnce(
6035
+ `abandon:${method}:${reason}`,
6036
+ { type: "deposit_modal_method_abandoned", step, reason },
6037
+ method
6038
+ );
6039
+ },
6040
+ close(source) {
6041
+ if (closed) return;
6042
+ closed = true;
6043
+ emit(
6044
+ {
6045
+ type: "deposit_modal_close",
6046
+ source,
6047
+ step,
6048
+ after_handoff: afterHandoff
6049
+ },
6050
+ method
6051
+ );
6052
+ },
6053
+ resetAttempt(nextMethod = null) {
6054
+ method = nextMethod;
6055
+ step = null;
6056
+ afterHandoff = false;
6057
+ dedupe.clear();
6058
+ },
6059
+ get method() {
6060
+ return method;
6061
+ },
6062
+ get step() {
6063
+ return step;
6064
+ },
6065
+ get afterHandoff() {
6066
+ return afterHandoff;
6067
+ }
6068
+ };
6069
+ return controller;
6070
+ }
6071
+ var DepositAnalyticsControllerContext = createContext(null);
6072
+ var noopController = createDepositAnalyticsController(() => {
6073
+ });
6074
+ function DepositAnalyticsControllerProvider({
6075
+ children,
6076
+ controllerRef
6077
+ }) {
6078
+ const emit = useDepositAnalyticsEmitter();
6079
+ const controller = useMemo7(
6080
+ () => createDepositAnalyticsController(emit),
6081
+ [emit]
6082
+ );
6083
+ if (controllerRef) controllerRef.current = controller;
6084
+ return /* @__PURE__ */ jsx27(DepositAnalyticsControllerContext.Provider, { value: controller, children });
6085
+ }
6086
+ function useDepositAnalyticsController() {
6087
+ return useContext(DepositAnalyticsControllerContext) ?? noopController;
6088
+ }
6089
+
5662
6090
  // src/store/index.ts
5663
- import { createContext, createElement, useContext } from "react";
6091
+ import { createContext as createContext2, createElement, useContext as useContext2 } from "react";
5664
6092
  import { useStore } from "zustand";
5665
6093
  import { createStore } from "zustand/vanilla";
5666
6094
 
@@ -6654,7 +7082,7 @@ function createDepositStore(overrides) {
6654
7082
  }
6655
7083
  };
6656
7084
  }
6657
- var DepositStoreContext = createContext(null);
7085
+ var DepositStoreContext = createContext2(null);
6658
7086
  function DepositStoreProvider({
6659
7087
  store,
6660
7088
  children
@@ -6666,7 +7094,7 @@ function DepositStoreProvider({
6666
7094
  );
6667
7095
  }
6668
7096
  function useDepositStoreApi() {
6669
- const store = useContext(DepositStoreContext);
7097
+ const store = useContext2(DepositStoreContext);
6670
7098
  if (!store) {
6671
7099
  throw new Error(
6672
7100
  "useDepositStore must be called inside <DepositStoreProvider>"
@@ -6680,7 +7108,7 @@ function useDepositStore(selector) {
6680
7108
  }
6681
7109
 
6682
7110
  // src/DepositFlow.tsx
6683
- import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
7111
+ import { Fragment as Fragment6, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
6684
7112
  function swappedWidgetPrefetchKey(method, methodSelectionSource) {
6685
7113
  return JSON.stringify([methodSelectionSource ?? null, method ?? null]);
6686
7114
  }
@@ -6689,17 +7117,17 @@ function AccountPreparingSkeleton({
6689
7117
  onRetry
6690
7118
  }) {
6691
7119
  return /* @__PURE__ */ jsxs23("div", { className: "rs-step", children: [
6692
- /* @__PURE__ */ jsx27("div", { className: "rs-step-body", style: { paddingTop: 0 }, children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-text", children: errorMessage ? /* @__PURE__ */ jsxs23(Fragment6, { children: [
6693
- /* @__PURE__ */ jsx27("div", { className: "rs-loading-title rs-text-error", children: "Couldn\u2019t prepare account" }),
6694
- /* @__PURE__ */ jsx27("div", { className: "rs-loading-subtitle", children: errorMessage })
6695
- ] }) : /* @__PURE__ */ jsx27("div", { className: "rs-loading-title", children: "Preparing\u2026" }) }) }) }),
6696
- errorMessage && onRetry && /* @__PURE__ */ jsx27("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx27(
7120
+ /* @__PURE__ */ jsx28("div", { className: "rs-step-body", style: { paddingTop: 0 }, children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-text", children: errorMessage ? /* @__PURE__ */ jsxs23(Fragment6, { children: [
7121
+ /* @__PURE__ */ jsx28("div", { className: "rs-loading-title rs-text-error", children: "Couldn\u2019t prepare account" }),
7122
+ /* @__PURE__ */ jsx28("div", { className: "rs-loading-subtitle", children: errorMessage })
7123
+ ] }) : /* @__PURE__ */ jsx28("div", { className: "rs-loading-title", children: "Preparing\u2026" }) }) }) }),
7124
+ errorMessage && onRetry && /* @__PURE__ */ jsx28("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx28(
6697
7125
  "button",
6698
7126
  {
6699
7127
  type: "button",
6700
7128
  className: "rs-button rs-button--default rs-button--full-width",
6701
7129
  onClick: onRetry,
6702
- children: /* @__PURE__ */ jsx27("span", { children: "Try again" })
7130
+ children: /* @__PURE__ */ jsx28("span", { children: "Try again" })
6703
7131
  }
6704
7132
  ) })
6705
7133
  ] });
@@ -6955,6 +7383,7 @@ function DepositFlow({
6955
7383
  fiatMethods,
6956
7384
  enableExchangeConnect = false,
6957
7385
  walletSession,
7386
+ walletIntegration,
6958
7387
  onConnect,
6959
7388
  onDisconnect,
6960
7389
  onRequestConnect,
@@ -6967,13 +7396,12 @@ function DepositFlow({
6967
7396
  onSubmittingChange,
6968
7397
  onClose,
6969
7398
  onLifecycle,
6970
- onEvent,
6971
7399
  onError,
6972
7400
  debug
6973
7401
  }) {
6974
7402
  const rpcUrls = useRpcUrls();
6975
7403
  const onStepChangeRef = useLatestRef(onStepChange);
6976
- const onEventRef = useLatestRef(onEvent);
7404
+ const analytics = useDepositAnalyticsController();
6977
7405
  const onLifecycleRef = useLatestRef(onLifecycle);
6978
7406
  const onErrorRef = useLatestRef(onError);
6979
7407
  const storeApi = useDepositStoreApi();
@@ -7021,14 +7449,14 @@ function DepositFlow({
7021
7449
  for (const link of links) link.remove();
7022
7450
  };
7023
7451
  }, [enableSwappedPreconnect]);
7024
- const dappSwitchChain = useMemo7(() => {
7452
+ const dappSwitchChain = useMemo8(() => {
7025
7453
  if (!walletClientProp?.switchChain) return void 0;
7026
7454
  return async (chainId) => {
7027
7455
  await walletClientProp.switchChain?.({ id: chainId });
7028
7456
  };
7029
7457
  }, [walletClientProp]);
7030
7458
  const connectedWalletAddress = walletClientProp?.account?.address ?? null;
7031
- const walletOptions = useMemo7(() => {
7459
+ const walletOptions = useMemo8(() => {
7032
7460
  const options = [];
7033
7461
  const seen = /* @__PURE__ */ new Set();
7034
7462
  if (connectedWalletAddress) {
@@ -7077,12 +7505,12 @@ function DepositFlow({
7077
7505
  walletSession?.solanaAddress,
7078
7506
  walletSession?.caipAddress
7079
7507
  ]);
7080
- const offeredFiatMethods = useMemo7(
7508
+ const offeredFiatMethods = useMemo8(
7081
7509
  () => fiatMethods ? FIAT_ONRAMP_METHODS.filter((m) => fiatMethods[m.method]) : FIAT_ONRAMP_METHODS,
7082
7510
  [fiatMethods]
7083
7511
  );
7084
7512
  const fiatEnabled = enableFiatOnramp && offeredFiatMethods.length > 0;
7085
- const enabledAssetMigrationIds = useMemo7(
7513
+ const enabledAssetMigrationIds = useMemo8(
7086
7514
  () => Object.entries(assetMigrations ?? {}).filter(([, on]) => on).map(([id]) => id),
7087
7515
  [assetMigrations]
7088
7516
  );
@@ -7105,7 +7533,7 @@ function DepositFlow({
7105
7533
  hasWalletClientProp && walletClientProp === void 0 || walletSession && !hasReownSession && !walletSession.isReady
7106
7534
  );
7107
7535
  const showConnectStep = flowMode === null && !isConnectSelectionConfirmed;
7108
- const walletSelectionKey = useMemo7(() => {
7536
+ const walletSelectionKey = useMemo8(() => {
7109
7537
  if (flowMode !== "wallet" && flowMode !== "dapp-import") return null;
7110
7538
  if (canAutoLock) {
7111
7539
  return getAddressKey(connectedWalletAddress);
@@ -7142,7 +7570,7 @@ function DepositFlow({
7142
7570
  cancelled = true;
7143
7571
  };
7144
7572
  }, [service, targetSymbol, isTargetStablecoin, targetChain, targetToken]);
7145
- const walletSignerContext = useMemo7(() => {
7573
+ const walletSignerContext = useMemo8(() => {
7146
7574
  if (flowMode === "deposit-address") {
7147
7575
  return null;
7148
7576
  }
@@ -7217,7 +7645,7 @@ function DepositFlow({
7217
7645
  stableWalletSignerRef.current = walletSignerContext;
7218
7646
  }
7219
7647
  }, [flowMode, walletSelectionKey, walletSignerContext]);
7220
- const signerContext = useMemo7(() => {
7648
+ const signerContext = useMemo8(() => {
7221
7649
  if (flowMode !== "wallet" && flowMode !== "dapp-import") {
7222
7650
  return null;
7223
7651
  }
@@ -7235,7 +7663,7 @@ function DepositFlow({
7235
7663
  walletSignerContext,
7236
7664
  walletSelectionKey
7237
7665
  ]);
7238
- const selectedEvmWalletOwner = useMemo7(() => {
7666
+ const selectedEvmWalletOwner = useMemo8(() => {
7239
7667
  if (!selectedWalletId) return null;
7240
7668
  const opt = walletOptions.find((o) => o.id === selectedWalletId);
7241
7669
  if (opt?.kind === "external" && opt.address) {
@@ -7246,7 +7674,7 @@ function DepositFlow({
7246
7674
  }
7247
7675
  return null;
7248
7676
  }, [selectedWalletId, walletOptions]);
7249
- const dappImportOwner = useMemo7(() => {
7677
+ const dappImportOwner = useMemo8(() => {
7250
7678
  if (selectedEvmWalletOwner) return selectedEvmWalletOwner;
7251
7679
  if (walletSession?.address && walletSession.isConnected) {
7252
7680
  return walletSession.address;
@@ -7259,7 +7687,7 @@ function DepositFlow({
7259
7687
  walletSession?.isConnected,
7260
7688
  connectedWalletAddress
7261
7689
  ]);
7262
- const activeOwner = useMemo7(
7690
+ const activeOwner = useMemo8(
7263
7691
  () => resolveOwnerForMode(flowMode, {
7264
7692
  walletOwner: signerContext?.ownerAddress ?? (canAutoLock ? connectedWalletAddress : selectedEvmWalletOwner),
7265
7693
  dappImportOwner
@@ -7324,7 +7752,7 @@ function DepositFlow({
7324
7752
  activeEntry.smartAccount,
7325
7753
  onLifecycleRef
7326
7754
  ]);
7327
- const effectiveStep = useMemo7(
7755
+ const effectiveStep = useMemo8(
7328
7756
  () => deriveStep(
7329
7757
  flowSlice,
7330
7758
  depositSlice,
@@ -7344,11 +7772,52 @@ function DepositFlow({
7344
7772
  );
7345
7773
  const step = effectiveStep;
7346
7774
  const handleBack = useCallback7(() => {
7775
+ if ([
7776
+ "deposit-address",
7777
+ "select-asset",
7778
+ "solana-token-select",
7779
+ "fiat-onramp",
7780
+ "exchange-select",
7781
+ "exchange-connect",
7782
+ "dapp-import-resolving",
7783
+ "dapp-import-select",
7784
+ "dapp-import-asset-select"
7785
+ ].includes(effectiveStep.type)) {
7786
+ analytics.abandon("back");
7787
+ analytics.resetAttempt(
7788
+ effectiveStep.type === "exchange-connect" ? "exchange_connect" : null
7789
+ );
7790
+ }
7791
+ storeApi.dispatch({
7792
+ type: "back/requested",
7793
+ hasWalletOptions: hasWalletOptions || Boolean(walletSession)
7794
+ });
7795
+ }, [
7796
+ analytics,
7797
+ effectiveStep.type,
7798
+ storeApi,
7799
+ hasWalletOptions,
7800
+ walletSession
7801
+ ]);
7802
+ const handleProviderBack = useCallback7(() => {
7803
+ analytics.abandon("provider_back");
7804
+ analytics.resetAttempt(
7805
+ flowMode === "exchange-connect" ? "exchange_connect" : null
7806
+ );
7807
+ storeApi.dispatch({
7808
+ type: "back/requested",
7809
+ hasWalletOptions: hasWalletOptions || Boolean(walletSession)
7810
+ });
7811
+ }, [analytics, flowMode, storeApi, hasWalletOptions, walletSession]);
7812
+ const handleWalletDisconnect = useCallback7(() => {
7813
+ analytics.abandon("wallet_disconnect");
7814
+ analytics.resetAttempt();
7815
+ onDisconnect?.();
7347
7816
  storeApi.dispatch({
7348
7817
  type: "back/requested",
7349
7818
  hasWalletOptions: hasWalletOptions || Boolean(walletSession)
7350
7819
  });
7351
- }, [storeApi, hasWalletOptions, walletSession]);
7820
+ }, [analytics, hasWalletOptions, onDisconnect, storeApi, walletSession]);
7352
7821
  const qrSourceAsset = effectiveStep.type === "qr-amount" ? effectiveStep.asset : null;
7353
7822
  const qrSourceKey = qrSourceAsset ? `${qrSourceAsset.chainId}:${qrSourceAsset.token}` : null;
7354
7823
  const [qrSourcePrice, setQrSourcePrice] = useState13({ resolved: false, usd: null });
@@ -7417,51 +7886,22 @@ function DepositFlow({
7417
7886
  });
7418
7887
  return () => cancelAnimationFrame(rafId);
7419
7888
  }, [stepPinKey]);
7420
- const stepSendToken = effectiveStep.type === "amount" ? effectiveStep.asset.symbol : null;
7421
- const stepOpenEventKey = effectiveStep.type === "select-asset" ? "select-asset" : effectiveStep.type === "deposit-address" ? "deposit-address" : effectiveStep.type === "amount" && stepSendToken ? `amount:${stepSendToken.toLowerCase()}` : null;
7422
- const lastStepOpenEventKeyRef = useRef8(null);
7889
+ const analyticsMethod = fundingMethodForFlowMode(flowMode);
7890
+ const analyticsStep = analyticsStepForFlowStep(
7891
+ analyticsMethod,
7892
+ showConnectStep ? "connect" : effectiveStep.type
7893
+ );
7423
7894
  useEffect12(() => {
7424
- if (!stepOpenEventKey) {
7425
- lastStepOpenEventKeyRef.current = null;
7426
- return;
7427
- }
7428
- if (lastStepOpenEventKeyRef.current === stepOpenEventKey) {
7429
- return;
7430
- }
7431
- lastStepOpenEventKeyRef.current = stepOpenEventKey;
7432
- if (effectiveStep.type === "select-asset") {
7433
- onEventRef.current?.({
7434
- type: "deposit_modal_connected_wallet_select_source_open",
7435
- total_balance_in_external_wallet: totalBalanceUsd,
7436
- pred_balance: totalBalanceUsd
7437
- });
7438
- } else if (effectiveStep.type === "deposit-address") {
7439
- const chainName = getChainName(targetChainId);
7440
- const tokenSymbol = getTargetTokenSymbol(targetToken, targetChainId);
7441
- onEventRef.current?.({
7442
- type: "deposit_modal_transfer_crypto_open",
7443
- default_chain: chainName,
7444
- default_token: tokenSymbol,
7445
- pred_balance: totalBalanceUsd
7446
- });
7447
- } else if (effectiveStep.type === "amount" && stepSendToken) {
7448
- const receiveSymbol = getTargetTokenSymbol(targetToken, targetChainId);
7449
- onEventRef.current?.({
7450
- type: "deposit_modal_connected_wallet_enter_value_open",
7451
- send_token: stepSendToken,
7452
- receive_token: receiveSymbol,
7453
- pred_balance: totalBalanceUsd
7454
- });
7895
+ analytics.openSession();
7896
+ analytics.openStep(analyticsStep);
7897
+ }, [analytics, analyticsStep]);
7898
+ useEffect12(() => {
7899
+ if (setupSlice.status === "loading") {
7900
+ analytics.friction("account_setup_pending", "account_setup");
7901
+ } else if (setupSlice.status === "error") {
7902
+ analytics.failure("account_setup_failed", true, "account_setup");
7455
7903
  }
7456
- }, [
7457
- effectiveStep.type,
7458
- stepOpenEventKey,
7459
- stepSendToken,
7460
- targetChain,
7461
- targetToken,
7462
- totalBalanceUsd,
7463
- onEventRef
7464
- ]);
7904
+ }, [analytics, setupSlice.status]);
7465
7905
  useEffect12(() => {
7466
7906
  logFlow("state:changed", {
7467
7907
  step: effectiveStep.type,
@@ -7490,30 +7930,35 @@ function DepositFlow({
7490
7930
  const isFiatOnrampMode = flowMode === "fiat-onramp";
7491
7931
  const isExchangeConnectMode = flowMode === "exchange-connect";
7492
7932
  const handleSelectTransferCrypto = useCallback7(() => {
7933
+ analytics.selectMethod("transfer", "user");
7493
7934
  storeApi.dispatch({ type: "connect/transfer-crypto-selected" });
7494
- }, [storeApi]);
7935
+ }, [analytics, storeApi]);
7495
7936
  const handleConfirmWallet = useCallback7(
7496
7937
  (walletId) => {
7497
7938
  const selectedOption = walletOptions.find((o) => o.id === walletId);
7498
7939
  const mode = selectedOption?.kind === "solana" ? "solana-wallet" : "wallet";
7940
+ analytics.selectMethod("wallet", "user", {
7941
+ network: selectedOption?.kind === "solana" ? "solana" : "evm",
7942
+ integration: walletIntegration ?? "none"
7943
+ });
7499
7944
  storeApi.dispatch({
7500
7945
  type: "connect/wallet-confirmed",
7501
7946
  walletId,
7502
7947
  mode
7503
7948
  });
7504
7949
  },
7505
- [walletOptions, storeApi]
7950
+ [analytics, walletIntegration, walletOptions, storeApi]
7506
7951
  );
7507
7952
  const isSolanaWalletConnected = Boolean(
7508
7953
  walletSession?.isConnected && walletSession?.isSolana
7509
7954
  );
7510
7955
  const assetMigrationsKey = assetMigrations ? Object.keys(assetMigrations).filter((k) => assetMigrations[k]).sort().join(",") : "";
7511
- const enabledDappImportProviders = useMemo7(
7956
+ const enabledDappImportProviders = useMemo8(
7512
7957
  () => isSolanaWalletConnected ? [] : getEnabledProviders(assetMigrations),
7513
7958
  // eslint-disable-next-line react-hooks/exhaustive-deps -- intentional: keyed on assetMigrationsKey, not the assetMigrations object identity
7514
7959
  [assetMigrationsKey, isSolanaWalletConnected]
7515
7960
  );
7516
- const initialAssetMigrationProvider = useMemo7(
7961
+ const initialAssetMigrationProvider = useMemo8(
7517
7962
  () => initialAssetMigration ? enabledDappImportProviders.find((p) => p.id === initialAssetMigration) ?? null : null,
7518
7963
  [initialAssetMigration, enabledDappImportProviders]
7519
7964
  );
@@ -7531,12 +7976,15 @@ function DepositFlow({
7531
7976
  });
7532
7977
  }
7533
7978
  }
7979
+ analytics.selectMethod("asset_migration", "user", {
7980
+ provider: providerId
7981
+ });
7534
7982
  storeApi.dispatch({
7535
7983
  type: "dapp-import/provider-selected",
7536
7984
  providerId
7537
7985
  });
7538
7986
  },
7539
- [storeApi, walletOptions, dappImportOwner]
7987
+ [analytics, storeApi, walletOptions, dappImportOwner]
7540
7988
  );
7541
7989
  const handleDappImportAssetSelected = useCallback7(
7542
7990
  (asset) => {
@@ -7582,6 +8030,12 @@ function DepositFlow({
7582
8030
  });
7583
8031
  }).catch(() => {
7584
8032
  if (controller.signal.aborted) return;
8033
+ if (analytics.method === "asset_migration") {
8034
+ analytics.friction(
8035
+ "migration_availability_failed",
8036
+ "migration_provider_selection"
8037
+ );
8038
+ }
7585
8039
  storeApi.dispatch({
7586
8040
  type: "dapp-import/availability-failed",
7587
8041
  providerId: provider.id,
@@ -7591,6 +8045,7 @@ function DepositFlow({
7591
8045
  }
7592
8046
  return () => controller.abort();
7593
8047
  }, [
8048
+ analytics,
7594
8049
  dappImportOwner,
7595
8050
  enabledDappImportProviders,
7596
8051
  dappImportAttemptNonce,
@@ -7603,11 +8058,14 @@ function DepositFlow({
7603
8058
  if (flowSlice.step !== "connect" || flowSlice.mode !== null || flowSlice.isConnectSelectionConfirmed || flowSlice.hasNavigatedBack) {
7604
8059
  return;
7605
8060
  }
8061
+ analytics.selectMethod("asset_migration", "initial_config", {
8062
+ provider: initialAssetMigrationProvider.id
8063
+ });
7606
8064
  storeApi.dispatch({
7607
8065
  type: "dapp-import/boot-requested",
7608
8066
  providerId: initialAssetMigrationProvider.id
7609
8067
  });
7610
- }, [initialAssetMigrationProvider, flowSlice, storeApi]);
8068
+ }, [analytics, initialAssetMigrationProvider, flowSlice, storeApi]);
7611
8069
  const dappImportAvailability = useDepositStore((s) => s.dappImport.availability);
7612
8070
  const dappImportAvailabilityOwner = useDepositStore(
7613
8071
  (s) => s.dappImport.availabilityOwner
@@ -7616,7 +8074,7 @@ function DepositFlow({
7616
8074
  (s) => s.dappImport.activeProviderId
7617
8075
  );
7618
8076
  const dappImportBootError = useDepositStore((s) => s.dappImport.bootError);
7619
- const dappImportSelectRows = useMemo7(
8077
+ const dappImportSelectRows = useMemo8(
7620
8078
  () => enabledDappImportProviders.map((provider) => ({
7621
8079
  id: provider.id,
7622
8080
  status: computeDappImportStatus(provider.id, {
@@ -7634,7 +8092,7 @@ function DepositFlow({
7634
8092
  dappImportOwner
7635
8093
  ]
7636
8094
  );
7637
- const dappImportTotal = useMemo7(() => {
8095
+ const dappImportTotal = useMemo8(() => {
7638
8096
  let totalUsd = 0;
7639
8097
  let pending = false;
7640
8098
  for (const row of dappImportSelectRows) {
@@ -7648,13 +8106,13 @@ function DepositFlow({
7648
8106
  }
7649
8107
  return { status: pending ? "loading" : "ready", totalUsd };
7650
8108
  }, [dappImportSelectRows]);
7651
- const activeDappImportProvider = useMemo7(() => {
8109
+ const activeDappImportProvider = useMemo8(() => {
7652
8110
  if (!activeDappImportProviderId) return null;
7653
8111
  return enabledDappImportProviders.find(
7654
8112
  (p) => p.id === activeDappImportProviderId
7655
8113
  ) ?? null;
7656
8114
  }, [activeDappImportProviderId, enabledDappImportProviders]);
7657
- const activeDappImportAvailability = useMemo7(() => {
8115
+ const activeDappImportAvailability = useMemo8(() => {
7658
8116
  if (!activeDappImportProviderId) return null;
7659
8117
  if (!dappImportOwner || dappImportAvailabilityOwner?.toLowerCase() !== dappImportOwner.toLowerCase()) {
7660
8118
  return null;
@@ -7683,6 +8141,8 @@ function DepositFlow({
7683
8141
  const providerId = activeDappImportProviderId;
7684
8142
  if (!providerId) return;
7685
8143
  if (!enabledDappImportProviders.some((p) => p.id === providerId)) {
8144
+ analytics.abandon("initial_migration_fallback");
8145
+ analytics.resetAttempt();
7686
8146
  storeApi.dispatch({
7687
8147
  type: "dapp-import/boot-resolved",
7688
8148
  providerId,
@@ -7712,6 +8172,9 @@ function DepositFlow({
7712
8172
  type: "wallet/id-selected",
7713
8173
  walletId: pinnableWallet.id
7714
8174
  });
8175
+ } else if (outcome === "unavailable") {
8176
+ analytics.abandon("initial_migration_fallback");
8177
+ analytics.resetAttempt();
7715
8178
  }
7716
8179
  storeApi.dispatch({
7717
8180
  type: "dapp-import/boot-resolved",
@@ -7730,9 +8193,14 @@ function DepositFlow({
7730
8193
  hasResolveDeadlinePassed,
7731
8194
  isDappImportWalletHydrating,
7732
8195
  walletOptions,
8196
+ analytics,
7733
8197
  storeApi
7734
8198
  ]);
7735
8199
  const handleBootRetry = useCallback7(() => {
8200
+ analytics.retry(
8201
+ "migration_availability_failed",
8202
+ "migration_boot_resolve"
8203
+ );
7736
8204
  const snapshot = storeApi.getState();
7737
8205
  const providerId = snapshot.dappImport.activeProviderId;
7738
8206
  if (!providerId) return;
@@ -7754,20 +8222,45 @@ function DepositFlow({
7754
8222
  type: "dapp-import/boot-requested",
7755
8223
  providerId
7756
8224
  });
7757
- }, [storeApi, dappImportOwner]);
8225
+ }, [analytics, storeApi, dappImportOwner]);
7758
8226
  const handleSelectFiatMethod = useCallback7(
7759
8227
  (paymentMethod, methodSelectionSource) => {
8228
+ analytics.selectMethod("fiat_onramp", "user", {
8229
+ payment_method: paymentMethod,
8230
+ source: methodSelectionSource
8231
+ });
7760
8232
  storeApi.dispatch({
7761
8233
  type: "connect/fiat-onramp-selected",
7762
8234
  paymentMethod,
7763
8235
  methodSelectionSource
7764
8236
  });
7765
8237
  },
7766
- [storeApi]
8238
+ [analytics, storeApi]
7767
8239
  );
7768
8240
  const handleSelectExchange = useCallback7(() => {
8241
+ analytics.selectMethod("exchange_connect", "user");
7769
8242
  storeApi.dispatch({ type: "connect/exchange-selected" });
7770
- }, [storeApi]);
8243
+ }, [analytics, storeApi]);
8244
+ const swappedAnalyticsCorrelatorRef = useRef8(null);
8245
+ const handleSwappedAttemptConsumed = useCallback7((externalCustomerId) => {
8246
+ swappedAnalyticsCorrelatorRef.current = externalCustomerId;
8247
+ }, []);
8248
+ const handleSwappedProviderHandoff = useCallback7(() => {
8249
+ const externalCustomerId = swappedAnalyticsCorrelatorRef.current;
8250
+ if (!externalCustomerId) return;
8251
+ analytics.handoff(
8252
+ flowMode === "exchange-connect" ? "exchange_connect" : "fiat_onramp",
8253
+ { type: "swapped_external_customer_id", value: externalCustomerId },
8254
+ flowMode === "exchange-connect" ? "exchange_provider_handoff" : "fiat_provider_handoff"
8255
+ );
8256
+ }, [analytics, flowMode]);
8257
+ const handleSwappedRetry = useCallback7(() => {
8258
+ analytics.retry(
8259
+ "swapped_mint_failed",
8260
+ flowMode === "exchange-connect" ? "exchange_provider_mint" : "fiat_provider_mint"
8261
+ );
8262
+ swappedAnalyticsCorrelatorRef.current = null;
8263
+ }, [analytics, flowMode]);
7771
8264
  const swappedConnectUrlRef = useRef8(/* @__PURE__ */ new Map());
7772
8265
  const acknowledgedConnectFeeRef = useRef8(/* @__PURE__ */ new Map());
7773
8266
  const handleSelectExchangeConnection = useCallback7(
@@ -7808,13 +8301,16 @@ function DepositFlow({
7808
8301
  }
7809
8302
  swappedConnectUrlRef.current.set(key, entry);
7810
8303
  acknowledgedConnectFeeRef.current.set(key, actualFeeBps);
8304
+ analytics.selectMethod("exchange_connect", "user", {
8305
+ exchange: connection
8306
+ });
7811
8307
  storeApi.dispatch({
7812
8308
  type: "exchange/connection-selected",
7813
8309
  connection
7814
8310
  });
7815
8311
  return actualFeeBps;
7816
8312
  },
7817
- [service, setupSlice.status, setupSlice.smartAccount, storeApi]
8313
+ [analytics, service, setupSlice.status, setupSlice.smartAccount, storeApi]
7818
8314
  );
7819
8315
  const loadSwappedConnectUrl = useCallback7(
7820
8316
  async (smartAccount, connection) => {
@@ -7916,9 +8412,10 @@ function DepositFlow({
7916
8412
  recommendedMethod: null
7917
8413
  });
7918
8414
  let settled = false;
7919
- const showFallback = () => {
8415
+ const showFallback = (reason) => {
7920
8416
  if (cancelled || settled) return;
7921
8417
  settled = true;
8418
+ analytics.friction(reason, "fiat_regional_payment_method");
7922
8419
  setRegionalMethods({
7923
8420
  status: "error",
7924
8421
  country: null,
@@ -7926,7 +8423,10 @@ function DepositFlow({
7926
8423
  recommendedMethod: null
7927
8424
  });
7928
8425
  };
7929
- const timeoutTimer = setTimeout(showFallback, REGIONAL_METHODS_TIMEOUT_MS);
8426
+ const timeoutTimer = setTimeout(
8427
+ () => showFallback("regional_methods_timeout"),
8428
+ REGIONAL_METHODS_TIMEOUT_MS
8429
+ );
7930
8430
  service.getSwappedPaymentMethods().then((res) => {
7931
8431
  if (cancelled || settled) return;
7932
8432
  settled = true;
@@ -7935,14 +8435,14 @@ function DepositFlow({
7935
8435
  }).catch(() => {
7936
8436
  if (cancelled) return;
7937
8437
  clearTimeout(timeoutTimer);
7938
- showFallback();
8438
+ showFallback("regional_methods_failed");
7939
8439
  });
7940
8440
  return () => {
7941
8441
  cancelled = true;
7942
8442
  clearTimeout(timeoutTimer);
7943
8443
  };
7944
- }, [fiatEnabled, hasConfiguredFiatMethods, service]);
7945
- const cashDisplay = useMemo7(() => {
8444
+ }, [analytics, fiatEnabled, hasConfiguredFiatMethods, service]);
8445
+ const cashDisplay = useMemo8(() => {
7946
8446
  if (!fiatEnabled) return { kind: "hidden" };
7947
8447
  if (hasConfiguredFiatMethods) {
7948
8448
  return {
@@ -7960,45 +8460,26 @@ function DepositFlow({
7960
8460
  offeredFiatMethods,
7961
8461
  regionalMethods
7962
8462
  ]);
7963
- const lastFiatMethodsRenderedEventRef = useRef8(null);
7964
8463
  useEffect12(() => {
7965
- if (cashDisplay.kind !== "list") return;
7966
- const emit = onEventRef.current;
7967
- if (!emit) return;
7968
- const paymentMethods = cashDisplay.methods.map(({ method }) => method);
7969
- const eventKey = [
7970
- cashDisplay.source,
7971
- cashDisplay.country ?? "none",
7972
- ...paymentMethods
7973
- ].join(":");
7974
- if (lastFiatMethodsRenderedEventRef.current === eventKey) return;
7975
- lastFiatMethodsRenderedEventRef.current = eventKey;
7976
- emit({
7977
- type: "deposit_modal_fiat_methods_rendered",
7978
- country: cashDisplay.country,
7979
- payment_methods: paymentMethods,
7980
- source: cashDisplay.source
7981
- });
7982
- }, [cashDisplay, onEvent, onEventRef]);
8464
+ if (cashDisplay.kind === "hidden" && fiatEnabled) {
8465
+ analytics.friction(
8466
+ "regional_methods_empty",
8467
+ "fiat_regional_payment_method"
8468
+ );
8469
+ } else if (cashDisplay.kind === "list" && cashDisplay.source === "fallback" && !hasConfiguredFiatMethods) {
8470
+ analytics.friction(
8471
+ "regional_methods_fallback",
8472
+ "fiat_regional_payment_method"
8473
+ );
8474
+ }
8475
+ }, [analytics, cashDisplay, fiatEnabled, hasConfiguredFiatMethods]);
7983
8476
  const displayedFiatSource = cashDisplay.kind === "list" ? cashDisplay.source : void 0;
7984
- const displayedFiatCountry = cashDisplay.kind === "list" ? cashDisplay.country : null;
7985
8477
  const handleSelectDisplayedFiatMethod = useCallback7(
7986
8478
  (method) => {
7987
8479
  if (!displayedFiatSource) return;
7988
- onEventRef.current?.({
7989
- type: "deposit_modal_fiat_method_click",
7990
- country: displayedFiatCountry,
7991
- payment_method: method,
7992
- source: displayedFiatSource
7993
- });
7994
8480
  handleSelectFiatMethod(method, displayedFiatSource);
7995
8481
  },
7996
- [
7997
- displayedFiatCountry,
7998
- displayedFiatSource,
7999
- handleSelectFiatMethod,
8000
- onEventRef
8001
- ]
8482
+ [displayedFiatSource, handleSelectFiatMethod]
8002
8483
  );
8003
8484
  const handlePrefetchDisplayedFiatMethod = useCallback7(
8004
8485
  (method) => {
@@ -8008,6 +8489,8 @@ function DepositFlow({
8008
8489
  [displayedFiatSource, handlePrefetchFiatMethod]
8009
8490
  );
8010
8491
  const handleNewDeposit = useCallback7(() => {
8492
+ analytics.completeStep();
8493
+ analytics.resetAttempt();
8011
8494
  onLifecycleRef.current?.({
8012
8495
  type: "smart-account-changed",
8013
8496
  evm: null,
@@ -8020,8 +8503,8 @@ function DepositFlow({
8020
8503
  swappedConnectUrlRef.current.clear();
8021
8504
  acknowledgedConnectFeeRef.current.clear();
8022
8505
  lastSmartAccountLifecycleKeyRef.current = null;
8023
- }, [onLifecycleRef, storeApi]);
8024
- const setupInput = useMemo7(
8506
+ }, [analytics, onLifecycleRef, storeApi]);
8507
+ const setupInput = useMemo8(
8025
8508
  () => ({
8026
8509
  targetChain,
8027
8510
  targetToken,
@@ -8099,11 +8582,11 @@ function DepositFlow({
8099
8582
  }
8100
8583
  })();
8101
8584
  }, [setupInput, service, debug, storeApi, setupSlice]);
8102
- const walletOptionsKey = useMemo7(
8585
+ const walletOptionsKey = useMemo8(
8103
8586
  () => walletOptions.map((option) => option.id).join(","),
8104
8587
  [walletOptions]
8105
8588
  );
8106
- const desiredPortfolios = useMemo7(
8589
+ const desiredPortfolios = useMemo8(
8107
8590
  () => walletOptions.flatMap((option) => {
8108
8591
  const network = option.kind === "solana" ? "solana" : "evm";
8109
8592
  const address = option.kind === "solana" ? option.solanaAddress : option.address;
@@ -8159,9 +8642,13 @@ function DepositFlow({
8159
8642
  sourceChain: data.sourceChain,
8160
8643
  amount: data.amount
8161
8644
  });
8645
+ analytics.observeCorrelator(
8646
+ { type: "transaction_hash", value: data.txHash },
8647
+ "transfer_tracking"
8648
+ );
8162
8649
  onLifecycleRef.current?.({ type: "submitted", ...data });
8163
8650
  },
8164
- [logFlow, onLifecycleRef]
8651
+ [analytics, logFlow, onLifecycleRef]
8165
8652
  );
8166
8653
  const handleSolanaTokenContinue = useCallback7(
8167
8654
  (token, balance, balanceUsd) => {
@@ -8209,6 +8696,11 @@ function DepositFlow({
8209
8696
  amountUnits,
8210
8697
  token: tokenAtSubmit.symbol
8211
8698
  });
8699
+ analytics.handoff(
8700
+ "wallet",
8701
+ { type: "transaction_hash", value: txHash },
8702
+ "wallet_submit"
8703
+ );
8212
8704
  storeApi.dispatch({
8213
8705
  type: "deposit/submitted",
8214
8706
  txHash,
@@ -8232,25 +8724,18 @@ function DepositFlow({
8232
8724
  amountUsd
8233
8725
  });
8234
8726
  },
8235
- [logFlow, onLifecycleRef, storeApi]
8727
+ [analytics, logFlow, onLifecycleRef, storeApi]
8236
8728
  );
8237
8729
  const handleAssetContinue = useCallback7(
8238
8730
  (asset) => {
8239
- onEventRef.current?.({
8240
- type: "deposit_modal_connected_wallet_select_source_cta_click",
8241
- total_balance_in_external_wallet: totalBalanceUsd,
8242
- pred_balance: totalBalanceUsd,
8243
- cta_name: "token_selected",
8244
- token_name: asset.symbol,
8245
- token_balance: asset.balance ?? "0"
8246
- });
8731
+ analytics.completeStep("wallet_source_asset");
8247
8732
  storeApi.dispatch({
8248
8733
  type: "asset/selected",
8249
8734
  asset,
8250
8735
  seedAmount: defaultAmount
8251
8736
  });
8252
8737
  },
8253
- [defaultAmount, onEventRef, totalBalanceUsd, storeApi]
8738
+ [analytics, defaultAmount, storeApi]
8254
8739
  );
8255
8740
  const handleAmountContinue = useCallback7(
8256
8741
  (amount, targetAmount, balance) => {
@@ -8298,6 +8783,21 @@ function DepositFlow({
8298
8783
  });
8299
8784
  const depositAtSubmit = storeApi.getState().deposit;
8300
8785
  const asset = depositAtSubmit.selectedAsset;
8786
+ const handoffMethod = flowMode === "dapp-import" ? "asset_migration" : "wallet";
8787
+ const handoffStep = flowMode === "dapp-import" ? "migration_submit" : "wallet_submit";
8788
+ if (routed.depositId) {
8789
+ analytics.handoff(
8790
+ handoffMethod,
8791
+ { type: "deposit_id", value: routed.depositId },
8792
+ handoffStep
8793
+ );
8794
+ } else if (!routed.sourceTxHashPending) {
8795
+ analytics.handoff(
8796
+ handoffMethod,
8797
+ { type: "transaction_hash", value: txHash },
8798
+ handoffStep
8799
+ );
8800
+ }
8301
8801
  storeApi.dispatch({
8302
8802
  type: "deposit/submitted",
8303
8803
  txHash,
@@ -8317,7 +8817,7 @@ function DepositFlow({
8317
8817
  quote
8318
8818
  });
8319
8819
  },
8320
- [logFlow, storeApi]
8820
+ [analytics, flowMode, logFlow, storeApi]
8321
8821
  );
8322
8822
  const handleSwappedComplete = useCallback7(
8323
8823
  (info) => {
@@ -8393,6 +8893,10 @@ function DepositFlow({
8393
8893
  const handleDepositComplete = useCallback7(
8394
8894
  (txHash, destinationTxHash, context) => {
8395
8895
  logFlow("deposit:complete", { txHash, destinationTxHash, ...context });
8896
+ analytics.openStep(
8897
+ analyticsStepForFlowStep(analyticsMethod, "processing")
8898
+ );
8899
+ analytics.outcome("completed");
8396
8900
  onLifecycleRef.current?.({
8397
8901
  type: "complete",
8398
8902
  txHash,
@@ -8400,21 +8904,40 @@ function DepositFlow({
8400
8904
  ...context
8401
8905
  });
8402
8906
  },
8403
- [logFlow, onLifecycleRef]
8907
+ [analytics, analyticsMethod, logFlow, onLifecycleRef]
8404
8908
  );
8405
8909
  const handleDepositFailed = useCallback7(
8406
8910
  (txHash, error) => {
8407
8911
  logFlowError("deposit:failed", error, { txHash });
8912
+ analytics.openStep(
8913
+ analyticsStepForFlowStep(analyticsMethod, "processing")
8914
+ );
8915
+ analytics.outcome("failed");
8916
+ analytics.failure("processor_failed", false);
8408
8917
  onLifecycleRef.current?.({ type: "failed", txHash, error });
8409
8918
  },
8410
- [logFlowError, onLifecycleRef]
8919
+ [analytics, analyticsMethod, logFlowError, onLifecycleRef]
8411
8920
  );
8412
8921
  const handleError = useCallback7(
8413
8922
  (message, code, cause) => {
8414
8923
  logFlowError("flow:error", cause ?? message, { code });
8924
+ if (code === "PROCESS_TIMEOUT") {
8925
+ analytics.friction("processor_status_poll_failed");
8926
+ } else {
8927
+ const reason = failureReasonForCode(
8928
+ code,
8929
+ `${message} ${cause ?? ""}`
8930
+ );
8931
+ const failureStep = code === "SWAPPED_URL_FAILED" ? "fiat_provider_mint" : code === "SWAPPED_CONNECT_URL_FAILED" ? "exchange_provider_mint" : void 0;
8932
+ analytics.failure(
8933
+ reason,
8934
+ reason !== "submission_uncertain",
8935
+ failureStep
8936
+ );
8937
+ }
8415
8938
  onErrorRef.current?.({ message, code, cause });
8416
8939
  },
8417
- [logFlowError, onErrorRef]
8940
+ [analytics, logFlowError, onErrorRef]
8418
8941
  );
8419
8942
  const handleTotalBalanceComputed = useCallback7((total) => {
8420
8943
  setTotalBalanceUsd(total);
@@ -8441,7 +8964,7 @@ function DepositFlow({
8441
8964
  signerContext,
8442
8965
  storeApi
8443
8966
  ]);
8444
- const walletRows = useMemo7(() => {
8967
+ const walletRows = useMemo8(() => {
8445
8968
  if (!enableWallet) return [];
8446
8969
  return walletOptions.map((option) => {
8447
8970
  const entry = setupSlice;
@@ -8470,10 +8993,11 @@ function DepositFlow({
8470
8993
  const transferCryptoEntry = setupSlice;
8471
8994
  const transferCryptoState = transferCryptoEntry.status === "ready" ? "ready" : transferCryptoEntry.status === "error" ? "error" : "loading";
8472
8995
  const handleRetrySetup = useCallback7(() => {
8996
+ analytics.retry("account_setup_failed", "account_setup");
8473
8997
  storeApi.dispatch({ type: "setup/retry-requested" });
8474
- }, [storeApi]);
8998
+ }, [analytics, storeApi]);
8475
8999
  if (showConnectStep) {
8476
- return /* @__PURE__ */ jsx27("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx27(
9000
+ return /* @__PURE__ */ jsx28("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx28(
8477
9001
  ConnectStep,
8478
9002
  {
8479
9003
  walletRows,
@@ -8518,7 +9042,10 @@ function DepositFlow({
8518
9042
  // hasn't landed must still surface the row and show it inside the
8519
9043
  // picker as "Coming soon" — keying this on implemented providers
8520
9044
  // hid the feature entirely for such a config.
8521
- enabledAssetMigrationIds.length > 0 ? () => storeApi.dispatch({ type: "dapp-import/picker-opened" }) : void 0
9045
+ enabledAssetMigrationIds.length > 0 ? () => {
9046
+ analytics.selectMethod("asset_migration", "user");
9047
+ storeApi.dispatch({ type: "dapp-import/picker-opened" });
9048
+ } : void 0
8522
9049
  ),
8523
9050
  migrateAssetsBalanceStatus: dappImportTotal.status,
8524
9051
  migrateAssetsBalanceUsd: dappImportTotal.totalUsd
@@ -8527,19 +9054,19 @@ function DepositFlow({
8527
9054
  }
8528
9055
  if (isDepositAddressMode) {
8529
9056
  return /* @__PURE__ */ jsxs23("div", { className: "rs-modal-body", children: [
8530
- effectiveStep.type === "setup" && (activeEntry.status === "error" ? /* @__PURE__ */ jsx27(
9057
+ effectiveStep.type === "setup" && (activeEntry.status === "error" ? /* @__PURE__ */ jsx28(
8531
9058
  AccountPreparingSkeleton,
8532
9059
  {
8533
9060
  errorMessage: activeEntry.message ?? void 0,
8534
9061
  onRetry: () => handleRetrySetup()
8535
9062
  }
8536
- ) : /* @__PURE__ */ jsx27(
9063
+ ) : /* @__PURE__ */ jsx28(
8537
9064
  DepositAddressSkeleton,
8538
9065
  {
8539
9066
  uiConfig
8540
9067
  }
8541
9068
  )),
8542
- effectiveStep.type === "deposit-address" && /* @__PURE__ */ jsx27(
9069
+ effectiveStep.type === "deposit-address" && /* @__PURE__ */ jsx28(
8543
9070
  DepositAddressStep,
8544
9071
  {
8545
9072
  smartAccount: effectiveStep.smartAccount,
@@ -8552,23 +9079,38 @@ function DepositFlow({
8552
9079
  onDepositSubmitted: handleDepositAddressSubmitted,
8553
9080
  onDepositComplete: handleDepositComplete,
8554
9081
  onDepositFailed: handleDepositFailed,
8555
- onCopyAddress: () => {
8556
- const chainName = getChainName(targetChainId);
8557
- const tokenSymbol = getTargetTokenSymbol(targetToken, targetChainId);
8558
- onEvent?.({
8559
- type: "deposit_modal_transfer_crypto_cta_click",
8560
- default_chain: chainName,
8561
- default_token: tokenSymbol,
8562
- pred_balance: totalBalanceUsd,
8563
- cta_name: "copy"
8564
- });
9082
+ onAddressShown: ({
9083
+ address,
9084
+ sourceChainCaip2,
9085
+ sourceTokenIdentity
9086
+ }) => {
9087
+ analytics.handoff(
9088
+ "transfer",
9089
+ { type: "deposit_address", value: address },
9090
+ "transfer_address_shown",
9091
+ {
9092
+ source_chain: sourceChainCaip2,
9093
+ source_token: sourceTokenIdentity
9094
+ }
9095
+ );
9096
+ },
9097
+ onCopyAddress: (success) => {
9098
+ if (success) {
9099
+ analytics.completeStep("transfer_copy");
9100
+ } else {
9101
+ analytics.failure(
9102
+ "transfer_clipboard_failed",
9103
+ true,
9104
+ "transfer_copy"
9105
+ );
9106
+ }
8565
9107
  },
8566
9108
  onReviewDeposit: handleQrReviewRequested,
8567
9109
  onError: handleError,
8568
9110
  debug
8569
9111
  }
8570
9112
  ),
8571
- effectiveStep.type === "qr-amount" && /* @__PURE__ */ jsx27(
9113
+ effectiveStep.type === "qr-amount" && /* @__PURE__ */ jsx28(
8572
9114
  AmountStep,
8573
9115
  {
8574
9116
  asset: effectiveStep.asset,
@@ -8584,7 +9126,7 @@ function DepositFlow({
8584
9126
  onContinue: handleQrAmountContinue
8585
9127
  }
8586
9128
  ),
8587
- effectiveStep.type === "qr-review" && /* @__PURE__ */ jsx27(
9129
+ effectiveStep.type === "qr-review" && /* @__PURE__ */ jsx28(
8588
9130
  QrReviewStep,
8589
9131
  {
8590
9132
  smartAccount: effectiveStep.smartAccount,
@@ -8608,14 +9150,14 @@ function DepositFlow({
8608
9150
  "data-flow-mode": "fiat-onramp",
8609
9151
  "data-step-type": step.type,
8610
9152
  children: [
8611
- step.type === "setup" && /* @__PURE__ */ jsx27(
9153
+ step.type === "setup" && /* @__PURE__ */ jsx28(
8612
9154
  AccountPreparingSkeleton,
8613
9155
  {
8614
9156
  errorMessage: activeEntry.status === "error" ? activeEntry.message ?? void 0 : void 0,
8615
9157
  onRetry: activeEntry.status === "error" ? () => handleRetrySetup() : void 0
8616
9158
  }
8617
9159
  ),
8618
- step.type === "fiat-onramp" && /* @__PURE__ */ jsx27(
9160
+ step.type === "fiat-onramp" && /* @__PURE__ */ jsx28(
8619
9161
  FiatOnrampStep,
8620
9162
  {
8621
9163
  smartAccount: step.smartAccount,
@@ -8625,15 +9167,20 @@ function DepositFlow({
8625
9167
  consumePrefetchedUrl: consumeSwappedWidgetUrlPrefetch,
8626
9168
  onSwappedComplete: handleSwappedComplete,
8627
9169
  onSwappedFailed: handleDepositFailed,
8628
- onClose: onClose ?? (() => {
8629
- }),
8630
- onGoBack: handleBack,
9170
+ onClose: () => onClose?.(
9171
+ openExternally ? "native_dismiss_request" : "header_button"
9172
+ ),
9173
+ onGoBack: handleProviderBack,
8631
9174
  onError: handleError,
9175
+ onAttemptConsumed: handleSwappedAttemptConsumed,
9176
+ onProviderHandoff: handleSwappedProviderHandoff,
9177
+ onRetry: handleSwappedRetry,
9178
+ onCancelled: () => analytics.outcome("cancelled"),
8632
9179
  onImmersiveChange: onSwappedImmersiveChange,
8633
9180
  openExternally
8634
9181
  }
8635
9182
  ),
8636
- step.type === "processing" && /* @__PURE__ */ jsx27(
9183
+ step.type === "processing" && /* @__PURE__ */ jsx28(
8637
9184
  ProcessingStep,
8638
9185
  {
8639
9186
  smartAccount: step.smartAccount,
@@ -8675,14 +9222,14 @@ function DepositFlow({
8675
9222
  "data-flow-mode": "exchange-connect",
8676
9223
  "data-step-type": step.type,
8677
9224
  children: [
8678
- step.type === "setup" && /* @__PURE__ */ jsx27(
9225
+ step.type === "setup" && /* @__PURE__ */ jsx28(
8679
9226
  AccountPreparingSkeleton,
8680
9227
  {
8681
9228
  errorMessage: activeEntry.status === "error" ? activeEntry.message ?? void 0 : void 0,
8682
9229
  onRetry: activeEntry.status === "error" ? () => handleRetrySetup() : void 0
8683
9230
  }
8684
9231
  ),
8685
- step.type === "exchange-select" && /* @__PURE__ */ jsx27(
9232
+ step.type === "exchange-select" && /* @__PURE__ */ jsx28(
8686
9233
  ExchangeSelectStep,
8687
9234
  {
8688
9235
  service,
@@ -8690,7 +9237,7 @@ function DepositFlow({
8690
9237
  onError: handleError
8691
9238
  }
8692
9239
  ),
8693
- step.type === "exchange-connect" && /* @__PURE__ */ jsx27(
9240
+ step.type === "exchange-connect" && /* @__PURE__ */ jsx28(
8694
9241
  ExchangeConnectStep,
8695
9242
  {
8696
9243
  smartAccount: step.smartAccount,
@@ -8699,15 +9246,20 @@ function DepositFlow({
8699
9246
  loadUrl: () => loadSwappedConnectUrl(step.smartAccount, step.connection),
8700
9247
  onSwappedComplete: handleSwappedComplete,
8701
9248
  onSwappedFailed: handleDepositFailed,
8702
- onClose: onClose ?? (() => {
8703
- }),
8704
- onGoBack: handleBack,
9249
+ onClose: () => onClose?.(
9250
+ openExternally ? "native_dismiss_request" : "header_button"
9251
+ ),
9252
+ onGoBack: handleProviderBack,
8705
9253
  onError: handleError,
9254
+ onAttemptConsumed: handleSwappedAttemptConsumed,
9255
+ onProviderHandoff: handleSwappedProviderHandoff,
9256
+ onRetry: handleSwappedRetry,
9257
+ onCancelled: () => analytics.outcome("cancelled"),
8706
9258
  onImmersiveChange: onSwappedImmersiveChange,
8707
9259
  openExternally
8708
9260
  }
8709
9261
  ),
8710
- step.type === "processing" && /* @__PURE__ */ jsx27(
9262
+ step.type === "processing" && /* @__PURE__ */ jsx28(
8711
9263
  ProcessingStep,
8712
9264
  {
8713
9265
  smartAccount: step.smartAccount,
@@ -8745,28 +9297,25 @@ function DepositFlow({
8745
9297
  const solanaAddr = walletSession?.solanaAddress;
8746
9298
  const solanaProvider = walletSession?.solanaProvider;
8747
9299
  return /* @__PURE__ */ jsxs23("div", { className: "rs-modal-body", children: [
8748
- effectiveStep.type === "setup" && /* @__PURE__ */ jsx27(
9300
+ effectiveStep.type === "setup" && /* @__PURE__ */ jsx28(
8749
9301
  AccountPreparingSkeleton,
8750
9302
  {
8751
9303
  errorMessage: activeEntry.status === "error" ? activeEntry.message ?? void 0 : void 0,
8752
9304
  onRetry: activeEntry.status === "error" ? () => handleRetrySetup() : void 0
8753
9305
  }
8754
9306
  ),
8755
- effectiveStep.type === "solana-token-select" && solanaAddr && /* @__PURE__ */ jsx27(
9307
+ effectiveStep.type === "solana-token-select" && solanaAddr && /* @__PURE__ */ jsx28(
8756
9308
  SolanaTokenSelectStep,
8757
9309
  {
8758
9310
  solanaAddress: solanaAddr,
8759
9311
  service,
8760
9312
  onContinue: handleSolanaTokenContinue,
8761
9313
  onTotalBalanceComputed: handleTotalBalanceComputed,
8762
- onDisconnect: onDisconnect ? () => {
8763
- onDisconnect();
8764
- handleBack();
8765
- } : void 0,
9314
+ onDisconnect: onDisconnect ? handleWalletDisconnect : void 0,
8766
9315
  debug
8767
9316
  }
8768
9317
  ),
8769
- effectiveStep.type === "solana-amount" && /* @__PURE__ */ jsx27(
9318
+ effectiveStep.type === "solana-amount" && /* @__PURE__ */ jsx28(
8770
9319
  SolanaAmountStep,
8771
9320
  {
8772
9321
  token: effectiveStep.token,
@@ -8782,7 +9331,7 @@ function DepositFlow({
8782
9331
  debug
8783
9332
  }
8784
9333
  ),
8785
- effectiveStep.type === "solana-confirm" && solanaAddr && solanaProvider ? /* @__PURE__ */ jsx27(
9334
+ effectiveStep.type === "solana-confirm" && solanaAddr && solanaProvider ? /* @__PURE__ */ jsx28(
8786
9335
  SolanaConfirmStep,
8787
9336
  {
8788
9337
  smartAccount: effectiveStep.smartAccount,
@@ -8805,14 +9354,14 @@ function DepositFlow({
8805
9354
  }
8806
9355
  ) : effectiveStep.type === "solana-confirm" ? /* @__PURE__ */ jsxs23("div", { className: "rs-step", children: [
8807
9356
  /* @__PURE__ */ jsxs23("div", { className: "rs-loading-state", children: [
8808
- /* @__PURE__ */ jsx27("div", { className: "rs-step-icon rs-step-icon--error", children: /* @__PURE__ */ jsx27(
9357
+ /* @__PURE__ */ jsx28("div", { className: "rs-step-icon rs-step-icon--error", children: /* @__PURE__ */ jsx28(
8809
9358
  "svg",
8810
9359
  {
8811
9360
  viewBox: "0 0 24 24",
8812
9361
  fill: "none",
8813
9362
  stroke: "currentColor",
8814
9363
  strokeWidth: "2",
8815
- children: /* @__PURE__ */ jsx27(
9364
+ children: /* @__PURE__ */ jsx28(
8816
9365
  "path",
8817
9366
  {
8818
9367
  strokeLinecap: "round",
@@ -8823,21 +9372,21 @@ function DepositFlow({
8823
9372
  }
8824
9373
  ) }),
8825
9374
  /* @__PURE__ */ jsxs23("div", { className: "rs-loading-text", children: [
8826
- /* @__PURE__ */ jsx27("div", { className: "rs-loading-title rs-text-error", children: "Wallet disconnected" }),
8827
- /* @__PURE__ */ jsx27("div", { className: "rs-loading-subtitle", children: "Please reconnect your Solana wallet to continue." })
9375
+ /* @__PURE__ */ jsx28("div", { className: "rs-loading-title rs-text-error", children: "Wallet disconnected" }),
9376
+ /* @__PURE__ */ jsx28("div", { className: "rs-loading-subtitle", children: "Please reconnect your Solana wallet to continue." })
8828
9377
  ] })
8829
9378
  ] }),
8830
- /* @__PURE__ */ jsx27("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx27(
9379
+ /* @__PURE__ */ jsx28("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx28(
8831
9380
  "button",
8832
9381
  {
8833
9382
  type: "button",
8834
9383
  className: "rs-button rs-button--default rs-button--full-width",
8835
9384
  onClick: handleBack,
8836
- children: /* @__PURE__ */ jsx27("span", { children: "Go Back" })
9385
+ children: /* @__PURE__ */ jsx28("span", { children: "Go Back" })
8837
9386
  }
8838
9387
  ) })
8839
9388
  ] }) : null,
8840
- effectiveStep.type === "processing" && /* @__PURE__ */ jsx27(
9389
+ effectiveStep.type === "processing" && /* @__PURE__ */ jsx28(
8841
9390
  ProcessingStep,
8842
9391
  {
8843
9392
  smartAccount: effectiveStep.smartAccount,
@@ -8867,13 +9416,13 @@ function DepositFlow({
8867
9416
  ] });
8868
9417
  }
8869
9418
  if (isDappImportMode && effectiveStep.type === "dapp-import-resolving") {
8870
- return /* @__PURE__ */ jsx27(
9419
+ return /* @__PURE__ */ jsx28(
8871
9420
  "div",
8872
9421
  {
8873
9422
  className: "rs-modal-body",
8874
9423
  "data-flow-mode": "dapp-import",
8875
9424
  "data-step-type": effectiveStep.type,
8876
- children: /* @__PURE__ */ jsx27(
9425
+ children: /* @__PURE__ */ jsx28(
8877
9426
  DappImportAssetSelectSkeleton,
8878
9427
  {
8879
9428
  sourceLabel: activeDappImportProvider?.sourceLabel ?? "",
@@ -8885,13 +9434,13 @@ function DepositFlow({
8885
9434
  );
8886
9435
  }
8887
9436
  if (effectiveStep.type === "dapp-import-select") {
8888
- return /* @__PURE__ */ jsx27(
9437
+ return /* @__PURE__ */ jsx28(
8889
9438
  "div",
8890
9439
  {
8891
9440
  className: "rs-modal-body",
8892
9441
  "data-flow-mode": "dapp-import",
8893
9442
  "data-step-type": effectiveStep.type,
8894
- children: /* @__PURE__ */ jsx27(
9443
+ children: /* @__PURE__ */ jsx28(
8895
9444
  DappImportSelectStep,
8896
9445
  {
8897
9446
  enabledIds: enabledAssetMigrationIds,
@@ -8918,7 +9467,7 @@ function DepositFlow({
8918
9467
  );
8919
9468
  }
8920
9469
  if (!signerContext?.walletClient || !signerContext?.publicClient) {
8921
- return /* @__PURE__ */ jsx27("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx27("div", { className: "rs-step", children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-text", children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-title", children: "Connecting wallet\u2026" }) }) }) }) });
9470
+ return /* @__PURE__ */ jsx28("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx28("div", { className: "rs-step", children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-text", children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-title", children: "Connecting wallet\u2026" }) }) }) }) });
8922
9471
  }
8923
9472
  const ownerAddress = signerContext.ownerAddress;
8924
9473
  const ownerChainId = signerContext.walletClient?.chain?.id ?? signerContext.publicClient.chain?.id ?? setupChainId;
@@ -8929,14 +9478,14 @@ function DepositFlow({
8929
9478
  return getPublicClient(chainId, rpcUrls);
8930
9479
  };
8931
9480
  return /* @__PURE__ */ jsxs23("div", { className: "rs-modal-body", children: [
8932
- effectiveStep.type === "setup" && /* @__PURE__ */ jsx27(
9481
+ effectiveStep.type === "setup" && /* @__PURE__ */ jsx28(
8933
9482
  AccountPreparingSkeleton,
8934
9483
  {
8935
9484
  errorMessage: activeEntry.status === "error" ? activeEntry.message ?? void 0 : void 0,
8936
9485
  onRetry: activeEntry.status === "error" ? () => handleRetrySetup() : void 0
8937
9486
  }
8938
9487
  ),
8939
- effectiveStep.type === "select-asset" && /* @__PURE__ */ jsx27(
9488
+ effectiveStep.type === "select-asset" && /* @__PURE__ */ jsx28(
8940
9489
  AssetSelectStep,
8941
9490
  {
8942
9491
  address: ownerAddress,
@@ -8946,13 +9495,10 @@ function DepositFlow({
8946
9495
  service,
8947
9496
  onContinue: handleAssetContinue,
8948
9497
  onTotalBalanceComputed: handleTotalBalanceComputed,
8949
- onDisconnect: onDisconnect ? () => {
8950
- onDisconnect();
8951
- handleBack();
8952
- } : void 0
9498
+ onDisconnect: onDisconnect ? handleWalletDisconnect : void 0
8953
9499
  }
8954
9500
  ),
8955
- effectiveStep.type === "dapp-import-asset-select" && activeDappImportProvider && activeDappImportAvailability && /* @__PURE__ */ jsx27(
9501
+ effectiveStep.type === "dapp-import-asset-select" && activeDappImportProvider && activeDappImportAvailability && /* @__PURE__ */ jsx28(
8956
9502
  DappImportAssetSelectStep,
8957
9503
  {
8958
9504
  sourceLabel: activeDappImportAvailability.assets[0]?.sourceLabel ?? activeDappImportProvider.sourceLabel,
@@ -8961,7 +9507,7 @@ function DepositFlow({
8961
9507
  onSelect: handleDappImportAssetSelected
8962
9508
  }
8963
9509
  ),
8964
- effectiveStep.type === "amount" && /* @__PURE__ */ jsx27(
9510
+ effectiveStep.type === "amount" && /* @__PURE__ */ jsx28(
8965
9511
  AmountStep,
8966
9512
  {
8967
9513
  walletClient: signerContext.walletClient,
@@ -8978,18 +9524,11 @@ function DepositFlow({
8978
9524
  service,
8979
9525
  onContinue: handleAmountContinue,
8980
9526
  onCtaClick: (ctaName) => {
8981
- const receiveSymbol = getTargetTokenSymbol(targetToken, targetChainId);
8982
- onEvent?.({
8983
- type: "deposit_modal_connected_wallet_enter_value_cta_click",
8984
- send_token: effectiveStep.asset.symbol,
8985
- receive_token: receiveSymbol,
8986
- pred_balance: totalBalanceUsd,
8987
- cta_name: ctaName
8988
- });
9527
+ if (ctaName === "continue") analytics.completeStep();
8989
9528
  }
8990
9529
  }
8991
9530
  ),
8992
- effectiveStep.type === "confirm" && /* @__PURE__ */ jsx27(
9531
+ effectiveStep.type === "confirm" && /* @__PURE__ */ jsx28(
8993
9532
  ConfirmStep,
8994
9533
  {
8995
9534
  walletClient: signerContext.walletClient,
@@ -9038,7 +9577,7 @@ function DepositFlow({
9038
9577
  onError: handleError
9039
9578
  }
9040
9579
  ),
9041
- effectiveStep.type === "processing" && /* @__PURE__ */ jsx27(
9580
+ effectiveStep.type === "processing" && /* @__PURE__ */ jsx28(
9042
9581
  ProcessingStep,
9043
9582
  {
9044
9583
  smartAccount: effectiveStep.smartAccount,
@@ -9058,6 +9597,10 @@ function DepositFlow({
9058
9597
  initialEvent: effectiveStep.initialEvent,
9059
9598
  quote: effectiveStep.quote,
9060
9599
  uiConfig,
9600
+ onSourceTransactionObserved: (txHash) => analytics.observeCorrelator(
9601
+ { type: "transaction_hash", value: txHash },
9602
+ flowMode === "dapp-import" ? "migration_processing" : "wallet_processing"
9603
+ ),
9061
9604
  onClose,
9062
9605
  onNewDeposit: handleNewDeposit,
9063
9606
  onRetry: handleNewDeposit,
@@ -9071,8 +9614,8 @@ function DepositFlow({
9071
9614
  }
9072
9615
 
9073
9616
  // src/components/history/DepositHistoryPanel.tsx
9074
- import { useCallback as useCallback8, useMemo as useMemo8, useState as useState14 } from "react";
9075
- import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
9617
+ import { useCallback as useCallback8, useMemo as useMemo9, useState as useState14 } from "react";
9618
+ import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
9076
9619
  function shortenHash(hash) {
9077
9620
  if (hash.length <= 14) return hash;
9078
9621
  return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
@@ -9188,7 +9731,7 @@ function DepositHistoryPanel({
9188
9731
  },
9189
9732
  [onClose]
9190
9733
  );
9191
- const visibleDeposits = useMemo8(() => {
9734
+ const visibleDeposits = useMemo9(() => {
9192
9735
  const sourceHashes = new Set(
9193
9736
  deposits.map((d) => d.sourceTxHash?.toLowerCase()).filter((h) => Boolean(h))
9194
9737
  );
@@ -9205,54 +9748,54 @@ function DepositHistoryPanel({
9205
9748
  onKeyDown: handleKeyDown,
9206
9749
  children: [
9207
9750
  /* @__PURE__ */ jsxs24("div", { className: "rs-modal-header--redesigned", children: [
9208
- /* @__PURE__ */ jsx28("div", { className: "rs-modal-header-nav-left", children: /* @__PURE__ */ jsx28(
9751
+ /* @__PURE__ */ jsx29("div", { className: "rs-modal-header-nav-left", children: /* @__PURE__ */ jsx29(
9209
9752
  "button",
9210
9753
  {
9211
9754
  type: "button",
9212
9755
  className: "rs-modal-header-back",
9213
9756
  "aria-label": "Back",
9214
9757
  onClick: onClose,
9215
- children: /* @__PURE__ */ jsx28(ChevronLeftIcon, {})
9758
+ children: /* @__PURE__ */ jsx29(ChevronLeftIcon, {})
9216
9759
  }
9217
9760
  ) }),
9218
- /* @__PURE__ */ jsx28("div", { className: "rs-modal-header-nav-right", children: onCloseModal && /* @__PURE__ */ jsx28(
9761
+ /* @__PURE__ */ jsx29("div", { className: "rs-modal-header-nav-right", children: onCloseModal && /* @__PURE__ */ jsx29(
9219
9762
  "button",
9220
9763
  {
9221
9764
  type: "button",
9222
9765
  className: "rs-modal-close",
9223
9766
  "aria-label": "Close",
9224
9767
  onClick: onCloseModal,
9225
- children: /* @__PURE__ */ jsx28(CloseIcon, {})
9768
+ children: /* @__PURE__ */ jsx29(CloseIcon, {})
9226
9769
  }
9227
9770
  ) })
9228
9771
  ] }),
9229
9772
  /* @__PURE__ */ jsxs24("div", { className: "rs-history-screen", children: [
9230
9773
  /* @__PURE__ */ jsxs24("div", { className: "rs-history-screen-body", children: [
9231
- /* @__PURE__ */ jsx28(BodyHeader, { icon: /* @__PURE__ */ jsx28(HistoryIcon, {}), title: "History" }),
9774
+ /* @__PURE__ */ jsx29(BodyHeader, { icon: /* @__PURE__ */ jsx29(HistoryIcon, {}), title: "History" }),
9232
9775
  isLoading && deposits.length === 0 && /* @__PURE__ */ jsxs24("div", { className: "rs-history-empty", children: [
9233
- /* @__PURE__ */ jsx28("span", { className: "rs-history-empty-glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx28(HistoryIcon, {}) }),
9776
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-empty-glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx29(HistoryIcon, {}) }),
9234
9777
  /* @__PURE__ */ jsxs24("div", { className: "rs-history-empty-text", children: [
9235
- /* @__PURE__ */ jsx28(Spinner, { className: "rs-spinner--sm" }),
9236
- /* @__PURE__ */ jsx28("span", { className: "rs-history-empty-hint", children: "Loading history\u2026" })
9778
+ /* @__PURE__ */ jsx29(Spinner, { className: "rs-spinner--sm" }),
9779
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-empty-hint", children: "Loading history\u2026" })
9237
9780
  ] })
9238
9781
  ] }),
9239
9782
  error && !isLoading && /* @__PURE__ */ jsxs24("div", { className: "rs-history-empty", children: [
9240
- /* @__PURE__ */ jsx28("span", { className: "rs-history-empty-glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx28(AlertTriangleIcon, {}) }),
9783
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-empty-glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx29(AlertTriangleIcon, {}) }),
9241
9784
  /* @__PURE__ */ jsxs24("div", { className: "rs-history-empty-text", children: [
9242
- /* @__PURE__ */ jsx28("span", { className: "rs-history-empty-title", children: "Couldn't load history" }),
9243
- /* @__PURE__ */ jsx28("span", { className: "rs-history-empty-hint", children: error })
9785
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-empty-title", children: "Couldn't load history" }),
9786
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-empty-hint", children: error })
9244
9787
  ] })
9245
9788
  ] }),
9246
9789
  !isLoading && !error && visibleDeposits.length === 0 && /* @__PURE__ */ jsxs24("div", { className: "rs-history-empty", children: [
9247
- /* @__PURE__ */ jsx28("span", { className: "rs-history-empty-glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx28(HistoryIcon, {}) }),
9790
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-empty-glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx29(HistoryIcon, {}) }),
9248
9791
  /* @__PURE__ */ jsxs24("div", { className: "rs-history-empty-text", children: [
9249
- /* @__PURE__ */ jsx28("span", { className: "rs-history-empty-title", children: "No deposits yet" }),
9250
- /* @__PURE__ */ jsx28("span", { className: "rs-history-empty-hint", children: "Your deposit history will appear here" })
9792
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-empty-title", children: "No deposits yet" }),
9793
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-empty-hint", children: "Your deposit history will appear here" })
9251
9794
  ] })
9252
9795
  ] }),
9253
9796
  visibleDeposits.length > 0 && /* @__PURE__ */ jsxs24("div", { className: "rs-history-list", children: [
9254
- visibleDeposits.map((deposit, i) => /* @__PURE__ */ jsx28(HistoryCard, { deposit }, deposit.txHash || i)),
9255
- hasMore && /* @__PURE__ */ jsx28(
9797
+ visibleDeposits.map((deposit, i) => /* @__PURE__ */ jsx29(HistoryCard, { deposit }, deposit.txHash || i)),
9798
+ hasMore && /* @__PURE__ */ jsx29(
9256
9799
  "button",
9257
9800
  {
9258
9801
  type: "button",
@@ -9264,7 +9807,7 @@ function DepositHistoryPanel({
9264
9807
  )
9265
9808
  ] })
9266
9809
  ] }),
9267
- /* @__PURE__ */ jsx28(PoweredBy, {})
9810
+ /* @__PURE__ */ jsx29(PoweredBy, {})
9268
9811
  ] })
9269
9812
  ]
9270
9813
  }
@@ -9301,35 +9844,35 @@ function HistoryCard({ deposit }) {
9301
9844
  children: [
9302
9845
  /* @__PURE__ */ jsxs24("div", { className: "rs-history-card-row", children: [
9303
9846
  /* @__PURE__ */ jsxs24("div", { className: "rs-history-card-icons", children: [
9304
- /* @__PURE__ */ jsx28("span", { className: "rs-history-card-token", children: /* @__PURE__ */ jsx28(TokenIcon, { symbol: sourceSymbol, fallback: sourceSymbol.slice(0, 2) }) }),
9305
- sourceChainIcon && /* @__PURE__ */ jsx28("span", { className: "rs-history-card-chain", children: /* @__PURE__ */ jsx28(CdnIcon, { src: sourceChainIcon }) })
9847
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-card-token", children: /* @__PURE__ */ jsx29(TokenIcon, { symbol: sourceSymbol, fallback: sourceSymbol.slice(0, 2) }) }),
9848
+ sourceChainIcon && /* @__PURE__ */ jsx29("span", { className: "rs-history-card-chain", children: /* @__PURE__ */ jsx29(CdnIcon, { src: sourceChainIcon }) })
9306
9849
  ] }),
9307
9850
  /* @__PURE__ */ jsxs24("div", { className: "rs-history-card-text", children: [
9308
- /* @__PURE__ */ jsx28("span", { className: "rs-history-card-title", children: txTypeLabel }),
9309
- date && /* @__PURE__ */ jsx28("span", { className: "rs-history-card-date", children: date })
9851
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-card-title", children: txTypeLabel }),
9852
+ date && /* @__PURE__ */ jsx29("span", { className: "rs-history-card-date", children: date })
9310
9853
  ] }),
9311
9854
  /* @__PURE__ */ jsxs24("div", { className: "rs-history-card-side", children: [
9312
- /* @__PURE__ */ jsx28("span", { className: "rs-history-card-amount", children: displayAmount }),
9313
- /* @__PURE__ */ jsx28("span", { className: `rs-history-badge rs-history-badge--${status}`, children: STATUS_LABEL[status] })
9855
+ /* @__PURE__ */ jsx29("span", { className: "rs-history-card-amount", children: displayAmount }),
9856
+ /* @__PURE__ */ jsx29("span", { className: `rs-history-badge rs-history-badge--${status}`, children: STATUS_LABEL[status] })
9314
9857
  ] })
9315
9858
  ] }),
9316
- /* @__PURE__ */ jsx28("div", { className: "rs-history-card-panel", children: /* @__PURE__ */ jsx28("div", { className: "rs-history-card-panel-inner", children: /* @__PURE__ */ jsxs24("div", { className: "rs-history-card-details", children: [
9859
+ /* @__PURE__ */ jsx29("div", { className: "rs-history-card-panel", children: /* @__PURE__ */ jsx29("div", { className: "rs-history-card-panel-inner", children: /* @__PURE__ */ jsxs24("div", { className: "rs-history-card-details", children: [
9317
9860
  sourceChainName && /* @__PURE__ */ jsxs24("div", { className: "rs-amount-detail-row", children: [
9318
- /* @__PURE__ */ jsx28("span", { children: "Source chain" }),
9861
+ /* @__PURE__ */ jsx29("span", { children: "Source chain" }),
9319
9862
  /* @__PURE__ */ jsxs24("span", { className: "rs-amount-detail-value", children: [
9320
- /* @__PURE__ */ jsx28("span", { children: sourceChainName }),
9321
- sourceChainIcon && /* @__PURE__ */ jsx28("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx28(CdnIcon, { src: sourceChainIcon }) })
9863
+ /* @__PURE__ */ jsx29("span", { children: sourceChainName }),
9864
+ sourceChainIcon && /* @__PURE__ */ jsx29("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx29(CdnIcon, { src: sourceChainIcon }) })
9322
9865
  ] })
9323
9866
  ] }),
9324
9867
  targetChainName && /* @__PURE__ */ jsxs24("div", { className: "rs-amount-detail-row", children: [
9325
- /* @__PURE__ */ jsx28("span", { children: "Destination chain" }),
9868
+ /* @__PURE__ */ jsx29("span", { children: "Destination chain" }),
9326
9869
  /* @__PURE__ */ jsxs24("span", { className: "rs-amount-detail-value", children: [
9327
- /* @__PURE__ */ jsx28("span", { children: targetChainName }),
9328
- targetChainIcon && /* @__PURE__ */ jsx28("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx28(CdnIcon, { src: targetChainIcon }) })
9870
+ /* @__PURE__ */ jsx29("span", { children: targetChainName }),
9871
+ targetChainIcon && /* @__PURE__ */ jsx29("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx29(CdnIcon, { src: targetChainIcon }) })
9329
9872
  ] })
9330
9873
  ] }),
9331
9874
  srcTxUrl && srcTxHash && /* @__PURE__ */ jsxs24("div", { className: "rs-amount-detail-row", children: [
9332
- /* @__PURE__ */ jsx28("span", { children: "Transaction details" }),
9875
+ /* @__PURE__ */ jsx29("span", { children: "Transaction details" }),
9333
9876
  /* @__PURE__ */ jsxs24(
9334
9877
  "a",
9335
9878
  {
@@ -9339,8 +9882,8 @@ function HistoryCard({ deposit }) {
9339
9882
  className: "rs-history-card-link",
9340
9883
  onClick: (e) => e.stopPropagation(),
9341
9884
  children: [
9342
- /* @__PURE__ */ jsx28("span", { children: shortenHash(srcTxHash) }),
9343
- /* @__PURE__ */ jsx28(ArrowUpRightIcon, {})
9885
+ /* @__PURE__ */ jsx29("span", { children: shortenHash(srcTxHash) }),
9886
+ /* @__PURE__ */ jsx29(ArrowUpRightIcon, {})
9344
9887
  ]
9345
9888
  }
9346
9889
  )
@@ -9353,10 +9896,12 @@ function HistoryCard({ deposit }) {
9353
9896
  DepositHistoryPanel.displayName = "DepositHistoryPanel";
9354
9897
 
9355
9898
  // src/DepositModal.tsx
9356
- import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
9357
- var ReownDepositInner = lazy2(
9358
- () => import("./DepositModalReown-3H75G3XQ.mjs").then((m) => ({ default: m.DepositModalReown }))
9359
- );
9899
+ import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
9900
+ var ReownDepositInner = lazy2(async () => {
9901
+ await loadReownDependencies();
9902
+ const module = await import("./DepositModalReown-2EVV64OA.mjs");
9903
+ return { default: module.DepositModalReown };
9904
+ });
9360
9905
  function sortByCreatedAtDesc(items) {
9361
9906
  return [...items].sort((a, b) => {
9362
9907
  const at = a.createdAt ? Date.parse(a.createdAt) : 0;
@@ -9364,6 +9909,55 @@ function sortByCreatedAtDesc(items) {
9364
9909
  return bt - at;
9365
9910
  });
9366
9911
  }
9912
+ function buildDepositAnalyticsSessionProperties({
9913
+ enableWallet = true,
9914
+ enableFiatOnramp = false,
9915
+ enableQrTransfer = true,
9916
+ enableGaslessDeposit = false,
9917
+ enableExchangeConnect = false,
9918
+ fiatMethods,
9919
+ assetMigrations,
9920
+ initialAssetMigration,
9921
+ inline = false,
9922
+ closeOnOverlayClick = false,
9923
+ sourceChain,
9924
+ sourceToken,
9925
+ defaultAmount,
9926
+ walletIntegration,
9927
+ targetChain,
9928
+ targetToken
9929
+ }) {
9930
+ const configuredFiatIdentifiers = fiatMethods ? Object.entries(fiatMethods).filter(([, enabled]) => enabled === true).map(([identifier]) => identifier).sort() : null;
9931
+ const migrationProviders = Object.entries(assetMigrations ?? {}).filter(([, enabled]) => enabled === true).map(([identifier]) => identifier).sort();
9932
+ const safeInitialMigration = initialAssetMigration && migrationProviders.includes(initialAssetMigration) ? initialAssetMigration : null;
9933
+ const enabledFundingMethods = [];
9934
+ if (enableWallet && walletIntegration !== "none") {
9935
+ enabledFundingMethods.push("wallet");
9936
+ }
9937
+ if (enableQrTransfer) enabledFundingMethods.push("transfer");
9938
+ if (enableFiatOnramp && configuredFiatIdentifiers?.length !== 0) {
9939
+ enabledFundingMethods.push("fiat_onramp");
9940
+ }
9941
+ if (enableExchangeConnect) enabledFundingMethods.push("exchange_connect");
9942
+ if (migrationProviders.length > 0) enabledFundingMethods.push("asset_migration");
9943
+ return {
9944
+ enabled_funding_methods: enabledFundingMethods,
9945
+ wallet_integration: walletIntegration,
9946
+ fiat_methods: configuredFiatIdentifiers === null ? { source: "backend_resolved" } : { source: "configured", identifiers: configuredFiatIdentifiers },
9947
+ asset_migration_providers: migrationProviders,
9948
+ initial_asset_migration: safeInitialMigration,
9949
+ gasless_wallet_flow_enabled: enableGaslessDeposit,
9950
+ presentation: inline ? "inline" : "overlay",
9951
+ overlay_close_enabled: !inline && closeOnOverlayClick,
9952
+ prefills: {
9953
+ source_chain: sourceChain !== void 0,
9954
+ source_token: sourceToken !== void 0,
9955
+ amount: defaultAmount !== void 0,
9956
+ initial_asset_migration: initialAssetMigration !== void 0
9957
+ },
9958
+ ...analyticsTargetProperties({ targetChain, targetToken })
9959
+ };
9960
+ }
9367
9961
  var WALLET_CLIENT_PROP = "walletClient";
9368
9962
  function hasSuppliedWalletClient(props) {
9369
9963
  return Object.prototype.hasOwnProperty.call(props, WALLET_CLIENT_PROP);
@@ -9374,7 +9968,7 @@ function DepositModal(props) {
9374
9968
  const needsReown = !!props.reownAppId;
9375
9969
  const hasWalletClientProp = hasSuppliedWalletClient(props);
9376
9970
  if (needsReown) {
9377
- return /* @__PURE__ */ jsx29(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx29(
9971
+ return /* @__PURE__ */ jsx30(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx30(
9378
9972
  ReownDepositInner,
9379
9973
  {
9380
9974
  ...props,
@@ -9382,7 +9976,7 @@ function DepositModal(props) {
9382
9976
  }
9383
9977
  ) });
9384
9978
  }
9385
- return /* @__PURE__ */ jsx29(
9979
+ return /* @__PURE__ */ jsx30(
9386
9980
  DepositModalInner,
9387
9981
  {
9388
9982
  ...props,
@@ -9430,11 +10024,16 @@ function DepositModalInner({
9430
10024
  onLifecycle,
9431
10025
  onEvent,
9432
10026
  onError,
10027
+ enableAnalyticsIngest,
10028
+ analyticsIngestUrl,
9433
10029
  onUiState,
9434
10030
  openExternally,
10031
+ walletIntegration: walletIntegrationProp,
9435
10032
  debug
9436
10033
  }) {
9437
10034
  const modalRef = useRef9(null);
10035
+ const analyticsControllerRef = useRef9(null);
10036
+ const previousOpenRef = useRef9(isOpen);
9438
10037
  const onReadyRef = useLatestRef(onReady);
9439
10038
  const onUiStateRef = useLatestRef(onUiState);
9440
10039
  const [currentScreen, setCurrentScreen] = useState15("connect");
@@ -9456,7 +10055,7 @@ function DepositModalInner({
9456
10055
  const targetChain = targetChainProp === "solana" || targetChainProp === HYPERCORE_SPOT_CAIP2 ? targetChainProp : getChainId(targetChainProp);
9457
10056
  const sourceChain = sourceChainProp ? getChainId(sourceChainProp) : void 0;
9458
10057
  const rpcUrls = useStableRpcUrls(rpcUrlsProp);
9459
- const service = useMemo9(
10058
+ const service = useMemo10(
9460
10059
  () => createDepositService(backendUrl, {
9461
10060
  debug,
9462
10061
  debugScope: "service:deposit"
@@ -9481,7 +10080,7 @@ function DepositModalInner({
9481
10080
  console.debug("[deposit] client setup config (not shown yet)", clientSetup);
9482
10081
  }
9483
10082
  }, [debug, clientSetup]);
9484
- const store = useMemo9(
10083
+ const store = useMemo10(
9485
10084
  () => createDepositStore({ targetChain, targetToken }),
9486
10085
  // eslint-disable-next-line react-hooks/exhaustive-deps
9487
10086
  []
@@ -9591,6 +10190,31 @@ function DepositModalInner({
9591
10190
  },
9592
10191
  [onLifecycleRef, markHistoryStale]
9593
10192
  );
10193
+ const closeWithSource = useCallback9(
10194
+ (source) => {
10195
+ const analytics = analyticsControllerRef.current;
10196
+ analytics?.abandon(source === "provider_back" ? "provider_back" : "modal_close");
10197
+ analytics?.close(source);
10198
+ onClose();
10199
+ },
10200
+ [onClose]
10201
+ );
10202
+ const handleModalDismiss = useCallback9(
10203
+ (reason) => {
10204
+ closeWithSource(
10205
+ reason === "escape" ? "escape" : reason === "overlay" ? "overlay" : "header_button"
10206
+ );
10207
+ },
10208
+ [closeWithSource]
10209
+ );
10210
+ useEffect13(() => {
10211
+ if (previousOpenRef.current && !isOpen) {
10212
+ const analytics = analyticsControllerRef.current;
10213
+ analytics?.abandon("modal_close");
10214
+ analytics?.close("host_controlled");
10215
+ }
10216
+ previousOpenRef.current = isOpen;
10217
+ }, [isOpen]);
9594
10218
  useEffect13(() => {
9595
10219
  if (!isOpen) {
9596
10220
  setHistoryOpen(false);
@@ -9611,116 +10235,153 @@ function DepositModalInner({
9611
10235
  store.dispatch({ type: "flow/reset" });
9612
10236
  }
9613
10237
  }, [isOpen, store]);
10238
+ const walletIntegration = walletIntegrationProp ?? (hasWalletClientProp || walletSession || onRequestConnect ? "host_supplied" : "none");
10239
+ const analyticsSessionProperties = buildDepositAnalyticsSessionProperties({
10240
+ enableWallet,
10241
+ enableFiatOnramp,
10242
+ enableQrTransfer,
10243
+ enableGaslessDeposit,
10244
+ enableExchangeConnect,
10245
+ fiatMethods,
10246
+ assetMigrations,
10247
+ initialAssetMigration,
10248
+ inline,
10249
+ closeOnOverlayClick,
10250
+ sourceChain: sourceChainProp,
10251
+ sourceToken,
10252
+ defaultAmount,
10253
+ walletIntegration,
10254
+ targetChain,
10255
+ targetToken
10256
+ });
9614
10257
  const showBackButton = uiConfig?.showBackButton ?? true;
9615
10258
  const canGoBack = backHandler !== void 0;
9616
10259
  const hideHeaderChrome = swappedImmersive;
9617
10260
  const modalClassName = `rs-modal${hideHeaderChrome ? " rs-modal--swapped-iframe" : ""}`;
9618
- return /* @__PURE__ */ jsx29(RpcUrlsProvider, { value: rpcUrls, children: /* @__PURE__ */ jsx29(ChainCatalogProvider, { service, rpcUrls, children: /* @__PURE__ */ jsx29(DepositStoreProvider, { store, children: /* @__PURE__ */ jsx29(
10261
+ return /* @__PURE__ */ jsx30(RpcUrlsProvider, { value: rpcUrls, children: /* @__PURE__ */ jsx30(ChainCatalogProvider, { service, rpcUrls, children: /* @__PURE__ */ jsx30(DepositStoreProvider, { store, children: /* @__PURE__ */ jsx30(
9619
10262
  Modal,
9620
10263
  {
9621
10264
  isOpen,
9622
- onClose,
10265
+ onClose: handleModalDismiss,
9623
10266
  className,
9624
10267
  inline,
9625
10268
  closeOnOverlayClick,
9626
- children: /* @__PURE__ */ jsxs25("div", { ref: modalRef, className: modalClassName, children: [
9627
- !hideHeaderChrome && /* @__PURE__ */ jsxs25("div", { className: "rs-modal-header--redesigned", children: [
9628
- /* @__PURE__ */ jsx29("div", { className: "rs-modal-header-nav-left", children: showBackButton && canGoBack && backHandler && /* @__PURE__ */ jsx29(
9629
- "button",
10269
+ children: /* @__PURE__ */ jsx30(
10270
+ AnalyticsSession,
10271
+ {
10272
+ modal: "deposit",
10273
+ sessionProperties: analyticsSessionProperties,
10274
+ onEvent,
10275
+ backendUrl,
10276
+ enableIngest: enableAnalyticsIngest,
10277
+ ingestUrl: analyticsIngestUrl,
10278
+ children: /* @__PURE__ */ jsx30(
10279
+ DepositAnalyticsControllerProvider,
9630
10280
  {
9631
- type: "button",
9632
- className: "rs-modal-header-back",
9633
- "aria-label": "Go back",
9634
- onClick: backHandler,
9635
- children: /* @__PURE__ */ jsx29(ChevronLeftIcon, {})
10281
+ controllerRef: analyticsControllerRef,
10282
+ children: /* @__PURE__ */ jsxs25("div", { ref: modalRef, className: modalClassName, children: [
10283
+ !hideHeaderChrome && /* @__PURE__ */ jsxs25("div", { className: "rs-modal-header--redesigned", children: [
10284
+ /* @__PURE__ */ jsx30("div", { className: "rs-modal-header-nav-left", children: showBackButton && canGoBack && backHandler && /* @__PURE__ */ jsx30(
10285
+ "button",
10286
+ {
10287
+ type: "button",
10288
+ className: "rs-modal-header-back",
10289
+ "aria-label": "Go back",
10290
+ onClick: backHandler,
10291
+ children: /* @__PURE__ */ jsx30(ChevronLeftIcon, {})
10292
+ }
10293
+ ) }),
10294
+ /* @__PURE__ */ jsxs25("div", { className: "rs-modal-header-nav-right", children: [
10295
+ historyButtonVisible && /* @__PURE__ */ jsx30(
10296
+ "button",
10297
+ {
10298
+ type: "button",
10299
+ className: "rs-modal-header-history",
10300
+ "aria-label": "Deposit history",
10301
+ onClick: handleHistoryOpen,
10302
+ disabled: !recipient,
10303
+ children: /* @__PURE__ */ jsx30(HistoryIcon, {})
10304
+ }
10305
+ ),
10306
+ /* @__PURE__ */ jsx30(
10307
+ "button",
10308
+ {
10309
+ type: "button",
10310
+ onClick: () => closeWithSource("header_button"),
10311
+ className: "rs-modal-close",
10312
+ "aria-label": "Close",
10313
+ children: /* @__PURE__ */ jsx30(CloseIcon, {})
10314
+ }
10315
+ )
10316
+ ] })
10317
+ ] }),
10318
+ /* @__PURE__ */ jsx30(
10319
+ DepositFlow,
10320
+ {
10321
+ walletClientProp,
10322
+ publicClientProp,
10323
+ hasWalletClientProp,
10324
+ targetChain,
10325
+ targetToken,
10326
+ service,
10327
+ sourceChain,
10328
+ sourceToken,
10329
+ amount: defaultAmount,
10330
+ recipient,
10331
+ appBalanceUsd,
10332
+ outputTokenRules,
10333
+ rejectUnmapped,
10334
+ forceRegister,
10335
+ assetMigrations,
10336
+ initialAssetMigration,
10337
+ enableFiatOnramp,
10338
+ enableQrTransfer,
10339
+ enableGaslessDeposit,
10340
+ fiatMethods,
10341
+ enableWallet,
10342
+ enableExchangeConnect,
10343
+ walletSession,
10344
+ walletIntegration,
10345
+ onConnect,
10346
+ onDisconnect,
10347
+ onRequestConnect,
10348
+ uiConfig,
10349
+ appFees: clientSetup?.appFees,
10350
+ appFeesResolved: clientSetup !== null,
10351
+ onStepChange: handleStepChange,
10352
+ onSwappedImmersiveChange: setSwappedImmersive,
10353
+ openExternally,
10354
+ onSubmittingChange: setSubmitting,
10355
+ onClose: (source) => closeWithSource(source ?? "header_button"),
10356
+ onLifecycle: handleLifecycle,
10357
+ onError,
10358
+ debug
10359
+ }
10360
+ ),
10361
+ historyOpen && /* @__PURE__ */ jsx30(
10362
+ DepositHistoryPanel,
10363
+ {
10364
+ deposits: historyDeposits,
10365
+ isLoading: historyLoading,
10366
+ error: historyError,
10367
+ hasMore: hasMoreHistory,
10368
+ isLoadingMore: historyLoadingMore,
10369
+ onLoadMore: handleHistoryLoadMore,
10370
+ onClose: handleHistoryClose,
10371
+ onCloseModal: () => closeWithSource("header_button")
10372
+ }
10373
+ )
10374
+ ] })
9636
10375
  }
9637
- ) }),
9638
- /* @__PURE__ */ jsxs25("div", { className: "rs-modal-header-nav-right", children: [
9639
- historyButtonVisible && /* @__PURE__ */ jsx29(
9640
- "button",
9641
- {
9642
- type: "button",
9643
- className: "rs-modal-header-history",
9644
- "aria-label": "Deposit history",
9645
- onClick: handleHistoryOpen,
9646
- disabled: !recipient,
9647
- children: /* @__PURE__ */ jsx29(HistoryIcon, {})
9648
- }
9649
- ),
9650
- /* @__PURE__ */ jsx29(
9651
- "button",
9652
- {
9653
- type: "button",
9654
- onClick: onClose,
9655
- className: "rs-modal-close",
9656
- "aria-label": "Close",
9657
- children: /* @__PURE__ */ jsx29(CloseIcon, {})
9658
- }
9659
- )
9660
- ] })
9661
- ] }),
9662
- /* @__PURE__ */ jsx29(
9663
- DepositFlow,
9664
- {
9665
- walletClientProp,
9666
- publicClientProp,
9667
- hasWalletClientProp,
9668
- targetChain,
9669
- targetToken,
9670
- service,
9671
- sourceChain,
9672
- sourceToken,
9673
- amount: defaultAmount,
9674
- recipient,
9675
- appBalanceUsd,
9676
- outputTokenRules,
9677
- rejectUnmapped,
9678
- forceRegister,
9679
- assetMigrations,
9680
- initialAssetMigration,
9681
- enableFiatOnramp,
9682
- enableQrTransfer,
9683
- enableGaslessDeposit,
9684
- fiatMethods,
9685
- enableWallet,
9686
- enableExchangeConnect,
9687
- walletSession,
9688
- onConnect,
9689
- onDisconnect,
9690
- onRequestConnect,
9691
- uiConfig,
9692
- appFees: clientSetup?.appFees,
9693
- appFeesResolved: clientSetup !== null,
9694
- onStepChange: handleStepChange,
9695
- onSwappedImmersiveChange: setSwappedImmersive,
9696
- openExternally,
9697
- onSubmittingChange: setSubmitting,
9698
- onClose,
9699
- onLifecycle: handleLifecycle,
9700
- onEvent,
9701
- onError,
9702
- debug
9703
- }
9704
- ),
9705
- historyOpen && /* @__PURE__ */ jsx29(
9706
- DepositHistoryPanel,
9707
- {
9708
- deposits: historyDeposits,
9709
- isLoading: historyLoading,
9710
- error: historyError,
9711
- hasMore: hasMoreHistory,
9712
- isLoadingMore: historyLoadingMore,
9713
- onLoadMore: handleHistoryLoadMore,
9714
- onClose: handleHistoryClose,
9715
- onCloseModal: onClose
9716
- }
9717
- )
9718
- ] })
10376
+ )
10377
+ }
10378
+ )
9719
10379
  }
9720
10380
  ) }) }) });
9721
10381
  }
9722
10382
 
9723
10383
  export {
10384
+ getReownDependencies,
9724
10385
  DepositModal,
9725
10386
  DepositModalInner
9726
10387
  };