Commit bcd4c1c1 authored by lynn's avatar lynn Committed by GitHub

feat: only track usdc, weth, native token balances (#4424)

* init

* fix unit test

* extract log token logic into custom hook
parent d954026c
import { Token } from '@uniswap/sdk-core'
import { nativeOnChain } from '../../constants/tokens'
/**
* Event names that can occur in this application.
*
......@@ -37,14 +41,21 @@ export enum CUSTOM_USER_PROPERTIES {
SCREEN_RESOLUTION_HEIGHT = 'screen_resolution_height',
SCREEN_RESOLUTION_WIDTH = 'screen_resolution_width',
WALLET_ADDRESS = 'wallet_address',
WALLET_NATIVE_CURRENCY_AMOUNT = 'wallet_native_currency_amount',
WALLET_NATIVE_CURRENCY_BALANCE_USD = 'wallet_native_currency_balance_usd',
WALLET_TOKENS_ADDRESSES = 'wallet_tokens_addresses',
WALLET_TOKENS_SYMBOLS = 'wallet_tokens_symbols',
WALLET_TYPE = 'wallet_type',
WALLET_USDC_AMOUNT = 'wallet_usdc_amount',
WALLET_USDC_BALANCE_USD = 'wallet_usdc_balance_usd',
WALLET_WETH_AMOUNT = 'wallet_weth_amount',
WALLET_WETH_BALANCE_USD = 'wallet_weth_balance_usd',
}
export enum CUSTOM_USER_PROPERTY_SUFFIXES {
WALLET_TOKEN_AMOUNT_SUFFIX = '_token_amount',
const ETH = nativeOnChain(1)
const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC')
export const TOKENS_TO_TRACK = {
USDC,
WETH: ETH.wrapped,
}
export enum BROWSER {
......
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core'
import * as connectionUtils from 'connection/utils'
import JSBI from 'jsbi'
import { ApplicationModal } from 'state/application/reducer'
import { nativeOnChain } from '../../constants/tokens'
......@@ -12,10 +11,7 @@ afterEach(() => {
jest.resetModules()
})
const currencyAmount = (token: Currency, amount: number) => CurrencyAmount.fromRawAmount(token, JSBI.BigInt(amount))
const mockEth = () => nativeOnChain(1)
const mockCurrencyAmount = currencyAmount(mockEth(), 1)
const UserAgentMock = jest.requireMock('utils/userAgent')
jest.mock('utils/userAgent', () => ({
......@@ -39,24 +35,14 @@ jest.mock('hooks/useStablecoinPrice', () => {
}
})
jest.mock('state/connection/hooks', () => {
return {
useAllTokenBalances: () => {
return [{}, false]
},
}
})
jest.mock('../../hooks/Tokens', () => {
return {
useAllTokens: () => ({}),
}
})
jest.mock('lib/hooks/useCurrencyBalance', () => {
return {
useCurrencyBalances: (account?: string, currencies?: (Currency | undefined)[]) => {
return [mockCurrencyAmount]
__esModule: true,
default: (account?: string, currency?: Currency) => {
return
},
useTokenBalance: (account?: string, token?: Token) => {
return
},
}
})
......
......@@ -5,23 +5,21 @@ import { Connector } from '@web3-react/types'
import { sendAnalyticsEvent, user } from 'components/AmplitudeAnalytics'
import {
CUSTOM_USER_PROPERTIES,
CUSTOM_USER_PROPERTY_SUFFIXES,
EventName,
TOKENS_TO_TRACK,
WALLET_CONNECTION_RESULT,
} from 'components/AmplitudeAnalytics/constants'
import { formatToDecimal, getTokenAddress } from 'components/AmplitudeAnalytics/utils'
import { formatToDecimal } from 'components/AmplitudeAnalytics/utils'
import { sendEvent } from 'components/analytics'
import { AutoColumn } from 'components/Column'
import { AutoRow } from 'components/Row'
import { getConnection, getConnectionName, getIsCoinbaseWallet, getIsInjected, getIsMetaMask } from 'connection/utils'
import { RedesignVariant, useRedesignFlag } from 'featureFlags/flags/redesign'
import { useStablecoinValue } from 'hooks/useStablecoinPrice'
import { useCurrencyBalances } from 'lib/hooks/useCurrencyBalance'
import useCurrencyBalance, { useTokenBalance } from 'lib/hooks/useCurrencyBalance'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { tokenComparator } from 'lib/hooks/useTokenList/sorting'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import { ArrowLeft } from 'react-feather'
import { useAllTokenBalances } from 'state/connection/hooks'
import { updateConnectionError } from 'state/connection/reducer'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { updateSelectedWallet } from 'state/user/reducer'
......@@ -30,7 +28,6 @@ import styled from 'styled-components/macro'
import { isMobile } from 'utils/userAgent'
import { ReactComponent as Close } from '../../assets/images/x.svg'
import { useAllTokens } from '../../hooks/Tokens'
import { useModalIsOpen, useToggleWalletModal } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { ExternalLink, ThemedText } from '../../theme'
......@@ -131,29 +128,6 @@ const WALLET_VIEWS = {
PENDING: 'pending',
}
const sendAnalyticsWalletBalanceUserInfo = (
balances: (CurrencyAmount<Currency> | undefined)[],
nativeCurrencyBalanceUsd: number
) => {
const walletTokensSymbols: string[] = []
const walletTokensAddresses: string[] = []
balances.forEach((currencyAmount) => {
if (currencyAmount !== undefined) {
const tokenBalanceAmount = formatToDecimal(currencyAmount, currencyAmount.currency.decimals)
if (tokenBalanceAmount > 0) {
const tokenAddress = getTokenAddress(currencyAmount.currency)
walletTokensAddresses.push(getTokenAddress(currencyAmount.currency))
walletTokensSymbols.push(currencyAmount.currency.symbol ?? '')
const tokenPrefix = currencyAmount.currency.symbol ?? tokenAddress
user.set(`${tokenPrefix}${CUSTOM_USER_PROPERTY_SUFFIXES.WALLET_TOKEN_AMOUNT_SUFFIX}`, tokenBalanceAmount)
}
}
})
user.set(CUSTOM_USER_PROPERTIES.WALLET_NATIVE_CURRENCY_BALANCE_USD, nativeCurrencyBalanceUsd)
user.set(CUSTOM_USER_PROPERTIES.WALLET_TOKENS_ADDRESSES, walletTokensAddresses)
user.set(CUSTOM_USER_PROPERTIES.WALLET_TOKENS_SYMBOLS, walletTokensSymbols)
}
const sendAnalyticsEventAndUserInfo = (
account: string,
walletType: string,
......@@ -174,6 +148,32 @@ const sendAnalyticsEventAndUserInfo = (
user.postInsert(CUSTOM_USER_PROPERTIES.ALL_WALLET_ADDRESSES_CONNECTED, account)
}
function useLogToken(
tokenBalanceUsdValue: string | undefined,
tokenBalance: CurrencyAmount<Token | Currency> | undefined,
shouldLogTokenBalance: boolean,
setShouldLogTokenBalance: (shouldLog: boolean) => void,
tokenAmountProperty: string,
tokenUsdBalanceProperty: string
) {
useEffect(() => {
if (shouldLogTokenBalance && tokenBalance && tokenBalanceUsdValue) {
const tokenBalanceUsd = tokenBalanceUsdValue ? parseFloat(tokenBalanceUsdValue) : 0
const tokenBalanceAmount = formatToDecimal(tokenBalance, tokenBalance.currency.decimals)
user.set(tokenAmountProperty, tokenBalanceAmount)
user.set(tokenUsdBalanceProperty, tokenBalanceUsd)
setShouldLogTokenBalance(false)
}
}, [
tokenBalanceUsdValue,
tokenBalance,
shouldLogTokenBalance,
setShouldLogTokenBalance,
tokenAmountProperty,
tokenUsdBalanceProperty,
])
}
export default function WalletModal({
pendingTransactions,
confirmedTransactions,
......@@ -191,7 +191,9 @@ export default function WalletModal({
const redesignFlagEnabled = redesignFlag === RedesignVariant.Enabled
const [walletView, setWalletView] = useState(WALLET_VIEWS.ACCOUNT)
const [lastActiveWalletAddress, setLastActiveWalletAddress] = useState<string | undefined>(account)
const [shouldLogWalletBalances, setShouldLogWalletBalances] = useState(false)
const [shouldLogUsdcBalance, setShouldLogUsdcBalance] = useState(false)
const [shouldLogWethBalance, setShouldLogWethBalance] = useState(false)
const [shouldLogNativeBalance, setShouldLogNativeBalance] = useState(false)
const [pendingConnector, setPendingConnector] = useState<Connector | undefined>()
const pendingError = useAppSelector((state) =>
......@@ -201,24 +203,14 @@ export default function WalletModal({
const walletModalOpen = useModalIsOpen(ApplicationModal.WALLET)
const toggleWalletModal = useToggleWalletModal()
const allTokens = useAllTokens()
const [tokenBalances, tokenBalancesIsLoading] = useAllTokenBalances()
const sortedTokens: Token[] = useMemo(
() => (!tokenBalancesIsLoading ? Object.values(allTokens).sort(tokenComparator.bind(null, tokenBalances)) : []),
[tokenBalances, allTokens, tokenBalancesIsLoading]
)
const native = useNativeCurrency()
const usdcBalance = useTokenBalance(account, TOKENS_TO_TRACK.USDC)
const wethBalance = useTokenBalance(account, TOKENS_TO_TRACK.WETH)
const nativeCurrencyBalance = useCurrencyBalance(account, native)
const sortedTokensWithETH: Currency[] = useMemo(
() =>
// Always bump the native token to the top of the list.
native ? [native, ...sortedTokens.filter((t) => !t.equals(native))] : sortedTokens,
[native, sortedTokens]
)
const balances = useCurrencyBalances(account, sortedTokensWithETH)
const nativeBalance = balances.length > 0 ? balances[0] : null
const nativeCurrencyBalanceUsdValue = useStablecoinValue(nativeBalance)?.toFixed(2)
const usdcBalanceUsdValue = useStablecoinValue(usdcBalance)?.toFixed(2)
const wethBalanceUsdValue = useStablecoinValue(wethBalance)?.toFixed(2)
const nativeCurrencyBalanceUsdValue = useStablecoinValue(nativeCurrencyBalance)?.toFixed(2)
const openOptions = useCallback(() => {
setWalletView(WALLET_VIEWS.OPTIONS)
......@@ -244,28 +236,39 @@ export default function WalletModal({
const isReconnect =
connectedWallets.filter((wallet) => wallet.account === account && wallet.walletType === walletType).length > 0
sendAnalyticsEventAndUserInfo(account, walletType, chainId, isReconnect)
setShouldLogWalletBalances(true)
setShouldLogNativeBalance(true)
setShouldLogUsdcBalance(true)
setShouldLogWethBalance(true)
if (!isReconnect) addWalletToConnectedWallets({ account, walletType })
}
setLastActiveWalletAddress(account)
}, [connectedWallets, addWalletToConnectedWallets, lastActiveWalletAddress, account, connector, chainId])
// Send wallet balance info once it becomes available.
useEffect(() => {
if (!tokenBalancesIsLoading && shouldLogWalletBalances && balances && nativeCurrencyBalanceUsdValue) {
const nativeCurrencyBalanceUsd =
native && nativeCurrencyBalanceUsdValue ? parseFloat(nativeCurrencyBalanceUsdValue) : 0
sendAnalyticsWalletBalanceUserInfo(balances, nativeCurrencyBalanceUsd)
setShouldLogWalletBalances(false)
}
}, [
balances,
// Send wallet balances info once it becomes available.
useLogToken(
nativeCurrencyBalanceUsdValue,
shouldLogWalletBalances,
setShouldLogWalletBalances,
tokenBalancesIsLoading,
native,
])
nativeCurrencyBalance,
shouldLogNativeBalance,
setShouldLogNativeBalance,
CUSTOM_USER_PROPERTIES.WALLET_NATIVE_CURRENCY_AMOUNT,
CUSTOM_USER_PROPERTIES.WALLET_NATIVE_CURRENCY_BALANCE_USD
)
useLogToken(
usdcBalanceUsdValue,
usdcBalance,
shouldLogUsdcBalance,
setShouldLogUsdcBalance,
CUSTOM_USER_PROPERTIES.WALLET_USDC_AMOUNT,
CUSTOM_USER_PROPERTIES.WALLET_USDC_BALANCE_USD
)
useLogToken(
wethBalanceUsdValue,
wethBalance,
shouldLogWethBalance,
setShouldLogWethBalance,
CUSTOM_USER_PROPERTIES.WALLET_WETH_AMOUNT,
CUSTOM_USER_PROPERTIES.WALLET_USDC_BALANCE_USD
)
const tryActivation = useCallback(
async (connector: Connector) => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment