Apply SWR to Sourcify contract source code fetching

This commit is contained in:
Willian Mitsuda 2022-08-10 04:47:26 -03:00
parent 49abfbda2f
commit 5ab336041e
No known key found for this signature in database
4 changed files with 81 additions and 69 deletions

View File

@ -1,40 +1,19 @@
import React from "react"; import React from "react";
import { SyntaxHighlighter, docco } from "../highlight-init"; import { SyntaxHighlighter, docco } from "../highlight-init";
import { useContract } from "../sourcify/useSourcify";
import { useAppConfigContext } from "../useAppConfig";
type ContractProps = { type ContractProps = {
checksummedAddress: string; content: any;
networkId: number;
filename: string;
source: any;
}; };
const Contract: React.FC<ContractProps> = ({ const Contract: React.FC<ContractProps> = ({ content }) => (
checksummedAddress, <SyntaxHighlighter
networkId, className="w-full h-full border font-code text-base"
filename, language="solidity"
source, style={docco}
}) => { showLineNumbers
const { sourcifySource } = useAppConfigContext(); >
const content = useContract( {content ?? ""}
checksummedAddress, </SyntaxHighlighter>
networkId, );
filename,
source,
sourcifySource
);
return (
<SyntaxHighlighter
className="w-full h-full border font-code text-base"
language="solidity"
style={docco}
showLineNumbers
>
{content ?? ""}
</SyntaxHighlighter>
);
};
export default React.memo(Contract); export default React.memo(Contract);

View File

@ -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<ContractFromRepoProps> = ({
checksummedAddress,
networkId,
filename,
}) => {
const { sourcifySource } = useAppConfigContext();
const content = useContract(
checksummedAddress,
networkId,
filename,
sourcifySource
);
return (
<SyntaxHighlighter
className="w-full h-full border font-code text-base"
language="solidity"
style={docco}
showLineNumbers
>
{content ?? ""}
</SyntaxHighlighter>
);
};
export default React.memo(ContractFromRepo);

View File

@ -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 { commify } from "@ethersproject/units";
import { Menu } from "@headlessui/react"; import { Menu } from "@headlessui/react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@ -6,6 +6,7 @@ import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown";
import ContentFrame from "../ContentFrame"; import ContentFrame from "../ContentFrame";
import InfoRow from "../components/InfoRow"; import InfoRow from "../components/InfoRow";
import Contract from "./Contract"; import Contract from "./Contract";
import ContractFromRepo from "./ContractFromRepo";
import { RuntimeContext } from "../useRuntime"; import { RuntimeContext } from "../useRuntime";
import { Metadata } from "../sourcify/useSourcify"; import { Metadata } from "../sourcify/useSourcify";
import ExternalLink from "../components/ExternalLink"; import ExternalLink from "../components/ExternalLink";
@ -113,12 +114,17 @@ const Contracts: React.FC<ContractsProps> = ({
</div> </div>
</Menu> </Menu>
{selected && ( {selected && (
<Contract <>
checksummedAddress={checksummedAddress} {rawMetadata.sources[selected].content ? (
networkId={provider!.network.chainId} <Contract content={rawMetadata.sources[selected].content} />
filename={selected} ) : (
source={rawMetadata.sources[selected]} <ContractFromRepo
/> checksummedAddress={checksummedAddress}
networkId={provider!.network.chainId}
filename={selected}
/>
)}
</>
)} )}
</div> </div>
</> </>

View File

@ -115,43 +115,33 @@ export const useSourcifyMetadata = (
return data; return data;
}; };
const contractFetcher = async (url: string): Promise<string | null> => {
const res = await fetch(url);
if (res.ok) {
return await res.text();
}
return null;
};
export const useContract = ( export const useContract = (
checksummedAddress: string, checksummedAddress: string,
networkId: number, networkId: number,
filename: string, filename: string,
source: any,
sourcifySource: SourcifySource sourcifySource: SourcifySource
) => { ) => {
const [content, setContent] = useState<string>(source.content); const normalizedFilename = filename.replaceAll(/[@:]/g, "_");
const url = sourcifySourceFile(
checksummedAddress,
networkId,
normalizedFilename,
sourcifySource
);
useEffect(() => { const { data, error } = useSWRImmutable(url, contractFetcher);
if (source.content) { if (error) {
return; return undefined;
} }
return data;
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;
}; };
export const useTransactionDescription = ( export const useTransactionDescription = (