diff --git a/app/components/UI/UrlAutocomplete/index.tsx b/app/components/UI/UrlAutocomplete/index.tsx index fec59762f4f6..1dddcb4f09c2 100644 --- a/app/components/UI/UrlAutocomplete/index.tsx +++ b/app/components/UI/UrlAutocomplete/index.tsx @@ -38,6 +38,8 @@ import { Hex } from '@metamask/utils'; import Engine from '../../../core/Engine'; import { selectCurrentCurrency, selectUsdConversionRate } from '../../../selectors/currencyRateController'; import { SwapBridgeNavigationLocation, useSwapBridgeNavigation } from '../Bridge/hooks/useSwapBridgeNavigation'; +import { MetaMetricsEvents, useMetrics } from '../../hooks/useMetrics'; +import { JsonMap } from '../../../core/Analytics/MetaMetrics.types'; export * from './types'; @@ -211,15 +213,33 @@ const UrlAutocomplete = forwardRef< sourcePage: 'MainView', }); + const { trackEvent, createEventBuilder } = useMetrics(); + const goToSwaps = useCallback(async (result: TokenSearchResult) => { try { + let properties: JsonMap; + if (latestSearchTerm.current?.startsWith('0x')) { + properties = { + token_address: latestSearchTerm.current, + }; + } else { + properties = { + token_symbol: result.symbol, + }; + } + trackEvent( + createEventBuilder(MetaMetricsEvents.TOKEN_SEARCH_DISCOVERY_TOKEN_SWAP_OPENED) + .addProperties(properties) + .build() + ); + await goToSwapsHook(result); } catch (error) { return; } hide(); onDismiss(); - }, [hide, onDismiss, goToSwapsHook]); + }, [hide, onDismiss, goToSwapsHook, trackEvent, createEventBuilder]); const renderSectionHeader = useCallback(({section: { category }}: {section: ResultsWithCategory}) => ( diff --git a/app/components/Views/BrowserTab/BrowserTab.tsx b/app/components/Views/BrowserTab/BrowserTab.tsx index 2561d3e96843..0bbf27921d90 100644 --- a/app/components/Views/BrowserTab/BrowserTab.tsx +++ b/app/components/Views/BrowserTab/BrowserTab.tsx @@ -114,6 +114,7 @@ import UrlAutocomplete, { UrlAutocompleteRef, } from '../../UI/UrlAutocomplete'; import { selectSearchEngine } from '../../../reducers/browser/selectors'; +import { JsonMap } from '../../../core/Analytics/MetaMetrics.types'; import { getPermittedEthChainIds } from '@metamask/chain-agnostic-permission'; import { getPhishingTestResult, @@ -169,6 +170,7 @@ export const BrowserTab: React.FC = React.memo(({ // Track if webview is loaded for the first time const isWebViewReadyToLoad = useRef(false); const urlBarRef = useRef(null); + const urlBarText = useRef(''); const autocompleteRef = useRef(null); const onSubmitEditingRef = useRef<(text: string) => Promise>( async () => { @@ -1248,15 +1250,38 @@ export const BrowserTab: React.FC = React.memo(({ urlBarRef.current?.hide(); if (item.category === 'tokens') { + let properties: JsonMap; + if (urlBarText.current.startsWith('0x')) { + properties = { + token_address: urlBarText.current, + }; + } else { + properties = { + token_symbol: item.symbol, + }; + } + trackEvent( + createEventBuilder(MetaMetricsEvents.TOKEN_SEARCH_DISCOVERY_TOKEN_DETAILS_OPENED) + .addProperties(properties) + .build() + ); + navigation.navigate(Routes.BROWSER.ASSET_LOADER, { chainId: item.chainId, address: item.address, }); } else { + trackEvent( + createEventBuilder(MetaMetricsEvents.TOKEN_SEARCH_DISCOVERY_SITE_OPENED) + .addProperties({ + url: item.url, + }) + .build() + ); onSubmitEditing(item.url); } }, - [onSubmitEditing, navigation], + [onSubmitEditing, navigation, trackEvent, createEventBuilder] ); /** @@ -1295,6 +1320,7 @@ export const BrowserTab: React.FC = React.memo(({ const onChangeUrlBar = useCallback((text: string) => { // Search the autocomplete results autocompleteRef.current?.search(text); + urlBarText.current = text; }, []); const handleWebviewNavigationChange = useCallback( diff --git a/app/core/Analytics/MetaMetrics.events.ts b/app/core/Analytics/MetaMetrics.events.ts index 0cc0110032e8..bd2d157d1c56 100644 --- a/app/core/Analytics/MetaMetrics.events.ts +++ b/app/core/Analytics/MetaMetrics.events.ts @@ -432,6 +432,11 @@ enum EVENT_NAME { // Tooltip TOOLTIP_OPENED = 'Tooltip Opened', + // Token Search and Discovery + TOKEN_SEARCH_DISCOVERY_SITE_OPENED = 'Token Search and Discovery Site Opened', + TOKEN_SEARCH_DISCOVERY_TOKEN_DETAILS_OPENED = 'Token Search and Discovery Token Details Opened', + TOKEN_SEARCH_DISCOVERY_TOKEN_SWAP_OPENED = 'Token Search and Discovery Token Swap Opened', + // RPC Failover RPC_SERVICE_UNAVAILABLE = 'RPC Service Unavailable', RPC_SERVICE_DEGRADED = 'RPC Service Degraded', @@ -1030,6 +1035,17 @@ const events = { ), TOKEN_DETAILS_OPENED: generateOpt(EVENT_NAME.TOKEN_LIST_ITEM_PRESSED), + // Token Search and Discovery + TOKEN_SEARCH_DISCOVERY_SITE_OPENED: generateOpt( + EVENT_NAME.TOKEN_SEARCH_DISCOVERY_SITE_OPENED, + ), + TOKEN_SEARCH_DISCOVERY_TOKEN_DETAILS_OPENED: generateOpt( + EVENT_NAME.TOKEN_SEARCH_DISCOVERY_TOKEN_DETAILS_OPENED, + ), + TOKEN_SEARCH_DISCOVERY_TOKEN_SWAP_OPENED: generateOpt( + EVENT_NAME.TOKEN_SEARCH_DISCOVERY_TOKEN_SWAP_OPENED, + ), + // Bridge BRIDGE_PAGE_VIEWED: generateOpt(EVENT_NAME.BRIDGE_PAGE_VIEWED), SWAP_PAGE_VIEWED: generateOpt(EVENT_NAME.SWAP_PAGE_VIEWED), // Temporary event until unified swap/bridge is done