diff --git a/package.json b/package.json index 2a84d3419..ff0feaaec 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "@shopify/restyle": "1.8.0", "@solana/spl-account-compression": "0.1.4", "@solana/spl-token": "0.3.6", + "@solana/spl-token-registry": "^0.2.4574", "@solana/wallet-adapter-react": "^0.15.33", "@solana/wallet-standard-features": "1.0.0", "@solana/web3.js": "1.64.0", diff --git a/src/App.tsx b/src/App.tsx index 48a9fc476..d49213172 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,6 +4,7 @@ import { AccountContext } from '@helium/account-fetch-cache-hooks' import { DarkTheme, NavigationContainer } from '@react-navigation/native' import MapboxGL from '@rnmapbox/maps' import { ThemeProvider } from '@shopify/restyle' +import { TokenListProvider } from '@storage/TokenListProvider' import TokensProvider from '@storage/TokensProvider' import globalStyles from '@theme/globalStyles' import { darkThemeColors, lightThemeColors, theme } from '@theme/theme' @@ -125,12 +126,14 @@ const App = () => { ref={navigationRef} > - - - - - - + + + + + + + + { + if (!tokenInfo) return undefined + + return { + json: { + name: tokenInfo.name, + symbol: tokenInfo.symbol, + image: tokenInfo.logoURI, + }, + symbol: tokenInfo.symbol, + name: tokenInfo.name, + } +} + export function useMetaplexMetadata(mint: PublicKey | undefined): { loading: boolean metadata: Metadata | undefined @@ -60,6 +79,14 @@ export function useMetaplexMetadata(mint: PublicKey | undefined): { symbol: string | undefined name: string | undefined } { + const tokenList = useTokenList() + const tokenListToken = useMemo(() => { + if (mint) { + return tokenList?.get(mint.toBase58()) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [tokenList, mint?.toBase58()]) + const metadataAddr = useMemo(() => { if (mint) { return getMetadataId(mint) @@ -72,6 +99,7 @@ export function useMetaplexMetadata(mint: PublicKey | undefined): { METADATA_PARSER, true, ) + const { result: json, loading: jsonLoading } = useAsync(getMetadata, [ metadataAcc?.uri, ]) @@ -93,9 +121,11 @@ export function useMetaplexMetadata(mint: PublicKey | undefined): { return { loading: jsonLoading || loading, - json: json?.data, + json: tokenListToken + ? tokenInfoToMetadata(tokenListToken)?.json + : json?.data, metadata: metadataAcc, - symbol: json?.data.symbol || metadataAcc?.symbol, - name: json?.data.name || metadataAcc?.name, + symbol: tokenListToken?.symbol || json?.data.symbol || metadataAcc?.symbol, + name: tokenListToken?.name || json?.data.name || metadataAcc?.name, } } diff --git a/src/hooks/useTokenList.ts b/src/hooks/useTokenList.ts new file mode 100644 index 000000000..7e62ffcbf --- /dev/null +++ b/src/hooks/useTokenList.ts @@ -0,0 +1,6 @@ +import { useContext } from 'react' +import { TokenListContext } from '../storage/TokenListProvider' + +export const useTokenList = () => { + return useContext(TokenListContext) +} diff --git a/src/storage/TokenListProvider.tsx b/src/storage/TokenListProvider.tsx new file mode 100644 index 000000000..17c7c944d --- /dev/null +++ b/src/storage/TokenListProvider.tsx @@ -0,0 +1,33 @@ +import { + TokenListProvider as Provider, + TokenInfo, + ENV, +} from '@solana/spl-token-registry' +import React, { ReactNode, useEffect, useState } from 'react' + +export const TokenListContext = React.createContext< + Map | undefined +>(undefined) + +export const TokenListProvider = ({ children }: { children: ReactNode }) => { + const [tokenMap, setTokenMap] = useState>(new Map()) + + useEffect(() => { + new Provider().resolve().then((tokens) => { + const tokenList = tokens.filterByChainId(ENV.MainnetBeta).getList() + + setTokenMap( + tokenList.reduce((map, item) => { + map.set(item.address, item) + return map + }, new Map()), + ) + }) + }, [setTokenMap]) + + return ( + + {children} + + ) +} diff --git a/yarn.lock b/yarn.lock index 2f750a3af..83610c9a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3813,6 +3813,13 @@ js-sha3 "^0.8.0" typescript-collections "^1.3.3" +"@solana/spl-token-registry@^0.2.4574": + version "0.2.4574" + resolved "https://registry.yarnpkg.com/@solana/spl-token-registry/-/spl-token-registry-0.2.4574.tgz#13f4636b7bec90d2bb43bbbb83512cd90d2ce257" + integrity sha512-JzlfZmke8Rxug20VT/VpI2XsXlsqMlcORIUivF+Yucj7tFi7A0dXG7h+2UnD0WaZJw8BrUz2ABNkUnv89vbv1A== + dependencies: + cross-fetch "3.0.6" + "@solana/spl-token@0.3.6": version "0.3.6" resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.3.6.tgz#35473ad2ed71fe91e5754a2ac72901e1b8b26a42" @@ -7029,6 +7036,13 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cross-fetch@3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" + integrity sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ== + dependencies: + node-fetch "2.6.1" + cross-fetch@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" @@ -12021,6 +12035,11 @@ node-fetch@2, node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetc dependencies: whatwg-url "^5.0.0" +node-fetch@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + node-fetch@2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"