import type { Config, ResolvedRegister, SimulateContractErrorType, SimulateContractParameters, } from '@wagmi/core' import type { ConfigParameter, QueryParameter, ScopeKeyParameter, UnionExactPartial, } from '@wagmi/core/internal' import type { SimulateContractData, SimulateContractQueryFnData, } from '@wagmi/core/query' import type { Abi, Address, ContractFunctionArgs, ContractFunctionName, } from 'viem' import { useChainId } from '../useChainId.js' import { useConfig } from '../useConfig.js' import { type UseSimulateContractReturnType, useSimulateContract, } from '../useSimulateContract.js' type stateMutability = 'nonpayable' | 'payable' export type CreateUseSimulateContractParameters< abi extends Abi | readonly unknown[], address extends Address | Record | undefined = undefined, functionName extends | ContractFunctionName | undefined = undefined, > = { abi: abi | Abi | readonly unknown[] address?: address | Address | Record | undefined functionName?: | functionName | ContractFunctionName | undefined } export type CreateUseSimulateContractReturnType< abi extends Abi | readonly unknown[], address extends Address | Record | undefined, functionName extends ContractFunctionName | undefined, > = < name extends functionName extends ContractFunctionName ? functionName : ContractFunctionName, const args extends ContractFunctionArgs, config extends Config = ResolvedRegister['config'], chainId extends config['chains'][number]['id'] | undefined = undefined, selectData = SimulateContractData, >( parameters?: { abi?: undefined address?: address extends undefined ? Address : undefined functionName?: functionName extends undefined ? name : undefined chainId?: address extends Record ? | keyof address | (chainId extends keyof address ? chainId : never) | undefined : chainId | number | undefined } & UnionExactPartial< // TODO: Take `abi` and `address` from above and omit from below (currently breaks inference) SimulateContractParameters > & ScopeKeyParameter & ConfigParameter & QueryParameter< SimulateContractQueryFnData, SimulateContractErrorType, selectData // TODO: Add `SimulateContractQueryKey` as 4th type param (currently causes TS2589) >, ) => UseSimulateContractReturnType export function createUseSimulateContract< const abi extends Abi | readonly unknown[], const address extends | Address | Record | undefined = undefined, functionName extends | ContractFunctionName | undefined = undefined, >( props: CreateUseSimulateContractParameters, ): CreateUseSimulateContractReturnType { if (props.address !== undefined && typeof props.address === 'object') return (parameters) => { const config = useConfig(parameters) const configChainId = useChainId({ config }) const chainId = (parameters as { chainId?: number })?.chainId ?? configChainId return useSimulateContract({ ...(parameters as any), ...(props.functionName ? { functionName: props.functionName } : {}), address: props.address?.[chainId], abi: props.abi, }) } return (parameters) => { return useSimulateContract({ ...(parameters as any), ...(props.address ? { address: props.address } : {}), ...(props.functionName ? { functionName: props.functionName } : {}), abi: props.abi, }) } }