import { type Account, type Hash, type SendTransactionParameters, type Transport, encodeFunctionData, } from 'viem' import { sendTransaction } from 'viem/actions' import type { ChainWithEns, ClientWithAccount } from '../../contracts/consts.js' import { ethRegistrarControllerRegisterSnippet } from '../../contracts/ethRegistrarController.js' import { getChainContractAddress } from '../../contracts/getChainContractAddress.js' import { UnsupportedNameTypeError } from '../../errors/general.js' import type { Prettify, SimpleTransactionRequest, WriteTransactionParameters, } from '../../types.js' import { getNameType } from '../../utils/getNameType.js' import { type RegistrationParameters, makeRegistrationCallData, } from '../../utils/registerHelpers.js' export type RegisterNameDataParameters = RegistrationParameters & { /** Value of registration */ value: bigint } export type RegisterNameDataReturnType = SimpleTransactionRequest & { value: bigint } export type RegisterNameParameters< TChain extends ChainWithEns, TAccount extends Account | undefined, TChainOverride extends ChainWithEns | undefined, > = Prettify< RegisterNameDataParameters & WriteTransactionParameters > export type RegisterNameReturnType = Hash export const makeFunctionData = < TChain extends ChainWithEns, TAccount extends Account | undefined, >( wallet: ClientWithAccount, { value, ...args }: RegisterNameDataParameters, ): RegisterNameDataReturnType => { const nameType = getNameType(args.name) if (nameType !== 'eth-2ld') throw new UnsupportedNameTypeError({ nameType, supportedNameTypes: ['eth-2ld'], details: 'Only 2ld-eth name registration is supported', }) return { to: getChainContractAddress({ client: wallet, contract: 'ensEthRegistrarController', }), data: encodeFunctionData({ abi: ethRegistrarControllerRegisterSnippet, functionName: 'register', args: [makeRegistrationCallData(args)], }), value, } } /** * Registers a name on ENS * @param wallet - {@link ClientWithAccount} * @param parameters - {@link RegisterNameParameters} * @returns Transaction hash. {@link RegisterNameReturnType} * * @example * import { createPublicClient, createWalletClient, http, custom } from 'viem' * import { mainnet } from 'viem/chains' * import { addEnsContracts } from '@etn-sc/ensjs' * import { getPrice } from '@etn-sc/ensjs/public' * import { randomSecret } from '@etn-sc/ensjs/utils' * import { commitName, registerName } from '@etn-sc/ensjs/wallet' * * const mainnetWithEns = addEnsContracts(mainnet) * const client = createPublicClient({ * chain: mainnetWithEns, * transport: http(), * }) * const wallet = createWalletClient({ * chain: mainnetWithEns, * transport: custom(window.ethereum), * }) * const secret = randomSecret() * const params = { * name: 'example.eth', * owner: '0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7', * duration: 31536000, // 1 year * secret, * } * * const commitmentHash = await commitName(wallet, params) * await client.waitForTransactionReceipt({ hash: commitmentHash }) // wait for commitment to finalise * await new Promise((resolve) => setTimeout(resolve, 60 * 1_000)) // wait for commitment to be valid * * const { base, premium } = await getPrice(client, { nameOrNames: params.name, duration: params.duration }) * const value = (base + premium) * 110n / 100n // add 10% to the price for buffer * const hash = await registerName(wallet, { ...params, value }) * // 0x... */ async function registerName< TChain extends ChainWithEns, TAccount extends Account | undefined, TChainOverride extends ChainWithEns | undefined = ChainWithEns, >( wallet: ClientWithAccount, { name, owner, duration, secret, resolverAddress, records, reverseRecord, referrer, value, ...txArgs }: RegisterNameParameters, ): Promise { const data = makeFunctionData(wallet, { name, owner, duration, secret, resolverAddress, records, reverseRecord, referrer, value, }) const writeArgs = { ...data, ...txArgs, } as SendTransactionParameters return sendTransaction(wallet, writeArgs) } registerName.makeFunctionData = makeFunctionData export default registerName