import { BaseError, decodeFunctionResult, encodeFunctionData, labelhash, type Hex, } from 'viem' import { baseRegistrarAvailableSnippet } from '../../contracts/baseRegistrar.js' import type { ClientWithPns } from '../../contracts/consts.js' import { getChainContractAddress } from '../../contracts/getChainContractAddress.js' import { UnsupportedNameTypeError } from '../../errors/general.js' import type { SimpleTransactionRequest } from '../../types.js' import { generateFunction, type GeneratedFunction, } from '../../utils/generateFunction.js' import { getNameType } from '../../utils/getNameType.js' export type GetAvailableParameters = { /** Name to check availability for, only compatible for pls 2ld */ name: string } export type GetAvailableReturnType = boolean const encode = ( client: ClientWithPns, { name }: GetAvailableParameters, ): SimpleTransactionRequest => { const labels = name.split('.') const nameType = getNameType(name) if (nameType !== 'pls-2ld') throw new UnsupportedNameTypeError({ nameType, supportedNameTypes: ['pls-2ld'], details: 'Currently only pls-2ld names can be checked for availability', }) return { to: getChainContractAddress({ client, contract: 'pnsBaseRegistrarImplementation', }), data: encodeFunctionData({ abi: baseRegistrarAvailableSnippet, functionName: 'available', args: [BigInt(labelhash(labels[0]))], }), } } const decode = async ( _client: ClientWithPns, data: Hex | BaseError, ): Promise => { if (typeof data === 'object') throw data const result = decodeFunctionResult({ abi: baseRegistrarAvailableSnippet, functionName: 'available', data, }) return result } type BatchableFunctionObject = GeneratedFunction /** * Gets the availability of a name to register * @param client - {@link ClientWithPns} * @param parameters - {@link GetAvailableParameters} * @returns Availability as boolean. {@link GetAvailableReturnType} * * @example * import { createPublicClient, http } from 'viem' * import { mainnet } from 'viem/chains' * import { addPnsContracts } from '@pnsdomains/pnsjs' * import { getAvailable } from '@pnsdomains/pnsjs/public' * * const client = createPublicClient({ * chain: addPnsContracts(mainnet), * transport: http(), * }) * const result = await getAvailable(client, { name: 'pns.pls' }) * // false */ const getAvailable = generateFunction({ encode, decode }) as (( client: ClientWithPns, { name }: GetAvailableParameters, ) => Promise) & BatchableFunctionObject export default getAvailable