Commit 4cdfeaae authored by cartcrom's avatar cartcrom Committed by GitHub

feat: use new token lists (#4733)

* initial commit

* updates

* prevent unsupported from being validated

* removed unused export

* removed unecessary in

* removed unecessary brackets
parent e54b4691
...@@ -30,7 +30,7 @@ or visit [app.uniswap.org](https://app.uniswap.org). ...@@ -30,7 +30,7 @@ or visit [app.uniswap.org](https://app.uniswap.org).
Check out `useUnsupportedTokenList()` in [src/state/lists/hooks.ts](./src/state/lists/hooks.ts) for blocking tokens in your instance of the interface. Check out `useUnsupportedTokenList()` in [src/state/lists/hooks.ts](./src/state/lists/hooks.ts) for blocking tokens in your instance of the interface.
You can block an entire list of tokens by passing in a tokenlist like [here](./src/constants/lists.ts) or you can block specific tokens by adding them to [unsupported.tokenlist.json](./src/constants/tokenLists/unsupported.tokenlist.json). You can block an entire list of tokens by passing in a tokenlist like [here](./src/constants/lists.ts)
## Contributions ## Contributions
......
import { TokenInfo } from '@uniswap/token-lists'
import store from '../state' import store from '../state'
import { UNI_EXTENDED_LIST, UNI_LIST } from './lists' import { UNI_EXTENDED_LIST, UNI_LIST, UNSUPPORTED_LIST_URLS } from './lists'
import brokenTokenList from './tokenLists/broken.tokenlist.json' import brokenTokenList from './tokenLists/broken.tokenlist.json'
import unsupportedTokenList from './tokenLists/unsupported.tokenlist.json'
export enum TOKEN_LIST_TYPES { export enum TOKEN_LIST_TYPES {
UNI_DEFAULT = 1, UNI_DEFAULT = 1,
...@@ -16,30 +17,29 @@ class TokenSafetyLookupTable { ...@@ -16,30 +17,29 @@ class TokenSafetyLookupTable {
createMap() { createMap() {
const dict: { [key: string]: TOKEN_LIST_TYPES } = {} const dict: { [key: string]: TOKEN_LIST_TYPES } = {}
let uniDefaultTokens = store.getState().lists.byUrl[UNI_LIST].current?.tokens
let uniExtendedTokens = store.getState().lists.byUrl[UNI_EXTENDED_LIST].current?.tokens
const brokenTokens = brokenTokenList.tokens
const unsupportTokens = unsupportedTokenList.tokens
if (!uniDefaultTokens) { // Initialize extended tokens first
uniDefaultTokens = [] store.getState().lists.byUrl[UNI_EXTENDED_LIST].current?.tokens.forEach((token) => {
}
if (!uniExtendedTokens) {
uniExtendedTokens = []
}
brokenTokens.forEach((token) => {
dict[token.address.toLowerCase()] = TOKEN_LIST_TYPES.BROKEN
})
unsupportTokens.forEach((token) => {
dict[token.address.toLowerCase()] = TOKEN_LIST_TYPES.BLOCKED
})
uniExtendedTokens.forEach((token) => {
dict[token.address.toLowerCase()] = TOKEN_LIST_TYPES.UNI_EXTENDED dict[token.address.toLowerCase()] = TOKEN_LIST_TYPES.UNI_EXTENDED
}) })
uniDefaultTokens.forEach((token) => {
// Initialize default tokens second, so that any tokens on both default and extended will display as default (no warning)
store.getState().lists.byUrl[UNI_LIST].current?.tokens.forEach((token) => {
dict[token.address.toLowerCase()] = TOKEN_LIST_TYPES.UNI_DEFAULT dict[token.address.toLowerCase()] = TOKEN_LIST_TYPES.UNI_DEFAULT
}) })
// TODO: Figure out if this list is still relevant
brokenTokenList.tokens.forEach((token) => {
dict[token.address.toLowerCase()] = TOKEN_LIST_TYPES.BROKEN
})
// Initialize blocked tokens from all urls included
UNSUPPORTED_LIST_URLS.map((url) => store.getState().lists.byUrl[url].current?.tokens)
.filter((x): x is TokenInfo[] => !!x)
.flat(1)
.forEach((token) => {
dict[token.address.toLowerCase()] = TOKEN_LIST_TYPES.BLOCKED
})
return dict return dict
} }
......
export const UNI_LIST = 'https://tokens.uniswap.org' export const UNI_LIST = 'https://tokens.uniswap.org'
export const UNI_EXTENDED_LIST = 'https://gateway.pinata.cloud/ipfs/QmaQvV3pWKKaWJcHvSBuvQMrpckV3KKtGJ6p3HZjakwFtX' export const UNI_EXTENDED_LIST = 'https://extendedtokens.uniswap.org/'
const UNI_UNSUPPORTED_LISTS = 'https://unsupportedtokens.uniswap.org/'
const AAVE_LIST = 'tokenlist.aave.eth' const AAVE_LIST = 'tokenlist.aave.eth'
const BA_LIST = 'https://raw.githubusercontent.com/The-Blockchain-Association/sec-notice-list/master/ba-sec-list.json' const BA_LIST = 'https://raw.githubusercontent.com/The-Blockchain-Association/sec-notice-list/master/ba-sec-list.json'
const CMC_ALL_LIST = 'https://api.coinmarketcap.com/data-api/v3/uniswap/all.json' const CMC_ALL_LIST = 'https://api.coinmarketcap.com/data-api/v3/uniswap/all.json'
...@@ -15,7 +16,7 @@ export const OPTIMISM_LIST = 'https://static.optimism.io/optimism.tokenlist.json ...@@ -15,7 +16,7 @@ export const OPTIMISM_LIST = 'https://static.optimism.io/optimism.tokenlist.json
export const ARBITRUM_LIST = 'https://bridge.arbitrum.io/token-list-42161.json' export const ARBITRUM_LIST = 'https://bridge.arbitrum.io/token-list-42161.json'
export const CELO_LIST = 'https://celo-org.github.io/celo-token-list/celo.tokenlist.json' export const CELO_LIST = 'https://celo-org.github.io/celo-token-list/celo.tokenlist.json'
export const UNSUPPORTED_LIST_URLS: string[] = [BA_LIST] export const UNSUPPORTED_LIST_URLS: string[] = [BA_LIST, UNI_UNSUPPORTED_LISTS]
// this is the default list of lists that are exposed to users // this is the default list of lists that are exposed to users
// lower index == higher priority for token import // lower index == higher priority for token import
......
...@@ -9,16 +9,22 @@ import { useAppDispatch } from 'state/hooks' ...@@ -9,16 +9,22 @@ import { useAppDispatch } from 'state/hooks'
import { fetchTokenList } from '../state/lists/actions' import { fetchTokenList } from '../state/lists/actions'
export function useFetchListCallback(): (listUrl: string, sendDispatch?: boolean) => Promise<TokenList> { export function useFetchListCallback(): (
listUrl: string,
sendDispatch?: boolean,
skipValidation?: boolean
) => Promise<TokenList> {
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
// note: prevent dispatch if using for list search or unsupported list // note: prevent dispatch if using for list search or unsupported list
return useCallback( return useCallback(
async (listUrl: string, sendDispatch = true) => { async (listUrl: string, sendDispatch = true, skipValidation?: boolean) => {
const requestId = nanoid() const requestId = nanoid()
sendDispatch && dispatch(fetchTokenList.pending({ requestId, url: listUrl })) sendDispatch && dispatch(fetchTokenList.pending({ requestId, url: listUrl }))
return getTokenList(listUrl, (ensName: string) => return getTokenList(
resolveENSContentHash(ensName, RPC_PROVIDERS[SupportedChainId.MAINNET]) listUrl,
(ensName: string) => resolveENSContentHash(ensName, RPC_PROVIDERS[SupportedChainId.MAINNET]),
skipValidation
) )
.then((tokenList) => { .then((tokenList) => {
sendDispatch && dispatch(fetchTokenList.fulfilled({ url: listUrl, tokenList, requestId })) sendDispatch && dispatch(fetchTokenList.fulfilled({ url: listUrl, tokenList, requestId }))
......
...@@ -12,7 +12,8 @@ const listCache = new Map<string, TokenList>() ...@@ -12,7 +12,8 @@ const listCache = new Map<string, TokenList>()
/** Fetches and validates a token list. */ /** Fetches and validates a token list. */
export default async function fetchTokenList( export default async function fetchTokenList(
listUrl: string, listUrl: string,
resolveENSContentHash: (ensName: string) => Promise<string> resolveENSContentHash: (ensName: string) => Promise<string>,
skipValidation?: boolean
): Promise<TokenList> { ): Promise<TokenList> {
const cached = listCache?.get(listUrl) // avoid spurious re-fetches const cached = listCache?.get(listUrl) // avoid spurious re-fetches
if (cached) { if (cached) {
...@@ -64,7 +65,7 @@ export default async function fetchTokenList( ...@@ -64,7 +65,7 @@ export default async function fetchTokenList(
} }
const json = await response.json() const json = await response.json()
const list = await validateTokenList(json) const list = skipValidation ? json : await validateTokenList(json)
listCache?.set(listUrl, list) listCache?.set(listUrl, list)
return list return list
} }
......
...@@ -4,7 +4,6 @@ import { useAppSelector } from 'state/hooks' ...@@ -4,7 +4,6 @@ import { useAppSelector } from 'state/hooks'
import sortByListPriority from 'utils/listSort' import sortByListPriority from 'utils/listSort'
import BROKEN_LIST from '../../constants/tokenLists/broken.tokenlist.json' import BROKEN_LIST from '../../constants/tokenLists/broken.tokenlist.json'
import UNSUPPORTED_TOKEN_LIST from '../../constants/tokenLists/unsupported.tokenlist.json'
import { AppState } from '../index' import { AppState } from '../index'
import { UNSUPPORTED_LIST_URLS } from './../../constants/lists' import { UNSUPPORTED_LIST_URLS } from './../../constants/lists'
...@@ -94,17 +93,11 @@ export function useUnsupportedTokenList(): TokenAddressMap { ...@@ -94,17 +93,11 @@ export function useUnsupportedTokenList(): TokenAddressMap {
// get hard-coded broken tokens // get hard-coded broken tokens
const brokenListMap = useMemo(() => tokensToChainTokenMap(BROKEN_LIST), []) const brokenListMap = useMemo(() => tokensToChainTokenMap(BROKEN_LIST), [])
// get hard-coded list of unsupported tokens
const localUnsupportedListMap = useMemo(() => tokensToChainTokenMap(UNSUPPORTED_TOKEN_LIST), [])
// get dynamic list of unsupported tokens // get dynamic list of unsupported tokens
const loadedUnsupportedListMap = useCombinedTokenMapFromUrls(UNSUPPORTED_LIST_URLS) const loadedUnsupportedListMap = useCombinedTokenMapFromUrls(UNSUPPORTED_LIST_URLS)
// format into one token address map // format into one token address map
return useMemo( return useMemo(() => combineMaps(brokenListMap, loadedUnsupportedListMap), [brokenListMap, loadedUnsupportedListMap])
() => combineMaps(brokenListMap, combineMaps(localUnsupportedListMap, loadedUnsupportedListMap)),
[brokenListMap, localUnsupportedListMap, loadedUnsupportedListMap]
)
} }
export function useIsListActive(url: string): boolean { export function useIsListActive(url: string): boolean {
const activeListUrls = useActiveListUrls() const activeListUrls = useActiveListUrls()
......
...@@ -59,7 +59,7 @@ export default function Updater(): null { ...@@ -59,7 +59,7 @@ export default function Updater(): null {
UNSUPPORTED_LIST_URLS.forEach((listUrl) => { UNSUPPORTED_LIST_URLS.forEach((listUrl) => {
const list = lists[listUrl] const list = lists[listUrl]
if (!list || (!list.current && !list.loadingRequestId && !list.error)) { if (!list || (!list.current && !list.loadingRequestId && !list.error)) {
fetchList(listUrl).catch((error) => console.debug('list added fetching error', error)) fetchList(listUrl, undefined, true).catch((error) => console.debug('list added fetching error', error))
} }
}) })
}, [dispatch, fetchList, lists]) }, [dispatch, fetchList, lists])
......
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