87 lines
3.0 KiB
TypeScript
87 lines
3.0 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { useIsMounted } from "usehooks-ts";
|
|
import { usePublicClient } from "wagmi";
|
|
import { useSelectedNetwork } from "~~/hooks/scaffold-eth";
|
|
import {
|
|
Contract,
|
|
ContractCodeStatus,
|
|
ContractName,
|
|
UseDeployedContractConfig,
|
|
contracts,
|
|
} from "~~/utils/scaffold-eth/contract";
|
|
|
|
type DeployedContractData<TContractName extends ContractName> = {
|
|
data: Contract<TContractName> | undefined;
|
|
isLoading: boolean;
|
|
};
|
|
|
|
/**
|
|
* Gets the matching contract info for the provided contract name from the contracts present in deployedContracts.ts
|
|
* and externalContracts.ts corresponding to targetNetworks configured in scaffold.config.ts
|
|
*/
|
|
export function useDeployedContractInfo<TContractName extends ContractName>(
|
|
config: UseDeployedContractConfig<TContractName>,
|
|
): DeployedContractData<TContractName>;
|
|
/**
|
|
* @deprecated Use object parameter version instead: useDeployedContractInfo({ contractName: "YourContract" })
|
|
*/
|
|
export function useDeployedContractInfo<TContractName extends ContractName>(
|
|
contractName: TContractName,
|
|
): DeployedContractData<TContractName>;
|
|
|
|
export function useDeployedContractInfo<TContractName extends ContractName>(
|
|
configOrName: UseDeployedContractConfig<TContractName> | TContractName,
|
|
): DeployedContractData<TContractName> {
|
|
const isMounted = useIsMounted();
|
|
|
|
const finalConfig: UseDeployedContractConfig<TContractName> =
|
|
typeof configOrName === "string" ? { contractName: configOrName } : (configOrName as any);
|
|
|
|
useEffect(() => {
|
|
if (typeof configOrName === "string") {
|
|
console.warn(
|
|
"Using `useDeployedContractInfo` with a string parameter is deprecated. Please use the object parameter version instead.",
|
|
);
|
|
}
|
|
}, [configOrName]);
|
|
const { contractName, chainId } = finalConfig;
|
|
const selectedNetwork = useSelectedNetwork(chainId);
|
|
const deployedContract = contracts?.[selectedNetwork.id]?.[contractName as ContractName] as Contract<TContractName>;
|
|
const [status, setStatus] = useState<ContractCodeStatus>(ContractCodeStatus.LOADING);
|
|
const publicClient = usePublicClient({ chainId: selectedNetwork.id });
|
|
|
|
useEffect(() => {
|
|
const checkContractDeployment = async () => {
|
|
try {
|
|
if (!isMounted() || !publicClient) return;
|
|
|
|
if (!deployedContract) {
|
|
setStatus(ContractCodeStatus.NOT_FOUND);
|
|
return;
|
|
}
|
|
|
|
const code = await publicClient.getBytecode({
|
|
address: deployedContract.address,
|
|
});
|
|
|
|
// If contract code is `0x` => no contract deployed on that address
|
|
if (code === "0x") {
|
|
setStatus(ContractCodeStatus.NOT_FOUND);
|
|
return;
|
|
}
|
|
setStatus(ContractCodeStatus.DEPLOYED);
|
|
} catch (e) {
|
|
console.error(e);
|
|
setStatus(ContractCodeStatus.NOT_FOUND);
|
|
}
|
|
};
|
|
|
|
checkContractDeployment();
|
|
}, [isMounted, contractName, deployedContract, publicClient]);
|
|
|
|
return {
|
|
data: status === ContractCodeStatus.DEPLOYED ? deployedContract : undefined,
|
|
isLoading: status === ContractCodeStatus.LOADING,
|
|
};
|
|
}
|