otterscan/src/address/Contracts.tsx

138 lines
4.9 KiB
TypeScript
Raw Normal View History

import React, { useState, useEffect, useContext } from "react";
2021-09-06 06:43:20 +00:00
import { commify } from "@ethersproject/units";
import { Menu } from "@headlessui/react";
2021-09-07 04:10:19 +00:00
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown";
2021-07-24 23:33:45 +00:00
import ContentFrame from "../ContentFrame";
import InfoRow from "../components/InfoRow";
import Contract from "./Contract";
import ContractFromRepo from "./ContractFromRepo";
2021-07-24 23:33:45 +00:00
import { RuntimeContext } from "../useRuntime";
2021-11-25 18:50:59 +00:00
import { Metadata } from "../sourcify/useSourcify";
2021-09-06 07:14:49 +00:00
import ExternalLink from "../components/ExternalLink";
import { openInRemixURL } from "../url";
2021-10-25 02:04:04 +00:00
import ContractABI from "./ContractABI";
2021-07-25 08:09:30 +00:00
2021-07-24 23:33:45 +00:00
type ContractsProps = {
checksummedAddress: string;
2021-09-06 00:13:01 +00:00
rawMetadata: Metadata | null | undefined;
2021-07-24 23:33:45 +00:00
};
2021-09-06 00:13:01 +00:00
const Contracts: React.FC<ContractsProps> = ({
checksummedAddress,
rawMetadata,
}) => {
2021-07-24 23:33:45 +00:00
const { provider } = useContext(RuntimeContext);
const [selected, setSelected] = useState<string>();
2021-09-06 00:08:06 +00:00
useEffect(() => {
if (rawMetadata) {
setSelected(Object.keys(rawMetadata.sources)[0]);
}
}, [rawMetadata]);
2021-07-24 23:33:45 +00:00
const optimizer = rawMetadata?.settings?.optimizer;
return (
<ContentFrame tabs>
{rawMetadata && (
<>
2021-07-25 08:09:30 +00:00
<InfoRow title="Language">
<span>{rawMetadata.language}</span>
</InfoRow>
2021-07-24 23:33:45 +00:00
<InfoRow title="Compiler">
2021-07-25 08:09:30 +00:00
<span>{rawMetadata.compiler.version}</span>
2021-07-24 23:33:45 +00:00
</InfoRow>
<InfoRow title="Optimizer Enabled">
{optimizer?.enabled ? (
<span>
2022-08-08 04:56:24 +00:00
<span className="font-bold text-emerald-600">Yes</span> with{" "}
<span className="font-bold text-emerald-600">
2021-09-06 06:43:20 +00:00
{commify(optimizer?.runs)}
2021-07-24 23:33:45 +00:00
</span>{" "}
runs
</span>
) : (
<span className="font-bold text-red-600">No</span>
)}
</InfoRow>
</>
)}
<div className="py-5">
{rawMetadata === undefined && (
<span>Getting data from Sourcify repository...</span>
)}
2021-07-24 23:33:45 +00:00
{rawMetadata === null && (
2021-09-10 07:31:24 +00:00
<span>
Address is not a contract or couldn't find contract metadata in
Sourcify repository.
</span>
2021-07-24 23:33:45 +00:00
)}
{rawMetadata !== undefined && rawMetadata !== null && (
2021-09-10 08:17:10 +00:00
<>
{rawMetadata.output.abi && (
2021-10-25 02:04:04 +00:00
<ContractABI abi={rawMetadata.output.abi} />
2021-07-24 23:33:45 +00:00
)}
2021-09-10 08:17:10 +00:00
<div>
<Menu>
<div className="flex space-x-2 justify-between items-baseline">
<Menu.Button className="flex space-x-2 text-sm border-l border-r border-t rounded-t px-2 py-1">
<span>{selected}</span>
<span className="self-center">
<FontAwesomeIcon icon={faChevronDown} size="xs" />
</span>
</Menu.Button>
{provider && (
<div className="text-sm">
<ExternalLink
href={openInRemixURL(
checksummedAddress,
provider.network.chainId
)}
>
Open in Remix
</ExternalLink>
</div>
)}
</div>
<div className="relative">
<Menu.Items className="absolute border p-1 rounded-b bg-white flex flex-col">
{Object.entries(rawMetadata.sources).map(([k]) => (
<Menu.Item key={k}>
<button
className={`flex text-sm px-2 py-1 ${
selected === k
? "font-bold bg-gray-200 text-gray-500"
: "hover:border-orange-200 hover:text-gray-500 text-gray-400 transition-transform transition-colors duration-75"
}`}
onClick={() => setSelected(k)}
>
{k}
</button>
</Menu.Item>
))}
</Menu.Items>
</div>
</Menu>
{selected && (
<>
{rawMetadata.sources[selected].content ? (
<Contract content={rawMetadata.sources[selected].content} />
) : (
<ContractFromRepo
checksummedAddress={checksummedAddress}
networkId={provider!.network.chainId}
filename={selected}
/>
)}
</>
2021-09-10 08:17:10 +00:00
)}
</div>
</>
2021-07-24 23:33:45 +00:00
)}
</div>
</ContentFrame>
);
};
export default React.memo(Contracts);