103 lines
3.0 KiB
TypeScript
103 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { InheritanceTooltip } from "./InheritanceTooltip";
|
|
import { Abi, AbiFunction } from "abitype";
|
|
import { Address } from "viem";
|
|
import { useReadContract } from "wagmi";
|
|
import {
|
|
ContractInput,
|
|
displayTxResult,
|
|
getFunctionInputKey,
|
|
getInitialFormState,
|
|
getParsedContractFunctionArgs,
|
|
transformAbiFunction,
|
|
} from "~~/app/debug/_components/contract";
|
|
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
|
|
import { getParsedError, notification } from "~~/utils/scaffold-eth";
|
|
|
|
type ReadOnlyFunctionFormProps = {
|
|
contractAddress: Address;
|
|
abiFunction: AbiFunction;
|
|
inheritedFrom?: string;
|
|
abi: Abi;
|
|
};
|
|
|
|
export const ReadOnlyFunctionForm = ({
|
|
contractAddress,
|
|
abiFunction,
|
|
inheritedFrom,
|
|
abi,
|
|
}: ReadOnlyFunctionFormProps) => {
|
|
const [form, setForm] = useState<Record<string, any>>(() => getInitialFormState(abiFunction));
|
|
const [result, setResult] = useState<unknown>();
|
|
const { targetNetwork } = useTargetNetwork();
|
|
|
|
const { isFetching, refetch, error } = useReadContract({
|
|
address: contractAddress,
|
|
functionName: abiFunction.name,
|
|
abi: abi,
|
|
args: getParsedContractFunctionArgs(form),
|
|
chainId: targetNetwork.id,
|
|
query: {
|
|
enabled: false,
|
|
retry: false,
|
|
},
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (error) {
|
|
const parsedError = getParsedError(error);
|
|
notification.error(parsedError);
|
|
}
|
|
}, [error]);
|
|
|
|
const transformedFunction = transformAbiFunction(abiFunction);
|
|
const inputElements = transformedFunction.inputs.map((input, inputIndex) => {
|
|
const key = getFunctionInputKey(abiFunction.name, input, inputIndex);
|
|
return (
|
|
<ContractInput
|
|
key={key}
|
|
setForm={updatedFormValue => {
|
|
setResult(undefined);
|
|
setForm(updatedFormValue);
|
|
}}
|
|
form={form}
|
|
stateObjectKey={key}
|
|
paramType={input}
|
|
/>
|
|
);
|
|
});
|
|
|
|
return (
|
|
<div className="flex flex-col gap-3 py-5 first:pt-0 last:pb-1">
|
|
<p className="font-medium my-0 break-words">
|
|
{abiFunction.name}
|
|
<InheritanceTooltip inheritedFrom={inheritedFrom} />
|
|
</p>
|
|
{inputElements}
|
|
<div className="flex flex-col md:flex-row justify-between gap-2 flex-wrap">
|
|
<div className="grow w-full md:max-w-[80%]">
|
|
{result !== null && result !== undefined && (
|
|
<div className="bg-secondary rounded-3xl text-sm px-4 py-1.5 break-words overflow-auto">
|
|
<p className="font-bold m-0 mb-1">Result:</p>
|
|
<pre className="whitespace-pre-wrap break-words">{displayTxResult(result, "sm")}</pre>
|
|
</div>
|
|
)}
|
|
</div>
|
|
<button
|
|
className="btn btn-secondary btn-sm self-end md:self-start"
|
|
onClick={async () => {
|
|
const { data } = await refetch();
|
|
setResult(data);
|
|
}}
|
|
disabled={isFetching}
|
|
>
|
|
{isFetching && <span className="loading loading-spinner loading-xs"></span>}
|
|
Read 📡
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|