From 2326b2041c1783dcdf2113fd062900f52837b704 Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Mon, 3 Jun 2024 10:45:51 -0400 Subject: [PATCH 1/6] add analytics --- .../screens/Swap/components/FlipButton.tsx | 11 ++- .../screens/Swap/components/GasButton.tsx | 28 ++++-- .../screens/Swap/components/SearchInput.tsx | 9 ++ .../components/TokenList/ChainSelection.tsx | 8 ++ .../screens/Swap/hooks/useSelectedGas.ts | 16 ++-- .../Swap/hooks/useSwapInputsController.ts | 7 ++ .../screens/Swap/hooks/useSwapSettings.ts | 20 +++- .../screens/Swap/providers/swap-provider.tsx | 39 +++++++- src/analytics/event.ts | 92 ++++++++++++++++++- 9 files changed, 204 insertions(+), 26 deletions(-) diff --git a/src/__swaps__/screens/Swap/components/FlipButton.tsx b/src/__swaps__/screens/Swap/components/FlipButton.tsx index c43134dd4e9..955844f086d 100644 --- a/src/__swaps__/screens/Swap/components/FlipButton.tsx +++ b/src/__swaps__/screens/Swap/components/FlipButton.tsx @@ -12,20 +12,27 @@ import { AnimatedBlurView } from '@/__swaps__/screens/Swap/components/AnimatedBl import { useSwapContext } from '@/__swaps__/screens/Swap/providers/swap-provider'; import { TIMING_CONFIGS } from '@/components/animations/animationConfigs'; import { SwapAssetType } from '@/__swaps__/types/swap'; +import { analyticsV2 } from '@/analytics'; export const FlipButton = () => { const { isDarkMode } = useColorMode(); - const { AnimatedSwapStyles, internalSelectedInputAsset, internalSelectedOutputAsset, setAsset } = useSwapContext(); + const { AnimatedSwapStyles, internalSelectedInputAsset, internalSelectedOutputAsset, setAsset, SwapInputController } = useSwapContext(); const handleSwapAssets = useCallback(() => { if (internalSelectedInputAsset.value && internalSelectedOutputAsset.value) { const assetTypeToSet = SwapAssetType.outputAsset; const assetToSet = internalSelectedInputAsset.value; + analyticsV2.track(analyticsV2.event.swapsFlippedAssets, { + inputAmount: SwapInputController.inputValues.value.inputAmount, + previousInputAsset: internalSelectedInputAsset.value, + previousOutputAsset: internalSelectedOutputAsset.value, + }); + setAsset({ type: assetTypeToSet, asset: assetToSet }); } - }, [internalSelectedInputAsset, internalSelectedOutputAsset, /* lastTypedInput, */ setAsset]); + }, [SwapInputController.inputValues.value, internalSelectedInputAsset.value, internalSelectedOutputAsset.value, setAsset]); const flipButtonInnerStyles = useAnimatedStyle(() => { return { diff --git a/src/__swaps__/screens/Swap/components/GasButton.tsx b/src/__swaps__/screens/Swap/components/GasButton.tsx index 76d45315560..cdd7a385608 100644 --- a/src/__swaps__/screens/Swap/components/GasButton.tsx +++ b/src/__swaps__/screens/Swap/components/GasButton.tsx @@ -1,5 +1,6 @@ import { ChainId } from '@/__swaps__/types/chains'; import { weiToGwei } from '@/__swaps__/utils/ethereum'; +import { OnPressMenuItemEventObject } from 'react-native-ios-context-menu'; import { getCachedCurrentBaseFee, useMeteorologySuggestions } from '@/__swaps__/utils/meteorology'; import { add } from '@/__swaps__/utils/numbers'; import { ContextMenu } from '@/components/context-menu'; @@ -8,7 +9,7 @@ import ContextMenuButton from '@/components/native-context-menu/contextMenu'; import { Box, Inline, Text, TextIcon, useColorMode, useForegroundColor } from '@/design-system'; import { IS_ANDROID } from '@/env'; import * as i18n from '@/languages'; -import { useSwapsStore } from '@/state/swaps/swapsStore'; +import { swapsStore, useSwapsStore } from '@/state/swaps/swapsStore'; import { gasUtils } from '@/utils'; import React, { ReactNode, useCallback, useMemo } from 'react'; import { StyleSheet } from 'react-native'; @@ -16,11 +17,13 @@ import { runOnJS, runOnUI } from 'react-native-reanimated'; import { ETH_COLOR, ETH_COLOR_DARK, THICK_BORDER_WIDTH } from '../constants'; import { formatNumber } from '../hooks/formatNumber'; import { GasSettings, useCustomGasSettings } from '../hooks/useCustomGas'; -import { GasSpeed, setSelectedGasSpeed, useSelectedGas, useSelectedGasSpeed } from '../hooks/useSelectedGas'; +import { GasSpeed } from '@/__swaps__/types/gas'; +import { setSelectedGasSpeed, useSelectedGas, useSelectedGasSpeed } from '../hooks/useSelectedGas'; import { useSwapContext } from '../providers/swap-provider'; import { EstimatedSwapGasFee } from './EstimatedSwapGasFee'; import { GestureHandlerV1Button } from './GestureHandlerV1Button'; import { ButtonPressAnimation } from '@/components/animations'; +import { analyticsV2 } from '@/analytics'; const { GAS_ICONS } = gasUtils; const GAS_BUTTON_HIT_SLOP = 16; @@ -87,13 +90,20 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c const metereologySuggestions = useMeteorologySuggestions({ chainId }); const customGasSettings = useCustomGasSettings(chainId); - const menuOptions = useMemo(() => [...keys(metereologySuggestions.data), 'custom'] as const, [metereologySuggestions.data]); + const menuOptions = useMemo(() => [...keys(metereologySuggestions.data), GasSpeed.CUSTOM] as const, [metereologySuggestions.data]); const handlePressSpeedOption = useCallback( (selectedGasSpeed: GasSpeed) => { - setSelectedGasSpeed(chainId, selectedGasSpeed); + const { inputAsset, outputAsset, quote } = swapsStore.getState(); + analyticsV2.track(analyticsV2.event.swapsChangedSelectedGasSpeed, { + inputAsset, + outputAsset, + selectedGasSpeed, + quote, + }); - if (selectedGasSpeed === 'custom') { + setSelectedGasSpeed(chainId, selectedGasSpeed); + if (selectedGasSpeed === GasSpeed.CUSTOM) { runOnUI(SwapNavigation.handleShowGas)({ backToReview }); } }, @@ -101,12 +111,12 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c ); const handlePressMenuItem = useCallback( - ({ nativeEvent: { actionKey } }: any) => handlePressSpeedOption(actionKey), + ({ nativeEvent: { actionKey } }: OnPressMenuItemEventObject) => handlePressSpeedOption(actionKey as GasSpeed), [handlePressSpeedOption] ); const handlePressActionSheet = useCallback( - (buttonIndex: number) => handlePressSpeedOption(menuOptions[buttonIndex]), + (buttonIndex: number) => handlePressSpeedOption(menuOptions[buttonIndex] as GasSpeed), [handlePressSpeedOption, menuOptions] ); @@ -115,7 +125,7 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c if (IS_ANDROID) return gasOption; const currentBaseFee = getCachedCurrentBaseFee(chainId); - const gasSettings = gasOption === 'custom' ? customGasSettings : metereologySuggestions.data?.[gasOption]; + const gasSettings = gasOption === GasSpeed.CUSTOM ? customGasSettings : metereologySuggestions.data?.[gasOption]; const subtitle = getEstimatedFeeRangeInGwei(gasSettings, currentBaseFee); return { @@ -176,7 +186,7 @@ export function ReviewGasButton() { const handleShowCustomGas = () => { 'worklet'; - runOnJS(setSelectedGasSpeed)(internalSelectedInputAsset.value?.chainId || ChainId.mainnet, 'custom'); + runOnJS(setSelectedGasSpeed)(internalSelectedInputAsset.value?.chainId || ChainId.mainnet, GasSpeed.CUSTOM); SwapNavigation.handleShowGas({ backToReview: true }); }; diff --git a/src/__swaps__/screens/Swap/components/SearchInput.tsx b/src/__swaps__/screens/Swap/components/SearchInput.tsx index ae2e3b8a5e7..a30109a323a 100644 --- a/src/__swaps__/screens/Swap/components/SearchInput.tsx +++ b/src/__swaps__/screens/Swap/components/SearchInput.tsx @@ -18,6 +18,7 @@ import { ExtendedAnimatedAssetWithColors } from '@/__swaps__/types/assets'; import { GestureHandlerV1Button } from './GestureHandlerV1Button'; import { useDebouncedCallback } from 'use-debounce'; import { useSwapsStore } from '@/state/swaps/swapsStore'; +import { analyticsV2 } from '@/analytics'; const AnimatedInput = Animated.createAnimatedComponent(Input); @@ -73,6 +74,10 @@ export const SearchInput = ({ const onInputSearchQueryChange = useDebouncedCallback( (text: string) => { userAssetsStore.getState().setSearchQuery(text); + analyticsV2.track(analyticsV2.event.swapsSearchedForToken, { + query: text, + type: 'input', + }); }, 50, { leading: true, trailing: true } @@ -80,6 +85,10 @@ export const SearchInput = ({ const onOutputSearchQueryChange = useDebouncedCallback( (text: string) => { + analyticsV2.track(analyticsV2.event.swapsSearchedForToken, { + query: text, + type: 'output', + }); useSwapsStore.setState({ outputSearchQuery: text }); }, 100, diff --git a/src/__swaps__/screens/Swap/components/TokenList/ChainSelection.tsx b/src/__swaps__/screens/Swap/components/TokenList/ChainSelection.tsx index e2663ab5593..f23e02f4b5b 100644 --- a/src/__swaps__/screens/Swap/components/TokenList/ChainSelection.tsx +++ b/src/__swaps__/screens/Swap/components/TokenList/ChainSelection.tsx @@ -17,6 +17,8 @@ import { OnPressMenuItemEventObject } from 'react-native-ios-context-menu'; import { userAssetsStore } from '@/state/assets/userAssets'; import { useSharedValueState } from '@/hooks/reanimated/useSharedValueState'; import { chainNameForChainIdWithMainnetSubstitution } from '@/__swaps__/utils/chains'; +import { analyticsV2 } from '@/analytics'; +import { swapsStore } from '@/state/swaps/swapsStore'; type ChainSelectionProps = { allText?: string; @@ -50,6 +52,12 @@ export const ChainSelection = memo(function ChainSelection({ allText, output }: const handleSelectChain = useCallback( ({ nativeEvent: { actionKey } }: Omit) => { + analyticsV2.track(analyticsV2.event.swapsChangedChainId, { + inputAsset: swapsStore.getState().inputAsset, + type: output ? 'output' : 'input', + chainId: Number(actionKey) as ChainId, + }); + if (output) { setSelectedOutputChainId(Number(actionKey) as ChainId); } else { diff --git a/src/__swaps__/screens/Swap/hooks/useSelectedGas.ts b/src/__swaps__/screens/Swap/hooks/useSelectedGas.ts index 1e8cfe3ec3d..b94d34de547 100644 --- a/src/__swaps__/screens/Swap/hooks/useSelectedGas.ts +++ b/src/__swaps__/screens/Swap/hooks/useSelectedGas.ts @@ -3,30 +3,30 @@ import { getCachedGasSuggestions, useMeteorologySuggestions } from '@/__swaps__/ import { createRainbowStore } from '@/state/internal/createRainbowStore'; import { useMemo } from 'react'; import { getCustomGasSettings, useCustomGasSettings } from './useCustomGas'; +import { GasSpeed } from '@/__swaps__/types/gas'; -export type GasSpeed = 'custom' | 'urgent' | 'fast' | 'normal'; const useSelectedGasSpeedStore = createRainbowStore<{ [c in ChainId]?: GasSpeed }>(() => ({}), { version: 0, storageKey: 'preferred gas speed', }); export const useSelectedGasSpeed = (chainId: ChainId) => useSelectedGasSpeedStore(s => { - const speed = s[chainId] || 'fast'; - if (speed === 'custom' && getCustomGasSettings(chainId) === undefined) return 'fast'; + const speed = s[chainId] || GasSpeed.FAST; + if (speed === GasSpeed.CUSTOM && getCustomGasSettings(chainId) === undefined) return GasSpeed.FAST; return speed; }); export const setSelectedGasSpeed = (chainId: ChainId, speed: GasSpeed) => useSelectedGasSpeedStore.setState({ [chainId]: speed }); -export const getSelectedGasSpeed = (chainId: ChainId) => useSelectedGasSpeedStore.getState()[chainId] || 'fast'; +export const getSelectedGasSpeed = (chainId: ChainId) => useSelectedGasSpeedStore.getState()[chainId] || GasSpeed.FAST; export function useGasSettings(chainId: ChainId, speed: GasSpeed) { const userCustomGasSettings = useCustomGasSettings(chainId); const { data: metereologySuggestions } = useMeteorologySuggestions({ chainId, - enabled: speed !== 'custom', + enabled: speed !== GasSpeed.CUSTOM, }); return useMemo(() => { - if (speed === 'custom') return userCustomGasSettings; + if (speed === GasSpeed.CUSTOM) return userCustomGasSettings; return metereologySuggestions?.[speed]; }, [speed, userCustomGasSettings, metereologySuggestions]); } @@ -45,11 +45,11 @@ export function getGasSettingsBySpeed(chainId: ChainId) { } export function getGasSettings(speed: GasSpeed, chainId: ChainId) { - if (speed === 'custom') return getCustomGasSettings(chainId); + if (speed === GasSpeed.CUSTOM) return getCustomGasSettings(chainId); return getCachedGasSuggestions(chainId)?.[speed]; } export function getSelectedGas(chainId: ChainId) { - const selectedGasSpeed = useSelectedGasSpeedStore.getState()[chainId] || 'fast'; + const selectedGasSpeed = useSelectedGasSpeedStore.getState()[chainId] || GasSpeed.FAST; return getGasSettings(selectedGasSpeed, chainId); } diff --git a/src/__swaps__/screens/Swap/hooks/useSwapInputsController.ts b/src/__swaps__/screens/Swap/hooks/useSwapInputsController.ts index 754712da8fe..a7c16f35a2e 100644 --- a/src/__swaps__/screens/Swap/hooks/useSwapInputsController.ts +++ b/src/__swaps__/screens/Swap/hooks/useSwapInputsController.ts @@ -30,6 +30,7 @@ import { import { ethereumUtils } from '@/utils'; import { queryClient } from '@/react-query'; import { userAssetsStore } from '@/state/assets/userAssets'; +import { analyticsV2 } from '@/analytics'; function getInitialInputValues() { const initialSelectedInputAsset = userAssetsStore.getState().getHighestValueAsset(); @@ -482,6 +483,12 @@ export function useSwapInputsController({ ) : undefined; + analyticsV2.track(analyticsV2.event.swapsReceivedQuote, { + inputAsset: internalSelectedInputAsset.value, + outputAsset: internalSelectedOutputAsset.value, + quote: quoteResponse, + }); + runOnUI(() => { setQuote({ data: quoteResponse, diff --git a/src/__swaps__/screens/Swap/hooks/useSwapSettings.ts b/src/__swaps__/screens/Swap/hooks/useSwapSettings.ts index de8ea866af8..819a7760a70 100644 --- a/src/__swaps__/screens/Swap/hooks/useSwapSettings.ts +++ b/src/__swaps__/screens/Swap/hooks/useSwapSettings.ts @@ -6,6 +6,8 @@ import { slippageStep } from '@/__swaps__/screens/Swap/constants'; import { getDefaultSlippageWorklet } from '@/__swaps__/utils/swaps'; import { ChainId } from '@/__swaps__/types/chains'; import { DEFAULT_CONFIG } from '@/model/remoteConfig'; +import { useCallback } from 'react'; +import { analyticsV2 } from '@/analytics'; export const useSwapSettings = ({ inputAsset }: { inputAsset: SharedValue }) => { const flashbots = useSharedValue(swapsStore.getState().flashbots); @@ -22,6 +24,22 @@ export const useSwapSettings = ({ inputAsset }: { inputAsset: SharedValue { + const { inputAsset, outputAsset, quote } = swapsStore.getState(); + + setSlippage(value); + + analyticsV2.track(analyticsV2.event.swapsChangedMaximumSlippage, { + slippage: value, + inputAsset, + outputAsset, + quote, + }); + }, + [setSlippage] + ); + const onUpdateSlippage = (operation: 'plus' | 'minus') => { 'worklet'; @@ -34,7 +52,7 @@ export const useSwapSettings = ({ inputAsset }: { inputAsset: SharedValue { }; } - const { errorMessage } = await walletExecuteRap(wallet, type, { + analyticsV2.track(analyticsV2.event.swapsSubmittedSwap, { + createdAt: Date.now(), + type, + parameters, + selectedGas, + slippage: swapsStore.getState().slippage, + }); + + const { errorMessage, nonce } = await walletExecuteRap(wallet, type, { ...parameters, gasParams, // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -207,6 +216,15 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { if (errorMessage) { SwapInputController.quoteFetchingInterval.start(); + analyticsV2.track(analyticsV2.event.swapsSwapFailed, { + createdAt: Date.now(), + type, + parameters, + selectedGas, + slippage: swapsStore.getState().slippage, + errorMessage, + }); + if (errorMessage !== 'handled') { logger.error(new RainbowError(`[getNonceAndPerformSwap]: Error executing swap: ${errorMessage}`)); const extractedError = errorMessage.split('[')[0]; @@ -223,7 +241,15 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { }), }); - // TODO: Analytics + analyticsV2.track(analyticsV2.event.swapsSwapSucceeded, { + createdAt: Date.now(), + nonce, + type, + parameters, + selectedGas, + slippage: swapsStore.getState().slippage, + }); + NotificationManager?.postNotification('rapCompleted'); Navigation.handleAction(Routes.PROFILE_SCREEN, {}); }; @@ -231,7 +257,6 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { const executeSwap = () => { 'worklet'; - // TODO: Analytics if (configProgress.value !== NavigationSteps.SHOW_REVIEW) return; const inputAsset = internalSelectedInputAsset.value; @@ -386,6 +411,12 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { ? internalSelectedInputAsset.value?.uniqueId !== extendedAsset?.uniqueId : internalSelectedOutputAsset.value?.uniqueId !== extendedAsset?.uniqueId; + analyticsV2.track(analyticsV2.event.swapsSelectedAsset, { + asset, + otherAsset: otherSelectedAsset, + type, + }); + runOnUI(() => { const didSelectedAssetChange = type === SwapAssetType.inputAsset diff --git a/src/analytics/event.ts b/src/analytics/event.ts index da792e577f4..1013ba15b32 100644 --- a/src/analytics/event.ts +++ b/src/analytics/event.ts @@ -1,9 +1,16 @@ -import { UnlockableAppIconKey, unlockableAppIcons } from '@/appIcons/appIcons'; +import { GasSettings } from '@/__swaps__/screens/Swap/hooks/useCustomGas'; +import { ExtendedAnimatedAssetWithColors, ParsedSearchAsset } from '@/__swaps__/types/assets'; +import { ChainId } from '@/__swaps__/types/chains'; +import { GasSpeed } from '@/__swaps__/types/gas'; +import { SwapAssetType } from '@/__swaps__/types/swap'; +import { UnlockableAppIconKey } from '@/appIcons/appIcons'; import { CardType } from '@/components/cards/GenericCard'; import { LearnCategory } from '@/components/cards/utils/types'; import { FiatProviderName } from '@/entities/f2c'; import { Network } from '@/networks/types'; +import { RapSwapActionParameters } from '@/raps/references'; import { RequestSource } from '@/utils/requestNavigationHandlers'; +import { CrosschainQuote, Quote, QuoteError } from '@rainbow-me/swaps'; /** * All events, used by `analytics.track()` @@ -20,7 +27,7 @@ export const event = { swapSubmitted: 'Submitted Swap', // notification promo sheet was shown notificationsPromoShown: 'notifications_promo.shown', - // only for iOS — initial prompt is not allowed — Android is enabled by default + // only for iOS — initial prompt is not allowed — Android is enabled by default notificationsPromoPermissionsBlocked: 'notifications_promo.permissions_blocked', // only for iOS, Android is enabled by default notificationsPromoPermissionsGranted: 'notifications_promo.permissions_granted', @@ -126,8 +133,37 @@ export const event = { txRequestApprove: 'request.approved', addNewWalletGroupName: 'add_new_wallet_group.name', + + // swaps related analytics + swapsSelectedAsset: 'swaps.selected_asset', + swapsSearchedForToken: 'swaps.searched_for_token', + swapsChangedChainId: 'swaps.changed_chain_id', + swapsFlippedAssets: 'swaps.flipped_assets', + swapsToggledFlashbots: 'swaps.toggled_flashbots', + swapsChangedMaximumSlippage: 'swaps.changed_maximum_slippage', + swapsChangedSelectedGasSpeed: 'swaps.changed_selected_gas_speed', + swapsReceivedQuote: 'swaps.received_quote', + swapsSubmittedSwap: 'swaps.submitted_swap', + swapsSwapFailed: 'swaps.swap_failed', + swapsSwapSucceeded: 'swaps.swap_succeeded', } as const; +type SwapEventParameters = { + createdAt: number; + type: T; + parameters: Omit, 'gasParams' | 'gasFeeParamsBySpeed' | 'selectedGasFee'>; + selectedGas: GasSettings; + slippage: string; +}; + +type SwapsEventFailedParameters = { + errorMessage: string | null; +} & SwapEventParameters; + +type SwapsEventSucceededParameters = { + nonce: number | undefined; +} & SwapEventParameters; + /** * Properties corresponding to each event */ @@ -474,4 +510,56 @@ export type EventProperties = { [event.addNewWalletGroupName]: { name: string; }; + + // swaps related events + [event.swapsSelectedAsset]: { + asset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + otherAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + type: SwapAssetType; + }; + + [event.swapsSearchedForToken]: { + query: string; + type: 'input' | 'output'; + }; + + [event.swapsChangedChainId]: { + inputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + type: 'input' | 'output'; + chainId: ChainId; + }; + + [event.swapsFlippedAssets]: { + inputAmount: string | number; + previousInputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + previousOutputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + }; + + [event.swapsToggledFlashbots]: { + enabled: boolean; + }; + + [event.swapsChangedMaximumSlippage]: { + inputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + outputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + quote: Quote | CrosschainQuote | QuoteError | null; + slippage: string; + }; + + [event.swapsChangedSelectedGasSpeed]: { + inputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + outputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + selectedGasSpeed: GasSpeed; + quote: Quote | CrosschainQuote | QuoteError | null; + }; + + [event.swapsReceivedQuote]: { + inputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + outputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; + quote: Quote | CrosschainQuote | QuoteError | null; + }; + + [event.swapsSubmittedSwap]: SwapEventParameters<'swap' | 'crosschainSwap'>; + [event.swapsSwapFailed]: SwapsEventFailedParameters<'swap' | 'crosschainSwap'>; + [event.swapsSwapSucceeded]: SwapsEventSucceededParameters<'swap' | 'crosschainSwap'>; }; From 00b0f2ce33013d375c0f7ee295c96c2ae46f8829 Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Mon, 3 Jun 2024 12:56:42 -0400 Subject: [PATCH 2/6] clean up analytics and add bridging and native values --- .../screens/Swap/providers/swap-provider.tsx | 28 ++++++++----------- src/analytics/event.ts | 13 +++++---- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/__swaps__/screens/Swap/providers/swap-provider.tsx b/src/__swaps__/screens/Swap/providers/swap-provider.tsx index 3e92c0a9786..08c19ba4034 100644 --- a/src/__swaps__/screens/Swap/providers/swap-provider.tsx +++ b/src/__swaps__/screens/Swap/providers/swap-provider.tsx @@ -166,6 +166,9 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { const providerUrl = provider?.connection?.url; const connectedToHardhat = isHardHat(providerUrl); + const isBridge = swapsStore.getState().inputAsset?.mainnetAddress === swapsStore.getState().outputAsset?.mainnetAddress; + const slippage = swapsStore.getState().slippage; + const selectedGas = getSelectedGas(parameters.chainId); if (!selectedGas) { runOnUI(resetSwappingStatus)(); @@ -197,31 +200,24 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { }; } - analyticsV2.track(analyticsV2.event.swapsSubmittedSwap, { - createdAt: Date.now(), - type, - parameters, - selectedGas, - slippage: swapsStore.getState().slippage, - }); - - const { errorMessage, nonce } = await walletExecuteRap(wallet, type, { + const { errorMessage } = await walletExecuteRap(wallet, type, { ...parameters, gasParams, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - gasFeeParamsBySpeed: gasFeeParamsBySpeed as any, + // @ts-expect-error - collision between old gas types and new + gasFeeParamsBySpeed: gasFeeParamsBySpeed, }); runOnUI(resetSwappingStatus)(); if (errorMessage) { SwapInputController.quoteFetchingInterval.start(); - analyticsV2.track(analyticsV2.event.swapsSwapFailed, { + analyticsV2.track(analyticsV2.event.swapsFailed, { createdAt: Date.now(), type, parameters, selectedGas, - slippage: swapsStore.getState().slippage, + slippage, + bridge: isBridge, errorMessage, }); @@ -241,13 +237,13 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { }), }); - analyticsV2.track(analyticsV2.event.swapsSwapSucceeded, { + analyticsV2.track(analyticsV2.event.swapsSubmitted, { createdAt: Date.now(), - nonce, type, parameters, selectedGas, - slippage: swapsStore.getState().slippage, + slippage, + bridge: isBridge, }); NotificationManager?.postNotification('rapCompleted'); diff --git a/src/analytics/event.ts b/src/analytics/event.ts index 1013ba15b32..5f06427af84 100644 --- a/src/analytics/event.ts +++ b/src/analytics/event.ts @@ -143,14 +143,15 @@ export const event = { swapsChangedMaximumSlippage: 'swaps.changed_maximum_slippage', swapsChangedSelectedGasSpeed: 'swaps.changed_selected_gas_speed', swapsReceivedQuote: 'swaps.received_quote', - swapsSubmittedSwap: 'swaps.submitted_swap', - swapsSwapFailed: 'swaps.swap_failed', - swapsSwapSucceeded: 'swaps.swap_succeeded', + swapsSubmitted: 'swaps.submitted', + swapsFailed: 'swaps.failed', + swapsSucceeded: 'swaps.succeeded', } as const; type SwapEventParameters = { createdAt: number; type: T; + bridge: boolean; parameters: Omit, 'gasParams' | 'gasFeeParamsBySpeed' | 'selectedGasFee'>; selectedGas: GasSettings; slippage: string; @@ -559,7 +560,7 @@ export type EventProperties = { quote: Quote | CrosschainQuote | QuoteError | null; }; - [event.swapsSubmittedSwap]: SwapEventParameters<'swap' | 'crosschainSwap'>; - [event.swapsSwapFailed]: SwapsEventFailedParameters<'swap' | 'crosschainSwap'>; - [event.swapsSwapSucceeded]: SwapsEventSucceededParameters<'swap' | 'crosschainSwap'>; + [event.swapsSubmitted]: SwapEventParameters<'swap' | 'crosschainSwap'>; + [event.swapsFailed]: SwapsEventFailedParameters<'swap' | 'crosschainSwap'>; + [event.swapsSucceeded]: SwapsEventSucceededParameters<'swap' | 'crosschainSwap'>; }; From 685e7338bc65a910d021f97fa878c1c65e0a7ab7 Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Mon, 3 Jun 2024 12:59:05 -0400 Subject: [PATCH 3/6] add native values and cleanup --- src/__swaps__/screens/Swap/providers/swap-provider.tsx | 6 ++++++ src/analytics/event.ts | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/__swaps__/screens/Swap/providers/swap-provider.tsx b/src/__swaps__/screens/Swap/providers/swap-provider.tsx index 08c19ba4034..778f775f573 100644 --- a/src/__swaps__/screens/Swap/providers/swap-provider.tsx +++ b/src/__swaps__/screens/Swap/providers/swap-provider.tsx @@ -219,6 +219,9 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { slippage, bridge: isBridge, errorMessage, + // TODO: Does this work from the JS thread? + inputNativeValue: SwapInputController.inputValues.value.inputNativeValue, + outputNativeValue: SwapInputController.inputValues.value.outputNativeValue, }); if (errorMessage !== 'handled') { @@ -244,6 +247,9 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { selectedGas, slippage, bridge: isBridge, + // TODO: Does this work from the JS thread? + inputNativeValue: SwapInputController.inputValues.value.inputNativeValue, + outputNativeValue: SwapInputController.inputValues.value.outputNativeValue, }); NotificationManager?.postNotification('rapCompleted'); diff --git a/src/analytics/event.ts b/src/analytics/event.ts index 5f06427af84..55a6de42f0d 100644 --- a/src/analytics/event.ts +++ b/src/analytics/event.ts @@ -152,6 +152,8 @@ type SwapEventParameters = { createdAt: number; type: T; bridge: boolean; + inputNativeValue: string | number; + outputNativeValue: string | number; parameters: Omit, 'gasParams' | 'gasFeeParamsBySpeed' | 'selectedGasFee'>; selectedGas: GasSettings; slippage: string; From da76f746d5896dc54931aee4fd32902f37b4543f Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Mon, 3 Jun 2024 13:38:46 -0400 Subject: [PATCH 4/6] fix lint --- src/__swaps__/screens/Swap/components/GasPanel.tsx | 5 +++-- src/__swaps__/utils/meteorology.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/__swaps__/screens/Swap/components/GasPanel.tsx b/src/__swaps__/screens/Swap/components/GasPanel.tsx index 2402552e183..f936dfe70d0 100644 --- a/src/__swaps__/screens/Swap/components/GasPanel.tsx +++ b/src/__swaps__/screens/Swap/components/GasPanel.tsx @@ -28,6 +28,7 @@ import { formatNumber } from '../hooks/formatNumber'; import { GasSettings, getCustomGasSettings, setCustomGasSettings, useCustomGasStore } from '../hooks/useCustomGas'; import { setSelectedGasSpeed, useSelectedGasSpeed } from '../hooks/useSelectedGas'; import { EstimatedSwapGasFee } from './EstimatedSwapGasFee'; +import { GasSpeed } from '@/__swaps__/types/gas'; const MINER_TIP_TYPE = 'minerTip'; const MAX_BASE_FEE_TYPE = 'maxBaseFee'; @@ -316,12 +317,12 @@ function saveCustomGasSettings() { const { inputAsset } = useSwapsStore.getState(); const chainId = inputAsset?.chainId || ChainId.mainnet; if (!unsaved) { - if (getCustomGasSettings(chainId)) setSelectedGasSpeed(chainId, 'custom'); + if (getCustomGasSettings(chainId)) setSelectedGasSpeed(chainId, GasSpeed.CUSTOM); return; } setCustomGasSettings(chainId, unsaved); - setSelectedGasSpeed(chainId, 'custom'); + setSelectedGasSpeed(chainId, GasSpeed.CUSTOM); useGasPanelStore.setState(undefined); } diff --git a/src/__swaps__/utils/meteorology.ts b/src/__swaps__/utils/meteorology.ts index cff7bc1b5f3..69d8c1fcec4 100644 --- a/src/__swaps__/utils/meteorology.ts +++ b/src/__swaps__/utils/meteorology.ts @@ -7,8 +7,9 @@ import { QueryConfig, QueryFunctionArgs, QueryFunctionResult, createQueryKey, qu import { getNetworkFromChainId } from '@/utils/ethereumUtils'; import { useCallback } from 'react'; import { GasSettings } from '../screens/Swap/hooks/useCustomGas'; -import { GasSpeed, getSelectedGasSpeed, useGasSettings } from '../screens/Swap/hooks/useSelectedGas'; +import { getSelectedGasSpeed, useGasSettings } from '../screens/Swap/hooks/useSelectedGas'; import { getMinimalTimeUnitStringForMs } from './time'; +import { GasSpeed } from '../types/gas'; // Query Types @@ -239,7 +240,7 @@ export function useMeteorologySuggestion select(speed === 'custom' ? undefined : selectGasSuggestions(d)[speed]), + (d: MeteorologyResult) => select(speed === GasSpeed.CUSTOM ? undefined : selectGasSuggestions(d)[speed]), [select, speed] ), enabled: enabled && speed !== 'custom', From c918add434b80dcd6c5f1cab7ef3444278a21c06 Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Wed, 5 Jun 2024 11:41:26 -0400 Subject: [PATCH 5/6] fix cast --- src/__swaps__/screens/Swap/components/GasButton.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/__swaps__/screens/Swap/components/GasButton.tsx b/src/__swaps__/screens/Swap/components/GasButton.tsx index cdd7a385608..c4bd872be85 100644 --- a/src/__swaps__/screens/Swap/components/GasButton.tsx +++ b/src/__swaps__/screens/Swap/components/GasButton.tsx @@ -90,7 +90,7 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c const metereologySuggestions = useMeteorologySuggestions({ chainId }); const customGasSettings = useCustomGasSettings(chainId); - const menuOptions = useMemo(() => [...keys(metereologySuggestions.data), GasSpeed.CUSTOM] as const, [metereologySuggestions.data]); + const menuOptions = useMemo(() => [...keys(metereologySuggestions.data), GasSpeed.CUSTOM] as GasSpeed[], [metereologySuggestions.data]); const handlePressSpeedOption = useCallback( (selectedGasSpeed: GasSpeed) => { @@ -116,7 +116,10 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c ); const handlePressActionSheet = useCallback( - (buttonIndex: number) => handlePressSpeedOption(menuOptions[buttonIndex] as GasSpeed), + (buttonIndex: number) => { + if (buttonIndex < 0) return; + handlePressSpeedOption(menuOptions[buttonIndex]); + }, [handlePressSpeedOption, menuOptions] ); From 14898730edd3f3a0e9270e48855c28c71b917c18 Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Tue, 11 Jun 2024 09:17:55 -0400 Subject: [PATCH 6/6] code review changes --- .../screens/Swap/components/FlipButton.tsx | 2 +- .../screens/Swap/components/GasButton.tsx | 17 +++------- .../screens/Swap/components/SearchInput.tsx | 31 +++++-------------- .../TokenList/TokenToBuySection.tsx | 12 +++++++ .../components/TokenList/TokenToSellList.tsx | 12 +++++++ .../screens/Swap/hooks/useSwapSettings.ts | 20 +----------- .../screens/Swap/providers/swap-provider.tsx | 25 ++++++++------- src/analytics/event.ts | 17 +--------- 8 files changed, 52 insertions(+), 84 deletions(-) diff --git a/src/__swaps__/screens/Swap/components/FlipButton.tsx b/src/__swaps__/screens/Swap/components/FlipButton.tsx index 955844f086d..53cdc34656a 100644 --- a/src/__swaps__/screens/Swap/components/FlipButton.tsx +++ b/src/__swaps__/screens/Swap/components/FlipButton.tsx @@ -32,7 +32,7 @@ export const FlipButton = () => { setAsset({ type: assetTypeToSet, asset: assetToSet }); } - }, [SwapInputController.inputValues.value, internalSelectedInputAsset.value, internalSelectedOutputAsset.value, setAsset]); + }, [SwapInputController.inputValues, internalSelectedInputAsset, internalSelectedOutputAsset, setAsset]); const flipButtonInnerStyles = useAnimatedStyle(() => { return { diff --git a/src/__swaps__/screens/Swap/components/GasButton.tsx b/src/__swaps__/screens/Swap/components/GasButton.tsx index c4bd872be85..71a31c8ea88 100644 --- a/src/__swaps__/screens/Swap/components/GasButton.tsx +++ b/src/__swaps__/screens/Swap/components/GasButton.tsx @@ -9,7 +9,7 @@ import ContextMenuButton from '@/components/native-context-menu/contextMenu'; import { Box, Inline, Text, TextIcon, useColorMode, useForegroundColor } from '@/design-system'; import { IS_ANDROID } from '@/env'; import * as i18n from '@/languages'; -import { swapsStore, useSwapsStore } from '@/state/swaps/swapsStore'; +import { swapsStore } from '@/state/swaps/swapsStore'; import { gasUtils } from '@/utils'; import React, { ReactNode, useCallback, useMemo } from 'react'; import { StyleSheet } from 'react-native'; @@ -23,13 +23,12 @@ import { useSwapContext } from '../providers/swap-provider'; import { EstimatedSwapGasFee } from './EstimatedSwapGasFee'; import { GestureHandlerV1Button } from './GestureHandlerV1Button'; import { ButtonPressAnimation } from '@/components/animations'; -import { analyticsV2 } from '@/analytics'; const { GAS_ICONS } = gasUtils; const GAS_BUTTON_HIT_SLOP = 16; function EstimatedGasFee() { - const chainId = useSwapsStore(s => s.inputAsset?.chainId || ChainId.mainnet); + const chainId = swapsStore(s => s.inputAsset?.chainId || ChainId.mainnet); const gasSettings = useSelectedGas(chainId); return ( @@ -43,7 +42,7 @@ function EstimatedGasFee() { } function SelectedGas() { - const chainId = useSwapsStore(s => s.inputAsset?.chainId || ChainId.mainnet); + const chainId = swapsStore(s => s.inputAsset?.chainId || ChainId.mainnet); const selectedGasSpeed = useSelectedGasSpeed(chainId); return ( @@ -86,7 +85,7 @@ function keys(obj: Record | undefined) { const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; children: ReactNode }) => { const { SwapNavigation } = useSwapContext(); - const chainId = useSwapsStore(s => s.inputAsset?.chainId || ChainId.mainnet); + const chainId = swapsStore(s => s.inputAsset?.chainId || ChainId.mainnet); const metereologySuggestions = useMeteorologySuggestions({ chainId }); const customGasSettings = useCustomGasSettings(chainId); @@ -94,14 +93,6 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c const handlePressSpeedOption = useCallback( (selectedGasSpeed: GasSpeed) => { - const { inputAsset, outputAsset, quote } = swapsStore.getState(); - analyticsV2.track(analyticsV2.event.swapsChangedSelectedGasSpeed, { - inputAsset, - outputAsset, - selectedGasSpeed, - quote, - }); - setSelectedGasSpeed(chainId, selectedGasSpeed); if (selectedGasSpeed === GasSpeed.CUSTOM) { runOnUI(SwapNavigation.handleShowGas)({ backToReview }); diff --git a/src/__swaps__/screens/Swap/components/SearchInput.tsx b/src/__swaps__/screens/Swap/components/SearchInput.tsx index 36c3cb3dede..1df585b4256 100644 --- a/src/__swaps__/screens/Swap/components/SearchInput.tsx +++ b/src/__swaps__/screens/Swap/components/SearchInput.tsx @@ -18,7 +18,6 @@ import { ExtendedAnimatedAssetWithColors } from '@/__swaps__/types/assets'; import { GestureHandlerV1Button } from './GestureHandlerV1Button'; import { useDebouncedCallback } from 'use-debounce'; import { useSwapsStore } from '@/state/swaps/swapsStore'; -import { analyticsV2 } from '@/analytics'; import * as i18n from '@/languages'; const AnimatedInput = Animated.createAnimatedComponent(Input); @@ -78,29 +77,15 @@ export const SearchInput = ({ }; }); - const onInputSearchQueryChange = useDebouncedCallback( - (text: string) => { - userAssetsStore.getState().setSearchQuery(text); - analyticsV2.track(analyticsV2.event.swapsSearchedForToken, { - query: text, - type: 'input', - }); - }, - 50, - { leading: true, trailing: true } - ); + const onInputSearchQueryChange = useDebouncedCallback((text: string) => userAssetsStore.getState().setSearchQuery(text), 50, { + leading: true, + trailing: true, + }); - const onOutputSearchQueryChange = useDebouncedCallback( - (text: string) => { - analyticsV2.track(analyticsV2.event.swapsSearchedForToken, { - query: text, - type: 'output', - }); - useSwapsStore.setState({ outputSearchQuery: text }); - }, - 100, - { leading: false, trailing: true } - ); + const onOutputSearchQueryChange = useDebouncedCallback((text: string) => useSwapsStore.setState({ outputSearchQuery: text }), 100, { + leading: false, + trailing: true, + }); const isSearchFocused = useDerivedValue( () => diff --git a/src/__swaps__/screens/Swap/components/TokenList/TokenToBuySection.tsx b/src/__swaps__/screens/Swap/components/TokenList/TokenToBuySection.tsx index e6f0cf370c8..bca98d0bbd8 100644 --- a/src/__swaps__/screens/Swap/components/TokenList/TokenToBuySection.tsx +++ b/src/__swaps__/screens/Swap/components/TokenList/TokenToBuySection.tsx @@ -19,6 +19,8 @@ import { userAssetsStore } from '@/state/assets/userAssets'; import { EXPANDED_INPUT_HEIGHT } from '../../constants'; import { DEVICE_WIDTH } from '@/utils/deviceUtils'; import { getStandardizedUniqueIdWorklet } from '@/__swaps__/utils/swaps'; +import { swapsStore } from '@/state/swaps/swapsStore'; +import { analyticsV2 } from '@/analytics'; interface SectionProp { color: TextStyle['color']; @@ -95,6 +97,16 @@ export const TokenToBuySection = ({ section }: { section: AssetToBuySection }) = type: SwapAssetType.outputAsset, asset: parsedAsset, }); + + const { outputSearchQuery } = swapsStore.getState(); + + // track what search query the user had prior to selecting an asset + if (outputSearchQuery.trim().length) { + analyticsV2.track(analyticsV2.event.swapsSearchedForToken, { + query: outputSearchQuery, + type: 'output', + }); + } }, [internalSelectedInputAsset, internalSelectedOutputAsset, isFetching, isQuoteStale, setAsset] ); diff --git a/src/__swaps__/screens/Swap/components/TokenList/TokenToSellList.tsx b/src/__swaps__/screens/Swap/components/TokenList/TokenToSellList.tsx index 811a989805e..fdd9455507b 100644 --- a/src/__swaps__/screens/Swap/components/TokenList/TokenToSellList.tsx +++ b/src/__swaps__/screens/Swap/components/TokenList/TokenToSellList.tsx @@ -14,6 +14,8 @@ import { EXPANDED_INPUT_HEIGHT } from '../../constants'; import { DEVICE_WIDTH } from '@/utils/deviceUtils'; import { getStandardizedUniqueIdWorklet } from '@/__swaps__/utils/swaps'; import { useDelayedMount } from '@/hooks/useDelayedMount'; +import { swapsStore } from '@/state/swaps/swapsStore'; +import { analyticsV2 } from '@/analytics'; export const TokenToSellList = () => { const shouldMount = useDelayedMount(); @@ -43,6 +45,16 @@ const TokenToSellListComponent = () => { type: SwapAssetType.inputAsset, asset: token, }); + + const { inputSearchQuery } = userAssetsStore.getState(); + + // track what search query the user had prior to selecting an asset + if (inputSearchQuery.trim().length) { + analyticsV2.track(analyticsV2.event.swapsSearchedForToken, { + query: inputSearchQuery, + type: 'input', + }); + } }, [internalSelectedInputAsset, internalSelectedOutputAsset, isFetching, isQuoteStale, setAsset] ); diff --git a/src/__swaps__/screens/Swap/hooks/useSwapSettings.ts b/src/__swaps__/screens/Swap/hooks/useSwapSettings.ts index 819a7760a70..de8ea866af8 100644 --- a/src/__swaps__/screens/Swap/hooks/useSwapSettings.ts +++ b/src/__swaps__/screens/Swap/hooks/useSwapSettings.ts @@ -6,8 +6,6 @@ import { slippageStep } from '@/__swaps__/screens/Swap/constants'; import { getDefaultSlippageWorklet } from '@/__swaps__/utils/swaps'; import { ChainId } from '@/__swaps__/types/chains'; import { DEFAULT_CONFIG } from '@/model/remoteConfig'; -import { useCallback } from 'react'; -import { analyticsV2 } from '@/analytics'; export const useSwapSettings = ({ inputAsset }: { inputAsset: SharedValue }) => { const flashbots = useSharedValue(swapsStore.getState().flashbots); @@ -24,22 +22,6 @@ export const useSwapSettings = ({ inputAsset }: { inputAsset: SharedValue { - const { inputAsset, outputAsset, quote } = swapsStore.getState(); - - setSlippage(value); - - analyticsV2.track(analyticsV2.event.swapsChangedMaximumSlippage, { - slippage: value, - inputAsset, - outputAsset, - quote, - }); - }, - [setSlippage] - ); - const onUpdateSlippage = (operation: 'plus' | 'minus') => { 'worklet'; @@ -52,7 +34,7 @@ export const useSwapSettings = ({ inputAsset }: { inputAsset: SharedValue { } const gasFeeParamsBySpeed = getGasSettingsBySpeed(parameters.chainId); + const selectedGasSpeed = getSelectedGasSpeed(parameters.chainId); let gasParams: TransactionGasParamAmounts | LegacyTransactionGasParamAmounts = {} as | TransactionGasParamAmounts @@ -225,10 +226,10 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { type, parameters, selectedGas, + selectedGasSpeed, slippage, bridge: isBridge, errorMessage, - // TODO: Does this work from the JS thread? inputNativeValue: SwapInputController.inputValues.value.inputNativeValue, outputNativeValue: SwapInputController.inputValues.value.outputNativeValue, }); @@ -249,20 +250,20 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { }), }); + NotificationManager?.postNotification('rapCompleted'); + Navigation.handleAction(Routes.PROFILE_SCREEN, {}); + analyticsV2.track(analyticsV2.event.swapsSubmitted, { createdAt: Date.now(), type, parameters, selectedGas, + selectedGasSpeed, slippage, bridge: isBridge, - // TODO: Does this work from the JS thread? inputNativeValue: SwapInputController.inputValues.value.inputNativeValue, outputNativeValue: SwapInputController.inputValues.value.outputNativeValue, }); - - NotificationManager?.postNotification('rapCompleted'); - Navigation.handleAction(Routes.PROFILE_SCREEN, {}); }; const executeSwap = () => { @@ -427,12 +428,6 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { ? internalSelectedInputAsset.value?.uniqueId !== extendedAsset?.uniqueId : internalSelectedOutputAsset.value?.uniqueId !== extendedAsset?.uniqueId; - analyticsV2.track(analyticsV2.event.swapsSelectedAsset, { - asset, - otherAsset: otherSelectedAsset, - type, - }); - runOnUI(() => { const didSelectedAssetChange = type === SwapAssetType.inputAsset @@ -503,6 +498,12 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { } logger.debug(`[setAsset]: Setting ${type} asset to ${extendedAsset?.name} on ${extendedAsset?.chainId}`); + + analyticsV2.track(analyticsV2.event.swapsSelectedAsset, { + asset, + otherAsset: otherSelectedAsset, + type, + }); }, [ SwapInputController.quoteFetchingInterval, diff --git a/src/analytics/event.ts b/src/analytics/event.ts index 8e8ca7fd703..3a9d2776d3e 100644 --- a/src/analytics/event.ts +++ b/src/analytics/event.ts @@ -139,8 +139,6 @@ export const event = { swapsChangedChainId: 'swaps.changed_chain_id', swapsFlippedAssets: 'swaps.flipped_assets', swapsToggledFlashbots: 'swaps.toggled_flashbots', - swapsChangedMaximumSlippage: 'swaps.changed_maximum_slippage', - swapsChangedSelectedGasSpeed: 'swaps.changed_selected_gas_speed', swapsReceivedQuote: 'swaps.received_quote', swapsSubmitted: 'swaps.submitted', swapsFailed: 'swaps.failed', @@ -158,6 +156,7 @@ type SwapEventParameters = { outputNativeValue: string | number; parameters: Omit, 'gasParams' | 'gasFeeParamsBySpeed' | 'selectedGasFee'>; selectedGas: GasSettings; + selectedGasSpeed: GasSpeed; slippage: string; }; @@ -543,20 +542,6 @@ export type EventProperties = { enabled: boolean; }; - [event.swapsChangedMaximumSlippage]: { - inputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; - outputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; - quote: Quote | CrosschainQuote | QuoteError | null; - slippage: string; - }; - - [event.swapsChangedSelectedGasSpeed]: { - inputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; - outputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; - selectedGasSpeed: GasSpeed; - quote: Quote | CrosschainQuote | QuoteError | null; - }; - [event.swapsReceivedQuote]: { inputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null; outputAsset: ParsedSearchAsset | ExtendedAnimatedAssetWithColors | null;