From d56b41421f20bc370c5a54a6362d330114afa038 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 16 Dec 2024 17:29:43 +0800 Subject: [PATCH 01/20] add legacy register name functions --- packages/ensjs/src/contracts/consts.ts | 29 ++ .../contracts/legacyEthRegistrarController.ts | 159 +++++++ packages/ensjs/src/errors/register.ts | 22 + .../functions/wallet/legacyCommitName.test.ts | 108 +++++ .../src/functions/wallet/legacyCommitName.ts | 136 ++++++ .../wallet/legacyRegisterName.test.ts | 68 +++ .../functions/wallet/legacyRegisterName.ts | 150 +++++++ packages/ensjs/src/test/addTestContracts.ts | 8 + .../src/utils/legacyRegisterHelpers.test.ts | 414 ++++++++++++++++++ .../ensjs/src/utils/legacyRegisterHelpers.ts | 131 ++++++ 10 files changed, 1225 insertions(+) create mode 100644 packages/ensjs/src/contracts/legacyEthRegistrarController.ts create mode 100644 packages/ensjs/src/errors/register.ts create mode 100644 packages/ensjs/src/functions/wallet/legacyCommitName.test.ts create mode 100644 packages/ensjs/src/functions/wallet/legacyCommitName.ts create mode 100644 packages/ensjs/src/functions/wallet/legacyRegisterName.test.ts create mode 100644 packages/ensjs/src/functions/wallet/legacyRegisterName.ts create mode 100644 packages/ensjs/src/utils/legacyRegisterHelpers.test.ts create mode 100644 packages/ensjs/src/utils/legacyRegisterHelpers.ts diff --git a/packages/ensjs/src/contracts/consts.ts b/packages/ensjs/src/contracts/consts.ts index af67f61f..001a6442 100644 --- a/packages/ensjs/src/contracts/consts.ts +++ b/packages/ensjs/src/contracts/consts.ts @@ -1,5 +1,6 @@ import type { Account, Address, Chain, Client, Transport } from 'viem' import type { Assign, Prettify } from '../types.js' +import { EMPTY_ADDRESS } from '../utils/consts.js' type ChainContract = { address: Address @@ -18,6 +19,8 @@ export const supportedContracts = [ 'ensRegistry', 'ensReverseRegistrar', 'ensUniversalResolver', + 'legacyEthRegistrarController', + 'legacyPublicResolver', ] as const export type SupportedChain = (typeof supportedChains)[number] @@ -55,6 +58,12 @@ export const addresses = { ensUniversalResolver: { address: '0xce01f8eee7E479C928F8919abD53E553a36CeF67', }, + legacyEthRegistrarController: { + address: '0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5', + }, + legacyPublicResolver: { + address: '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41', + }, }, 5: { ensBaseRegistrarImplementation: { @@ -87,6 +96,12 @@ export const addresses = { ensUniversalResolver: { address: '0x898A1182F3C2BBBF0b16b4DfEf63E9c3e9eB4821', }, + legacyEthRegistrarController: { + address: '0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5', + }, + legacyPublicResolver: { + address: '0xDaaF96c344f63131acadD0Ea35170E7892d3dfBA', + }, }, 17000: { ensBaseRegistrarImplementation: { @@ -119,6 +134,12 @@ export const addresses = { ensUniversalResolver: { address: '0xa6ac935d4971e3cd133b950ae053becd16fe7f3b', }, + legacyEthRegistrarController: { + address: '0xf13fC748601fDc5afA255e9D9166EB43f603a903', + }, + legacyPublicResolver: { + address: '0xc5e43b622b5e6C379a984E9BdB34E9A545564fA5', + }, }, 11155111: { ensBaseRegistrarImplementation: { @@ -151,6 +172,12 @@ export const addresses = { ensUniversalResolver: { address: '0xc8af999e38273d658be1b921b88a9ddf005769cc', }, + legacyEthRegistrarController: { + address: '0x7e02892cfc2Bfd53a75275451d73cF620e793fc0', + }, + legacyPublicResolver: { + address: '0x0CeEC524b2807841739D3B5E161F5bf1430FFA48', + }, }, } as const satisfies Record< SupportedChain, @@ -195,6 +222,8 @@ type EnsChainContracts = { ensReverseRegistrar: ChainContract ensBulkRenewal: ChainContract ensDnssecImpl: ChainContract + legacyEthRegistrarController: ChainContract + legacyPublicResolver: ChainContract } type BaseChainContracts = { diff --git a/packages/ensjs/src/contracts/legacyEthRegistrarController.ts b/packages/ensjs/src/contracts/legacyEthRegistrarController.ts new file mode 100644 index 00000000..166bf9b5 --- /dev/null +++ b/packages/ensjs/src/contracts/legacyEthRegistrarController.ts @@ -0,0 +1,159 @@ +export const legacyEthRegistrarControllerAvailableSnippet = [ + { + constant: true, + inputs: [{ internalType: 'string', name: 'name', type: 'string' }], + name: 'available', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerCommitSnippet = [ + { + constant: false, + inputs: [{ internalType: 'bytes32', name: 'commitment', type: 'bytes32' }], + name: 'commit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerCommitmentsSnippet = [ + { + constant: true, + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'commitments', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerMakeCommitmentSnippet = [ + { + constant: true, + inputs: [ + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'bytes32', name: 'secret', type: 'bytes32' }, + ], + name: 'makeCommitment', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'pure', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet = [ + { + constant: true, + inputs: [ + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'bytes32', name: 'secret', type: 'bytes32' }, + { internalType: 'address', name: 'resolver', type: 'address' }, + { internalType: 'address', name: 'addr', type: 'address' }, + ], + name: 'makeCommitmentWithConfig', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'pure', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerRegisterSnippet = [ + { + constant: false, + inputs: [ + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'duration', type: 'uint256' }, + { internalType: 'bytes32', name: 'secret', type: 'bytes32' }, + ], + name: 'register', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerRegisterWithConfigSnippet = [ + { + constant: false, + inputs: [ + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'duration', type: 'uint256' }, + { internalType: 'bytes32', name: 'secret', type: 'bytes32' }, + { internalType: 'address', name: 'resolver', type: 'address' }, + { internalType: 'address', name: 'addr', type: 'address' }, + ], + name: 'registerWithConfig', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerRenewSnippet = [ + { + constant: false, + inputs: [ + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'uint256', name: 'duration', type: 'uint256' }, + ], + name: 'renew', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerRentPriceSnippet = [ + { + constant: true, + inputs: [ + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'uint256', name: 'duration', type: 'uint256' }, + ], + name: 'rentPrice', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerSupportsInterfaceSnippet = [ + { + constant: true, + inputs: [{ internalType: 'bytes4', name: 'interfaceID', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'pure', + type: 'function', + }, +] + +export const legacyEthRegistrarControllerTransferOwnershipSnippet = [ + { + constant: false, + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, +] diff --git a/packages/ensjs/src/errors/register.ts b/packages/ensjs/src/errors/register.ts new file mode 100644 index 00000000..69d84ec0 --- /dev/null +++ b/packages/ensjs/src/errors/register.ts @@ -0,0 +1,22 @@ +import type { Address } from 'viem' +import { BaseError } from './base.js' +import { EMPTY_ADDRESS } from '../utils/consts.js' + +export class LegacyRegistrationInvalidConfigError extends BaseError { + override name = 'LegacyRegistrationInvalidConfigError' + + constructor({ + resolverAddress, + address, + }: { + resolverAddress?: Address + address?: Address + }) { + super(`Resolver address is required when setting an address`, { + metaMessages: [ + `- resolverAddress: ${resolverAddress || EMPTY_ADDRESS}`, + `- addr: ${address || EMPTY_ADDRESS}`, + ], + }) + } +} diff --git a/packages/ensjs/src/functions/wallet/legacyCommitName.test.ts b/packages/ensjs/src/functions/wallet/legacyCommitName.test.ts new file mode 100644 index 00000000..b3ade829 --- /dev/null +++ b/packages/ensjs/src/functions/wallet/legacyCommitName.test.ts @@ -0,0 +1,108 @@ +import { labelhash, type Address, type Hex } from 'viem' +import { afterEach, beforeAll, beforeEach, expect, it } from 'vitest' +import { ethRegistrarControllerCommitmentsSnippet } from '../../contracts/ethRegistrarController.js' +import { getChainContractAddress } from '../../contracts/getChainContractAddress.js' +import { + publicClient, + testClient, + waitForTransaction, + walletClient, +} from '../../test/addTestContracts.js' +import { + makeLegacyCommitment, + type LegacyRegistrationParameters, +} from '../../utils/legacyRegisterHelpers.js' +import legacyCommitName from './legacyCommitName.js' +import { legacyEthRegistrarControllerCommitmentsSnippet, legacyEthRegistrarControllerMakeCommitmentSnippet, legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet } from '../../contracts/legacyEthRegistrarController.js' +import { EMPTY_ADDRESS } from '../../utils/consts.js' + +let snapshot: Hex +let accounts: Address[] + +beforeAll(async () => { + accounts = await walletClient.getAddresses() +}) + +beforeEach(async () => { + snapshot = await testClient.snapshot() +}) + +afterEach(async () => { + await testClient.revert({ id: snapshot }) +}) + +const secret = `0x${'a'.repeat(64)}` as Hex + +it.only('should something', async () => { + const params: LegacyRegistrationParameters = { + name: 'wrapped-with-subnames.eth', + duration: 31536000, + owner: accounts[1], + secret, + } + const label = params.name.split('.')[0] + const labelHash = labelhash(params.name.split('.')[0]) + const makeCommitment = await publicClient.readContract({ + abi: legacyEthRegistrarControllerMakeCommitmentSnippet, + functionName: 'makeCommitment', + address: getChainContractAddress({ + client: publicClient, + contract: 'legacyEthRegistrarController', + }), + args: [label, params.owner, params.secret], + }) + console.log('makeCommitment', makeCommitment) + + const test = makeLegacyCommitment(params) + expect(test).toEqual(makeCommitment) +}) + +it('should something 2', async () => { + const params: LegacyRegistrationParameters = { + name: 'wrapped-with-subnames.eth', + duration: 31536000, + owner: accounts[1], + secret, + } + const labelHash = labelhash(params.name.split('.')[0]) + const makeCommitment = await publicClient.readContract({ + abi: legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet, + functionName: 'makeCommitmentWithConfig', + address: getChainContractAddress({ + client: publicClient, + contract: 'legacyEthRegistrarController', + }), + args: [labelHash, params.owner, params.secret, EMPTY_ADDRESS, EMPTY_ADDRESS], + }) + console.log('>>> 2', makeCommitment) + + const test = makeLegacyCommitment(params) + expect(test).toEqual(makeCommitment) +}) + +it('should return a commit transaction and succeed', async () => { + const params: LegacyRegistrationParameters = { + name: 'wrapped-with-subnames.eth', + duration: 31536000, + owner: accounts[1], + secret, + } + const tx = await legacyCommitName(walletClient, { + ...params, + account: accounts[1], + }) + expect(tx).toBeTruthy() + const receipt = await waitForTransaction(tx) + expect(receipt.status).toBe('success') + + const commitment = await publicClient.readContract({ + abi: legacyEthRegistrarControllerCommitmentsSnippet, + functionName: 'commitments', + address: getChainContractAddress({ + client: publicClient, + contract: 'legacyEthRegistrarController', + }), + args: [makeLegacyCommitment(params)], + }) + expect(commitment).toBeTruthy() +}) diff --git a/packages/ensjs/src/functions/wallet/legacyCommitName.ts b/packages/ensjs/src/functions/wallet/legacyCommitName.ts new file mode 100644 index 00000000..5a2d49e9 --- /dev/null +++ b/packages/ensjs/src/functions/wallet/legacyCommitName.ts @@ -0,0 +1,136 @@ +import { + encodeFunctionData, + type Account, + type Hash, + type SendTransactionParameters, + type Transport, +} from 'viem' +import { sendTransaction } from 'viem/actions' +import type { ChainWithEns, ClientWithAccount } from '../../contracts/consts.js' +import { + legacyEthRegistrarControllerCommitSnippet, + legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet, +} from '../../contracts/legacyEthRegistrarController.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 { + makeLegacyCommitment, + type LegacyRegistrationParameters, +} from '../../utils/legacyRegisterHelpers.js' +import { wrappedLabelLengthCheck } from '../../utils/wrapper.js' + +export type CommitNameDataParameters = LegacyRegistrationParameters + +export type CommitNameDataReturnType = SimpleTransactionRequest + +export type CommitNameParameters< + TChain extends ChainWithEns, + TAccount extends Account | undefined, + TChainOverride extends ChainWithEns | undefined, +> = Prettify< + CommitNameDataParameters & + WriteTransactionParameters +> + +export type CommitNameReturnType = Hash + +export const makeFunctionData = < + TChain extends ChainWithEns, + TAccount extends Account | undefined, +>( + wallet: ClientWithAccount, + args: CommitNameDataParameters, +): CommitNameDataReturnType => { + const labels = args.name.split('.') + const nameType = getNameType(args.name) + if (nameType !== 'eth-2ld') + throw new UnsupportedNameTypeError({ + nameType, + supportedNameTypes: ['eth-2ld'], + details: 'Only 2ld-eth name registration is supported', + }) + wrappedLabelLengthCheck(labels[0]) + + console.log('>>>', getChainContractAddress({ + client: wallet, + contract: 'legacyEthRegistrarController', + })) + return { + to: getChainContractAddress({ + client: wallet, + contract: 'legacyEthRegistrarController', + }), + data: encodeFunctionData({ + abi: legacyEthRegistrarControllerCommitSnippet, + functionName: 'commit', + args: [makeLegacyCommitment(args)], + }), + } +} + +/** + * Commits a name to be registered + * @param wallet - {@link ClientWithAccount} + * @param parameters - {@link CommitNameParameters} + * @returns Transaction hash. {@link CommitNameReturnType} + * + * @example + * import { createWalletClient, custom } from 'viem' + * import { mainnet } from 'viem/chains' + * import { addEnsContracts } from '@ensdomains/ensjs' + * import { commitName } from '@ensdomains/ensjs/wallet' + * import { randomSecret } from '@ensdomains/ensjs/utils' + * + * const wallet = createWalletClient({ + * chain: addEnsContracts(mainnet), + * transport: custom(window.ethereum), + * }) + * const secret = randomSecret() + * const hash = await commitName(wallet, { + * name: 'example.eth', + * owner: '0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7', + * duration: 31536000, // 1 year + * secret, + * }) + * // 0x... + */ +async function legacyCommitName< + TChain extends ChainWithEns, + TAccount extends Account | undefined, + TChainOverride extends ChainWithEns | undefined = ChainWithEns, +>( + wallet: ClientWithAccount, + { + name, + owner, + duration, + secret, + resolverAddress, + addr, + ...txArgs + }: CommitNameParameters, +): Promise { + const data = makeFunctionData(wallet, { + name, + owner, + duration, + secret, + resolverAddress, + addr, + }) + const writeArgs = { + ...data, + ...txArgs, + } as SendTransactionParameters + return sendTransaction(wallet, writeArgs) +} + +legacyCommitName.makeFunctionData = makeFunctionData + +export default legacyCommitName diff --git a/packages/ensjs/src/functions/wallet/legacyRegisterName.test.ts b/packages/ensjs/src/functions/wallet/legacyRegisterName.test.ts new file mode 100644 index 00000000..613eb06b --- /dev/null +++ b/packages/ensjs/src/functions/wallet/legacyRegisterName.test.ts @@ -0,0 +1,68 @@ +import type { Address, Hex } from 'viem' +import { afterEach, beforeAll, beforeEach, expect, it } from 'vitest' +import { + publicClient, + testClient, + waitForTransaction, + walletClient, +} from '../../test/addTestContracts.js' +import type { RegistrationParameters } from '../../utils/registerHelpers.js' +import getPrice from '../public/getPrice.js' +import legacyCommitName from './legacyCommitName.js' +import legacyRegisterName from './legacyRegisterName.js' +import getOwner from '../public/getOwner.js' + +let snapshot: Hex +let accounts: Address[] + +beforeAll(async () => { + accounts = await walletClient.getAddresses() +}) + +beforeEach(async () => { + snapshot = await testClient.snapshot() +}) + +afterEach(async () => { + await testClient.revert({ id: snapshot }) +}) + +const secret = `0x${'a'.repeat(64)}` as Hex + +it.only('should return a registration transaction and succeed', async () => { + const params: RegistrationParameters = { + name: 'cool-swag.eth', + duration: 31536000, + owner: accounts[1], + secret, + } + const commitTx = await legacyCommitName(walletClient, { + ...params, + account: accounts[1], + }) + expect(commitTx).toBeTruthy() + const commitReceipt = await waitForTransaction(commitTx) + + expect(commitReceipt.status).toBe('success') + + await testClient.increaseTime({ seconds: 61 }) + await testClient.mine({ blocks: 1 }) + + const price = await getPrice(publicClient, { + nameOrNames: params.name, + duration: params.duration, + }) + const total = price!.base + price!.premium + + const tx = await legacyRegisterName(walletClient, { + ...params, + account: accounts[1], + value: total, + }) + expect(tx).toBeTruthy() + const receipt = await waitForTransaction(tx) + expect(receipt.status).toBe('success') + + const owner = await getOwner(publicClient, { name: params.name }) + expect(owner?.registrant).toBe(accounts[1]) +}) diff --git a/packages/ensjs/src/functions/wallet/legacyRegisterName.ts b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts new file mode 100644 index 00000000..9514fda2 --- /dev/null +++ b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts @@ -0,0 +1,150 @@ +import { + encodeFunctionData, + type Account, + type Hash, + type SendTransactionParameters, + type Transport, +} from 'viem' +import { sendTransaction } from 'viem/actions' +import type { ChainWithEns, ClientWithAccount } from '../../contracts/consts.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 { + makeLegacyRegistrationTuple, + type LegacyRegistrationParameters, +} from '../../utils/legacyRegisterHelpers.js' +import { wrappedLabelLengthCheck } from '../../utils/wrapper.js' +import { legacyEthRegistrarControllerRegisterSnippet } from '../../contracts/legacyEthRegistrarController.js' + +export type LegacyRegisterNameDataParameters = LegacyRegistrationParameters & { + /** Value of registration */ + value: bigint +} + +export type LegacyRegisterNameDataReturnType = SimpleTransactionRequest & { + value: bigint +} + +export type LegacyRegisterNameParameters< + TChain extends ChainWithEns, + TAccount extends Account | undefined, + TChainOverride extends ChainWithEns | undefined, +> = Prettify< + LegacyRegisterNameDataParameters & + WriteTransactionParameters +> + +export type LegacyRegisterNameReturnType = Hash + +export const makeFunctionData = < + TChain extends ChainWithEns, + TAccount extends Account | undefined, +>( + wallet: ClientWithAccount, + { value, ...args }: LegacyRegisterNameDataParameters, +): LegacyRegisterNameDataReturnType => { + const nameType = getNameType(args.name) + if (nameType !== 'eth-2ld') + throw new UnsupportedNameTypeError({ + nameType, + supportedNameTypes: ['eth-2ld'], + details: 'Only 2ld-eth name registration is supported', + }) + + const labels = args.name.split('.') + // wrappedLabelLengthCheck(labels[0]) + + return { + to: getChainContractAddress({ + client: wallet, + contract: 'legacyEthRegistrarController', + }), + data: encodeFunctionData({ + abi: legacyEthRegistrarControllerRegisterSnippet, + functionName: 'register', + args: makeLegacyRegistrationTuple(args), + }), + value, + } +} + +/** + * Registers a name on ENS + * @param wallet - {@link ClientWithAccount} + * @param parameters - {@link RegisterNameParameters} + * @returns Transaction hash. {@link LegacyRegisterNameReturnType} + * + * @example + * import { createPublicClient, createWalletClient, http, custom } from 'viem' + * import { mainnet } from 'viem/chains' + * import { addEnsContracts } from '@ensdomains/ensjs' + * import { getPrice } from '@ensdomains/ensjs/public' + * import { randomSecret } from '@ensdomains/ensjs/utils' + * import { commitName, registerName } from '@ensdomains/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, + value, + ...txArgs + }: LegacyRegisterNameParameters, +): Promise { + const data = makeFunctionData(wallet, { + name, + owner, + duration, + secret, + resolverAddress, + value, + }) + const writeArgs = { + ...data, + ...txArgs, + } as SendTransactionParameters + return sendTransaction(wallet, writeArgs) +} + +registerName.makeFunctionData = makeFunctionData + +export default registerName diff --git a/packages/ensjs/src/test/addTestContracts.ts b/packages/ensjs/src/test/addTestContracts.ts index 58945e49..32aebaf3 100644 --- a/packages/ensjs/src/test/addTestContracts.ts +++ b/packages/ensjs/src/test/addTestContracts.ts @@ -34,6 +34,8 @@ type ContractName = | 'StaticBulkRenewal' | 'DNSSECImpl' | 'Root' + | 'LegacyETHRegistrarController' + | 'LegacyPublicResolver' export const deploymentAddresses = JSON.parse( process.env.DEPLOYMENT_ADDRESSES!, @@ -82,6 +84,12 @@ export const localhost = { ensDnssecImpl: { address: deploymentAddresses.DNSSECImpl, }, + legacyEthRegistrarController: { + address: deploymentAddresses.LegacyETHRegistrarController, + }, + legacyPublicResolver: { + address: deploymentAddresses.LegacyPublicResolver, + }, }, subgraphs: { ens: { diff --git a/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts b/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts new file mode 100644 index 00000000..f7702087 --- /dev/null +++ b/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts @@ -0,0 +1,414 @@ +import { labelhash } from 'viem' +import { beforeAll, describe, expect, it } from 'vitest' +import { + isLegacyRegistrationWithConfig, + normalizeLegacyRegistrationParameters, + makeLegacyCommitment, + makeLegacyCommitmentFromTuple, + makeLegacyCommitmentTuple, + makeLegacyRegistrationTuple, + type LegacyRegistrationParameters, +} from './legacyRegisterHelpers.js' +import { EMPTY_ADDRESS } from './consts.js' +import { randomSecret } from './registerHelpers.js' +import { publicClient, walletClient } from '../test/addTestContracts.js' +import { legacyEthRegistrarControllerMakeCommitmentSnippet, legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet } from '../contracts/legacyEthRegistrarController.js' +import { getChainContractAddress } from '../contracts/getChainContractAddress.js' + +let accounts: Address[] + +beforeAll(async () => { + accounts = await walletClient.getAddresses() +}) + +describe('isLegacyRegistrationWithConfig', () => { + it('return false when no resolverAddress and no address is supplied', () => { + expect( + isLegacyRegistrationWithConfig({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + }), + ).toBe(false) + }) + + it('return false when resolverAddress and address are empty addresses', () => { + expect( + isLegacyRegistrationWithConfig({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: EMPTY_ADDRESS, + address: EMPTY_ADDRESS, + }), + ).toBe(false) + }) + + it('return true when resolverAddress and address are defined', () => { + expect( + isLegacyRegistrationWithConfig({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: '0xresolverAddress', + address: '0xaddress', + }), + ).toBe(true) + }) + + it('return true when resolverAddress is defined and address is NOT defined', () => { + expect( + isLegacyRegistrationWithConfig({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: '0xresolverAddress', + }), + ).toBe(true) + }) + + it('return true when address is defined and resolverAddress is NOT defined', () => { + expect( + isLegacyRegistrationWithConfig({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + address: '0xaddress', + }), + ).toBe(true) + }) +}) + +describe('normalizeLegacyRegistrationParameters', () => { + it('should return parameters without config if resolverAddress and address are NOT defined ', () => { + expect( + normalizeLegacyRegistrationParameters({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + }), + ).toEqual({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + }) + }) + + it('should return parameters without config if resolverAddress and address are empty addresses ', () => { + expect( + normalizeLegacyRegistrationParameters({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: EMPTY_ADDRESS, + address: EMPTY_ADDRESS, + }), + ).toEqual({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + }) + }) + + it('should return parameters with config if resolverAddress and address are defined ', () => { + expect( + normalizeLegacyRegistrationParameters({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: '0xresolverAddress', + address: '0xaddress', + }), + ).toEqual({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: '0xresolverAddress', + address: '0xaddress', + }) + }) + + it('should replace address with empty address if it is undefined ', () => { + expect( + normalizeLegacyRegistrationParameters({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: '0xresolverAddress', + }), + ).toEqual({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: '0xresolverAddress', + address: EMPTY_ADDRESS, + }) + }) + + it('should pass through params if empty address is empty address ', () => { + expect( + normalizeLegacyRegistrationParameters({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: '0xresolverAddress', + address: EMPTY_ADDRESS, + }), + ).toEqual({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: '0xresolverAddress', + address: EMPTY_ADDRESS, + }) + }) + + it('should throw an error if resolverAddress is not defined and address is defined', async () => { + expect(() => + normalizeLegacyRegistrationParameters({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + address: '0xaddress', + }), + ).toThrowErrorMatchingInlineSnapshot(` + [LegacyRegistrationInvalidConfigError: Resolver address is required when setting an address + + - resolverAddress: 0x0000000000000000000000000000000000000000 + - addr: 0xaddress + + Version: @ensdomains/ensjs@1.0.0-mock.0] + `) + }) + + it('should throw an error if resolverAddress is empty address and address is defined', async () => { + expect(() => + normalizeLegacyRegistrationParameters({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + resolverAddress: EMPTY_ADDRESS, + address: '0xaddress', + }), + ).toThrowErrorMatchingInlineSnapshot(` + [LegacyRegistrationInvalidConfigError: Resolver address is required when setting an address + + - resolverAddress: 0x0000000000000000000000000000000000000000 + - addr: 0xaddress + + Version: @ensdomains/ensjs@1.0.0-mock.0] + `) + }) +}) + +describe('makeLegacyCommitmentTuple()', () => { + it('generates a commitment tuple', () => { + const tuple = makeLegacyCommitmentTuple({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + }) + // labelhash + expect(tuple[0]).toBe(labelhash('test')) + // owner + expect(tuple[1]).toBe('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266') + // duration + expect(tuple[2]).toBe(31536000n) + // secret + expect(tuple[3]).toBe('0xsecret') + // resolver address + expect(tuple[4]).toBe('0x0000000000000000000000000000000000000000') + // records + expect(tuple[5]).toStrictEqual([]) + // reverse record + expect(tuple[6]).toBe(false) + // owner controlled fuses + expect(tuple[7]).toBe(0) + }) + it('encodes fuses when supplied', () => { + const tuple = makeLegacyCommitmentTuple({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + fuses: { + named: ['CANNOT_UNWRAP', 'CANNOT_BURN_FUSES'], + }, + }) + expect(tuple[7]).toBe(3) + }) + it('adds ETH coin when reverse record is supplied and no ETH coin is supplied', () => { + const tuple = makeLegacyCommitmentTuple({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + reverseRecord: true, + resolverAddress: '0xresolverAddress', + }) + expect(tuple[5]).toMatchInlineSnapshot(` + [ + "0x8b95dd71eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f1000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", + ] + `) + expect(tuple[6]).toBe(true) + }) + it('does not add ETH coin when reverse record is supplied and ETH coin is supplied', () => { + const tuple = makeLegacyCommitmentTuple({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + records: { + coins: [ + { coin: 'ETH', value: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' }, + ], + }, + resolverAddress: '0xresolverAddress', + secret: '0xsecret', + reverseRecord: true, + }) + expect(tuple[5]).toMatchInlineSnapshot(` + [ + "0x8b95dd71eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f1000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", + ] + `) + expect(tuple[6]).toBe(true) + }) + it('throws when records are supplied without a resolver address', () => { + expect(() => + makeLegacyCommitmentTuple({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + records: { + coins: [ + { + coin: 'ETH', + value: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + }, + ], + }, + secret: '0xsecret', + reverseRecord: true, + }), + ).toThrowErrorMatchingInlineSnapshot(` + [ResolverAddressRequiredError: Resolver address is required when data is supplied + + Supplied data: + - name: test.eth + - owner: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + - duration: 31536000 + - resolverAddress: 0x0000000000000000000000000000000000000000 + - records: [object Object] + - reverseRecord: true + - fuses: undefined + + Version: @ensdomains/ensjs@1.0.0-mock.0] + `) + }) +}) + +describe('makeLegacyRegistrationTuple()', () => { + it('replaces labelhash from commitment tuple with label', () => { + const data: LegacyRegistrationParameters = { + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: '0xsecret', + } + const commitmentTuple = makeLegacyCommitmentTuple(data) + const registrationTuple = makeLegacyRegistrationTuple(data) + expect(registrationTuple[0]).toBe('test') + expect(registrationTuple.slice(1)).toEqual(commitmentTuple.slice(1)) + }) +}) + +describe('makeLegacyCommitment', () => { + it('should match a commitment generated from makeCommitment', async () => { + const secret = randomSecret() + const params = { + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret, + } as const + const commitment = makeLegacyCommitment(params) + + const commitment2 = await publicClient.readContract({ + abi: legacyEthRegistrarControllerMakeCommitmentSnippet, + functionName: 'makeCommitment', + address: getChainContractAddress({ + client: publicClient, + contract: 'legacyEthRegistrarController', + }), + args: makeLegacyCommitmentTuple(params), + }) + + expect(commitment).toBe(commitment2) + }) + + it.only('should match a commitment generated from makeCommitmentWithConfig', async () => { + const secret = randomSecret() + const params = { + name: 'test.eth', + owner: accounts[0], + duration: 31536000, + secret, + resolverAddress: getChainContractAddress({ + client: publicClient, + contract: 'legacyPublicResolver', + }), + address: accounts[1], + } as const + + console.log('params', params) + console.log('makeLegacyCommitmentTuple', makeLegacyCommitmentTuple(params)) + const commitment = makeLegacyCommitment(params) + + const commitment2 = await publicClient.readContract({ + abi: legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet, + functionName: 'makeCommitmentWithConfig', + address: getChainContractAddress({ + client: publicClient, + contract: 'legacyEthRegistrarController', + }), + args: makeLegacyCommitmentTuple(params), + }) + + expect(commitment).toBe(commitment2) + console.log(commitment) + }) +}) + +describe('makeLegacyCommitment()', () => { + it('generates a commitment from a RegistrationParameters', () => { + const commitment = makeLegacyCommitment({ + name: 'test.eth', + owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + duration: 31536000, + secret: + '0xde99acb8241826c5b3012b2c7a05dc28043428744a9c39445b4707c92b3fc054', + }) + expect(commitment).toMatchInlineSnapshot( + `"0x0d7fe28313600187945700f6c6374cc0ba4a360df039b3e62d435506e69dbe63"`, + ) + }) +}) diff --git a/packages/ensjs/src/utils/legacyRegisterHelpers.ts b/packages/ensjs/src/utils/legacyRegisterHelpers.ts new file mode 100644 index 00000000..4dde050f --- /dev/null +++ b/packages/ensjs/src/utils/legacyRegisterHelpers.ts @@ -0,0 +1,131 @@ +import { + keccak256, + labelhash, + type Address, + type Hex, + encodePacked, +} from 'viem' +import { EMPTY_ADDRESS } from './consts.js' +import { LegacyRegistrationInvalidConfigError } from '../errors/register.js' + +export type LegacyRegistrationBaseParameters = { + /** Name to register */ + name: string + /** Address to set owner to */ + owner: Address + /** Duration of registration */ + duration: number + /** Random 32 bytes to use for registration */ + secret: Hex +} + +export type LegacyRegistrationWithConfigParameters = + LegacyRegistrationBaseParameters & { + /** Custom resolver address, defaults to empty address */ + resolverAddress: Address + /** Address to set upon registration, defaults to empty address */ + address?: Address + } + +export type LegacyRegistrationParameters = + | LegacyRegistrationBaseParameters + | LegacyRegistrationWithConfigParameters + +export const isLegacyRegistrationWithConfig = ( + params: LegacyRegistrationParameters, +): params is LegacyRegistrationWithConfigParameters => { + const { resolverAddress = EMPTY_ADDRESS, address = EMPTY_ADDRESS } = + params as LegacyRegistrationWithConfigParameters + return resolverAddress !== EMPTY_ADDRESS || address !== EMPTY_ADDRESS +} + +export type LegacyCommitmentTuple = + | [label: string, owner: Address, secret: Hex] + | [ + label: string, + owner: Address, + resolverAddress: Address, + address: Address, + secret: Hex, + ] + +export type LegacyRegistrationTuple = + | [label: string, owner: Address, duration: bigint, secret: Hex] + | [ + label: string, + owner: Address, + duration: bigint, + secret: Hex, + resolverAddress: Address, + address: Address, + ] + +export const normalizeLegacyRegistrationParameters = ( + params: LegacyRegistrationParameters, +): LegacyRegistrationParameters => { + const { + resolverAddress = EMPTY_ADDRESS, + address = EMPTY_ADDRESS, + ...base + } = params as LegacyRegistrationWithConfigParameters + + if (!isLegacyRegistrationWithConfig(params)) return base + + if (resolverAddress === EMPTY_ADDRESS && address !== EMPTY_ADDRESS) + throw new LegacyRegistrationInvalidConfigError({ + resolverAddress, + address, + }) + + return { ...base, resolverAddress, address } +} + +export const makeLegacyCommitmentTuple = ( + params: LegacyRegistrationParameters, +): LegacyCommitmentTuple => { + const { name, owner, secret, resolverAddress, address } = + params as LegacyRegistrationWithConfigParameters + + const label = name.split('.')[0] + + if (resolverAddress || address) { + return [label, owner, secret, resolverAddress, address ?? EMPTY_ADDRESS] + } + return [label, owner, secret] +} + +export const makeLegacyRegistrationTuple = ( + params: LegacyRegistrationParameters, +): LegacyRegistrationTuple => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [, owner, secret, ...rest] = makeLegacyCommitmentTuple(params) + const label = params.name.split('.')[0] + if (rest.length) + return [label, owner, BigInt(params.duration), secret, ...rest] + return [label, owner, BigInt(params.duration), secret] +} + +export const makeLegacyCommitmentFromTuple = ([ + label, + ...others +]: LegacyCommitmentTuple): Hex => { + const labelHash = labelhash(label) + const params = [labelHash, ...others] as const + if (params.length === 3) + return keccak256(encodePacked(['bytes32', 'address', 'bytes32'], params)) + + const [owner, secret, resolverAddress, address] = others + return keccak256( + encodePacked( + ['bytes32', 'address', 'address', 'address', 'bytes32'], + [labelHash, owner, resolverAddress, address, secret], + ), + ) +} + +export const makeLegacyCommitment = ( + params: LegacyRegistrationParameters, +): Hex => + makeLegacyCommitmentFromTuple( + makeLegacyCommitmentTuple(normalizeLegacyRegistrationParameters(params)), + ) From db176b40ba640911e02fe8a76f9e3dec2b560ea8 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Wed, 18 Dec 2024 17:00:48 +0800 Subject: [PATCH 02/20] fix and add tests --- packages/ensjs/src/contracts/consts.ts | 1 - .../functions/wallet/legacyCommitName.test.ts | 53 +-- .../src/functions/wallet/legacyCommitName.ts | 19 +- .../wallet/legacyRegisterName.test.ts | 49 +- .../functions/wallet/legacyRegisterName.ts | 34 +- .../src/utils/legacyRegisterHelpers.test.ts | 432 ++++++------------ .../ensjs/src/utils/legacyRegisterHelpers.ts | 71 +-- 7 files changed, 253 insertions(+), 406 deletions(-) diff --git a/packages/ensjs/src/contracts/consts.ts b/packages/ensjs/src/contracts/consts.ts index 001a6442..c9837de2 100644 --- a/packages/ensjs/src/contracts/consts.ts +++ b/packages/ensjs/src/contracts/consts.ts @@ -1,6 +1,5 @@ import type { Account, Address, Chain, Client, Transport } from 'viem' import type { Assign, Prettify } from '../types.js' -import { EMPTY_ADDRESS } from '../utils/consts.js' type ChainContract = { address: Address diff --git a/packages/ensjs/src/functions/wallet/legacyCommitName.test.ts b/packages/ensjs/src/functions/wallet/legacyCommitName.test.ts index b3ade829..7796346d 100644 --- a/packages/ensjs/src/functions/wallet/legacyCommitName.test.ts +++ b/packages/ensjs/src/functions/wallet/legacyCommitName.test.ts @@ -1,6 +1,5 @@ -import { labelhash, type Address, type Hex } from 'viem' +import { type Address, type Hex } from 'viem' import { afterEach, beforeAll, beforeEach, expect, it } from 'vitest' -import { ethRegistrarControllerCommitmentsSnippet } from '../../contracts/ethRegistrarController.js' import { getChainContractAddress } from '../../contracts/getChainContractAddress.js' import { publicClient, @@ -13,8 +12,7 @@ import { type LegacyRegistrationParameters, } from '../../utils/legacyRegisterHelpers.js' import legacyCommitName from './legacyCommitName.js' -import { legacyEthRegistrarControllerCommitmentsSnippet, legacyEthRegistrarControllerMakeCommitmentSnippet, legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet } from '../../contracts/legacyEthRegistrarController.js' -import { EMPTY_ADDRESS } from '../../utils/consts.js' +import { legacyEthRegistrarControllerCommitmentsSnippet } from '../../contracts/legacyEthRegistrarController.js' let snapshot: Hex let accounts: Address[] @@ -33,53 +31,6 @@ afterEach(async () => { const secret = `0x${'a'.repeat(64)}` as Hex -it.only('should something', async () => { - const params: LegacyRegistrationParameters = { - name: 'wrapped-with-subnames.eth', - duration: 31536000, - owner: accounts[1], - secret, - } - const label = params.name.split('.')[0] - const labelHash = labelhash(params.name.split('.')[0]) - const makeCommitment = await publicClient.readContract({ - abi: legacyEthRegistrarControllerMakeCommitmentSnippet, - functionName: 'makeCommitment', - address: getChainContractAddress({ - client: publicClient, - contract: 'legacyEthRegistrarController', - }), - args: [label, params.owner, params.secret], - }) - console.log('makeCommitment', makeCommitment) - - const test = makeLegacyCommitment(params) - expect(test).toEqual(makeCommitment) -}) - -it('should something 2', async () => { - const params: LegacyRegistrationParameters = { - name: 'wrapped-with-subnames.eth', - duration: 31536000, - owner: accounts[1], - secret, - } - const labelHash = labelhash(params.name.split('.')[0]) - const makeCommitment = await publicClient.readContract({ - abi: legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet, - functionName: 'makeCommitmentWithConfig', - address: getChainContractAddress({ - client: publicClient, - contract: 'legacyEthRegistrarController', - }), - args: [labelHash, params.owner, params.secret, EMPTY_ADDRESS, EMPTY_ADDRESS], - }) - console.log('>>> 2', makeCommitment) - - const test = makeLegacyCommitment(params) - expect(test).toEqual(makeCommitment) -}) - it('should return a commit transaction and succeed', async () => { const params: LegacyRegistrationParameters = { name: 'wrapped-with-subnames.eth', diff --git a/packages/ensjs/src/functions/wallet/legacyCommitName.ts b/packages/ensjs/src/functions/wallet/legacyCommitName.ts index 5a2d49e9..aa04652f 100644 --- a/packages/ensjs/src/functions/wallet/legacyCommitName.ts +++ b/packages/ensjs/src/functions/wallet/legacyCommitName.ts @@ -7,10 +7,7 @@ import { } from 'viem' import { sendTransaction } from 'viem/actions' import type { ChainWithEns, ClientWithAccount } from '../../contracts/consts.js' -import { - legacyEthRegistrarControllerCommitSnippet, - legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet, -} from '../../contracts/legacyEthRegistrarController.js' +import { legacyEthRegistrarControllerCommitSnippet } from '../../contracts/legacyEthRegistrarController.js' import { getChainContractAddress } from '../../contracts/getChainContractAddress.js' import { UnsupportedNameTypeError } from '../../errors/general.js' import type { @@ -23,7 +20,7 @@ import { makeLegacyCommitment, type LegacyRegistrationParameters, } from '../../utils/legacyRegisterHelpers.js' -import { wrappedLabelLengthCheck } from '../../utils/wrapper.js' +import { EMPTY_ADDRESS } from '../../utils/consts.js' export type CommitNameDataParameters = LegacyRegistrationParameters @@ -47,7 +44,6 @@ export const makeFunctionData = < wallet: ClientWithAccount, args: CommitNameDataParameters, ): CommitNameDataReturnType => { - const labels = args.name.split('.') const nameType = getNameType(args.name) if (nameType !== 'eth-2ld') throw new UnsupportedNameTypeError({ @@ -55,12 +51,7 @@ export const makeFunctionData = < supportedNameTypes: ['eth-2ld'], details: 'Only 2ld-eth name registration is supported', }) - wrappedLabelLengthCheck(labels[0]) - console.log('>>>', getChainContractAddress({ - client: wallet, - contract: 'legacyEthRegistrarController', - })) return { to: getChainContractAddress({ client: wallet, @@ -111,8 +102,8 @@ async function legacyCommitName< owner, duration, secret, - resolverAddress, - addr, + resolverAddress = EMPTY_ADDRESS, + address = EMPTY_ADDRESS, ...txArgs }: CommitNameParameters, ): Promise { @@ -122,7 +113,7 @@ async function legacyCommitName< duration, secret, resolverAddress, - addr, + address, }) const writeArgs = { ...data, diff --git a/packages/ensjs/src/functions/wallet/legacyRegisterName.test.ts b/packages/ensjs/src/functions/wallet/legacyRegisterName.test.ts index 613eb06b..0bade3db 100644 --- a/packages/ensjs/src/functions/wallet/legacyRegisterName.test.ts +++ b/packages/ensjs/src/functions/wallet/legacyRegisterName.test.ts @@ -1,4 +1,4 @@ -import type { Address, Hex } from 'viem' +import { type Address, type Hex } from 'viem' import { afterEach, beforeAll, beforeEach, expect, it } from 'vitest' import { publicClient, @@ -11,6 +11,8 @@ import getPrice from '../public/getPrice.js' import legacyCommitName from './legacyCommitName.js' import legacyRegisterName from './legacyRegisterName.js' import getOwner from '../public/getOwner.js' +import { getChainContractAddress } from '../../contracts/getChainContractAddress.js' +import type { LegacyRegistrationParameters } from '../../utils/legacyRegisterHelpers.js' let snapshot: Hex let accounts: Address[] @@ -29,7 +31,7 @@ afterEach(async () => { const secret = `0x${'a'.repeat(64)}` as Hex -it.only('should return a registration transaction and succeed', async () => { +it('should return a registration without resolverAddress or address transaction and succeed', async () => { const params: RegistrationParameters = { name: 'cool-swag.eth', duration: 31536000, @@ -66,3 +68,46 @@ it.only('should return a registration transaction and succeed', async () => { const owner = await getOwner(publicClient, { name: params.name }) expect(owner?.registrant).toBe(accounts[1]) }) + +it('should return a registration transaction and succeed', async () => { + const params: LegacyRegistrationParameters = { + name: 'cool-swaggy.eth', + duration: 31536000, + owner: accounts[1], + secret, + resolverAddress: getChainContractAddress({ + client: walletClient, + contract: 'legacyPublicResolver', + }), + address: accounts[2], + } + const commitTx = await legacyCommitName(walletClient, { + ...params, + account: accounts[1], + }) + expect(commitTx).toBeTruthy() + const commitReceipt = await waitForTransaction(commitTx) + + expect(commitReceipt.status).toBe('success') + + await testClient.increaseTime({ seconds: 61 }) + await testClient.mine({ blocks: 1 }) + + const price = await getPrice(publicClient, { + nameOrNames: params.name, + duration: params.duration, + }) + const total = price!.base + price!.premium + + const tx = await legacyRegisterName(walletClient, { + ...params, + account: accounts[1], + value: total * 2n, + }) + expect(tx).toBeTruthy() + const receipt = await waitForTransaction(tx) + expect(receipt.status).toBe('success') + + const owner = await getOwner(publicClient, { name: params.name }) + expect(owner?.registrant).toBe(accounts[1]) +}) diff --git a/packages/ensjs/src/functions/wallet/legacyRegisterName.ts b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts index 9514fda2..4b6f2db7 100644 --- a/packages/ensjs/src/functions/wallet/legacyRegisterName.ts +++ b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts @@ -18,9 +18,12 @@ import { getNameType } from '../../utils/getNameType.js' import { makeLegacyRegistrationTuple, type LegacyRegistrationParameters, + isLegacyRegistrationWithConfig, } from '../../utils/legacyRegisterHelpers.js' -import { wrappedLabelLengthCheck } from '../../utils/wrapper.js' -import { legacyEthRegistrarControllerRegisterSnippet } from '../../contracts/legacyEthRegistrarController.js' +import { + legacyEthRegistrarControllerRegisterSnippet, + legacyEthRegistrarControllerRegisterWithConfigSnippet, +} from '../../contracts/legacyEthRegistrarController.js' export type LegacyRegisterNameDataParameters = LegacyRegistrationParameters & { /** Value of registration */ @@ -57,19 +60,24 @@ export const makeFunctionData = < details: 'Only 2ld-eth name registration is supported', }) - const labels = args.name.split('.') - // wrappedLabelLengthCheck(labels[0]) + const data = isLegacyRegistrationWithConfig(args) + ? encodeFunctionData({ + abi: legacyEthRegistrarControllerRegisterWithConfigSnippet, + functionName: 'registerWithConfig', + args: makeLegacyRegistrationTuple(args), + }) + : encodeFunctionData({ + abi: legacyEthRegistrarControllerRegisterSnippet, + functionName: 'register', + args: makeLegacyRegistrationTuple(args), + }) return { to: getChainContractAddress({ client: wallet, contract: 'legacyEthRegistrarController', }), - data: encodeFunctionData({ - abi: legacyEthRegistrarControllerRegisterSnippet, - functionName: 'register', - args: makeLegacyRegistrationTuple(args), - }), + data, value, } } @@ -114,7 +122,7 @@ export const makeFunctionData = < * const hash = await registerName(wallet, { ...params, value }) * // 0x... */ -async function registerName< +async function legacyRegisterName< TChain extends ChainWithEns, TAccount extends Account | undefined, TChainOverride extends ChainWithEns | undefined = ChainWithEns, @@ -126,6 +134,7 @@ async function registerName< duration, secret, resolverAddress, + address, value, ...txArgs }: LegacyRegisterNameParameters, @@ -136,6 +145,7 @@ async function registerName< duration, secret, resolverAddress, + address, value, }) const writeArgs = { @@ -145,6 +155,6 @@ async function registerName< return sendTransaction(wallet, writeArgs) } -registerName.makeFunctionData = makeFunctionData +legacyRegisterName.makeFunctionData = makeFunctionData -export default registerName +export default legacyRegisterName diff --git a/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts b/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts index f7702087..c52a95ff 100644 --- a/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts +++ b/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts @@ -1,10 +1,8 @@ -import { labelhash } from 'viem' +import { type Address, type Hex } from 'viem' import { beforeAll, describe, expect, it } from 'vitest' import { isLegacyRegistrationWithConfig, - normalizeLegacyRegistrationParameters, makeLegacyCommitment, - makeLegacyCommitmentFromTuple, makeLegacyCommitmentTuple, makeLegacyRegistrationTuple, type LegacyRegistrationParameters, @@ -12,23 +10,46 @@ import { import { EMPTY_ADDRESS } from './consts.js' import { randomSecret } from './registerHelpers.js' import { publicClient, walletClient } from '../test/addTestContracts.js' -import { legacyEthRegistrarControllerMakeCommitmentSnippet, legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet } from '../contracts/legacyEthRegistrarController.js' +import { + legacyEthRegistrarControllerMakeCommitmentSnippet, + legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet, +} from '../contracts/legacyEthRegistrarController.js' import { getChainContractAddress } from '../contracts/getChainContractAddress.js' let accounts: Address[] +let resolverAddress: Address +let secret: Hex +let owner: Address +let address: Address +const duration = 31536000 +const name = 'test.eth' +const makeSnapshot = (addr: Address) => ` + [LegacyRegistrationInvalidConfigError: Resolver address is required when setting an address + + - resolverAddress: 0x0000000000000000000000000000000000000000 + - addr: ${addr} + + Version: @ensdomains/ensjs@1.0.0-mock.0] + ` beforeAll(async () => { accounts = await walletClient.getAddresses() + resolverAddress = getChainContractAddress({ + client: publicClient, + contract: 'legacyPublicResolver', + }) + secret = randomSecret() + ;[owner, address] = accounts }) describe('isLegacyRegistrationWithConfig', () => { - it('return false when no resolverAddress and no address is supplied', () => { + it('return false when resolverAddress and address are undefined', () => { expect( isLegacyRegistrationWithConfig({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', + name, + owner, + duration, + secret, }), ).toBe(false) }) @@ -36,10 +57,10 @@ describe('isLegacyRegistrationWithConfig', () => { it('return false when resolverAddress and address are empty addresses', () => { expect( isLegacyRegistrationWithConfig({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', + name, + owner, + duration, + secret, resolverAddress: EMPTY_ADDRESS, address: EMPTY_ADDRESS, }), @@ -49,12 +70,12 @@ describe('isLegacyRegistrationWithConfig', () => { it('return true when resolverAddress and address are defined', () => { expect( isLegacyRegistrationWithConfig({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - resolverAddress: '0xresolverAddress', - address: '0xaddress', + name, + owner, + duration, + secret, + resolverAddress, + address, }), ).toBe(true) }) @@ -62,291 +83,140 @@ describe('isLegacyRegistrationWithConfig', () => { it('return true when resolverAddress is defined and address is NOT defined', () => { expect( isLegacyRegistrationWithConfig({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - resolverAddress: '0xresolverAddress', + name, + owner, + duration, + secret, + resolverAddress, }), ).toBe(true) }) - it('return true when address is defined and resolverAddress is NOT defined', () => { - expect( + it('should throw an error when address is defined and resolverAddress is NOT defined', () => { + expect(() => isLegacyRegistrationWithConfig({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - address: '0xaddress', + name, + owner, + duration, + secret, + address, }), - ).toBe(true) + ).toThrowErrorMatchingInlineSnapshot(makeSnapshot(address)) }) -}) -describe('normalizeLegacyRegistrationParameters', () => { - it('should return parameters without config if resolverAddress and address are NOT defined ', () => { - expect( - normalizeLegacyRegistrationParameters({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - }), - ).toEqual({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - }) - }) - - it('should return parameters without config if resolverAddress and address are empty addresses ', () => { - expect( - normalizeLegacyRegistrationParameters({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', + it('should throw an error when address is defined and resolverAddress is empty address', () => { + expect(() => + isLegacyRegistrationWithConfig({ + name, + owner, + duration, + secret, resolverAddress: EMPTY_ADDRESS, - address: EMPTY_ADDRESS, + address, }), - ).toEqual({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - }) - }) - - it('should return parameters with config if resolverAddress and address are defined ', () => { - expect( - normalizeLegacyRegistrationParameters({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - resolverAddress: '0xresolverAddress', - address: '0xaddress', - }), - ).toEqual({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - resolverAddress: '0xresolverAddress', - address: '0xaddress', - }) + ).toThrowErrorMatchingInlineSnapshot(makeSnapshot(address)) }) +}) - it('should replace address with empty address if it is undefined ', () => { - expect( - normalizeLegacyRegistrationParameters({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - resolverAddress: '0xresolverAddress', - }), - ).toEqual({ +describe('makeLegacyCommitmentTuple', () => { + it('should return args for makeCommit if resolverAddress and address are undefined', () => { + const tuple = makeLegacyCommitmentTuple({ name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - resolverAddress: '0xresolverAddress', - address: EMPTY_ADDRESS, + owner, + duration, + secret, }) + expect(tuple).toEqual(['test', owner, secret]) }) - it('should pass through params if empty address is empty address ', () => { - expect( - normalizeLegacyRegistrationParameters({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - resolverAddress: '0xresolverAddress', - address: EMPTY_ADDRESS, - }), - ).toEqual({ + it('should return args for makeCommitWithConfig if resolverAddress is defined', () => { + const tuple = makeLegacyCommitmentTuple({ name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - resolverAddress: '0xresolverAddress', - address: EMPTY_ADDRESS, + owner, + duration, + secret, + resolverAddress, }) + expect(tuple).toEqual([ + 'test', + owner, + secret, + resolverAddress, + EMPTY_ADDRESS, + ]) }) - it('should throw an error if resolverAddress is not defined and address is defined', async () => { - expect(() => - normalizeLegacyRegistrationParameters({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - address: '0xaddress', - }), - ).toThrowErrorMatchingInlineSnapshot(` - [LegacyRegistrationInvalidConfigError: Resolver address is required when setting an address - - - resolverAddress: 0x0000000000000000000000000000000000000000 - - addr: 0xaddress - - Version: @ensdomains/ensjs@1.0.0-mock.0] - `) - }) - - it('should throw an error if resolverAddress is empty address and address is defined', async () => { + it('should throw error if resolverAddress is NOT defined and address is defined', () => { expect(() => - normalizeLegacyRegistrationParameters({ + makeLegacyCommitmentTuple({ name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - resolverAddress: EMPTY_ADDRESS, - address: '0xaddress', + owner, + duration, + secret, + address, }), - ).toThrowErrorMatchingInlineSnapshot(` - [LegacyRegistrationInvalidConfigError: Resolver address is required when setting an address - - - resolverAddress: 0x0000000000000000000000000000000000000000 - - addr: 0xaddress - - Version: @ensdomains/ensjs@1.0.0-mock.0] - `) + ).toThrowErrorMatchingInlineSnapshot(makeSnapshot(address)) }) }) -describe('makeLegacyCommitmentTuple()', () => { - it('generates a commitment tuple', () => { - const tuple = makeLegacyCommitmentTuple({ +describe('makeLegacyRegistrationTuple', () => { + it('should return args for register if resolverAddress and address or undefined', () => { + const params: LegacyRegistrationParameters = { name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - }) - // labelhash - expect(tuple[0]).toBe(labelhash('test')) - // owner - expect(tuple[1]).toBe('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266') - // duration - expect(tuple[2]).toBe(31536000n) - // secret - expect(tuple[3]).toBe('0xsecret') - // resolver address - expect(tuple[4]).toBe('0x0000000000000000000000000000000000000000') - // records - expect(tuple[5]).toStrictEqual([]) - // reverse record - expect(tuple[6]).toBe(false) - // owner controlled fuses - expect(tuple[7]).toBe(0) - }) - it('encodes fuses when supplied', () => { - const tuple = makeLegacyCommitmentTuple({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - fuses: { - named: ['CANNOT_UNWRAP', 'CANNOT_BURN_FUSES'], - }, - }) - expect(tuple[7]).toBe(3) - }) - it('adds ETH coin when reverse record is supplied and no ETH coin is supplied', () => { - const tuple = makeLegacyCommitmentTuple({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', - reverseRecord: true, - resolverAddress: '0xresolverAddress', - }) - expect(tuple[5]).toMatchInlineSnapshot(` - [ - "0x8b95dd71eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f1000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", - ] - `) - expect(tuple[6]).toBe(true) - }) - it('does not add ETH coin when reverse record is supplied and ETH coin is supplied', () => { - const tuple = makeLegacyCommitmentTuple({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + owner: accounts[0], duration: 31536000, - records: { - coins: [ - { coin: 'ETH', value: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' }, - ], - }, - resolverAddress: '0xresolverAddress', - secret: '0xsecret', - reverseRecord: true, - }) - expect(tuple[5]).toMatchInlineSnapshot(` - [ - "0x8b95dd71eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f1000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", - ] - `) - expect(tuple[6]).toBe(true) + secret, + } + expect(makeLegacyRegistrationTuple(params)).toEqual([ + 'test', + accounts[0], + 31536000n, + secret, + ]) }) - it('throws when records are supplied without a resolver address', () => { - expect(() => - makeLegacyCommitmentTuple({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - records: { - coins: [ - { - coin: 'ETH', - value: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - }, - ], - }, - secret: '0xsecret', - reverseRecord: true, - }), - ).toThrowErrorMatchingInlineSnapshot(` - [ResolverAddressRequiredError: Resolver address is required when data is supplied - Supplied data: - - name: test.eth - - owner: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 - - duration: 31536000 - - resolverAddress: 0x0000000000000000000000000000000000000000 - - records: [object Object] - - reverseRecord: true - - fuses: undefined - - Version: @ensdomains/ensjs@1.0.0-mock.0] - `) + it('should return args for register if resolverAddress and address are empty addresses', () => { + const params: LegacyRegistrationParameters = { + name, + owner, + duration, + secret, + resolverAddress: EMPTY_ADDRESS, + address: EMPTY_ADDRESS, + } + expect(makeLegacyRegistrationTuple(params)).toEqual([ + 'test', + owner, + 31536000n, + secret, + ]) }) -}) -describe('makeLegacyRegistrationTuple()', () => { - it('replaces labelhash from commitment tuple with label', () => { - const data: LegacyRegistrationParameters = { + it('should return args for register if resolverAddress and address are not undefined', () => { + const params: LegacyRegistrationParameters = { name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: '0xsecret', + owner, + duration, + secret, + resolverAddress, + address, } - const commitmentTuple = makeLegacyCommitmentTuple(data) - const registrationTuple = makeLegacyRegistrationTuple(data) - expect(registrationTuple[0]).toBe('test') - expect(registrationTuple.slice(1)).toEqual(commitmentTuple.slice(1)) + expect(makeLegacyRegistrationTuple(params)).toEqual([ + 'test', + owner, + 31536000n, + secret, + resolverAddress, + address, + ]) }) }) describe('makeLegacyCommitment', () => { it('should match a commitment generated from makeCommitment', async () => { - const secret = randomSecret() const params = { - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + name, + owner, duration: 31536000, secret, } as const @@ -365,22 +235,16 @@ describe('makeLegacyCommitment', () => { expect(commitment).toBe(commitment2) }) - it.only('should match a commitment generated from makeCommitmentWithConfig', async () => { - const secret = randomSecret() + it('should match a commitment generated from makeCommitmentWithConfig', async () => { const params = { - name: 'test.eth', - owner: accounts[0], - duration: 31536000, + name, + owner, + duration, secret, - resolverAddress: getChainContractAddress({ - client: publicClient, - contract: 'legacyPublicResolver', - }), - address: accounts[1], + resolverAddress, + address, } as const - console.log('params', params) - console.log('makeLegacyCommitmentTuple', makeLegacyCommitmentTuple(params)) const commitment = makeLegacyCommitment(params) const commitment2 = await publicClient.readContract({ @@ -394,21 +258,5 @@ describe('makeLegacyCommitment', () => { }) expect(commitment).toBe(commitment2) - console.log(commitment) - }) -}) - -describe('makeLegacyCommitment()', () => { - it('generates a commitment from a RegistrationParameters', () => { - const commitment = makeLegacyCommitment({ - name: 'test.eth', - owner: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - duration: 31536000, - secret: - '0xde99acb8241826c5b3012b2c7a05dc28043428744a9c39445b4707c92b3fc054', - }) - expect(commitment).toMatchInlineSnapshot( - `"0x0d7fe28313600187945700f6c6374cc0ba4a360df039b3e62d435506e69dbe63"`, - ) }) }) diff --git a/packages/ensjs/src/utils/legacyRegisterHelpers.ts b/packages/ensjs/src/utils/legacyRegisterHelpers.ts index 4dde050f..0e2cafc3 100644 --- a/packages/ensjs/src/utils/legacyRegisterHelpers.ts +++ b/packages/ensjs/src/utils/legacyRegisterHelpers.ts @@ -17,13 +17,15 @@ export type LegacyRegistrationBaseParameters = { duration: number /** Random 32 bytes to use for registration */ secret: Hex + /** Custom resolver address, defaults to empty address */ + resolverAddress?: Address + /** Address to set upon registration, defaults to empty address */ + address?: Address } export type LegacyRegistrationWithConfigParameters = LegacyRegistrationBaseParameters & { - /** Custom resolver address, defaults to empty address */ resolverAddress: Address - /** Address to set upon registration, defaults to empty address */ address?: Address } @@ -36,6 +38,12 @@ export const isLegacyRegistrationWithConfig = ( ): params is LegacyRegistrationWithConfigParameters => { const { resolverAddress = EMPTY_ADDRESS, address = EMPTY_ADDRESS } = params as LegacyRegistrationWithConfigParameters + + if (resolverAddress === EMPTY_ADDRESS && address !== EMPTY_ADDRESS) + throw new LegacyRegistrationInvalidConfigError({ + resolverAddress, + address, + }) return resolverAddress !== EMPTY_ADDRESS || address !== EMPTY_ADDRESS } @@ -60,36 +68,21 @@ export type LegacyRegistrationTuple = address: Address, ] -export const normalizeLegacyRegistrationParameters = ( +export const makeLegacyCommitmentTuple = ( params: LegacyRegistrationParameters, -): LegacyRegistrationParameters => { +): LegacyCommitmentTuple => { const { + name, + owner, + secret, resolverAddress = EMPTY_ADDRESS, address = EMPTY_ADDRESS, - ...base } = params as LegacyRegistrationWithConfigParameters - if (!isLegacyRegistrationWithConfig(params)) return base - - if (resolverAddress === EMPTY_ADDRESS && address !== EMPTY_ADDRESS) - throw new LegacyRegistrationInvalidConfigError({ - resolverAddress, - address, - }) - - return { ...base, resolverAddress, address } -} - -export const makeLegacyCommitmentTuple = ( - params: LegacyRegistrationParameters, -): LegacyCommitmentTuple => { - const { name, owner, secret, resolverAddress, address } = - params as LegacyRegistrationWithConfigParameters - const label = name.split('.')[0] - if (resolverAddress || address) { - return [label, owner, secret, resolverAddress, address ?? EMPTY_ADDRESS] + if (isLegacyRegistrationWithConfig(params)) { + return [label, owner, secret, resolverAddress, address] } return [label, owner, secret] } @@ -97,11 +90,17 @@ export const makeLegacyCommitmentTuple = ( export const makeLegacyRegistrationTuple = ( params: LegacyRegistrationParameters, ): LegacyRegistrationTuple => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [, owner, secret, ...rest] = makeLegacyCommitmentTuple(params) - const label = params.name.split('.')[0] - if (rest.length) - return [label, owner, BigInt(params.duration), secret, ...rest] + const { + name, + owner, + secret, + duration, + resolverAddress = EMPTY_ADDRESS, + address = EMPTY_ADDRESS, + } = params as LegacyRegistrationWithConfigParameters + const label = name.split('.')[0] + if (isLegacyRegistrationWithConfig(params)) + return [label, owner, BigInt(duration), secret, resolverAddress, address] return [label, owner, BigInt(params.duration), secret] } @@ -111,10 +110,17 @@ export const makeLegacyCommitmentFromTuple = ([ ]: LegacyCommitmentTuple): Hex => { const labelHash = labelhash(label) const params = [labelHash, ...others] as const + if (params.length === 3) return keccak256(encodePacked(['bytes32', 'address', 'bytes32'], params)) - const [owner, secret, resolverAddress, address] = others + const [ + owner, + secret, + resolverAddress = EMPTY_ADDRESS, + address = EMPTY_ADDRESS, + ] = others + return keccak256( encodePacked( ['bytes32', 'address', 'address', 'address', 'bytes32'], @@ -125,7 +131,4 @@ export const makeLegacyCommitmentFromTuple = ([ export const makeLegacyCommitment = ( params: LegacyRegistrationParameters, -): Hex => - makeLegacyCommitmentFromTuple( - makeLegacyCommitmentTuple(normalizeLegacyRegistrationParameters(params)), - ) +): Hex => makeLegacyCommitmentFromTuple(makeLegacyCommitmentTuple(params)) From 0aef6bffcd831278d822efe66c4e1a47de5b4caf Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Wed, 18 Dec 2024 17:38:42 +0800 Subject: [PATCH 03/20] add export code --- .../src/functions/wallet/legacyCommitName.ts | 22 +++++++++---------- packages/ensjs/src/utils/index.ts | 9 ++++++++ packages/ensjs/src/wallet.ts | 14 ++++++++++++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/packages/ensjs/src/functions/wallet/legacyCommitName.ts b/packages/ensjs/src/functions/wallet/legacyCommitName.ts index aa04652f..85fb2a09 100644 --- a/packages/ensjs/src/functions/wallet/legacyCommitName.ts +++ b/packages/ensjs/src/functions/wallet/legacyCommitName.ts @@ -22,28 +22,28 @@ import { } from '../../utils/legacyRegisterHelpers.js' import { EMPTY_ADDRESS } from '../../utils/consts.js' -export type CommitNameDataParameters = LegacyRegistrationParameters +export type LegacyCommitNameDataParameters = LegacyRegistrationParameters -export type CommitNameDataReturnType = SimpleTransactionRequest +export type LegacyCommitNameDataReturnType = SimpleTransactionRequest -export type CommitNameParameters< +export type LegacyCommitNameParameters< TChain extends ChainWithEns, TAccount extends Account | undefined, TChainOverride extends ChainWithEns | undefined, > = Prettify< - CommitNameDataParameters & + LegacyCommitNameDataParameters & WriteTransactionParameters > -export type CommitNameReturnType = Hash +export type LegacyCommitNameReturnType = Hash export const makeFunctionData = < TChain extends ChainWithEns, TAccount extends Account | undefined, >( wallet: ClientWithAccount, - args: CommitNameDataParameters, -): CommitNameDataReturnType => { + args: LegacyCommitNameDataParameters, +): LegacyCommitNameDataReturnType => { const nameType = getNameType(args.name) if (nameType !== 'eth-2ld') throw new UnsupportedNameTypeError({ @@ -68,8 +68,8 @@ export const makeFunctionData = < /** * Commits a name to be registered * @param wallet - {@link ClientWithAccount} - * @param parameters - {@link CommitNameParameters} - * @returns Transaction hash. {@link CommitNameReturnType} + * @param parameters - {@link LegacyCommitNameParameters} + * @returns Transaction hash. {@link LegacyCommitNameReturnType} * * @example * import { createWalletClient, custom } from 'viem' @@ -105,8 +105,8 @@ async function legacyCommitName< resolverAddress = EMPTY_ADDRESS, address = EMPTY_ADDRESS, ...txArgs - }: CommitNameParameters, -): Promise { + }: LegacyCommitNameParameters, +): Promise { const data = makeFunctionData(wallet, { name, owner, diff --git a/packages/ensjs/src/utils/index.ts b/packages/ensjs/src/utils/index.ts index 1132520b..874dd708 100644 --- a/packages/ensjs/src/utils/index.ts +++ b/packages/ensjs/src/utils/index.ts @@ -104,6 +104,15 @@ export { saveLabel, saveName, } from './labels.js' +export { + makeLegacyCommitment, + makeLegacyCommitmentFromTuple, + makeLegacyCommitmentTuple, + makeLegacyRegistrationTuple, + type LegacyCommitmentTuple, + type LegacyRegistrationParameters, + type LegacyRegistrationTuple, +} from './legacyRegisterHelpers.js' export { makeSafeSecondsDate } from './makeSafeSecondsDate.js' export { beautify, diff --git a/packages/ensjs/src/wallet.ts b/packages/ensjs/src/wallet.ts index b4ae0382..d0f463ce 100644 --- a/packages/ensjs/src/wallet.ts +++ b/packages/ensjs/src/wallet.ts @@ -26,6 +26,20 @@ export { type DeleteSubnameParameters, type DeleteSubnameReturnType, } from './functions/wallet/deleteSubname.js' +export { + default as legacyCommitName, + type LegacyCommitNameDataParameters, + type LegacyCommitNameDataReturnType, + type LegacyCommitNameParameters, + type LegacyCommitNameReturnType, +} from './functions/wallet/legacyCommitName.js' +export { + default as legacyRegisterName, + type LegacyRegisterNameDataParameters, + type LegacyRegisterNameDataReturnType, + type LegacyRegisterNameParameters, + type LegacyRegisterNameReturnType, +} from './functions/wallet/legacyRegisterName.js' export { default as registerName, type RegisterNameDataParameters, From d548d9555741b6d9a99b1e2ec3c20eaca7a186f6 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Thu, 19 Dec 2024 17:55:24 +0800 Subject: [PATCH 04/20] add prelease changeset --- .changeset/clever-rings-lick.md | 5 +++++ .changeset/pre.json | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 .changeset/clever-rings-lick.md create mode 100644 .changeset/pre.json diff --git a/.changeset/clever-rings-lick.md b/.changeset/clever-rings-lick.md new file mode 100644 index 00000000..33d280de --- /dev/null +++ b/.changeset/clever-rings-lick.md @@ -0,0 +1,5 @@ +--- +'@ensdomains/ensjs': minor +--- + +Add legacy commit and registration functions diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000..f932cc54 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,10 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "@ensdomains/ens-test-env": "0.5.0-beta.1", + "@ensdomains/ensjs": "4.0.2", + "@ensdomains/ensjs-react": "0.0.4" + }, + "changesets": [] +} From 00e52b0c72eac41527d28972f313469ec003b345 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Fri, 20 Dec 2024 09:58:49 +0800 Subject: [PATCH 05/20] add minor changeset --- .changeset/pre.json | 4 +++- packages/ensjs/CHANGELOG.md | 6 ++++++ packages/ensjs/package.json | 2 +- packages/react/CHANGELOG.md | 7 +++++++ packages/react/package.json | 2 +- 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index f932cc54..be4c14b0 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -6,5 +6,7 @@ "@ensdomains/ensjs": "4.0.2", "@ensdomains/ensjs-react": "0.0.4" }, - "changesets": [] + "changesets": [ + "clever-rings-lick" + ] } diff --git a/packages/ensjs/CHANGELOG.md b/packages/ensjs/CHANGELOG.md index 4627c491..a5379d6b 100644 --- a/packages/ensjs/CHANGELOG.md +++ b/packages/ensjs/CHANGELOG.md @@ -1,5 +1,11 @@ # @ensdomains/ensjs +## 4.1.0-next.0 + +### Minor Changes + +- [#220](https://github.com/ensdomains/ensjs/pull/220) [`d548d95`](https://github.com/ensdomains/ensjs/commit/d548d9555741b6d9a99b1e2ec3c20eaca7a186f6) Thanks [@storywithoutend](https://github.com/storywithoutend)! - Add legacy commit and registration functions + ## 4.0.2 ### Patch Changes diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index a119e637..0e63e509 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs", - "version": "4.0.2", + "version": "4.1.0-next.0", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 80aa6881..e91ff71f 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @ensdomains/ensjs-react +## 0.0.5-next.0 + +### Patch Changes + +- Updated dependencies [[`d548d95`](https://github.com/ensdomains/ensjs/commit/d548d9555741b6d9a99b1e2ec3c20eaca7a186f6)]: + - @ensdomains/ensjs@4.1.0-next.0 + ## 0.0.4 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index c89cb091..b3167622 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs-react", - "version": "0.0.4", + "version": "0.0.5-next.0", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", From 78211a9cebf0fa9209ae29c84f147f782ad4f205 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Tue, 7 Jan 2025 17:03:52 +0800 Subject: [PATCH 06/20] revert to before changeset pre enter command --- .changeset/clever-rings-lick.md | 5 --- .changeset/pre.json | 12 ----- .github/workflows/release.yml | 78 ++++++++++++++++++--------------- package.json | 1 + packages/ensjs/CHANGELOG.md | 6 --- packages/ensjs/package.json | 2 +- packages/react/CHANGELOG.md | 7 --- packages/react/package.json | 2 +- 8 files changed, 45 insertions(+), 68 deletions(-) delete mode 100644 .changeset/clever-rings-lick.md delete mode 100644 .changeset/pre.json diff --git a/.changeset/clever-rings-lick.md b/.changeset/clever-rings-lick.md deleted file mode 100644 index 33d280de..00000000 --- a/.changeset/clever-rings-lick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ensdomains/ensjs': minor ---- - -Add legacy commit and registration functions diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index be4c14b0..00000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "mode": "pre", - "tag": "next", - "initialVersions": { - "@ensdomains/ens-test-env": "0.5.0-beta.1", - "@ensdomains/ensjs": "4.0.2", - "@ensdomains/ensjs-react": "0.0.4" - }, - "changesets": [ - "clever-rings-lick" - ] -} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3aadad4..b48ce487 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,55 +1,61 @@ -name: Release +name: Prerelease on: release: types: [published] + +defaults: + run: + shell: bash + +env: + FORCE_COLOR: true + jobs: - release: - name: Release + changelog: + name: PR or Release + if: ${{ github.repository_owner == 'ensdomains' }} + runs-on: ubuntu-latest permissions: - id-token: write contents: write - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18] + id-token: write + pull-requests: write steps: - uses: actions/checkout@v4 - with: - ref: ${{ github.event.release.target_commitish }} - - uses: pnpm/action-setup@v4 - with: - version: 9.4.0 + - uses: actions/checkout@v4 + - name: Enable corepack + run: corepack enable pnpm - - name: Install Node.js - uses: actions/setup-node@v4 + - uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} cache: 'pnpm' + node-version: 18 + registry-url: 'https://registry.npmjs.org' - - run: pnpm install --frozen-lockfile - - - name: Set up git - run: | - git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com' - git config --local user.name 'github-actions[bot]' + - name: Install dependencies + run: pnpm install - - name: Bump version to ${{ github.event.release.tag_name }} - run: | - pnpm -F @ensdomains/ensjs ver ${{ github.event.release.tag_name }} - git add . - git commit -m "${{ github.event.release.tag_name }}" + - name: Build Packages + run: pnpm -r build - - name: Publish + - name: Fix npmrc + run: npm config set "//registry.npmjs.org/:_authToken" "$NPM_TOKEN" env: - NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - NPM_CONFIG_PROVENANCE: true - run: | - pnpm config set //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} - pnpm -F @ensdomains/ensjs publish --no-git-checks + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Create Release Pull Request or Publish + id: changesets + uses: changesets/action@v1 + with: + # Note: pnpm install after versioning is necessary to refresh lockfile - - name: Push changes - run: git push + version: pnpm chgset:version:prerelease + publish: pnpm release + commit: "chore: release" + title: "[ci] release" env: - github-token: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Needs access to publish to npm + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_CONFIG_PROVENANCE: true diff --git a/package.json b/package.json index 23c342c3..52198bd5 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "publish:local:ens-test-env": "yalc publish packages/ens-test-env --push --up", "publish:local:ensjs": "yalc publish packages/ensjs --push --up", "chgset:version": "changeset version && pnpm install", + "chgset:version:prerelease": "changeset pre enter next && pnpm chgset:version", "chgset:run": "changeset", "release": "pnpm publish -r --access public && changeset tag", "chgset": "pnpm chgset:run && pnpm chgset:version" diff --git a/packages/ensjs/CHANGELOG.md b/packages/ensjs/CHANGELOG.md index a5379d6b..4627c491 100644 --- a/packages/ensjs/CHANGELOG.md +++ b/packages/ensjs/CHANGELOG.md @@ -1,11 +1,5 @@ # @ensdomains/ensjs -## 4.1.0-next.0 - -### Minor Changes - -- [#220](https://github.com/ensdomains/ensjs/pull/220) [`d548d95`](https://github.com/ensdomains/ensjs/commit/d548d9555741b6d9a99b1e2ec3c20eaca7a186f6) Thanks [@storywithoutend](https://github.com/storywithoutend)! - Add legacy commit and registration functions - ## 4.0.2 ### Patch Changes diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index 0e63e509..a119e637 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs", - "version": "4.1.0-next.0", + "version": "4.0.2", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index e91ff71f..80aa6881 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,12 +1,5 @@ # @ensdomains/ensjs-react -## 0.0.5-next.0 - -### Patch Changes - -- Updated dependencies [[`d548d95`](https://github.com/ensdomains/ensjs/commit/d548d9555741b6d9a99b1e2ec3c20eaca7a186f6)]: - - @ensdomains/ensjs@4.1.0-next.0 - ## 0.0.4 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index b3167622..c89cb091 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs-react", - "version": "0.0.5-next.0", + "version": "0.0.4", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", From f63d3083f4b6ab2e1718567c08c1afe36312f54c Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Tue, 7 Jan 2025 17:27:46 +0800 Subject: [PATCH 07/20] Revert "revert to before changeset pre enter command" This reverts commit 78211a9cebf0fa9209ae29c84f147f782ad4f205. --- .changeset/clever-rings-lick.md | 5 +++ .changeset/pre.json | 12 +++++ .github/workflows/release.yml | 78 +++++++++++++++------------------ package.json | 1 - packages/ensjs/CHANGELOG.md | 6 +++ packages/ensjs/package.json | 2 +- packages/react/CHANGELOG.md | 7 +++ packages/react/package.json | 2 +- 8 files changed, 68 insertions(+), 45 deletions(-) create mode 100644 .changeset/clever-rings-lick.md create mode 100644 .changeset/pre.json diff --git a/.changeset/clever-rings-lick.md b/.changeset/clever-rings-lick.md new file mode 100644 index 00000000..33d280de --- /dev/null +++ b/.changeset/clever-rings-lick.md @@ -0,0 +1,5 @@ +--- +'@ensdomains/ensjs': minor +--- + +Add legacy commit and registration functions diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000..be4c14b0 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,12 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "@ensdomains/ens-test-env": "0.5.0-beta.1", + "@ensdomains/ensjs": "4.0.2", + "@ensdomains/ensjs-react": "0.0.4" + }, + "changesets": [ + "clever-rings-lick" + ] +} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b48ce487..a3aadad4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,61 +1,55 @@ -name: Prerelease +name: Release on: release: types: [published] - -defaults: - run: - shell: bash - -env: - FORCE_COLOR: true - jobs: - changelog: - name: PR or Release - if: ${{ github.repository_owner == 'ensdomains' }} - runs-on: ubuntu-latest + release: + name: Release permissions: - contents: write id-token: write - pull-requests: write + contents: write + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18] steps: - uses: actions/checkout@v4 + with: + ref: ${{ github.event.release.target_commitish }} - - uses: actions/checkout@v4 - - name: Enable corepack - run: corepack enable pnpm + - uses: pnpm/action-setup@v4 + with: + version: 9.4.0 - - uses: actions/setup-node@v4 + - name: Install Node.js + uses: actions/setup-node@v4 with: + node-version: ${{ matrix.node-version }} cache: 'pnpm' - node-version: 18 - registry-url: 'https://registry.npmjs.org' - - - name: Install dependencies - run: pnpm install - - name: Build Packages - run: pnpm -r build + - run: pnpm install --frozen-lockfile - - name: Fix npmrc - run: npm config set "//registry.npmjs.org/:_authToken" "$NPM_TOKEN" - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Set up git + run: | + git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com' + git config --local user.name 'github-actions[bot]' - - name: Create Release Pull Request or Publish - id: changesets - uses: changesets/action@v1 - with: - # Note: pnpm install after versioning is necessary to refresh lockfile + - name: Bump version to ${{ github.event.release.tag_name }} + run: | + pnpm -F @ensdomains/ensjs ver ${{ github.event.release.tag_name }} + git add . + git commit -m "${{ github.event.release.tag_name }}" - version: pnpm chgset:version:prerelease - publish: pnpm release - commit: "chore: release" - title: "[ci] release" + - name: Publish env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Needs access to publish to npm - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_CONFIG_PROVENANCE: true + run: | + pnpm config set //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} + pnpm -F @ensdomains/ensjs publish --no-git-checks + + - name: Push changes + run: git push + env: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index 52198bd5..23c342c3 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "publish:local:ens-test-env": "yalc publish packages/ens-test-env --push --up", "publish:local:ensjs": "yalc publish packages/ensjs --push --up", "chgset:version": "changeset version && pnpm install", - "chgset:version:prerelease": "changeset pre enter next && pnpm chgset:version", "chgset:run": "changeset", "release": "pnpm publish -r --access public && changeset tag", "chgset": "pnpm chgset:run && pnpm chgset:version" diff --git a/packages/ensjs/CHANGELOG.md b/packages/ensjs/CHANGELOG.md index 4627c491..a5379d6b 100644 --- a/packages/ensjs/CHANGELOG.md +++ b/packages/ensjs/CHANGELOG.md @@ -1,5 +1,11 @@ # @ensdomains/ensjs +## 4.1.0-next.0 + +### Minor Changes + +- [#220](https://github.com/ensdomains/ensjs/pull/220) [`d548d95`](https://github.com/ensdomains/ensjs/commit/d548d9555741b6d9a99b1e2ec3c20eaca7a186f6) Thanks [@storywithoutend](https://github.com/storywithoutend)! - Add legacy commit and registration functions + ## 4.0.2 ### Patch Changes diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index a119e637..0e63e509 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs", - "version": "4.0.2", + "version": "4.1.0-next.0", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 80aa6881..e91ff71f 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @ensdomains/ensjs-react +## 0.0.5-next.0 + +### Patch Changes + +- Updated dependencies [[`d548d95`](https://github.com/ensdomains/ensjs/commit/d548d9555741b6d9a99b1e2ec3c20eaca7a186f6)]: + - @ensdomains/ensjs@4.1.0-next.0 + ## 0.0.4 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index c89cb091..b3167622 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs-react", - "version": "0.0.4", + "version": "0.0.5-next.0", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", From bcbdd64791a4e828c221eee7cf2854ae4efcd9e5 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Tue, 7 Jan 2025 17:28:10 +0800 Subject: [PATCH 08/20] revert changeset changes --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7d5af147..d1355fb9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -51,7 +51,7 @@ jobs: with: # Note: pnpm install after versioning is necessary to refresh lockfile version: pnpm chgset:version - publish: pnpm release + publish: pnpm release --no-git-checks commit: "chore: release" title: "[ci] release" env: From d5615f597f47b060ebd79fc6fc39b5122b2ad279 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Tue, 7 Jan 2025 17:41:24 +0800 Subject: [PATCH 09/20] revert changeset changes --- .changeset/clever-rings-lick.md | 5 --- .changeset/pre.json | 12 ----- .github/workflows/publish.yml | 2 +- .github/workflows/release.yml | 78 ++++++++++++++++++--------------- package.json | 1 + packages/ensjs/CHANGELOG.md | 6 --- packages/ensjs/package.json | 2 +- packages/react/CHANGELOG.md | 7 --- packages/react/package.json | 2 +- 9 files changed, 46 insertions(+), 69 deletions(-) delete mode 100644 .changeset/clever-rings-lick.md delete mode 100644 .changeset/pre.json diff --git a/.changeset/clever-rings-lick.md b/.changeset/clever-rings-lick.md deleted file mode 100644 index 33d280de..00000000 --- a/.changeset/clever-rings-lick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ensdomains/ensjs': minor ---- - -Add legacy commit and registration functions diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index be4c14b0..00000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "mode": "pre", - "tag": "next", - "initialVersions": { - "@ensdomains/ens-test-env": "0.5.0-beta.1", - "@ensdomains/ensjs": "4.0.2", - "@ensdomains/ensjs-react": "0.0.4" - }, - "changesets": [ - "clever-rings-lick" - ] -} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d1355fb9..7d5af147 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -51,7 +51,7 @@ jobs: with: # Note: pnpm install after versioning is necessary to refresh lockfile version: pnpm chgset:version - publish: pnpm release --no-git-checks + publish: pnpm release commit: "chore: release" title: "[ci] release" env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3aadad4..76266583 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,55 +1,61 @@ -name: Release +name: Prerelease on: release: types: [published] +name: Release + +defaults: + run: + shell: bash + +env: + FORCE_COLOR: true + jobs: - release: - name: Release + changelog: + name: PR or Release + if: ${{ github.repository_owner == 'ensdomains' }} + runs-on: ubuntu-latest permissions: - id-token: write contents: write - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18] + id-token: write + pull-requests: write steps: - uses: actions/checkout@v4 - with: - ref: ${{ github.event.release.target_commitish }} - - uses: pnpm/action-setup@v4 - with: - version: 9.4.0 + - uses: actions/checkout@v4 + - name: Enable corepack + run: corepack enable pnpm - - name: Install Node.js - uses: actions/setup-node@v4 + - uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} cache: 'pnpm' + node-version: 18 + registry-url: 'https://registry.npmjs.org' - - run: pnpm install --frozen-lockfile + - name: Install dependencies + run: pnpm install - - name: Set up git - run: | - git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com' - git config --local user.name 'github-actions[bot]' + - name: Build Packages + run: pnpm -r build - - name: Bump version to ${{ github.event.release.tag_name }} - run: | - pnpm -F @ensdomains/ensjs ver ${{ github.event.release.tag_name }} - git add . - git commit -m "${{ github.event.release.tag_name }}" - - - name: Publish + - name: Fix npmrc + run: npm config set "//registry.npmjs.org/:_authToken" "$NPM_TOKEN" env: - NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - NPM_CONFIG_PROVENANCE: true - run: | - pnpm config set //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} - pnpm -F @ensdomains/ensjs publish --no-git-checks + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Push changes - run: git push + - name: Create Release Pull Request or Publish + id: changesets + uses: changesets/action@v1 + with: + # Note: pnpm install after versioning is necessary to refresh lockfile + version: pnpm chgset:version:prerelease + publish: pnpm release --no-git-checks + commit: "chore: release" + title: "[ci] release" env: - github-token: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Needs access to publish to npm + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_CONFIG_PROVENANCE: true diff --git a/package.json b/package.json index 23c342c3..52198bd5 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "publish:local:ens-test-env": "yalc publish packages/ens-test-env --push --up", "publish:local:ensjs": "yalc publish packages/ensjs --push --up", "chgset:version": "changeset version && pnpm install", + "chgset:version:prerelease": "changeset pre enter next && pnpm chgset:version", "chgset:run": "changeset", "release": "pnpm publish -r --access public && changeset tag", "chgset": "pnpm chgset:run && pnpm chgset:version" diff --git a/packages/ensjs/CHANGELOG.md b/packages/ensjs/CHANGELOG.md index a5379d6b..4627c491 100644 --- a/packages/ensjs/CHANGELOG.md +++ b/packages/ensjs/CHANGELOG.md @@ -1,11 +1,5 @@ # @ensdomains/ensjs -## 4.1.0-next.0 - -### Minor Changes - -- [#220](https://github.com/ensdomains/ensjs/pull/220) [`d548d95`](https://github.com/ensdomains/ensjs/commit/d548d9555741b6d9a99b1e2ec3c20eaca7a186f6) Thanks [@storywithoutend](https://github.com/storywithoutend)! - Add legacy commit and registration functions - ## 4.0.2 ### Patch Changes diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index 0e63e509..a119e637 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs", - "version": "4.1.0-next.0", + "version": "4.0.2", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index e91ff71f..80aa6881 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,12 +1,5 @@ # @ensdomains/ensjs-react -## 0.0.5-next.0 - -### Patch Changes - -- Updated dependencies [[`d548d95`](https://github.com/ensdomains/ensjs/commit/d548d9555741b6d9a99b1e2ec3c20eaca7a186f6)]: - - @ensdomains/ensjs@4.1.0-next.0 - ## 0.0.4 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index b3167622..c89cb091 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs-react", - "version": "0.0.5-next.0", + "version": "0.0.4", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", From 8890de9ffafc5ab09f2a8af9da7c36095b80fa0c Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Tue, 7 Jan 2025 17:43:37 +0800 Subject: [PATCH 10/20] fix typo in release.yml --- .github/workflows/release.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 76266583..e203e3c3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,6 @@ name: Prerelease on: release: types: [published] -name: Release defaults: run: From a9c1192cb76fe465173cb5110a8bbb1ccf569555 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Tue, 7 Jan 2025 23:25:29 +0800 Subject: [PATCH 11/20] update release.yml for prerelease --- .github/workflows/release.yml | 75 ++++++++++++++++------------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e203e3c3..bb80ce4c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,58 +3,53 @@ name: Prerelease on: release: types: [published] - -defaults: - run: - shell: bash - -env: - FORCE_COLOR: true - jobs: - changelog: - name: PR or Release - if: ${{ github.repository_owner == 'ensdomains' }} - runs-on: ubuntu-latest + release: + name: Release permissions: - contents: write id-token: write - pull-requests: write + contents: write + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18] steps: - uses: actions/checkout@v4 + with: + ref: ${{ github.event.release.target_commitish }} - - uses: actions/checkout@v4 - - name: Enable corepack - run: corepack enable pnpm + - uses: pnpm/action-setup@v4 + with: + version: 9.4.0 - - uses: actions/setup-node@v4 + - name: Install Node.js + uses: actions/setup-node@v4 with: + node-version: ${{ matrix.node-version }} cache: 'pnpm' - node-version: 18 - registry-url: 'https://registry.npmjs.org' - - name: Install dependencies - run: pnpm install + - run: pnpm install --frozen-lockfile - - name: Build Packages - run: pnpm -r build + - name: Set up git + run: | + git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com' + git config --local user.name 'github-actions[bot]' - - name: Fix npmrc - run: npm config set "//registry.npmjs.org/:_authToken" "$NPM_TOKEN" - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Bump version to ${{ github.event.release.tag_name }} + run: | + pnpm -F @ensdomains/ensjs ver ${{ github.event.release.tag_name }} + git add . + git commit -m "${{ github.event.release.tag_name }}" - - name: Create Release Pull Request or Publish - id: changesets - uses: changesets/action@v1 - with: - # Note: pnpm install after versioning is necessary to refresh lockfile - version: pnpm chgset:version:prerelease - publish: pnpm release --no-git-checks - commit: "chore: release" - title: "[ci] release" + - name: Publish env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Needs access to publish to npm - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_CONFIG_PROVENANCE: true + run: | + pnpm config set //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} + pnpm -F @ensdomains/ensjs publish --tag next --no-git-checks + + - name: Push changes + run: git push + env: + github-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 688e6f08e464eab07e1d9967cea382e0dfc36d92 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:33:28 +0000 Subject: [PATCH 12/20] v4.0.3-alpha.0 --- packages/ensjs/package.json | 2 +- packages/ensjs/src/errors/version.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index a119e637..b1ee2655 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs", - "version": "4.0.2", + "version": "4.0.3-alpha.0", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", diff --git a/packages/ensjs/src/errors/version.ts b/packages/ensjs/src/errors/version.ts index bc2da28e..6042cab9 100644 --- a/packages/ensjs/src/errors/version.ts +++ b/packages/ensjs/src/errors/version.ts @@ -1 +1 @@ -export const version = 'v4.0.2-alpha.5' +export const version = 'v4.0.3-alpha.0' From f530c914fcdd98ee9d63238f240342a4232c9ccd Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Thu, 9 Jan 2025 19:08:01 +0800 Subject: [PATCH 13/20] add more abi snippet for ethcontroller and legacyethcontroller --- .../src/contracts/ethRegistrarController.ts | 41 +++++++++++++ packages/ensjs/src/contracts/index.ts | 15 +++++ .../contracts/legacyEthRegistrarController.ts | 57 +++++++++++++++---- 3 files changed, 102 insertions(+), 11 deletions(-) diff --git a/packages/ensjs/src/contracts/ethRegistrarController.ts b/packages/ensjs/src/contracts/ethRegistrarController.ts index 41349ac0..389a4071 100644 --- a/packages/ensjs/src/contracts/ethRegistrarController.ts +++ b/packages/ensjs/src/contracts/ethRegistrarController.ts @@ -206,3 +206,44 @@ export const ethRegistrarControllerRenewSnippet = [ type: 'function', }, ] as const + +export const ethRegistrarControllerNameRegisteredEventSnippet = [ + { + anonymous: false, + inputs: [ + { + indexed: false, + name: 'name', + type: 'string', + }, + { + indexed: true, + name: 'label', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + name: 'baseCost', + type: 'uint256', + }, + { + indexed: false, + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + name: 'expires', + type: 'uint256', + }, + ], + name: 'NameRegistered', + type: 'event', + }, +] as const diff --git a/packages/ensjs/src/contracts/index.ts b/packages/ensjs/src/contracts/index.ts index b998202a..57a0af38 100644 --- a/packages/ensjs/src/contracts/index.ts +++ b/packages/ensjs/src/contracts/index.ts @@ -40,8 +40,23 @@ export { ethRegistrarControllerRegisterSnippet, ethRegistrarControllerRenewSnippet, ethRegistrarControllerRentPriceSnippet, + ethRegistrarControllerNameRegisteredEventSnippet, } from './ethRegistrarController.js' export { getChainContractAddress } from './getChainContractAddress.js' +export { + legacyEthRegistrarControllerAvailableSnippet, + legacyEthRegistrarControllerCommitSnippet, + legacyEthRegistrarControllerCommitmentsSnippet, + legacyEthRegistrarControllerMakeCommitmentSnippet, + legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet, + legacyEthRegistrarControllerRegisterSnippet, + legacyEthRegistrarControllerRegisterWithConfigSnippet, + legacyEthRegistrarControllerRenewSnippet, + legacyEthRegistrarControllerRentPriceSnippet, + legacyEthRegistrarControllerSupportsInterfaceSnippet, + legacyEthRegistrarControllerTransferOwnershipSnippet, + legacyEthRegistrarControllerNameRegisteredEventSnippet as legacyNameRegisteredEventSnippet, +} from './legacyEthRegistrarController.js' export { multicallGetCurrentBlockTimestampSnippet, multicallTryAggregateSnippet, diff --git a/packages/ensjs/src/contracts/legacyEthRegistrarController.ts b/packages/ensjs/src/contracts/legacyEthRegistrarController.ts index 166bf9b5..c92ed99a 100644 --- a/packages/ensjs/src/contracts/legacyEthRegistrarController.ts +++ b/packages/ensjs/src/contracts/legacyEthRegistrarController.ts @@ -8,7 +8,7 @@ export const legacyEthRegistrarControllerAvailableSnippet = [ stateMutability: 'view', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerCommitSnippet = [ { @@ -20,7 +20,7 @@ export const legacyEthRegistrarControllerCommitSnippet = [ stateMutability: 'nonpayable', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerCommitmentsSnippet = [ { @@ -32,7 +32,7 @@ export const legacyEthRegistrarControllerCommitmentsSnippet = [ stateMutability: 'view', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerMakeCommitmentSnippet = [ { @@ -48,7 +48,7 @@ export const legacyEthRegistrarControllerMakeCommitmentSnippet = [ stateMutability: 'pure', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet = [ { @@ -66,7 +66,7 @@ export const legacyEthRegistrarControllerMakeCommitmentWithConfigSnippet = [ stateMutability: 'pure', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerRegisterSnippet = [ { @@ -83,7 +83,7 @@ export const legacyEthRegistrarControllerRegisterSnippet = [ stateMutability: 'payable', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerRegisterWithConfigSnippet = [ { @@ -102,7 +102,7 @@ export const legacyEthRegistrarControllerRegisterWithConfigSnippet = [ stateMutability: 'payable', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerRenewSnippet = [ { @@ -117,7 +117,7 @@ export const legacyEthRegistrarControllerRenewSnippet = [ stateMutability: 'payable', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerRentPriceSnippet = [ { @@ -132,7 +132,7 @@ export const legacyEthRegistrarControllerRentPriceSnippet = [ stateMutability: 'view', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerSupportsInterfaceSnippet = [ { @@ -144,7 +144,7 @@ export const legacyEthRegistrarControllerSupportsInterfaceSnippet = [ stateMutability: 'pure', type: 'function', }, -] +] as const export const legacyEthRegistrarControllerTransferOwnershipSnippet = [ { @@ -156,4 +156,39 @@ export const legacyEthRegistrarControllerTransferOwnershipSnippet = [ stateMutability: 'nonpayable', type: 'function', }, -] +] as const + +export const legacyEthRegistrarControllerNameRegisteredEventSnippet = [ + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'string', name: 'name', type: 'string' }, + { + indexed: true, + internalType: 'bytes32', + name: 'label', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'cost', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'expires', + type: 'uint256', + }, + ], + name: 'NameRegistered', + type: 'event', + }, +] as const From 984d63a3bb2a108cf0eec00b8bcbfa17f31a2134 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Fri, 10 Jan 2025 15:36:54 +0800 Subject: [PATCH 14/20] refactor and split out legacyregistration and legacyregistraionwithconfig functions --- .../functions/wallet/legacyRegisterName.ts | 3 +- packages/ensjs/src/utils/index.ts | 2 +- .../ensjs/src/utils/legacyRegisterHelpers.ts | 115 ++++++++++-------- 3 files changed, 67 insertions(+), 53 deletions(-) diff --git a/packages/ensjs/src/functions/wallet/legacyRegisterName.ts b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts index 4b6f2db7..8e68ff64 100644 --- a/packages/ensjs/src/functions/wallet/legacyRegisterName.ts +++ b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts @@ -19,6 +19,7 @@ import { makeLegacyRegistrationTuple, type LegacyRegistrationParameters, isLegacyRegistrationWithConfig, + makeLegacyRegistrationWithConfigTuple, } from '../../utils/legacyRegisterHelpers.js' import { legacyEthRegistrarControllerRegisterSnippet, @@ -64,7 +65,7 @@ export const makeFunctionData = < ? encodeFunctionData({ abi: legacyEthRegistrarControllerRegisterWithConfigSnippet, functionName: 'registerWithConfig', - args: makeLegacyRegistrationTuple(args), + args: makeLegacyRegistrationWithConfigTuple(args), }) : encodeFunctionData({ abi: legacyEthRegistrarControllerRegisterSnippet, diff --git a/packages/ensjs/src/utils/index.ts b/packages/ensjs/src/utils/index.ts index 874dd708..b120793f 100644 --- a/packages/ensjs/src/utils/index.ts +++ b/packages/ensjs/src/utils/index.ts @@ -111,7 +111,7 @@ export { makeLegacyRegistrationTuple, type LegacyCommitmentTuple, type LegacyRegistrationParameters, - type LegacyRegistrationTuple, + type LegacyRegistrationBaseTuple as LegacyRegistrationTuple, } from './legacyRegisterHelpers.js' export { makeSafeSecondsDate } from './makeSafeSecondsDate.js' export { diff --git a/packages/ensjs/src/utils/legacyRegisterHelpers.ts b/packages/ensjs/src/utils/legacyRegisterHelpers.ts index 0e2cafc3..63f05b38 100644 --- a/packages/ensjs/src/utils/legacyRegisterHelpers.ts +++ b/packages/ensjs/src/utils/legacyRegisterHelpers.ts @@ -8,7 +8,7 @@ import { import { EMPTY_ADDRESS } from './consts.js' import { LegacyRegistrationInvalidConfigError } from '../errors/register.js' -export type LegacyRegistrationBaseParameters = { +export type LegacyRegistrationParameters = { /** Name to register */ name: string /** Address to set owner to */ @@ -24,15 +24,11 @@ export type LegacyRegistrationBaseParameters = { } export type LegacyRegistrationWithConfigParameters = - LegacyRegistrationBaseParameters & { + LegacyRegistrationParameters & { resolverAddress: Address address?: Address } -export type LegacyRegistrationParameters = - | LegacyRegistrationBaseParameters - | LegacyRegistrationWithConfigParameters - export const isLegacyRegistrationWithConfig = ( params: LegacyRegistrationParameters, ): params is LegacyRegistrationWithConfigParameters => { @@ -47,67 +43,79 @@ export const isLegacyRegistrationWithConfig = ( return resolverAddress !== EMPTY_ADDRESS || address !== EMPTY_ADDRESS } -export type LegacyCommitmentTuple = - | [label: string, owner: Address, secret: Hex] - | [ - label: string, - owner: Address, - resolverAddress: Address, - address: Address, - secret: Hex, - ] - -export type LegacyRegistrationTuple = - | [label: string, owner: Address, duration: bigint, secret: Hex] - | [ - label: string, - owner: Address, - duration: bigint, - secret: Hex, - resolverAddress: Address, - address: Address, - ] +export type LegacyCommitmentTuple = [label: string, owner: Address, secret: Hex] + +export type LegacyCommitmentWithConfigTuple = [ + label: string, + owner: Address, + resolverAddress: Address, + address: Address, + secret: Hex, +] + +export type LegacyRegistrationTuple = [ + label: string, + owner: Address, + duration: bigint, + secret: Hex, +] + +export type LegacyRegistrationWithConfigTuple = [ + label: string, + owner: Address, + duration: bigint, + secret: Hex, + resolverAddress: Address, + address: Address, +] export const makeLegacyCommitmentTuple = ( params: LegacyRegistrationParameters, ): LegacyCommitmentTuple => { - const { - name, - owner, - secret, - resolverAddress = EMPTY_ADDRESS, - address = EMPTY_ADDRESS, - } = params as LegacyRegistrationWithConfigParameters - + const { name, owner, secret } = params const label = name.split('.')[0] - - if (isLegacyRegistrationWithConfig(params)) { - return [label, owner, secret, resolverAddress, address] - } return [label, owner, secret] } -export const makeLegacyRegistrationTuple = ( - params: LegacyRegistrationParameters, -): LegacyRegistrationTuple => { +export const makeLegacyCommitmentWithConfigTuple = ( + params: LegacyRegistrationWithConfigParameters, +): LegacyCommitmentWithConfigTuple => { const { name, owner, secret, - duration, resolverAddress = EMPTY_ADDRESS, address = EMPTY_ADDRESS, } = params as LegacyRegistrationWithConfigParameters const label = name.split('.')[0] - if (isLegacyRegistrationWithConfig(params)) - return [label, owner, BigInt(duration), secret, resolverAddress, address] - return [label, owner, BigInt(params.duration), secret] + return [label, owner, secret, resolverAddress, address] +} + +export const makeLegacyRegistrationTuple = ({ + name, + owner, + secret, + duration, +}: LegacyRegistrationParameters): LegacyRegistrationTuple => { + const label = name.split('.')[0] + return [label, owner, BigInt(duration), secret] } -export const makeLegacyCommitmentFromTuple = ([ - label, - ...others -]: LegacyCommitmentTuple): Hex => { +export const makeLegacyRegistrationWithConfigTuple = ({ + name, + owner, + secret, + duration, + resolverAddress, + address = EMPTY_ADDRESS, +}: LegacyRegistrationWithConfigParameters): LegacyRegistrationWithConfigTuple => { + const label = name.split('.')[0] + return [label, owner, BigInt(duration), secret, resolverAddress, address] +} + +export const makeLegacyCommitmentFromTuple = ([label, ...others]: + | LegacyCommitmentTuple + | LegacyCommitmentWithConfigTuple): Hex => { const labelHash = labelhash(label) const params = [labelHash, ...others] as const @@ -130,5 +138,10 @@ export const makeLegacyCommitmentFromTuple = ([ } export const makeLegacyCommitment = ( - params: LegacyRegistrationParameters, -): Hex => makeLegacyCommitmentFromTuple(makeLegacyCommitmentTuple(params)) + params: LegacyRegistrationParameters | LegacyRegistrationWithConfigParameters, +): Hex => { + const touple = isLegacyRegistrationWithConfig(params) + ? makeLegacyCommitmentWithConfigTuple(params) + : makeLegacyCommitmentTuple(params) + return makeLegacyCommitmentFromTuple(touple) +} From 9fc9abaab51df468cad57b0fe93103d9a30e4df9 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Fri, 10 Jan 2025 16:41:09 +0800 Subject: [PATCH 15/20] update legacyRegisterHelpers test --- .../functions/wallet/legacyRegisterName.ts | 4 +- .../src/utils/legacyRegisterHelpers.test.ts | 63 ++++++------------- .../ensjs/src/utils/legacyRegisterHelpers.ts | 4 +- 3 files changed, 24 insertions(+), 47 deletions(-) diff --git a/packages/ensjs/src/functions/wallet/legacyRegisterName.ts b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts index 8e68ff64..2ac9eec5 100644 --- a/packages/ensjs/src/functions/wallet/legacyRegisterName.ts +++ b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts @@ -18,7 +18,7 @@ import { getNameType } from '../../utils/getNameType.js' import { makeLegacyRegistrationTuple, type LegacyRegistrationParameters, - isLegacyRegistrationWithConfig, + isLegacyRegistrationWithConfigParameters, makeLegacyRegistrationWithConfigTuple, } from '../../utils/legacyRegisterHelpers.js' import { @@ -61,7 +61,7 @@ export const makeFunctionData = < details: 'Only 2ld-eth name registration is supported', }) - const data = isLegacyRegistrationWithConfig(args) + const data = isLegacyRegistrationWithConfigParameters(args) ? encodeFunctionData({ abi: legacyEthRegistrarControllerRegisterWithConfigSnippet, functionName: 'registerWithConfig', diff --git a/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts b/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts index c52a95ff..28ea2d2e 100644 --- a/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts +++ b/packages/ensjs/src/utils/legacyRegisterHelpers.test.ts @@ -1,11 +1,13 @@ import { type Address, type Hex } from 'viem' import { beforeAll, describe, expect, it } from 'vitest' import { - isLegacyRegistrationWithConfig, + isLegacyRegistrationWithConfigParameters, makeLegacyCommitment, makeLegacyCommitmentTuple, makeLegacyRegistrationTuple, type LegacyRegistrationParameters, + makeLegacyCommitmentWithConfigTuple, + makeLegacyRegistrationWithConfigTuple, } from './legacyRegisterHelpers.js' import { EMPTY_ADDRESS } from './consts.js' import { randomSecret } from './registerHelpers.js' @@ -42,10 +44,10 @@ beforeAll(async () => { ;[owner, address] = accounts }) -describe('isLegacyRegistrationWithConfig', () => { +describe('isLegacyRegistrationWithConfigParameters', () => { it('return false when resolverAddress and address are undefined', () => { expect( - isLegacyRegistrationWithConfig({ + isLegacyRegistrationWithConfigParameters({ name, owner, duration, @@ -56,7 +58,7 @@ describe('isLegacyRegistrationWithConfig', () => { it('return false when resolverAddress and address are empty addresses', () => { expect( - isLegacyRegistrationWithConfig({ + isLegacyRegistrationWithConfigParameters({ name, owner, duration, @@ -69,7 +71,7 @@ describe('isLegacyRegistrationWithConfig', () => { it('return true when resolverAddress and address are defined', () => { expect( - isLegacyRegistrationWithConfig({ + isLegacyRegistrationWithConfigParameters({ name, owner, duration, @@ -82,7 +84,7 @@ describe('isLegacyRegistrationWithConfig', () => { it('return true when resolverAddress is defined and address is NOT defined', () => { expect( - isLegacyRegistrationWithConfig({ + isLegacyRegistrationWithConfigParameters({ name, owner, duration, @@ -94,7 +96,7 @@ describe('isLegacyRegistrationWithConfig', () => { it('should throw an error when address is defined and resolverAddress is NOT defined', () => { expect(() => - isLegacyRegistrationWithConfig({ + isLegacyRegistrationWithConfigParameters({ name, owner, duration, @@ -106,7 +108,7 @@ describe('isLegacyRegistrationWithConfig', () => { it('should throw an error when address is defined and resolverAddress is empty address', () => { expect(() => - isLegacyRegistrationWithConfig({ + isLegacyRegistrationWithConfigParameters({ name, owner, duration, @@ -128,9 +130,11 @@ describe('makeLegacyCommitmentTuple', () => { }) expect(tuple).toEqual(['test', owner, secret]) }) +}) +describe('makeLegacyCommitmentWithConfigTuple', () => { it('should return args for makeCommitWithConfig if resolverAddress is defined', () => { - const tuple = makeLegacyCommitmentTuple({ + const tuple = makeLegacyCommitmentWithConfigTuple({ name: 'test.eth', owner, duration, @@ -145,18 +149,6 @@ describe('makeLegacyCommitmentTuple', () => { EMPTY_ADDRESS, ]) }) - - it('should throw error if resolverAddress is NOT defined and address is defined', () => { - expect(() => - makeLegacyCommitmentTuple({ - name: 'test.eth', - owner, - duration, - secret, - address, - }), - ).toThrowErrorMatchingInlineSnapshot(makeSnapshot(address)) - }) }) describe('makeLegacyRegistrationTuple', () => { @@ -174,34 +166,19 @@ describe('makeLegacyRegistrationTuple', () => { secret, ]) }) +}) - it('should return args for register if resolverAddress and address are empty addresses', () => { - const params: LegacyRegistrationParameters = { - name, - owner, - duration, - secret, - resolverAddress: EMPTY_ADDRESS, - address: EMPTY_ADDRESS, - } - expect(makeLegacyRegistrationTuple(params)).toEqual([ - 'test', - owner, - 31536000n, - secret, - ]) - }) - - it('should return args for register if resolverAddress and address are not undefined', () => { - const params: LegacyRegistrationParameters = { +describe('makeLegacyRegistrationWithConfigTuple', () => { + it('should return args for register if resolverAddress and address are defined', () => { + const tuple = makeLegacyRegistrationWithConfigTuple({ name: 'test.eth', owner, duration, secret, resolverAddress, address, - } - expect(makeLegacyRegistrationTuple(params)).toEqual([ + }) + expect(tuple).toEqual([ 'test', owner, 31536000n, @@ -254,7 +231,7 @@ describe('makeLegacyCommitment', () => { client: publicClient, contract: 'legacyEthRegistrarController', }), - args: makeLegacyCommitmentTuple(params), + args: makeLegacyCommitmentWithConfigTuple(params), }) expect(commitment).toBe(commitment2) diff --git a/packages/ensjs/src/utils/legacyRegisterHelpers.ts b/packages/ensjs/src/utils/legacyRegisterHelpers.ts index 63f05b38..7f305bf4 100644 --- a/packages/ensjs/src/utils/legacyRegisterHelpers.ts +++ b/packages/ensjs/src/utils/legacyRegisterHelpers.ts @@ -29,7 +29,7 @@ export type LegacyRegistrationWithConfigParameters = address?: Address } -export const isLegacyRegistrationWithConfig = ( +export const isLegacyRegistrationWithConfigParameters = ( params: LegacyRegistrationParameters, ): params is LegacyRegistrationWithConfigParameters => { const { resolverAddress = EMPTY_ADDRESS, address = EMPTY_ADDRESS } = @@ -140,7 +140,7 @@ export const makeLegacyCommitmentFromTuple = ([label, ...others]: export const makeLegacyCommitment = ( params: LegacyRegistrationParameters | LegacyRegistrationWithConfigParameters, ): Hex => { - const touple = isLegacyRegistrationWithConfig(params) + const touple = isLegacyRegistrationWithConfigParameters(params) ? makeLegacyCommitmentWithConfigTuple(params) : makeLegacyCommitmentTuple(params) return makeLegacyCommitmentFromTuple(touple) From 9e63758654aa2450ed614ff105f1897ff3ede820 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Fri, 10 Jan 2025 16:50:06 +0800 Subject: [PATCH 16/20] fix lint error --- packages/ensjs/src/utils/index.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/ensjs/src/utils/index.ts b/packages/ensjs/src/utils/index.ts index b120793f..9c54f572 100644 --- a/packages/ensjs/src/utils/index.ts +++ b/packages/ensjs/src/utils/index.ts @@ -108,10 +108,16 @@ export { makeLegacyCommitment, makeLegacyCommitmentFromTuple, makeLegacyCommitmentTuple, + makeLegacyCommitmentWithConfigTuple, makeLegacyRegistrationTuple, + makeLegacyRegistrationWithConfigTuple, + isLegacyRegistrationWithConfigParameters, type LegacyCommitmentTuple, + type LegacyCommitmentWithConfigTuple, type LegacyRegistrationParameters, - type LegacyRegistrationBaseTuple as LegacyRegistrationTuple, + type LegacyRegistrationWithConfigParameters, + type LegacyRegistrationTuple, + type LegacyRegistrationWithConfigTuple, } from './legacyRegisterHelpers.js' export { makeSafeSecondsDate } from './makeSafeSecondsDate.js' export { From 951874e330ca676054740c4185e544dbace03187 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 11:18:14 +0000 Subject: [PATCH 17/20] v4.0.3-alpha.11 --- packages/ensjs/package.json | 2 +- packages/ensjs/src/errors/version.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index b1ee2655..1689fceb 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs", - "version": "4.0.3-alpha.0", + "version": "4.0.3-alpha.11", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", diff --git a/packages/ensjs/src/errors/version.ts b/packages/ensjs/src/errors/version.ts index 6042cab9..c19bba5c 100644 --- a/packages/ensjs/src/errors/version.ts +++ b/packages/ensjs/src/errors/version.ts @@ -1 +1 @@ -export const version = 'v4.0.3-alpha.0' +export const version = 'v4.0.3-alpha.11' From 930cf26aef55c9b801db3167ef600d6ae96fb8e8 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 13 Jan 2025 22:32:40 +0800 Subject: [PATCH 18/20] refactor legacyRegisterName --- .../functions/wallet/legacyRegisterName.ts | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/ensjs/src/functions/wallet/legacyRegisterName.ts b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts index 2ac9eec5..a3dbbf42 100644 --- a/packages/ensjs/src/functions/wallet/legacyRegisterName.ts +++ b/packages/ensjs/src/functions/wallet/legacyRegisterName.ts @@ -61,24 +61,22 @@ export const makeFunctionData = < details: 'Only 2ld-eth name registration is supported', }) - const data = isLegacyRegistrationWithConfigParameters(args) - ? encodeFunctionData({ - abi: legacyEthRegistrarControllerRegisterWithConfigSnippet, - functionName: 'registerWithConfig', - args: makeLegacyRegistrationWithConfigTuple(args), - }) - : encodeFunctionData({ - abi: legacyEthRegistrarControllerRegisterSnippet, - functionName: 'register', - args: makeLegacyRegistrationTuple(args), - }) - return { to: getChainContractAddress({ client: wallet, contract: 'legacyEthRegistrarController', }), - data, + data: isLegacyRegistrationWithConfigParameters(args) + ? encodeFunctionData({ + abi: legacyEthRegistrarControllerRegisterWithConfigSnippet, + functionName: 'registerWithConfig', + args: makeLegacyRegistrationWithConfigTuple(args), + }) + : encodeFunctionData({ + abi: legacyEthRegistrarControllerRegisterSnippet, + functionName: 'register', + args: makeLegacyRegistrationTuple(args), + }), value, } } From 28c004bdf6f71a8d95e7591da013fba05a882e2d Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Tue, 14 Jan 2025 01:21:50 +0800 Subject: [PATCH 19/20] fix typo in legacyEthEthRegistrarControllerNameRegisteredEventSnippet --- packages/ensjs/src/contracts/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ensjs/src/contracts/index.ts b/packages/ensjs/src/contracts/index.ts index 57a0af38..0b64bb81 100644 --- a/packages/ensjs/src/contracts/index.ts +++ b/packages/ensjs/src/contracts/index.ts @@ -55,7 +55,7 @@ export { legacyEthRegistrarControllerRentPriceSnippet, legacyEthRegistrarControllerSupportsInterfaceSnippet, legacyEthRegistrarControllerTransferOwnershipSnippet, - legacyEthRegistrarControllerNameRegisteredEventSnippet as legacyNameRegisteredEventSnippet, + legacyEthRegistrarControllerNameRegisteredEventSnippet, } from './legacyEthRegistrarController.js' export { multicallGetCurrentBlockTimestampSnippet, From 5397a10edeca1f6ed1b87230daf47a8e457833bf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:22:25 +0000 Subject: [PATCH 20/20] v4.0.3-alpha.12 --- packages/ensjs/package.json | 2 +- packages/ensjs/src/errors/version.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index 1689fceb..eb91c48d 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -1,6 +1,6 @@ { "name": "@ensdomains/ensjs", - "version": "4.0.3-alpha.11", + "version": "4.0.3-alpha.12", "description": "ENS javascript library for contract interaction", "type": "module", "main": "./dist/cjs/index.js", diff --git a/packages/ensjs/src/errors/version.ts b/packages/ensjs/src/errors/version.ts index c19bba5c..d3221612 100644 --- a/packages/ensjs/src/errors/version.ts +++ b/packages/ensjs/src/errors/version.ts @@ -1 +1 @@ -export const version = 'v4.0.3-alpha.11' +export const version = 'v4.0.3-alpha.12'