import { TokenAddressMap , useUnsupportedTokenList } from './../state/lists/hooks' ; import { parseBytes32String } from '@ethersproject/strings' ; import { Token } from '@uniswap/sdk-core' ; import { useMemo } from 'react' ; import { useCombinedActiveList , useCombinedInactiveList } from '../state/lists/hooks' ; import { NEVER_RELOAD , useSingleCallResult } from '../state/multicall/hooks' ; import { useUserAddedTokens } from '../state/user/hooks' ; import { isAddress } from '../utils' ; import { useActiveWeb3React } from './index' ; import { useBytes32TokenContract , useTokenContract } from './useContract' ; import { arrayify } from 'ethers/lib/utils' ; function useTokensFromMap ( tokenMap , includeUserAdded ) { const { chainId } = useActiveWeb3React ( ) ; const userAddedTokens = useUserAddedTokens ( ) ; return useMemo ( ( ) => { if ( ! chainId ) return { } ; const mapWithoutUrls = Object . keys ( tokenMap [ chainId ] ) . reduce < { [ address ] : Token ; } > ( ( newMap , address ) => { newMap [ address ] = tokenMap [ chainId ] [ address ] . token ; return newMap ; } , { } ) ; if ( includeUserAdded ) { return ( userAddedTokens . reduce < { [ address ] : Token ; } > ( ( tokenMap , token ) => { tokenMap [ token . address ] = token ; return tokenMap ; } , { ... mapWithoutUrls } ) ) ; } return mapWithoutUrls ; } , [ chainId , userAddedTokens , tokenMap , includeUserAdded ] ) ; } export function useAllTokens ( ) { const allTokens = useCombinedActiveList ( ) ; return useTokensFromMap ( allTokens , true ) ; } export function useAllInactiveTokens ( ) { const inactiveTokensMap = useCombinedInactiveList ( ) ; const inactiveTokens = useTokensFromMap ( inactiveTokensMap , false ) ; const activeTokensAddresses = Object . keys ( useAllTokens ( ) ) ; const filteredInactive = activeTokensAddresses ? Object . keys ( inactiveTokens ) . reduce < { [ address ] : Token ; } > ( ( newMap , address ) => { if ( ! activeTokensAddresses . includes ( address ) ) { newMap [ address ] = inactiveTokens [ address ] ; } return newMap ; } , { } ) : inactiveTokens ; return filteredInactive ; } export function useUnsupportedTokens ( ) { const unsupportedTokensMap = useUnsupportedTokenList ( ) ; return useTokensFromMap ( unsupportedTokensMap , false ) ; } export function useIsTokenActive ( token ) { const activeTokens = useAllTokens ( ) ; if ( ! activeTokens || ! token ) { return false ; } return ! ! activeTokens [ token . address ] ; } const BYTES32_REGEX = /^0x[a-fA-F0-9]{64}$/ ; function parseStringOrBytes32 ( str , bytes32 , defaultValue ) { return str && str . length > 0 ? str : bytes32 && BYTES32_REGEX . test ( bytes32 ) && arrayify ( bytes32 ) [ 31 ] === 0 ? parseBytes32String ( bytes32 ) : defaultValue ; } export function useToken ( tokenAddress ? ) { const { chainId } = useActiveWeb3React ( ) ; const tokens = useAllTokens ( ) ; const address = isAddress ( tokenAddress ) ; const tokenContract = useTokenContract ( address ? address : undefined , false ) ; const tokenContractBytes32 = useBytes32TokenContract ( address ? address : undefined , false ) ; const token = address ? tokens [ address ] : undefined ; const tokenName = useSingleCallResult ( token ? undefined : tokenContract , 'name' , undefined , NEVER_RELOAD ) ; const tokenNameBytes32 = useSingleCallResult ( token ? undefined : tokenContractBytes32 , 'name' , undefined , NEVER_RELOAD ) ; const symbol = useSingleCallResult ( token ? undefined : tokenContract , 'symbol' , undefined , NEVER_RELOAD ) ; const symbolBytes32 = useSingleCallResult ( token ? undefined : tokenContractBytes32 , 'symbol' , undefined , NEVER_RELOAD ) ; const decimals = useSingleCallResult ( token ? undefined : tokenContract , 'decimals' , undefined , NEVER_RELOAD ) ; return useMemo ( ( ) => { if ( token ) return token ; if ( ! chainId || ! address ) return undefined ; if ( decimals . loading || symbol . loading || tokenName . loading ) return null ; if ( decimals . result ) { return new Token ( chainId , address , decimals . result [ 0 ] , parseStringOrBytes32 ( symbol . result ?. [ 0 ] , symbolBytes32 . result ?. [ 0 ] , 'UNKNOWN' ) , parseStringOrBytes32 ( tokenName . result ?. [ 0 ] , tokenNameBytes32 . result ?. [ 0 ] , 'Unknown Token' ) ) ; } return undefined ; } , [ address , chainId , decimals . loading , decimals . result , symbol . loading , symbol . result , symbolBytes32 . result , token , tokenName . loading , tokenName . result , tokenNameBytes32 . result , ] ) ; }