diff --git a/public/config.json b/public/config.json index d602ced..1db5aa7 100644 --- a/public/config.json +++ b/public/config.json @@ -1,3 +1,4 @@ { - "erigonURL": "http://localhost:8545" + "erigonURL": "http://localhost:8545", + "assetsURLPrefix": "http://localhost:3001" } \ No newline at end of file diff --git a/src/components/MethodName.tsx b/src/components/MethodName.tsx index 27ad8ca..974e69e 100644 --- a/src/components/MethodName.tsx +++ b/src/components/MethodName.tsx @@ -1,10 +1,14 @@ import React, { useState, useEffect } from "react"; +import { fourBytesURL } from "../url"; +import { useRuntime } from "../useRuntime"; type MethodNameProps = { data: string; }; const MethodName: React.FC = ({ data }) => { + const runtime = useRuntime(); + const [name, setName] = useState(); useEffect(() => { if (data === "0x") { @@ -16,7 +20,13 @@ const MethodName: React.FC = ({ data }) => { // Try to resolve 4bytes name const fourBytes = _name.slice(2); - const signatureURL = `http://localhost:3001/signatures/${fourBytes}`; + const { config } = runtime; + if (!config) { + setName(_name); + return; + } + + const signatureURL = fourBytesURL(config.assetsURLPrefix, fourBytes); fetch(signatureURL) .then(async (res) => { if (!res.ok) { @@ -37,7 +47,7 @@ const MethodName: React.FC = ({ data }) => { // Use the default 4 bytes as name setName(_name); - }, [data]); + }, [runtime, data]); return (
diff --git a/src/components/TokenLogo.tsx b/src/components/TokenLogo.tsx index 738de1c..fab9e2c 100644 --- a/src/components/TokenLogo.tsx +++ b/src/components/TokenLogo.tsx @@ -1,5 +1,7 @@ import React, { Suspense } from "react"; import { useImage } from "react-image"; +import { tokenLogoURL } from "../url"; +import { useRuntime } from "../useRuntime"; type TokenLogoProps = { address: string; @@ -13,12 +15,14 @@ const TokenLogo: React.FC = (props) => ( ); const InternalTokenLogo: React.FC = ({ address, name }) => { - const { src } = useImage({ - srcList: [ - `http://localhost:3001/assets/${address}/logo.png`, - "/eth-diamond-black.png", - ], - }); + const { config } = useRuntime(); + + const srcList: string[] = []; + if (config) { + srcList.push(tokenLogoURL(config.assetsURLPrefix, address)); + } + srcList.push("/eth-diamond-black.png"); + const { src } = useImage({ srcList }); return (
diff --git a/src/url.ts b/src/url.ts new file mode 100644 index 0000000..0586dbe --- /dev/null +++ b/src/url.ts @@ -0,0 +1,9 @@ +export const fourBytesURL = ( + assetsURLPrefix: string, + fourBytes: string +): string => `${assetsURLPrefix}/signatures/${fourBytes}`; + +export const tokenLogoURL = ( + assetsURLPrefix: string, + address: string +): string => `${assetsURLPrefix}/assets/${address}/logo.png`; diff --git a/src/useConfig.ts b/src/useConfig.ts index df8deb2..4e53fb6 100644 --- a/src/useConfig.ts +++ b/src/useConfig.ts @@ -2,6 +2,7 @@ import { useState, useEffect } from "react"; export type OtterscanConfig = { erigonURL: string; + assetsURLPrefix: string; }; export const useConfig = (): [boolean?, OtterscanConfig?] => { @@ -14,6 +15,8 @@ export const useConfig = (): [boolean?, OtterscanConfig?] => { if (res.ok) { const _config: OtterscanConfig = await res.json(); + console.info("Loaded app config"); + console.info(_config); setConfig(_config); setConfigOK(res.ok); } diff --git a/src/useProvider.ts b/src/useProvider.ts index 08208cf..cd4024d 100644 --- a/src/useProvider.ts +++ b/src/useProvider.ts @@ -1,16 +1,11 @@ +import { useMemo } from "react"; import { ethers } from "ethers"; -import { OtterscanConfig } from "./useConfig"; export const DEFAULT_ERIGON_URL = "http://127.0.0.1:8545"; export const useProvider = ( - config?: OtterscanConfig + erigonURL?: string ): ethers.providers.JsonRpcProvider | undefined => { - if (!config) { - return undefined; - } - - let erigonURL = config?.erigonURL; if (erigonURL === "") { console.info(`Using default erigon URL: ${DEFAULT_ERIGON_URL}`); erigonURL = DEFAULT_ERIGON_URL; @@ -18,5 +13,12 @@ export const useProvider = ( console.log(`Using configured erigon URL: ${erigonURL}`); } - return new ethers.providers.JsonRpcProvider(erigonURL, "mainnet"); + const provider = useMemo( + () => new ethers.providers.JsonRpcProvider(erigonURL, "mainnet"), + [erigonURL] + ); + if (!erigonURL) { + return undefined; + } + return provider; }; diff --git a/src/useRuntime.ts b/src/useRuntime.ts index 2ebb766..ed2bcc9 100644 --- a/src/useRuntime.ts +++ b/src/useRuntime.ts @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useMemo } from "react"; import { ethers } from "ethers"; import { OtterscanConfig, useConfig } from "./useConfig"; import { useProvider } from "./useProvider"; @@ -10,13 +10,17 @@ export type OtterscanRuntime = { export const useRuntime = (): OtterscanRuntime => { const [configOK, config] = useConfig(); - const provider = useProvider(config); + const provider = useProvider(configOK ? config?.erigonURL : undefined); + + const runtime = useMemo( + (): OtterscanRuntime => ({ config, provider }), + [config, provider] + ); if (!configOK) { return {}; } - - return { config, provider }; + return runtime; }; export const RuntimeContext = React.createContext(null!);