feat: use new token lists (#4733)

* initial commit

* updates

* prevent unsupported from being validated

* removed unused export

* removed unecessary in

* removed unecessary brackets
This commit is contained in:
cartcrom 2022-09-27 16:57:29 -04:00 committed by GitHub
parent e54b46910a
commit 4cdfeaae34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 38 deletions

@ -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.
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

@ -1,7 +1,8 @@
import { TokenInfo } from '@uniswap/token-lists'
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 unsupportedTokenList from './tokenLists/unsupported.tokenlist.json'
export enum TOKEN_LIST_TYPES {
UNI_DEFAULT = 1,
@ -16,30 +17,29 @@ class TokenSafetyLookupTable {
createMap() {
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) {
uniDefaultTokens = []
}
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) => {
// Initialize extended tokens first
store.getState().lists.byUrl[UNI_EXTENDED_LIST].current?.tokens.forEach((token) => {
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
})
// 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
}

@ -1,5 +1,6 @@
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 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'
@ -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 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
// lower index == higher priority for token import

@ -9,16 +9,22 @@ import { useAppDispatch } from 'state/hooks'
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()
// note: prevent dispatch if using for list search or unsupported list
return useCallback(
async (listUrl: string, sendDispatch = true) => {
async (listUrl: string, sendDispatch = true, skipValidation?: boolean) => {
const requestId = nanoid()
sendDispatch && dispatch(fetchTokenList.pending({ requestId, url: listUrl }))
return getTokenList(listUrl, (ensName: string) =>
resolveENSContentHash(ensName, RPC_PROVIDERS[SupportedChainId.MAINNET])
return getTokenList(
listUrl,
(ensName: string) => resolveENSContentHash(ensName, RPC_PROVIDERS[SupportedChainId.MAINNET]),
skipValidation
)
.then((tokenList) => {
sendDispatch && dispatch(fetchTokenList.fulfilled({ url: listUrl, tokenList, requestId }))

@ -12,7 +12,8 @@ const listCache = new Map<string, TokenList>()
/** Fetches and validates a token list. */
export default async function fetchTokenList(
listUrl: string,
resolveENSContentHash: (ensName: string) => Promise<string>
resolveENSContentHash: (ensName: string) => Promise<string>,
skipValidation?: boolean
): Promise<TokenList> {
const cached = listCache?.get(listUrl) // avoid spurious re-fetches
if (cached) {
@ -64,7 +65,7 @@ export default async function fetchTokenList(
}
const json = await response.json()
const list = await validateTokenList(json)
const list = skipValidation ? json : await validateTokenList(json)
listCache?.set(listUrl, list)
return list
}

@ -4,7 +4,6 @@ import { useAppSelector } from 'state/hooks'
import sortByListPriority from 'utils/listSort'
import BROKEN_LIST from '../../constants/tokenLists/broken.tokenlist.json'
import UNSUPPORTED_TOKEN_LIST from '../../constants/tokenLists/unsupported.tokenlist.json'
import { AppState } from '../index'
import { UNSUPPORTED_LIST_URLS } from './../../constants/lists'
@ -94,17 +93,11 @@ export function useUnsupportedTokenList(): TokenAddressMap {
// get hard-coded broken tokens
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
const loadedUnsupportedListMap = useCombinedTokenMapFromUrls(UNSUPPORTED_LIST_URLS)
// format into one token address map
return useMemo(
() => combineMaps(brokenListMap, combineMaps(localUnsupportedListMap, loadedUnsupportedListMap)),
[brokenListMap, localUnsupportedListMap, loadedUnsupportedListMap]
)
return useMemo(() => combineMaps(brokenListMap, loadedUnsupportedListMap), [brokenListMap, loadedUnsupportedListMap])
}
export function useIsListActive(url: string): boolean {
const activeListUrls = useActiveListUrls()

@ -59,7 +59,7 @@ export default function Updater(): null {
UNSUPPORTED_LIST_URLS.forEach((listUrl) => {
const list = lists[listUrl]
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])