Files
sre-01-tokenization/packages/nextjs/app/debug/_components/contract/ReadOnlyFunctionForm.tsx
2026-01-10 18:17:37 +07:00

103 lines
3.1 KiB
TypeScript

"use client";
import { useEffect, useMemo, 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 = useMemo(() => transformAbiFunction(abiFunction), [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>
);
};