diff --git a/src/analytics/event.ts b/src/analytics/event.ts index ee0bea6145..a14b86f457 100644 --- a/src/analytics/event.ts +++ b/src/analytics/event.ts @@ -207,6 +207,10 @@ export const event = { */ settingsRainbowDefaultProviderEnabled: 'settings.rainbow_default_provider.enabled', + /** + * Called when a user enters the swaps flow + */ + swapOpened: 'swap.opened', /** * Called when the user completes a Swap/Bridge and submits the transaction. * This includes cross-chain swaps, while `bridgeSubmitted` is instead called @@ -755,6 +759,18 @@ export type EventProperties = { [event.settingsRainbowDefaultProviderEnabled]: undefined; [event.settingsFlashbotsDisabled]: undefined; [event.settingsFlashbotsEnabled]: undefined; + [event.swapOpened]: { + /** + * Entrypoint of the swaps flow. + */ + entryPoint: + | 'commandk' // command k action + | 'home_header_swap_button' // Home header swap button + | 'home_shortcut_x_key' // 'X' key shortcut + | 'token_context_menu' // Token context menu + | 'token_details' // Token details + | 'token_details_shortcut_x_key'; // Token details 'X' key shortcut + }; [event.swapSubmitted]: { /** * Symbol of the input asset being swapped. diff --git a/src/entries/popup/components/CommandK/useCommands.tsx b/src/entries/popup/components/CommandK/useCommands.tsx index d90e34481e..d64a174296 100644 --- a/src/entries/popup/components/CommandK/useCommands.tsx +++ b/src/entries/popup/components/CommandK/useCommands.tsx @@ -4,6 +4,8 @@ import { To } from 'react-router-dom'; import { Address } from 'viem'; import { useEnsName } from 'wagmi'; +import { analytics } from '~/analytics'; +import { event } from '~/analytics/event'; import { i18n } from '~/core/languages'; import { shortcuts } from '~/core/references/shortcuts'; import { useCurrentAddressStore, useFlashbotsEnabledStore } from '~/core/state'; @@ -733,6 +735,15 @@ export const useCommands = ( const isFullScreen = useIsFullScreen(); const navigate = useRainbowNavigate(); const navigateToSwaps = useNavigateToSwaps(); + + // Wrapped to add analytics + const wrappedNavigateToSwaps = React.useCallback(() => { + navigateToSwaps(); + analytics.track(event.swapOpened, { + entryPoint: 'commandk', + }); + }, [navigateToSwaps]); + const { isWatchingWallet } = useWallets(); const save = useSavedEnsNames.use.save(); const toggleHideNFTStore = useNftsStore.use.toggleHideNFT(); @@ -1019,7 +1030,7 @@ export const useCommands = ( () => ({ // PAGE: HOME swap: { - action: navigateToSwaps, + action: wrappedNavigateToSwaps, }, bridge: { action: () => navigate(ROUTES.BRIDGE), @@ -1415,7 +1426,7 @@ export const useCommands = ( }, }), [ - navigateToSwaps, + wrappedNavigateToSwaps, isWatchingWallet, ensName, address, diff --git a/src/entries/popup/hooks/useHomeShortcuts.ts b/src/entries/popup/hooks/useHomeShortcuts.ts index 6d02312b9b..cbebed6d06 100644 --- a/src/entries/popup/hooks/useHomeShortcuts.ts +++ b/src/entries/popup/hooks/useHomeShortcuts.ts @@ -2,6 +2,8 @@ import { useCallback, useMemo } from 'react'; import { useLocation } from 'react-router-dom'; import { useEnsName } from 'wagmi'; +import { analytics } from '~/analytics'; +import { event } from '~/analytics/event'; import { i18n } from '~/core/languages'; import { shortcuts } from '~/core/references/shortcuts'; import { useDappMetadata } from '~/core/resources/metadata/dapp'; @@ -159,11 +161,14 @@ export function useHomeShortcuts() { navigate(ROUTES.SETTINGS); break; case shortcuts.home.GO_TO_SWAP.key: + navigateToSwaps(); + analytics.track(event.swapOpened, { + entryPoint: 'home_shortcut_x_key', + }); trackShortcut({ key: shortcuts.home.GO_TO_SWAP.display, type: 'home.goToSwap', }); - navigateToSwaps(); break; case shortcuts.home.GO_TO_PROFILE.key: if (!selectedToken && !isTokenDetailsPage) { diff --git a/src/entries/popup/hooks/useTokensShortcuts.ts b/src/entries/popup/hooks/useTokensShortcuts.ts index 5c75081190..417eef46b1 100644 --- a/src/entries/popup/hooks/useTokensShortcuts.ts +++ b/src/entries/popup/hooks/useTokensShortcuts.ts @@ -2,6 +2,8 @@ import { useCallback, useMemo } from 'react'; import { useLocation } from 'react-router'; import { Address } from 'viem'; +import { analytics } from '~/analytics'; +import { event } from '~/analytics/event'; import config from '~/core/firebase/remoteConfig'; import { i18n } from '~/core/languages'; import { shortcuts } from '~/core/references/shortcuts'; @@ -134,11 +136,14 @@ export function useTokensShortcuts() { if (selectedToken && isHomeRoute) { if (e.key === shortcuts.tokens.SWAP_ASSET.key) { if (allowSwap) { + navigateToSwaps(); + analytics.track(event.swapOpened, { + entryPoint: 'token_details_shortcut_x_key', + }); trackShortcut({ key: shortcuts.tokens.SWAP_ASSET.display, type: 'tokens.goToSwap', }); - navigateToSwaps(); } else { triggerAlert({ text: i18n.t('alert.coming_soon') }); // clear selected token diff --git a/src/entries/popup/pages/home/Header.tsx b/src/entries/popup/pages/home/Header.tsx index 941a6425bb..75da1c76e0 100644 --- a/src/entries/popup/pages/home/Header.tsx +++ b/src/entries/popup/pages/home/Header.tsx @@ -2,6 +2,8 @@ import { motion, useTransform } from 'framer-motion'; import * as React from 'react'; +import { analytics } from '~/analytics'; +import { event } from '~/analytics/event'; import config from '~/core/firebase/remoteConfig'; import { i18n } from '~/core/languages'; import { shortcuts } from '~/core/references/shortcuts'; @@ -228,6 +230,9 @@ function ActionButtonsSection() { } } else { navigateToSwaps(); + analytics.track(event.swapOpened, { + entryPoint: 'home_header_swap_button', + }); } }} tooltipHint={shortcuts.home.GO_TO_SWAP.display} diff --git a/src/entries/popup/pages/home/TokenDetails/TokenContextMenu.tsx b/src/entries/popup/pages/home/TokenDetails/TokenContextMenu.tsx index cde9892606..857893b441 100644 --- a/src/entries/popup/pages/home/TokenDetails/TokenContextMenu.tsx +++ b/src/entries/popup/pages/home/TokenDetails/TokenContextMenu.tsx @@ -1,5 +1,7 @@ import { ReactNode, useCallback } from 'react'; +import { analytics } from '~/analytics'; +import { event } from '~/analytics/event'; import config from '~/core/firebase/remoteConfig'; import { i18n } from '~/core/languages'; import { shortcuts } from '~/core/references/shortcuts'; @@ -74,6 +76,9 @@ export function TokenContextMenu({ children, token }: TokenContextMenuProps) { if (allowSwap) { isNavigating = true; navigateToSwaps(); + analytics.track(event.swapOpened, { + entryPoint: 'token_context_menu', + }); } else { triggerAlert({ text: i18n.t('alert.coming_soon') }); setSelectedToken(); // clear selected token diff --git a/src/entries/popup/pages/home/TokenDetails/TokenDetails.tsx b/src/entries/popup/pages/home/TokenDetails/TokenDetails.tsx index b5e42f9158..19fbff1377 100644 --- a/src/entries/popup/pages/home/TokenDetails/TokenDetails.tsx +++ b/src/entries/popup/pages/home/TokenDetails/TokenDetails.tsx @@ -2,6 +2,8 @@ import { useCallback, useEffect, useReducer } from 'react'; import { Navigate, To, useParams, useSearchParams } from 'react-router-dom'; import { Address } from 'viem'; +import { analytics } from '~/analytics'; +import { event } from '~/analytics/event'; import { i18n } from '~/core/languages'; import { ETH_ADDRESS } from '~/core/references'; import { shortcuts } from '~/core/references/shortcuts'; @@ -197,7 +199,12 @@ function SwapSend({ width="full" color="accent" symbol="arrow.triangle.swap" - onClick={() => selectTokenAndNavigate(ROUTES.SWAP)} + onClick={() => { + selectTokenAndNavigate(ROUTES.SWAP); + analytics.track(event.swapOpened, { + entryPoint: 'token_details', + }); + }} tabIndex={0} > {i18n.t('token_details.swap')}