wagmi
Version:
React Hooks for Ethereum
119 lines (113 loc) • 4.01 kB
text/typescript
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<number, Address> | undefined = undefined,
functionName extends
| ContractFunctionName<abi, stateMutability>
| undefined = undefined,
> = {
abi: abi | Abi | readonly unknown[]
address?: address | Address | Record<number, Address> | undefined
functionName?:
| functionName
| ContractFunctionName<abi, stateMutability>
| undefined
}
export type CreateUseSimulateContractReturnType<
abi extends Abi | readonly unknown[],
address extends Address | Record<number, Address> | undefined,
functionName extends ContractFunctionName<abi, stateMutability> | undefined,
> = <
name extends functionName extends ContractFunctionName<abi, stateMutability>
? functionName
: ContractFunctionName<abi, stateMutability>,
const args extends ContractFunctionArgs<abi, stateMutability, name>,
config extends Config = ResolvedRegister['config'],
chainId extends config['chains'][number]['id'] | undefined = undefined,
selectData = SimulateContractData<abi, name, args, config, chainId>,
>(
parameters?: {
abi?: undefined
address?: address extends undefined ? Address : undefined
functionName?: functionName extends undefined ? name : undefined
chainId?: address extends Record<number, Address>
?
| 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<abi, name, args, config, chainId>
> &
ScopeKeyParameter &
ConfigParameter<config> &
QueryParameter<
SimulateContractQueryFnData<abi, name, args, config, chainId>,
SimulateContractErrorType,
selectData
// TODO: Add `SimulateContractQueryKey<abi, name, args, config, chainId>` as 4th type param (currently causes TS2589)
>,
) => UseSimulateContractReturnType<abi, name, args, config, chainId, selectData>
export function createUseSimulateContract<
const abi extends Abi | readonly unknown[],
const address extends
| Address
| Record<number, Address>
| undefined = undefined,
functionName extends
| ContractFunctionName<abi, stateMutability>
| undefined = undefined,
>(
props: CreateUseSimulateContractParameters<abi, address, functionName>,
): CreateUseSimulateContractReturnType<abi, address, functionName> {
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,
})
}
}