import { BaseError, decodeFunctionResult, encodeFunctionData, getContractError, toHex, type Address, type Hex, } from 'viem' import type { ClientWithPns } from '../../contracts/consts.js' import { getChainContractAddress } from '../../contracts/getChainContractAddress.js' import { universalResolverFindResolverSnippet } from '../../contracts/universalResolver.js' import type { GenericPassthrough, TransactionRequestWithPassthrough, } from '../../types.js' import { EMPTY_ADDRESS } from '../../utils/consts.js' import { generateFunction, type GeneratedFunction, } from '../../utils/generateFunction.js' import { packetToBytes } from '../../utils/hexEncodedName.js' export type GetResolverParameters = { /** Name to get resolver for */ name: string } export type GetResolverReturnType = Address | null const encode = ( client: ClientWithPns, { name }: GetResolverParameters, ): TransactionRequestWithPassthrough => { const address = getChainContractAddress({ client, contract: 'ensUniversalResolver', }) const args = [toHex(packetToBytes(name))] as const return { to: address, data: encodeFunctionData({ abi: universalResolverFindResolverSnippet, functionName: 'findResolver', args, }), passthrough: { address, args }, } } const decode = async ( _client: ClientWithPns, data: Hex | BaseError, passthrough: GenericPassthrough, ): Promise => { if (typeof data === 'object') throw getContractError(data, { abi: universalResolverFindResolverSnippet, functionName: 'findResolver', args: passthrough.args, address: passthrough.address, }) as BaseError const response = decodeFunctionResult({ abi: universalResolverFindResolverSnippet, functionName: 'findResolver', data, }) if (response[0] === EMPTY_ADDRESS) return null return response[0] } type BatchableFunctionObject = GeneratedFunction /** * Gets the resolver address for a name. * @param client - {@link ClientWithPns} * @param parameters - {@link GetResolverParameters} * @returns Resolver address, or null if none is found. {@link GetResolverReturnType} * * @example * import { createPublicClient, http } from 'viem' * import { mainnet } from 'viem/chains' * import { addPnsContracts } from '@pnsdomains/pnsjs' * import { getResolver } from '@pnsdomains/pnsjs/public' * * const client = createPublicClient({ * chain: addPnsContracts(mainnet), * transport: http(), * }) * const result = await getResolver(client, { name: 'pns.pls' }) * // 0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41 */ const getResolver = generateFunction({ encode, decode }) as (( client: ClientWithPns, { name }: GetResolverParameters, ) => Promise) & BatchableFunctionObject export default getResolver