diff --git a/src/address/Contract.tsx b/src/address/Contract.tsx index 360e8bc..2f366a8 100644 --- a/src/address/Contract.tsx +++ b/src/address/Contract.tsx @@ -1,40 +1,19 @@ import React from "react"; import { SyntaxHighlighter, docco } from "../highlight-init"; -import { useContract } from "../sourcify/useSourcify"; -import { useAppConfigContext } from "../useAppConfig"; type ContractProps = { - checksummedAddress: string; - networkId: number; - filename: string; - source: any; + content: any; }; -const Contract: React.FC = ({ - checksummedAddress, - networkId, - filename, - source, -}) => { - const { sourcifySource } = useAppConfigContext(); - const content = useContract( - checksummedAddress, - networkId, - filename, - source, - sourcifySource - ); - - return ( - - {content ?? ""} - - ); -}; +const Contract: React.FC = ({ content }) => ( + + {content ?? ""} + +); export default React.memo(Contract); diff --git a/src/address/ContractFromRepo.tsx b/src/address/ContractFromRepo.tsx new file mode 100644 index 0000000..568babf --- /dev/null +++ b/src/address/ContractFromRepo.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import { SyntaxHighlighter, docco } from "../highlight-init"; +import { useContract } from "../sourcify/useSourcify"; +import { useAppConfigContext } from "../useAppConfig"; + +type ContractFromRepoProps = { + checksummedAddress: string; + networkId: number; + filename: string; +}; + +const ContractFromRepo: React.FC = ({ + checksummedAddress, + networkId, + filename, +}) => { + const { sourcifySource } = useAppConfigContext(); + const content = useContract( + checksummedAddress, + networkId, + filename, + sourcifySource + ); + + return ( + + {content ?? ""} + + ); +}; + +export default React.memo(ContractFromRepo); diff --git a/src/address/Contracts.tsx b/src/address/Contracts.tsx index 19ce669..ffd92b0 100644 --- a/src/address/Contracts.tsx +++ b/src/address/Contracts.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useContext, Fragment } from "react"; +import React, { useState, useEffect, useContext } from "react"; import { commify } from "@ethersproject/units"; import { Menu } from "@headlessui/react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -6,6 +6,7 @@ import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown"; import ContentFrame from "../ContentFrame"; import InfoRow from "../components/InfoRow"; import Contract from "./Contract"; +import ContractFromRepo from "./ContractFromRepo"; import { RuntimeContext } from "../useRuntime"; import { Metadata } from "../sourcify/useSourcify"; import ExternalLink from "../components/ExternalLink"; @@ -113,12 +114,17 @@ const Contracts: React.FC = ({ {selected && ( - + <> + {rawMetadata.sources[selected].content ? ( + + ) : ( + + )} + )} diff --git a/src/sourcify/useSourcify.ts b/src/sourcify/useSourcify.ts index f4f0a8a..a925943 100644 --- a/src/sourcify/useSourcify.ts +++ b/src/sourcify/useSourcify.ts @@ -115,43 +115,33 @@ export const useSourcifyMetadata = ( return data; }; +const contractFetcher = async (url: string): Promise => { + const res = await fetch(url); + if (res.ok) { + return await res.text(); + } + return null; +}; + export const useContract = ( checksummedAddress: string, networkId: number, filename: string, - source: any, sourcifySource: SourcifySource ) => { - const [content, setContent] = useState(source.content); + const normalizedFilename = filename.replaceAll(/[@:]/g, "_"); + const url = sourcifySourceFile( + checksummedAddress, + networkId, + normalizedFilename, + sourcifySource + ); - useEffect(() => { - if (source.content) { - return; - } - - const abortController = new AbortController(); - const readContent = async () => { - const normalizedFilename = filename.replaceAll(/[@:]/g, "_"); - const url = sourcifySourceFile( - checksummedAddress, - networkId, - normalizedFilename, - sourcifySource - ); - const res = await fetch(url, { signal: abortController.signal }); - if (res.ok) { - const _content = await res.text(); - setContent(_content); - } - }; - readContent(); - - return () => { - abortController.abort(); - }; - }, [checksummedAddress, networkId, filename, source.content, sourcifySource]); - - return content; + const { data, error } = useSWRImmutable(url, contractFetcher); + if (error) { + return undefined; + } + return data; }; export const useTransactionDescription = (