import { BaseError, decodeFunctionResult, encodeFunctionData, getContractError, hexToBytes, type Hex, } from 'viem' import type { ClientWithPns } from '../../contracts/consts.js' import { getChainContractAddress } from '../../contracts/getChainContractAddress.js' import { nameWrapperNamesSnippet } from '../../contracts/nameWrapper.js' import type { GenericPassthrough, TransactionRequestWithPassthrough, } from '../../types.js' import { generateFunction, type GeneratedFunction, } from '../../utils/generateFunction.js' import { bytesToPacket } from '../../utils/hexEncodedName.js' import { namehash } from '../../utils/normalise.js' export type GetWrapperNameParameters = { /** Name with unknown labels, e.g. "[4ca938ec1b323ca71c4fb47a712abb68cce1cabf39ea4d6789e42fbc1f95459b].pls" */ name: string } export type GetWrapperNameReturnType = string | null const encode = ( client: ClientWithPns, { name }: GetWrapperNameParameters, ): TransactionRequestWithPassthrough => { const address = getChainContractAddress({ client, contract: 'pnsNameWrapper', }) const args = [namehash(name)] as const return { to: address, data: encodeFunctionData({ abi: nameWrapperNamesSnippet, functionName: 'names', args, }), passthrough: { address, args }, } } const decode = async ( _client: ClientWithPns, data: Hex | BaseError, passthrough: GenericPassthrough, ): Promise => { if (typeof data === 'object') throw getContractError(data, { abi: nameWrapperNamesSnippet, functionName: 'names', args: passthrough.args, address: passthrough.address, }) as BaseError const result = decodeFunctionResult({ abi: nameWrapperNamesSnippet, functionName: 'names', data, }) if (!result || result === '0x' || BigInt(result) === 0n) return null return bytesToPacket(hexToBytes(result)) } type BatchableFunctionObject = GeneratedFunction /** * Gets the full name for a name with unknown labels from the NameWrapper. * @param client - {@link ClientWithPns} * @param parameters - {@link GetWrapperNameParameters} * @returns Full name, or null if name was not found. {@link GetWrapperNameReturnType} * * @example * import { createPublicClient, http } from 'viem' * import { mainnet } from 'viem/chains' * import { addPnsContracts } from '@pnsdomains/pnsjs' * import { getWrapperName } from '@pnsdomains/pnsjs/public' * * const client = createPublicClient({ * chain: addPnsContracts(mainnet), * transport: http(), * }) * const result = await getWrapperName(client, { name: '[4ca938ec1b323ca71c4fb47a712abb68cce1cabf39ea4d6789e42fbc1f95459b].pls' }) * // wrapped.pls */ const getWrapperName = generateFunction({ encode, decode }) as (( client: ClientWithPns, { name }: GetWrapperNameParameters, ) => Promise) & BatchableFunctionObject export default getWrapperName