xchange-create
Version:
Create Xchange Project
86 lines (80 loc) • 2.75 kB
text/typescript
import { useEffect } from "react"
import { useTargetNetwork } from "./useTargetNetwork"
import {
QueryObserverResult,
RefetchOptions,
useQueryClient,
} from "@tanstack/react-query"
import type { ExtractAbiFunctionNames } from "abitype"
import { ReadContractErrorType } from "viem"
import { useBlockNumber, useReadContract } from "wagmi"
import { useDeployedContractInfo } from "~~/hooks/xchange-create"
import {
AbiFunctionReturnType,
ContractAbi,
ContractName,
UseReadConfig,
} from "~~/utils/xchange/contract"
/**
* Wrapper around wagmi's useContractRead hook which automatically loads (by name) the contract ABI and address from
* the contracts present in deployedContracts.ts & externalContracts.ts corresponding to targetNetworks configured in xchange.config.ts
* @param config - The config settings, including extra wagmi configuration
* @param config.contractName - deployed contract name
* @param config.functionName - name of the function to be called
* @param config.args - args to be passed to the function call
*/
export const useWagmiReadContract = <
TContractName extends ContractName,
TFunctionName extends ExtractAbiFunctionNames<
ContractAbi<TContractName>,
"pure" | "view"
>,
>({
contractName,
functionName,
args,
...readConfig
}: UseReadConfig<TContractName, TFunctionName>) => {
const { data: deployedContract } = useDeployedContractInfo(contractName)
const { targetNetwork } = useTargetNetwork()
const { query: queryOptions, watch, ...readContractConfig } = readConfig
// set watch to true by default
const defaultWatch = watch ?? true
const readContractHookRes = useWagmiReadContract({
chainId: targetNetwork.id,
functionName,
address: deployedContract?.address,
abi: deployedContract?.abi,
args,
...(readContractConfig as any),
query: {
enabled: !Array.isArray(args) || !args.some(arg => arg === undefined),
...queryOptions,
},
}) as Omit<ReturnType<typeof useReadContract>, "data" | "refetch"> & {
data: AbiFunctionReturnType<ContractAbi, TFunctionName> | undefined
refetch: (
options?: RefetchOptions | undefined
) => Promise<
QueryObserverResult<
AbiFunctionReturnType<ContractAbi, TFunctionName>,
ReadContractErrorType
>
>
}
const queryClient = useQueryClient()
const { data: blockNumber } = useBlockNumber({
watch: defaultWatch,
chainId: targetNetwork.id,
query: {
enabled: defaultWatch,
},
})
useEffect(() => {
if (defaultWatch) {
queryClient.invalidateQueries({ queryKey: readContractHookRes.queryKey })
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [blockNumber])
return readContractHookRes
}