import type { Abi, Account, Address, Chain, ContractFunctionArgs, ContractFunctionName, SimulateContractParameters as viem_SimulateContractParameters, } from 'viem' import type { Config } from '../../createConfig.js' import type { SelectChains } from '../../types/chain.js' import type { ChainIdParameter, ConnectorParameter, } from '../../types/properties.js' import type { UnionCompute, UnionStrictOmit } from '../../types/utils.js' import { getChainId } from '../getChainId.js' import { type SimulateContractReturnType, simulateContract, } from '../simulateContract.js' type stateMutability = 'nonpayable' | 'payable' export type CreateSimulateContractParameters< 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 CreateSimulateContractReturnType< abi extends Abi | readonly unknown[], address extends Address | Record | undefined, functionName extends ContractFunctionName | undefined, > = < config extends Config, name extends functionName extends ContractFunctionName ? functionName : ContractFunctionName, args extends ContractFunctionArgs, chainId extends config['chains'][number]['id'] | undefined = undefined, /// chains extends readonly Chain[] = SelectChains, >( config: config, parameters: { [key in keyof chains]: UnionCompute< UnionStrictOmit< viem_SimulateContractParameters< abi, name, args, chains[key], chains[key], Account | Address >, | 'abi' | 'chain' | (address extends undefined ? never : 'address') | (functionName extends undefined ? never : 'functionName') > > & ChainIdParameter & ConnectorParameter & { chainId?: address extends Record ? | keyof address | (chainId extends keyof address ? chainId : never) | undefined : chainId | number | undefined } }[number], ) => Promise> export function createSimulateContract< const abi extends Abi | readonly unknown[], const address extends | Address | Record | undefined = undefined, functionName extends | ContractFunctionName | undefined = undefined, >( c: CreateSimulateContractParameters, ): CreateSimulateContractReturnType { if (c.address !== undefined && typeof c.address === 'object') return (config, parameters) => { const configChainId = getChainId(config) const chainId = (parameters as { chainId?: number })?.chainId ?? configChainId return simulateContract(config, { ...(parameters as any), ...(c.functionName ? { functionName: c.functionName } : {}), address: c.address?.[chainId], abi: c.abi, }) } return (config, parameters) => { return simulateContract(config, { ...(parameters as any), ...(c.address ? { address: c.address } : {}), ...(c.functionName ? { functionName: c.functionName } : {}), abi: c.abi, }) } }