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 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);
|
||||||
|
|
|
@ -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 { 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>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -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 = (
|
||||||
|
|
Loading…
Reference in New Issue