Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useMemo } from 'react'

import { getTokenId } from '@cowprotocol/common-utils'
import { CurrencyAmount } from '@uniswap/sdk-core'

import { getUsdPriceStateKey, useUsdPrices } from 'modules/usdAmount'
Expand All @@ -25,7 +26,7 @@ export function useRefundAmounts(): TokenUsdAmounts | null {
return tokensToRefund.reduce<TokenUsdAmounts>((acc, { token, balance }) => {
const usdPrice = usdPrices[getUsdPriceStateKey(token)]

const tokenKey = token.address.toLowerCase()
const tokenKey = getTokenId(token)

acc[tokenKey] = {
token,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useMemo } from 'react'

import { useTokensBalances } from '@cowprotocol/balances-and-allowances'
import { TokenWithLogo } from '@cowprotocol/common-const'
import { getTokenAddressKey } from '@cowprotocol/common-utils'
import { useTokensByAddressMap } from '@cowprotocol/tokens'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'

Expand All @@ -16,7 +17,7 @@ export function useTokenBalanceAndUsdValue(tokenAddress: string | undefined): To
const tokensByAddress = useTokensByAddressMap()
const { values: balances } = useTokensBalances()

const tokenKey = tokenAddress?.toLowerCase() || undefined
const tokenKey = tokenAddress ? getTokenAddressKey(tokenAddress) : undefined

const token = !!tokenKey && tokensByAddress[tokenKey]
const balanceRaw = !!tokenKey && balances[tokenKey]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useMemo } from 'react'

import { useTokensBalances } from '@cowprotocol/balances-and-allowances'
import { TokenWithLogo } from '@cowprotocol/common-const'
import { getTokenAddressKey } from '@cowprotocol/common-utils'
import { useTokensByAddressMap } from '@cowprotocol/tokens'
import { BigNumber } from '@ethersproject/bignumber'

Expand All @@ -17,7 +18,7 @@ export function useTokensToRefund(): TokenToRefund[] | undefined {
return useMemo(() => {
return Object.keys(balances.values)
.reduce<TokenToRefund[]>((acc, tokenAddress) => {
const token = tokensByAddress[tokenAddress.toLowerCase()]
const token = tokensByAddress[getTokenAddressKey(tokenAddress)]
const balance = balances.values[tokenAddress]

if (token && balance?.gt(0)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import * as styledEl from './styled'

import { useDeferredVisibility } from '../../hooks/useDeferredVisibility'
import { TokenSelectionHandler } from '../../types'
import { getTokenUniqueKey } from '../../utils/tokenKey'
import { TokenInfo } from '../TokenInfo'
import { TokenTags } from '../TokenTags'

Expand Down Expand Up @@ -60,7 +61,7 @@ export function TokenListItem(props: TokenListItemProps): ReactNode {
className,
} = props

const tokenKey = `${token.chainId}:${token.address.toLowerCase()}`
const tokenKey = getTokenUniqueKey(token)
// Defer heavyweight UI (tooltips, formatted numbers) until the row is about to enter the viewport.
const { ref: visibilityRef, isVisible: hasIntersected } = useDeferredVisibility<HTMLDivElement>({
resetKey: tokenKey,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { TokenWithLogo } from '@cowprotocol/common-const'
import { getTokenId } from '@cowprotocol/common-utils'

type TokenIdentifier = Pick<TokenWithLogo, 'address' | 'chainId'>

export function getTokenUniqueKey(token: TokenIdentifier): string {
return `${token.chainId}:${token.address.toLowerCase()}`
return getTokenId(token)
}
5 changes: 3 additions & 2 deletions apps/explorer/src/hooks/useTokenList.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useMemo } from 'react'

import { COW_CDN, SWR_NO_REFRESH_OPTIONS } from '@cowprotocol/common-const'
import { getTokenAddressKey } from '@cowprotocol/common-utils'
import { ALL_SUPPORTED_CHAIN_IDS, mapSupportedNetworks, SupportedChainId } from '@cowprotocol/cow-sdk'
import type { TokenInfo, TokenList } from '@uniswap/token-lists'

Expand Down Expand Up @@ -65,7 +66,7 @@ export function useTokenList(chainId: SupportedChainId | undefined): { data: Tok

const nativeToken = NATIVE_TOKEN_PER_NETWORK[chainId]

data[NATIVE_TOKEN_ADDRESS.toLowerCase()] = {
data[getTokenAddressKey(NATIVE_TOKEN_ADDRESS)] = {
...nativeToken,
name: nativeToken.name || '',
symbol: nativeToken.symbol || '',
Expand Down Expand Up @@ -93,7 +94,7 @@ function fetcher(tokenListUrl: string): Promise<TokenListPerNetwork> {
tokens.reduce((acc, token) => {
// Pick only supported chains
if (SUPPORTED_CHAIN_IDS_SET.has(token.chainId)) {
acc[token.chainId][token.address.toLowerCase()] = token
acc[token.chainId][getTokenAddressKey(token.address)] = token
}
return acc
}, INITIAL_TOKEN_LIST_PER_NETWORK),
Expand Down
7 changes: 5 additions & 2 deletions libs/common-utils/src/areAddressesEqual.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Nullish } from '@cowprotocol/types'

import { getTokenAddressKey } from './tokens'

export function areAddressesEqual(a: Nullish<string>, b: Nullish<string>): boolean {
if ((a && !b) || (!a && b)) return false
if (!a && !b) return true
if (!a || !b) return false

return a?.toLowerCase() === b?.toLowerCase()
return getTokenAddressKey(a) === getTokenAddressKey(b)
}
13 changes: 13 additions & 0 deletions libs/common-utils/src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,16 @@ export function isNativeAddress(tokenAddress: string, chainId: ChainId): boolean

return native && doesTokenMatchSymbolOrAddress(native, tokenAddressLower)
}

export function getTokenAddressKey(address: string): string {
return address.toLowerCase()
}

export interface TokenIdentifier {
address: string
chainId: number
}

export function getTokenId(token: TokenIdentifier): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: would be nice to define a type for that like export type TokenId = ${number}:${string}
for better understanding

return `${token.chainId}:${getTokenAddressKey(token.address)}`
}