Apply SWR to Sourcify contract source code fetching
This commit is contained in:
parent
49abfbda2f
commit
5ab336041e
@ -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<ContractProps> = ({
|
||||
checksummedAddress,
|
||||
networkId,
|
||||
filename,
|
||||
source,
|
||||
}) => {
|
||||
const { sourcifySource } = useAppConfigContext();
|
||||
const content = useContract(
|
||||
checksummedAddress,
|
||||
networkId,
|
||||
filename,
|
||||
source,
|
||||
sourcifySource
|
||||
);
|
||||
|
||||
return (
|
||||
<SyntaxHighlighter
|
||||
className="w-full h-full border font-code text-base"
|
||||
language="solidity"
|
||||
style={docco}
|
||||
showLineNumbers
|
||||
>
|
||||
{content ?? ""}
|
||||
</SyntaxHighlighter>
|
||||
);
|
||||
};
|
||||
const Contract: React.FC<ContractProps> = ({ content }) => (
|
||||
<SyntaxHighlighter
|
||||
className="w-full h-full border font-code text-base"
|
||||
language="solidity"
|
||||
style={docco}
|
||||
showLineNumbers
|
||||
>
|
||||
{content ?? ""}
|
||||
</SyntaxHighlighter>
|
||||
);
|
||||
|
||||
export default React.memo(Contract);
|
||||
|
37
src/address/ContractFromRepo.tsx
Normal file
37
src/address/ContractFromRepo.tsx
Normal 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);
|
@ -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<ContractsProps> = ({
|
||||
</div>
|
||||
</Menu>
|
||||
{selected && (
|
||||
<Contract
|
||||
checksummedAddress={checksummedAddress}
|
||||
networkId={provider!.network.chainId}
|
||||
filename={selected}
|
||||
source={rawMetadata.sources[selected]}
|
||||
/>
|
||||
<>
|
||||
{rawMetadata.sources[selected].content ? (
|
||||
<Contract content={rawMetadata.sources[selected].content} />
|
||||
) : (
|
||||
<ContractFromRepo
|
||||
checksummedAddress={checksummedAddress}
|
||||
networkId={provider!.network.chainId}
|
||||
filename={selected}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
@ -115,43 +115,33 @@ 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);
|
||||
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 = (
|
||||
|
Loading…
Reference in New Issue
Block a user