-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: mv token hooks to lib (#3122)
* refactor: mv useNativeCurrency to lib/hooks * refactor: mv useCurrency logic to lib/hooks
- Loading branch information
Showing
8 changed files
with
162 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import { arrayify } from '@ethersproject/bytes' | ||
import { parseBytes32String } from '@ethersproject/strings' | ||
import { Currency, Token } from '@uniswap/sdk-core' | ||
import useActiveWeb3React from 'hooks/useActiveWeb3React' | ||
import { useBytes32TokenContract, useTokenContract } from 'hooks/useContract' | ||
import { NEVER_RELOAD, useSingleCallResult } from 'lib/hooks/multicall' | ||
import useNativeCurrency from 'lib/hooks/useNativeCurrency' | ||
import { useMemo } from 'react' | ||
|
||
import { isAddress } from '../../utils' | ||
import { useTokenMap } from './useTokenList' | ||
import { TokenMap } from './useTokenList' | ||
|
||
// parse a name or symbol from a token response | ||
const BYTES32_REGEX = /^0x[a-fA-F0-9]{64}$/ | ||
|
||
function parseStringOrBytes32(str: string | undefined, bytes32: string | undefined, defaultValue: string): string { | ||
return str && str.length > 0 | ||
? str | ||
: // need to check for proper bytes string and valid terminator | ||
bytes32 && BYTES32_REGEX.test(bytes32) && arrayify(bytes32)[31] === 0 | ||
? parseBytes32String(bytes32) | ||
: defaultValue | ||
} | ||
|
||
/** | ||
* Returns a Token from the tokenAddress. | ||
* Returns null if token is loading or null was passed. | ||
* Returns undefined if tokenAddress is invalid or token does not exist. | ||
*/ | ||
export function useTokenFromMap(tokens: TokenMap, tokenAddress?: string | null): Token | null | undefined { | ||
const { chainId } = useActiveWeb3React() | ||
|
||
const address = isAddress(tokenAddress) | ||
|
||
const tokenContract = useTokenContract(address ? address : undefined, false) | ||
const tokenContractBytes32 = useBytes32TokenContract(address ? address : undefined, false) | ||
const token: Token | undefined = 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 (tokenAddress === null) return null | ||
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, | ||
tokenAddress, | ||
tokenName.loading, | ||
tokenName.result, | ||
tokenNameBytes32.result, | ||
]) | ||
} | ||
|
||
/** | ||
* Returns a Token from the tokenAddress. | ||
* Returns null if token is loading or null was passed. | ||
* Returns undefined if tokenAddress is invalid or token does not exist. | ||
*/ | ||
export function useToken(tokenAddress?: string | null): Token | null | undefined { | ||
const tokens = useTokenMap() | ||
return useTokenFromMap(tokens, tokenAddress) | ||
} | ||
|
||
/** | ||
* Returns a Currency from the currencyId. | ||
* Returns null if currency is loading or null was passed. | ||
* Returns undefined if currencyId is invalid or token does not exist. | ||
*/ | ||
export function useCurrencyFromMap(tokens: TokenMap, currencyId?: string | null): Currency | null | undefined { | ||
const nativeCurrency = useNativeCurrency() | ||
const isNative = Boolean(nativeCurrency && currencyId?.toUpperCase() === 'ETH') | ||
const token = useTokenFromMap(tokens, isNative ? undefined : currencyId) | ||
|
||
if (currencyId === null || currencyId === undefined) return currencyId | ||
|
||
// this case so we use our builtin wrapped token instead of wrapped tokens on token lists | ||
const wrappedNative = nativeCurrency?.wrapped | ||
if (wrappedNative?.address?.toUpperCase() === currencyId?.toUpperCase()) return wrappedNative | ||
|
||
return isNative ? nativeCurrency : token | ||
} | ||
|
||
/** | ||
* Returns a Currency from the currencyId. | ||
* Returns null if currency is loading or null was passed. | ||
* Returns undefined if currencyId is invalid or token does not exist. | ||
*/ | ||
export function useCurrency(currencyId?: string | null): Currency | null | undefined { | ||
const tokens = useTokenMap() | ||
return useCurrencyFromMap(tokens, currencyId) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Currency } from '@uniswap/sdk-core' | ||
import { SupportedChainId } from 'constants/chains' | ||
import { nativeOnChain } from 'constants/tokens' | ||
import useActiveWeb3React from 'hooks/useActiveWeb3React' | ||
import { useMemo } from 'react' | ||
|
||
export default function useNativeCurrency(): Currency { | ||
const { chainId } = useActiveWeb3React() | ||
return useMemo( | ||
() => | ||
chainId | ||
? nativeOnChain(chainId) | ||
: // display mainnet when not connected | ||
nativeOnChain(SupportedChainId.MAINNET), | ||
[chainId] | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters