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,31 +1,11 @@
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<ContractProps> = ({
checksummedAddress,
networkId,
filename,
source,
}) => {
const { sourcifySource } = useAppConfigContext();
const content = useContract(
checksummedAddress,
networkId,
filename,
source,
sourcifySource
);
return (
const Contract: React.FC<ContractProps> = ({ content }) => (
<SyntaxHighlighter
className="w-full h-full border font-code text-base"
language="solidity"
@ -34,7 +14,6 @@ const Contract: React.FC<ContractProps> = ({
>
{content ?? ""}
</SyntaxHighlighter>
);
};
);
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 { 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,13 +114,18 @@ const Contracts: React.FC<ContractsProps> = ({
</div>
</Menu>
{selected && (
<Contract
<>
{rawMetadata.sources[selected].content ? (
<Contract content={rawMetadata.sources[selected].content} />
) : (
<ContractFromRepo
checksummedAddress={checksummedAddress}
networkId={provider!.network.chainId}
filename={selected}
source={rawMetadata.sources[selected]}
/>
)}
</>
)}
</div>
</>
)}

View File

@ -115,22 +115,20 @@ export const useSourcifyMetadata = (
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 = (
checksummedAddress: string,
networkId: number,
filename: string,
source: any,
sourcifySource: SourcifySource
) => {
const [content, setContent] = useState<string>(source.content);
useEffect(() => {
if (source.content) {
return;
}
const abortController = new AbortController();
const readContent = async () => {
const normalizedFilename = filename.replaceAll(/[@:]/g, "_");
const url = sourcifySourceFile(
checksummedAddress,
@ -138,20 +136,12 @@ export const useContract = (
normalizedFilename,
sourcifySource
);
const res = await fetch(url, { signal: abortController.signal });
if (res.ok) {
const _content = await res.text();
setContent(_content);
const { data, error } = useSWRImmutable(url, contractFetcher);
if (error) {
return undefined;
}
};
readContent();
return () => {
abortController.abort();
};
}, [checksummedAddress, networkId, filename, source.content, sourcifySource]);
return content;
return data;
};
export const useTransactionDescription = (