forked from Uniswap/interface
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseAssetLogoSource.ts
More file actions
81 lines (69 loc) · 2.82 KB
/
Copy pathuseAssetLogoSource.ts
File metadata and controls
81 lines (69 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import TokenLogoLookupTable from 'constants/TokenLogoLookupTable'
import { chainIdToNetworkName, getNativeLogoURI } from 'lib/hooks/useCurrencyLogoURIs'
import uriToHttp from 'lib/utils/uriToHttp'
import { useCallback, useEffect, useState } from 'react'
import { isAddress } from 'utils'
const BAD_SRCS: { [tokenAddress: string]: true } = {}
// Converts uri's into fetchable urls
function parseLogoSources(uris: string[]) {
const urls: string[] = []
uris.forEach((uri) => urls.push(...uriToHttp(uri)))
return urls
}
// Parses uri's, favors non-coingecko images, and improves coingecko logo quality
function prioritizeLogoSources(uris: string[]) {
const parsedUris = uris.map((uri) => uriToHttp(uri)).flat(1)
const preferredUris: string[] = []
// Consolidate duplicate coingecko urls into one fallback source
let coingeckoUrl: string | undefined = undefined
parsedUris.forEach((uri) => {
if (uri.startsWith('https://assets.coingecko')) {
if (!coingeckoUrl) {
coingeckoUrl = uri.replace(/small|thumb/g, 'large')
}
} else {
preferredUris.push(uri)
}
})
// Places coingecko urls in the back of the source array
return coingeckoUrl ? [...preferredUris, coingeckoUrl] : preferredUris
}
function getInitialUrl(address?: string | null, chainId?: number | null, isNative?: boolean) {
if (chainId && isNative) return getNativeLogoURI(chainId)
const networkName = chainId ? chainIdToNetworkName(chainId) : 'ethereum'
const checksummedAddress = isAddress(address)
if (checksummedAddress) {
return `https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/${networkName}/assets/${checksummedAddress}/logo.png`
} else {
return undefined
}
}
export default function useAssetLogoSource(
address?: string | null,
chainId?: number | null,
isNative?: boolean,
backupImg?: string | null
): [string | undefined, () => void] {
const [current, setCurrent] = useState<string | undefined>(getInitialUrl(address, chainId, isNative))
const [fallbackSrcs, setFallbackSrcs] = useState<string[] | undefined>(undefined)
useEffect(() => {
setCurrent(getInitialUrl(address, chainId, isNative))
setFallbackSrcs(undefined)
}, [address, chainId, isNative])
const nextSrc = useCallback(() => {
if (current) {
BAD_SRCS[current] = true
}
// Parses and stores logo sources from tokenlists if assets repo url fails
if (!fallbackSrcs) {
const uris = TokenLogoLookupTable.getIcons(address) ?? []
if (backupImg) uris.push(backupImg)
const tokenListIcons = prioritizeLogoSources(parseLogoSources(uris))
setCurrent(tokenListIcons.find((src) => !BAD_SRCS[src]))
setFallbackSrcs(tokenListIcons)
} else {
setCurrent(fallbackSrcs.find((src) => !BAD_SRCS[src]))
}
}, [current, fallbackSrcs, address, backupImg])
return [current, nextSrc]
}