From d56b41421f20bc370c5a54a6362d330114afa038 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 16 Dec 2024 17:29:43 +0800 Subject: [PATCH 01/36] 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 af67f61f6..001a6442b 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 000000000..166bf9b5f --- /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 000000000..69d84ec0e --- /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 000000000..b3ade8294 --- /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 000000000..5a2d49e95 --- /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 000000000..613eb06b2 --- /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 000000000..9514fda27 --- /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 58945e49c..32aebaf39 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 000000000..f77020879 --- /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 000000000..4dde050f9 --- /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/36] 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 001a6442b..c9837de27 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 b3ade8294..7796346df 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 5a2d49e95..aa04652fe 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 613eb06b2..0bade3dbd 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 9514fda27..4b6f2db79 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 f77020879..c52a95ff6 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 4dde050f9..0e2cafc3d 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/36] 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 aa04652fe..85fb2a09d 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 1132520bd..874dd7088 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 b4ae03820..d0f463cec 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/36] 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 000000000..33d280de2 --- /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 000000000..f932cc543 --- /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/36] 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 f932cc543..be4c14b04 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 4627c4912..a5379d6bc 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 a119e637a..0e63e509d 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 80aa6881f..e91ff71f7 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 c89cb0912..b3167622c 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/36] 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 33d280de2..000000000 --- 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 be4c14b04..000000000 --- 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 a3aadad4c..b48ce4877 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 23c342c31..52198bd57 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 a5379d6bc..4627c4912 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 0e63e509d..a119e637a 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 e91ff71f7..80aa6881f 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 b3167622c..c89cb0912 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/36] 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 000000000..33d280de2 --- /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 000000000..be4c14b04 --- /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 b48ce4877..a3aadad4c 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 52198bd57..23c342c31 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 4627c4912..a5379d6bc 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 a119e637a..0e63e509d 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 80aa6881f..e91ff71f7 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 c89cb0912..b3167622c 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/36] 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 7d5af147b..d1355fb95 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/36] 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 33d280de2..000000000 --- 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 be4c14b04..000000000 --- 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 d1355fb95..7d5af147b 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 a3aadad4c..76266583f 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 23c342c31..52198bd57 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 a5379d6bc..4627c4912 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 0e63e509d..a119e637a 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 e91ff71f7..80aa6881f 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 b3167622c..c89cb0912 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/36] 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 76266583f..e203e3c3a 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/36] 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 e203e3c3a..bb80ce4cd 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/36] 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 a119e637a..b1ee2655a 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 bc2da28ee..6042cab97 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/36] 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 41349ac0f..389a40713 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 b998202ac..57a0af38a 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 166bf9b5f..c92ed99ab 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/36] 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 4b6f2db79..8e68ff648 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 874dd7088..b120793f4 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 0e2cafc3d..63f05b382 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/36] 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 8e68ff648..2ac9eec57 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 c52a95ff6..28ea2d2e3 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 63f05b382..7f305bf40 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/36] 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 b120793f4..9c54f5729 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/36] 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 b1ee2655a..1689fcebf 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 6042cab97..c19bba5c2 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/36] 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 2ac9eec57..a3dbbf422 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/36] 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 57a0af38a..0b64bb81e 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/36] 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 1689fcebf..eb91c48d7 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 c19bba5c2..d32216124 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' From e029b417d6d1fc76511dcca08314ce311b524c52 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Thu, 14 Aug 2025 17:56:44 +0800 Subject: [PATCH 21/36] update address-encoder --- packages/ensjs/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index ab2f0e987..7b80f5b3d 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -88,7 +88,7 @@ }, "dependencies": { "@adraffy/ens-normalize": "1.10.1", - "@ensdomains/address-encoder": "1.1.1", + "@ensdomains/address-encoder": "1.1.3", "@ensdomains/content-hash": "3.1.0-rc.1", "@ensdomains/dnsprovejs": "^0.5.1", "abitype": "^1.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2129486ae..e1476374a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,8 +66,8 @@ importers: specifier: 1.10.1 version: 1.10.1 '@ensdomains/address-encoder': - specifier: 1.1.1 - version: 1.1.1 + specifier: 1.1.3 + version: 1.1.3 '@ensdomains/content-hash': specifier: 3.1.0-rc.1 version: 3.1.0-rc.1 @@ -369,8 +369,8 @@ packages: '@ensdomains/address-encoder@1.0.0-rc.3': resolution: {integrity: sha512-8o6zH69rObIqDY4PusEWuN9jvVOct+9jj9AOPO7ifc3ev8nmsly0e8TE1sHkhk0iKFbd3DlSsUnJ+yuRWmdLCQ==} - '@ensdomains/address-encoder@1.1.1': - resolution: {integrity: sha512-yg7s+suCuKRhaGsgLu57W/jxIs/Lnqs/SU7jT7UwS4ATSnW94jbUCbmyyZ82CQwKsmwaUE8uYvvVb4N6lfz29A==} + '@ensdomains/address-encoder@1.1.3': + resolution: {integrity: sha512-QS4ax0YkA8tsbQcWgBNmLLtb3aG0jsOQtED9SRyX9Ixflt1jDMuC/0i3ONMnNJNG5HTIko0Te4Y1JIGXjNcnUg==} '@ensdomains/buffer@0.1.1': resolution: {integrity: sha512-92SfSiNS8XorgU7OUBHo/i1ZU7JV7iz/6bKuLPNVsMxV79/eI7fJR6jfJJc40zAHjs3ha+Xo965Idomlq3rqnw==} @@ -5323,7 +5323,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 - '@ensdomains/address-encoder@1.1.1': + '@ensdomains/address-encoder@1.1.3': dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 From b0d8ca3e686d63896e2107ce5c617b64f39169f8 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Thu, 14 Aug 2025 18:41:32 +0800 Subject: [PATCH 22/36] add verbosity to ci logs --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fa643dbd5..f11c63114 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: run: pnpm -F @ensdomains/ensjs build - name: Run tests - run: pnpm -F @ensdomains/ensjs tenv start --extra-time 11368000 + run: pnpm -F @ensdomains/ensjs tenv start --extra-time 11368000 --verbosity 1 lint: name: Lint runs-on: ubuntu-latest From 6e4327b9837902f5ecd2e8f1fe1b856ca3c344ac Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 18 Aug 2025 16:42:12 +0800 Subject: [PATCH 23/36] update the contracts --- .github/workflows/test.yml | 3 + CLAUDE.md | 75 ++++++++++++ packages/ensjs/.claude/settings.local.json | 15 +++ packages/ensjs/src/contracts/consts.ts | 16 ++- packages/ensjs/src/test/setup.ts | 20 ++++ packages/ensjs/vitest.config.ts | 1 + pnpm-lock.yaml | 133 +++++++++++++-------- 7 files changed, 211 insertions(+), 52 deletions(-) create mode 100644 CLAUDE.md create mode 100644 packages/ensjs/.claude/settings.local.json diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f11c63114..e18c2472b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,6 +25,9 @@ jobs: - name: Build ensjs run: pnpm -F @ensdomains/ensjs build + - name: Publish on pkg.pr.new + run: pnpm dlx pkg-pr-new publish './packages/ensjs' + - name: Run tests run: pnpm -F @ensdomains/ensjs tenv start --extra-time 11368000 --verbosity 1 lint: diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..702fd1bde --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,75 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Commands + +### Development +```bash +# Install dependencies (from root) +pnpm install + +# Build the main package +cd packages/ensjs && pnpm build + +# Run tests +cd packages/ensjs && pnpm test + +# Run tests in watch mode +cd packages/ensjs && pnpm test:watch + +# Run a single test file +cd packages/ensjs && pnpm test path/to/file.test.ts + +# Lint/format code (from root or package) +pnpm lint + +# Start test environment +cd packages/ensjs && pnpm tenv +``` + +### Publishing +```bash +# Version packages with changesets +pnpm chgset:version + +# Publish packages +pnpm release +``` + +## Architecture + +ENSjs v3 is a monorepo containing the core ENS JavaScript library built on top of viem. + +### Client Types +- **EnsPublicClient**: Read operations (getOwner, getResolver, getName, etc.) +- **EnsWalletClient**: Write operations (registerName, transferName, setRecords, etc.) +- **EnsSubgraphClient**: Subgraph queries for historical/aggregate data + +### Function Organization +``` +src/functions/ +├── public/ # Read functions (e.g., getAddressRecord, getTextRecord) +├── wallet/ # Write functions (e.g., setResolver, setRecords) +├── subgraph/ # Subgraph queries (e.g., getNamesForAddress) +└── dns/ # DNS-related functions +``` + +### Key Patterns +- All functions are designed to be batchable using viem's multicall +- Extensive use of TypeScript generics for type safety +- Custom error types in `/errors/` for detailed error handling +- Utility functions in `/utils/` for common operations like name normalization + +### Testing +- Uses Vitest with happy-dom environment +- Test files co-located with source (*.test.ts) +- ENS test environment available via `pnpm tenv` for integration testing +- Tests should not run in parallel due to shared blockchain state + +### Code Style +- Biome for linting and formatting (2 spaces, single quotes) +- TypeScript strict mode enabled +- No explicit `any` types (warning) +- No non-null assertions allowed +- Imports are automatically organized \ No newline at end of file diff --git a/packages/ensjs/.claude/settings.local.json b/packages/ensjs/.claude/settings.local.json new file mode 100644 index 000000000..ca797eca7 --- /dev/null +++ b/packages/ensjs/.claude/settings.local.json @@ -0,0 +1,15 @@ +{ + "permissions": { + "allow": [ + "Bash(node:*)", + "Bash(pnpm tenv start:*)", + "Bash(pnpm tenv:*)", + "Bash(pnpm -F @ensdomains/ensjs tenv start:*)", + "Bash(grep:*)", + "Bash(pnpm list:*)", + "Bash(pnpm add:*)", + "Bash(pnpm test:*)" + ], + "deny": [] + } +} \ No newline at end of file diff --git a/packages/ensjs/src/contracts/consts.ts b/packages/ensjs/src/contracts/consts.ts index e6ef5f6f6..4d3d2efe1 100644 --- a/packages/ensjs/src/contracts/consts.ts +++ b/packages/ensjs/src/contracts/consts.ts @@ -19,6 +19,7 @@ export const supportedContracts = [ 'ensRegistry', 'ensReverseRegistrar', 'ensUniversalResolver', + 'ensDefaultReverseRegistrar', ] as const export type SupportedChain = (typeof supportedChains)[number] @@ -54,7 +55,10 @@ export const addresses = { address: '0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb', }, ensUniversalResolver: { - address: '0x5a9236e72a66d3e08b83dcf489b4d850792b6009', + address: '0xaBd80E8a13596fEeA40Fd26fD6a24c3fe76F05fB', + }, + ensDefaultReverseRegistrar: { + address: '0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9', }, }, [holesky.id]: { @@ -88,6 +92,9 @@ export const addresses = { ensUniversalResolver: { address: '0xf606bc986635dab91b189aee8f565f45a0336f89', }, + ensDefaultReverseRegistrar: { + address: '0x0000000000000000000000000000000000000000', + }, }, [sepolia.id]: { ensBaseRegistrarImplementation: { @@ -115,10 +122,13 @@ export const addresses = { address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', }, ensReverseRegistrar: { - address: '0xCF75B92126B02C9811d8c632144288a3eb84afC8', + address: '0xA0a1AbcDAe1a2a4A2EF8e9113Ff0e02DD81DC0C6', }, ensUniversalResolver: { - address: '0x49c9331501b37191d54f5e332b307df82d15e9cc', + address: '0xb7B7DAdF4D42a08B3eC1d3A1079959Dfbc8CFfCC', + }, + ensDefaultReverseRegistrar: { + address: '0x4F382928805ba0e23B30cFB75fC9E848e82DFD47', }, }, } as const satisfies Record< diff --git a/packages/ensjs/src/test/setup.ts b/packages/ensjs/src/test/setup.ts index 3342ef1c4..3ac4cb1de 100644 --- a/packages/ensjs/src/test/setup.ts +++ b/packages/ensjs/src/test/setup.ts @@ -1,5 +1,25 @@ import { beforeAll, vi } from 'vitest' +// Mock localStorage for Node environment +const localStorageMock = (() => { + let store: Record = {} + return { + getItem: (key: string) => store[key] || null, + setItem: (key: string, value: string) => { + store[key] = value.toString() + }, + removeItem: (key: string) => { + delete store[key] + }, + clear: () => { + store = {} + }, + } +})() + +// @ts-ignore +global.localStorage = localStorageMock + beforeAll(() => { vi.mock('../errors/error-utils.ts', () => ({ getVersion: vi.fn().mockReturnValue('@ensdomains/ensjs@1.0.0-mock.0'), diff --git a/packages/ensjs/vitest.config.ts b/packages/ensjs/vitest.config.ts index 9ca54c28f..57422543f 100644 --- a/packages/ensjs/vitest.config.ts +++ b/packages/ensjs/vitest.config.ts @@ -11,5 +11,6 @@ export default defineConfig({ setupFiles: ['./src/test/setup.ts'], include: ['src/**/*.test.ts'], exclude: ['data/**/*'], + testTimeout: 10000, }, }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e1476374a..5fa722a48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,18 +7,9 @@ settings: overrides: '@nomiclabs/hardhat-ethers': npm:hardhat-deploy-ethers@0.3.0-beta.13 -patchedDependencies: - hardhat-deploy: - hash: c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61 - path: patches/hardhat-deploy.patch - importers: .: - dependenciesMeta: - ens-contracts: - built: false - unplugged: true devDependencies: '@biomejs/biome': specifier: ^1.9.4 @@ -35,6 +26,10 @@ importers: typescript: specifier: ^5.8.3 version: 5.8.3 + dependenciesMeta: + ens-contracts: + built: false + unplugged: true examples/basic-esm: dependencies: @@ -76,7 +71,7 @@ importers: version: 0.5.1 abitype: specifier: ^1.0.0 - version: 1.0.8(typescript@5.8.3)(zod@3.22.4) + version: 1.0.8 dns-packet: specifier: ^5.3.1 version: 5.6.1 @@ -104,13 +99,13 @@ importers: version: 1.0.1 '@ensdomains/hardhat-toolbox-viem-extended': specifier: ^0.0.5 - version: 0.0.5(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(hardhat-deploy@1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3) + version: 0.0.5(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(hardhat-deploy@1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10)) '@nomicfoundation/hardhat-toolbox-viem': specifier: ^3.0.0 - version: 3.0.0(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(@types/node@22.15.29)(chai@4.5.0)(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)) + version: 3.0.0(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/node@22.15.29)(chai@4.5.0)(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@22.15.29))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@nomicfoundation/hardhat-viem': specifier: 2.0.6 - version: 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + version: 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@openzeppelin/contracts': specifier: ^4.5.0 version: 4.9.6 @@ -143,13 +138,13 @@ importers: version: 13.10.1 hardhat: specifier: 2.24.1 - version: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + version: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) hardhat-abi-exporter: specifier: ^2.8.0 - version: 2.11.0(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) + version: 2.11.0(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10)) hardhat-deploy: specifier: ^1.0.2 - version: 1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) jsonfile: specifier: ^6.1.0 version: 6.1.0 @@ -161,16 +156,16 @@ importers: version: 0.8.30 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@22.15.29)(typescript@5.8.3) + version: 10.9.2(@types/node@22.15.29) typedoc: specifier: ^0.24.8 - version: 0.24.8(typescript@5.8.3) + version: 0.24.8 typedoc-plugin-markdown: specifier: ^4.0.0-next.16 - version: 4.6.4(typedoc@0.24.8(typescript@5.8.3)) + version: 4.6.4(typedoc@0.24.8) viem: specifier: ^2.30.6 - version: 2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + version: 2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10) vitest: specifier: ^1.3.1 version: 1.6.1(@types/node@22.15.29)(happy-dom@13.10.1) @@ -5388,12 +5383,11 @@ snapshots: - bufferutil - utf-8-validate - '@ensdomains/hardhat-toolbox-viem-extended@0.0.5(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(hardhat-deploy@1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)': + '@ensdomains/hardhat-toolbox-viem-extended@0.0.5(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(hardhat-deploy@1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))': dependencies: - '@nomicfoundation/hardhat-viem': 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) - hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) - hardhat-deploy: 1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10) - typescript: 5.8.3 + '@nomicfoundation/hardhat-viem': 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) + hardhat-deploy: 1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@ensdomains/resolver@0.2.4': {} @@ -6066,23 +6060,22 @@ snapshots: '@nomicfoundation/edr-linux-x64-musl': 0.11.0 '@nomicfoundation/edr-win32-x64-msvc': 0.11.0 - '@nomicfoundation/hardhat-toolbox-viem@3.0.0(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(@types/node@22.15.29)(chai@4.5.0)(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))': + '@nomicfoundation/hardhat-toolbox-viem@3.0.0(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/node@22.15.29)(chai@4.5.0)(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@22.15.29))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@nomicfoundation/hardhat-viem': 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + '@nomicfoundation/hardhat-viem': 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@types/node': 22.15.29 chai: 4.5.0 chai-as-promised: 7.1.2(chai@4.5.0) - hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) - ts-node: 10.9.2(@types/node@22.15.29)(typescript@5.8.3) - typescript: 5.8.3 - viem: 2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) + ts-node: 10.9.2(@types/node@22.15.29) + viem: 2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)': + '@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - abitype: 0.9.10(typescript@5.8.3)(zod@3.22.4) - hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + abitype: 0.9.10 + hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) lodash.memoize: 4.1.2 - viem: 2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - typescript - zod @@ -7335,10 +7328,9 @@ snapshots: '@walletconnect/window-getters': 1.0.1 tslib: 1.14.1 - abitype@0.9.10(typescript@5.8.3)(zod@3.22.4): - optionalDependencies: - typescript: 5.8.3 - zod: 3.22.4 + abitype@0.9.10: {} + + abitype@1.0.8: {} abitype@1.0.8(typescript@5.8.3)(zod@3.22.4): optionalDependencies: @@ -8816,13 +8808,13 @@ snapshots: ajv: 6.12.6 har-schema: 2.0.0 - hardhat-abi-exporter@2.11.0(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)): + hardhat-abi-exporter@2.11.0(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10)): dependencies: '@ethersproject/abi': 5.8.0 delete-empty: 3.0.0 - hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) - hardhat-deploy@1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10): + hardhat-deploy@1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/abstract-signer': 5.8.0 @@ -8853,7 +8845,7 @@ snapshots: - supports-color - utf-8-validate - hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10): + hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10): dependencies: '@ethereumjs/util': 9.1.0 '@ethersproject/abi': 5.8.0 @@ -8897,8 +8889,7 @@ snapshots: uuid: 8.3.2 ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - ts-node: 10.9.2(@types/node@22.15.29)(typescript@5.8.3) - typescript: 5.8.3 + ts-node: 10.9.2(@types/node@22.15.29) transitivePeerDependencies: - bufferutil - supports-color @@ -9652,6 +9643,19 @@ snapshots: transitivePeerDependencies: - zod + ox@0.7.1: + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8 + eventemitter3: 5.0.1 + transitivePeerDependencies: + - zod + ox@0.7.1(typescript@5.8.3)(zod@3.22.4): dependencies: '@adraffy/ens-normalize': 1.10.1 @@ -10560,6 +10564,23 @@ snapshots: tree-kill@1.2.2: {} + ts-node@10.9.2(@types/node@22.15.29): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.15.29 + acorn: 8.14.1 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -10611,17 +10632,16 @@ snapshots: dependencies: is-typedarray: 1.0.0 - typedoc-plugin-markdown@4.6.4(typedoc@0.24.8(typescript@5.8.3)): + typedoc-plugin-markdown@4.6.4(typedoc@0.24.8): dependencies: - typedoc: 0.24.8(typescript@5.8.3) + typedoc: 0.24.8 - typedoc@0.24.8(typescript@5.8.3): + typedoc@0.24.8: dependencies: lunr: 2.3.9 marked: 4.3.0 minimatch: 9.0.5 shiki: 0.14.7 - typescript: 5.8.3 typescript-logging@1.0.1: dependencies: @@ -10782,6 +10802,21 @@ snapshots: - utf-8-validate - zod + viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8 + isows: 1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.7.1 + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + vite-node@1.6.1(@types/node@22.15.29): dependencies: cac: 6.7.14 From e330e76ac7438857624083ec746cfe85f747b909 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 18 Aug 2025 16:45:20 +0800 Subject: [PATCH 24/36] Update pnpm-lock.yaml --- pnpm-lock.yaml | 133 ++++++++++++++++++------------------------------- 1 file changed, 49 insertions(+), 84 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5fa722a48..e1476374a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,9 +7,18 @@ settings: overrides: '@nomiclabs/hardhat-ethers': npm:hardhat-deploy-ethers@0.3.0-beta.13 +patchedDependencies: + hardhat-deploy: + hash: c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61 + path: patches/hardhat-deploy.patch + importers: .: + dependenciesMeta: + ens-contracts: + built: false + unplugged: true devDependencies: '@biomejs/biome': specifier: ^1.9.4 @@ -26,10 +35,6 @@ importers: typescript: specifier: ^5.8.3 version: 5.8.3 - dependenciesMeta: - ens-contracts: - built: false - unplugged: true examples/basic-esm: dependencies: @@ -71,7 +76,7 @@ importers: version: 0.5.1 abitype: specifier: ^1.0.0 - version: 1.0.8 + version: 1.0.8(typescript@5.8.3)(zod@3.22.4) dns-packet: specifier: ^5.3.1 version: 5.6.1 @@ -99,13 +104,13 @@ importers: version: 1.0.1 '@ensdomains/hardhat-toolbox-viem-extended': specifier: ^0.0.5 - version: 0.0.5(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(hardhat-deploy@1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10)) + version: 0.0.5(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(hardhat-deploy@1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3) '@nomicfoundation/hardhat-toolbox-viem': specifier: ^3.0.0 - version: 3.0.0(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/node@22.15.29)(chai@4.5.0)(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@22.15.29))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 3.0.0(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(@types/node@22.15.29)(chai@4.5.0)(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)) '@nomicfoundation/hardhat-viem': specifier: 2.0.6 - version: 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) '@openzeppelin/contracts': specifier: ^4.5.0 version: 4.9.6 @@ -138,13 +143,13 @@ importers: version: 13.10.1 hardhat: specifier: 2.24.1 - version: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) + version: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) hardhat-abi-exporter: specifier: ^2.8.0 - version: 2.11.0(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10)) + version: 2.11.0(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)) hardhat-deploy: specifier: ^1.0.2 - version: 1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10) jsonfile: specifier: ^6.1.0 version: 6.1.0 @@ -156,16 +161,16 @@ importers: version: 0.8.30 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@22.15.29) + version: 10.9.2(@types/node@22.15.29)(typescript@5.8.3) typedoc: specifier: ^0.24.8 - version: 0.24.8 + version: 0.24.8(typescript@5.8.3) typedoc-plugin-markdown: specifier: ^4.0.0-next.16 - version: 4.6.4(typedoc@0.24.8) + version: 4.6.4(typedoc@0.24.8(typescript@5.8.3)) viem: specifier: ^2.30.6 - version: 2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) vitest: specifier: ^1.3.1 version: 1.6.1(@types/node@22.15.29)(happy-dom@13.10.1) @@ -5383,11 +5388,12 @@ snapshots: - bufferutil - utf-8-validate - '@ensdomains/hardhat-toolbox-viem-extended@0.0.5(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(hardhat-deploy@1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))': + '@ensdomains/hardhat-toolbox-viem-extended@0.0.5(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(hardhat-deploy@1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)': dependencies: - '@nomicfoundation/hardhat-viem': 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) - hardhat-deploy: 1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@nomicfoundation/hardhat-viem': 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + hardhat-deploy: 1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + typescript: 5.8.3 '@ensdomains/resolver@0.2.4': {} @@ -6060,22 +6066,23 @@ snapshots: '@nomicfoundation/edr-linux-x64-musl': 0.11.0 '@nomicfoundation/edr-win32-x64-msvc': 0.11.0 - '@nomicfoundation/hardhat-toolbox-viem@3.0.0(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/node@22.15.29)(chai@4.5.0)(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@22.15.29))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-toolbox-viem@3.0.0(@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4))(@types/node@22.15.29)(chai@4.5.0)(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))': dependencies: - '@nomicfoundation/hardhat-viem': 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-viem': 2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) '@types/node': 22.15.29 chai: 4.5.0 chai-as-promised: 7.1.2(chai@4.5.0) - hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) - ts-node: 10.9.2(@types/node@22.15.29) - viem: 2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10) + hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) + ts-node: 10.9.2(@types/node@22.15.29)(typescript@5.8.3) + typescript: 5.8.3 + viem: 2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10))(viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@nomicfoundation/hardhat-viem@2.0.6(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10))(typescript@5.8.3)(viem@2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)': dependencies: - abitype: 0.9.10 - hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) + abitype: 0.9.10(typescript@5.8.3)(zod@3.22.4) + hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) lodash.memoize: 4.1.2 - viem: 2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10) + viem: 2.30.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) transitivePeerDependencies: - typescript - zod @@ -7328,9 +7335,10 @@ snapshots: '@walletconnect/window-getters': 1.0.1 tslib: 1.14.1 - abitype@0.9.10: {} - - abitype@1.0.8: {} + abitype@0.9.10(typescript@5.8.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.8.3 + zod: 3.22.4 abitype@1.0.8(typescript@5.8.3)(zod@3.22.4): optionalDependencies: @@ -8808,13 +8816,13 @@ snapshots: ajv: 6.12.6 har-schema: 2.0.0 - hardhat-abi-exporter@2.11.0(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10)): + hardhat-abi-exporter@2.11.0(hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10)): dependencies: '@ethersproject/abi': 5.8.0 delete-empty: 3.0.0 - hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10) + hardhat: 2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10) - hardhat-deploy@1.0.2(bufferutil@4.0.9)(utf-8-validate@5.0.10): + hardhat-deploy@1.0.2(patch_hash=c9b002689c306ba5344f19cacaf42b412c5f9ed46771e6667640e123ae4dcd61)(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/abstract-signer': 5.8.0 @@ -8845,7 +8853,7 @@ snapshots: - supports-color - utf-8-validate - hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29))(utf-8-validate@5.0.10): + hardhat@2.24.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3))(typescript@5.8.3)(utf-8-validate@5.0.10): dependencies: '@ethereumjs/util': 9.1.0 '@ethersproject/abi': 5.8.0 @@ -8889,7 +8897,8 @@ snapshots: uuid: 8.3.2 ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - ts-node: 10.9.2(@types/node@22.15.29) + ts-node: 10.9.2(@types/node@22.15.29)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - bufferutil - supports-color @@ -9643,19 +9652,6 @@ snapshots: transitivePeerDependencies: - zod - ox@0.7.1: - dependencies: - '@adraffy/ens-normalize': 1.10.1 - '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.1 - '@noble/hashes': 1.8.0 - '@scure/bip32': 1.7.0 - '@scure/bip39': 1.6.0 - abitype: 1.0.8 - eventemitter3: 5.0.1 - transitivePeerDependencies: - - zod - ox@0.7.1(typescript@5.8.3)(zod@3.22.4): dependencies: '@adraffy/ens-normalize': 1.10.1 @@ -10564,23 +10560,6 @@ snapshots: tree-kill@1.2.2: {} - ts-node@10.9.2(@types/node@22.15.29): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 22.15.29 - acorn: 8.14.1 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - ts-node@10.9.2(@types/node@22.15.29)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -10632,16 +10611,17 @@ snapshots: dependencies: is-typedarray: 1.0.0 - typedoc-plugin-markdown@4.6.4(typedoc@0.24.8): + typedoc-plugin-markdown@4.6.4(typedoc@0.24.8(typescript@5.8.3)): dependencies: - typedoc: 0.24.8 + typedoc: 0.24.8(typescript@5.8.3) - typedoc@0.24.8: + typedoc@0.24.8(typescript@5.8.3): dependencies: lunr: 2.3.9 marked: 4.3.0 minimatch: 9.0.5 shiki: 0.14.7 + typescript: 5.8.3 typescript-logging@1.0.1: dependencies: @@ -10802,21 +10782,6 @@ snapshots: - utf-8-validate - zod - viem@2.30.6(bufferutil@4.0.9)(utf-8-validate@5.0.10): - dependencies: - '@noble/curves': 1.9.1 - '@noble/hashes': 1.8.0 - '@scure/bip32': 1.7.0 - '@scure/bip39': 1.6.0 - abitype: 1.0.8 - isows: 1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.7.1 - ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - zod - vite-node@1.6.1(@types/node@22.15.29): dependencies: cac: 6.7.14 From ceb259b069116a4757d68b5a4dfe26a25805a4bb Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 18 Aug 2025 17:35:28 +0800 Subject: [PATCH 25/36] Update prepack.ts --- packages/ensjs/scripts/prepack.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/ensjs/scripts/prepack.ts b/packages/ensjs/scripts/prepack.ts index 42249cbc1..a79b69fc9 100644 --- a/packages/ensjs/scripts/prepack.ts +++ b/packages/ensjs/scripts/prepack.ts @@ -2,16 +2,20 @@ import fs from 'node:fs' import path from 'node:path' +import { fileURLToPath } from 'node:url' /* eslint-disable no-continue */ import jsonFs from 'jsonfile' +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + type Exports = { [key: string]: string | { types?: string; import: string; default: string } } // Generates a package.json to be published to NPM with only the necessary fields. function generatePackageJson() { - const packageJsonPath = path.join(import.meta.dirname, '../package.json') + const packageJsonPath = path.join(__dirname, '../package.json') const tmpPackageJson = jsonFs.readFileSync(packageJsonPath) jsonFs.writeFileSync(`${packageJsonPath}.tmp`, tmpPackageJson, { spaces: 2 }) @@ -42,10 +46,11 @@ function generatePackageJson() { // Generate proxy packages for each export. const files_ = [...files] for (const [key, value] of Object.entries(exports_ as Exports)) { + console.log(key, value) if (typeof value === 'string') continue if (key === '.') continue - if (!value.default || !value.import) - throw new Error('`default` and `import` are required.') + if (!value.default) + throw new Error('`default` is required.') if (!fs.existsSync(key)) fs.mkdirSync(key) if (!fs.existsSync(`${key}/package.json`)) fs.writeFileSync( @@ -57,7 +62,7 @@ function generatePackageJson() { if (k === 'import') return 'module' if (k === 'default') return 'main' if (k === 'types') return 'types' - throw new Error('Invalid key') + return k // Allow other keys to pass through })() return `"${key_}": "${v.replace('./', '../')}"` }) From cb6c6db8b1c76b53f2e571a2e31125d338a17fc4 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 18 Aug 2025 17:41:46 +0800 Subject: [PATCH 26/36] update prepack command --- packages/ensjs/.claude/settings.local.json | 3 ++- packages/ensjs/package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/ensjs/.claude/settings.local.json b/packages/ensjs/.claude/settings.local.json index ca797eca7..5fa201833 100644 --- a/packages/ensjs/.claude/settings.local.json +++ b/packages/ensjs/.claude/settings.local.json @@ -8,7 +8,8 @@ "Bash(grep:*)", "Bash(pnpm list:*)", "Bash(pnpm add:*)", - "Bash(pnpm test:*)" + "Bash(pnpm test:*)", + "Bash(pnpm prepack:*)" ], "deny": [] } diff --git a/packages/ensjs/package.json b/packages/ensjs/package.json index 7b80f5b3d..e24e381ed 100644 --- a/packages/ensjs/package.json +++ b/packages/ensjs/package.json @@ -78,7 +78,7 @@ "clean": "rm -rf ./dist ./README.md ./LICENSE", "lint": "eslint ./src/* --no-error-on-unmatched-pattern", "build": "tsc --project tsconfig.build.json", - "tsn": "TS_NODE_PROJECT=tsconfig.node.json node --loader ts-node/esm", + "tsn": "node --loader ts-node/esm", "prepublish": "pnpm build && cp ../../README.md ../../LICENSE ./", "prepack": "pnpm tsn ./scripts/prepack.ts", "ver": "pnpm tsn ./scripts/updateVersion.ts", From 2c017c07d5a4ef6d8ddcc3ad4d26b85c66df70b5 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 18 Aug 2025 20:30:41 +0800 Subject: [PATCH 27/36] Update test.yml --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e18c2472b..434a848de 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,11 +25,11 @@ jobs: - name: Build ensjs run: pnpm -F @ensdomains/ensjs build - - name: Publish on pkg.pr.new - run: pnpm dlx pkg-pr-new publish './packages/ensjs' - - name: Run tests run: pnpm -F @ensdomains/ensjs tenv start --extra-time 11368000 --verbosity 1 + + - name: Publish on pkg.pr.new + run: pnpm dlx pkg-pr-new publish './packages/ensjs' lint: name: Lint runs-on: ubuntu-latest From edbdd4190515f35546945fd30cb33d714908c17e Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Mon, 18 Aug 2025 21:10:01 +0800 Subject: [PATCH 28/36] Revert "Merge branch 'main' into add-register-commit-without-namewrapper" This reverts commit 68e66ad03dd214e47fa1adadaa8f9627692ae586, reversing changes made to 5397a10edeca1f6ed1b87230daf47a8e457833bf. --- .changeset/config.json | 19 +- .devcontainer/devcontainer.json | 5 +- .eslintrc.json | 21 + .github/workflows/publish.yml | 2 +- .github/workflows/test.yml | 17 +- .npmrc | 3 +- .nvmrc | 1 + .prettierrc.json | 9 + .vscode/extensions.json | 6 +- .vscode/settings.json | 19 +- biome.json | 58 - docs/basics/custom-subgraph-uris.md | 18 +- docs/wallet/function.setContentHashRecord.md | 2 +- examples/basic-esm/package.json | 2 +- examples/basic-esm/src/index.js | 12 +- examples/basic-tsnode-esm/package.json | 2 +- examples/basic-tsnode-esm/src/index.ts | 10 +- examples/basic-tsnode-esm/tsconfig.json | 16 +- package.json | 18 +- packages/ens-test-env/.gitignore | 1 + packages/ens-test-env/README.md | 140 + packages/ens-test-env/package.json | 32 + packages/ens-test-env/src/config.d.ts | 19 + packages/ens-test-env/src/docker-compose.yml | 63 + .../src/ens-test-env.example.config.js | 28 + packages/ens-test-env/src/fetch-data.js | 150 + packages/ens-test-env/src/index.d.ts | 1 + packages/ens-test-env/src/index.js | 139 + packages/ens-test-env/src/manager.js | 424 + packages/ens-test-env/src/subgraph.js | 40 + packages/ens-test-env/tsconfig.json | 3 + packages/ensjs/.eslintrc.json | 49 + packages/ensjs/archive.tar.lz4 | Bin 0 -> 11790996 bytes .../ensjs/contracts/NoMulticallResolver.json | 684 - packages/ensjs/contracts/OldResolver.json | 404 +- packages/ensjs/contracts/OldestResolver.json | 170 + packages/ensjs/deploy/.eslintrc.json | 6 + .../ensjs/deploy/00_deploy_bulk_renewal.cjs | 101 + .../ensjs/deploy/00_deploy_bulk_renewal.ts | 98 - ...y_multicall.ts => 00_deploy_multicall.cjs} | 21 +- packages/ensjs/deploy/00_legacy_registry.cjs | 59 + packages/ensjs/deploy/00_legacy_registry.ts | 54 - ...rently.ts => 00_register_concurrently.cjs} | 104 +- ...ister_legacy.ts => 00_register_legacy.cjs} | 169 +- ...ter_wrapped.ts => 00_register_wrapped.cjs} | 79 +- packages/ensjs/deploy/01_delete_names.cjs | 73 + packages/ensjs/deploy/01_delete_names.ts | 63 - .../ensjs/deploy/01_set_legacy_resolver.cjs | 69 + .../ensjs/deploy/01_set_legacy_resolver.ts | 66 - .../ensjs/deploy/01_set_oldest_resolver.cjs | 69 + .../ensjs/deploy/01_set_oldest_resolver.ts | 64 - packages/ensjs/deploy/01_set_primary.cjs | 39 + packages/ensjs/deploy/01_set_primary.ts | 32 - .../deploy/02_get_contract_addresses.cjs | 29 + .../ensjs/deploy/02_get_contract_addresses.ts | 27 - ...-env.config.js => ens-test-env.config.cjs} | 10 +- ...{hardhat.config.cts => hardhat.config.cjs} | 61 +- packages/ensjs/package.json | 101 +- packages/ensjs/scripts/generateDocs.ts | 3 + packages/ensjs/scripts/prepack.ts | 9 +- packages/ensjs/scripts/rcBranchVersion.ts | 13 +- packages/ensjs/scripts/updateVersion.ts | 12 +- .../ensjs/src/@types/dns-packet/types.d.ts | 1 - packages/ensjs/src/@types/pako.d.ts | 1 + packages/ensjs/src/clients/public.ts | 6 +- packages/ensjs/src/clients/subgraph.ts | 4 +- packages/ensjs/src/clients/wallet.ts | 4 +- .../ensjs/src/contracts/addEnsContracts.ts | 4 +- packages/ensjs/src/contracts/consts.ts | 58 +- packages/ensjs/src/contracts/index.ts | 1 + packages/ensjs/src/contracts/multicall.ts | 20 - packages/ensjs/src/contracts/nameWrapper.ts | 2 +- .../ensjs/src/contracts/universalResolver.ts | 180 +- packages/ensjs/src/errors/base.ts | 4 +- packages/ensjs/src/errors/utils.ts | 4 +- .../src/functions/dns/getDnsImportData.ts | 5 +- .../functions/dns/getDnsOffchainData.test.ts | 6 +- .../src/functions/dns/getDnsOffchainData.ts | 4 +- .../src/functions/dns/getDnsOwner.test.ts | 18 +- .../ensjs/src/functions/dns/getDnsOwner.ts | 2 +- .../src/functions/dns/importDnsName.test.ts | 2 +- .../ensjs/src/functions/dns/importDnsName.ts | 4 +- .../src/functions/public/_getAbi.test.ts | 7 +- .../ensjs/src/functions/public/_getAbi.ts | 2 +- .../src/functions/public/_getAddr.test.ts | 7 +- .../ensjs/src/functions/public/_getAddr.ts | 2 +- .../functions/public/_getContentHash.test.ts | 2 +- .../src/functions/public/_getContentHash.ts | 4 +- .../src/functions/public/_getText.test.ts | 7 +- .../ensjs/src/functions/public/_getText.ts | 2 +- .../ensjs/src/functions/public/batch.test.ts | 2 +- packages/ensjs/src/functions/public/batch.ts | 2 +- .../ensjs/src/functions/public/ccip.test.ts | 2 +- .../src/functions/public/getAbiRecord.test.ts | 21 +- .../src/functions/public/getAbiRecord.ts | 2 +- .../functions/public/getAddressRecord.test.ts | 29 +- .../src/functions/public/getAddressRecord.ts | 2 +- .../src/functions/public/getAvailable.ts | 6 +- .../public/getContentHashRecord.test.ts | 21 +- .../functions/public/getContentHashRecord.ts | 2 +- .../ensjs/src/functions/public/getExpiry.ts | 8 +- .../src/functions/public/getName.test.ts | 56 +- .../ensjs/src/functions/public/getName.ts | 91 +- .../ensjs/src/functions/public/getOwner.ts | 20 +- .../ensjs/src/functions/public/getPrice.ts | 6 +- .../src/functions/public/getRecords.test.ts | 20 +- .../ensjs/src/functions/public/getRecords.ts | 44 +- .../ensjs/src/functions/public/getResolver.ts | 8 +- .../public/getSupportedInterfaces.ts | 6 +- .../functions/public/getTextRecord.test.ts | 21 +- .../src/functions/public/getTextRecord.ts | 2 +- .../src/functions/public/getWrapperData.ts | 10 +- .../src/functions/public/getWrapperName.ts | 6 +- .../src/functions/public/multicallWrapper.ts | 4 +- .../functions/public/universalWrapper.test.ts | 52 +- .../src/functions/public/universalWrapper.ts | 8 +- .../src/functions/subgraph/client.test.ts | 2 + .../ensjs/src/functions/subgraph/client.ts | 3 +- .../ensjs/src/functions/subgraph/filters.ts | 20 +- .../src/functions/subgraph/getDecodedName.ts | 6 +- .../src/functions/subgraph/getNameHistory.ts | 2 +- .../subgraph/getNamesForAddress.test.ts | 14 +- .../functions/subgraph/getNamesForAddress.ts | 6 +- .../functions/subgraph/getSubgraphRecords.ts | 2 +- .../subgraph/getSubgraphRegistrant.ts | 2 +- .../functions/subgraph/getSubnames.test.ts | 8 +- .../src/functions/subgraph/getSubnames.ts | 6 +- .../ensjs/src/functions/subgraph/utils.ts | 16 +- .../src/functions/wallet/commitName.test.ts | 2 +- .../ensjs/src/functions/wallet/commitName.ts | 4 +- .../functions/wallet/createSubname.test.ts | 2 +- .../src/functions/wallet/createSubname.ts | 10 +- .../src/functions/wallet/deleteSubname.ts | 2 +- .../src/functions/wallet/registerName.ts | 4 +- .../src/functions/wallet/renewNames.test.ts | 2 +- .../ensjs/src/functions/wallet/renewNames.ts | 2 +- .../src/functions/wallet/setAbiRecord.test.ts | 2 +- .../src/functions/wallet/setAbiRecord.ts | 2 +- .../src/functions/wallet/setChildFuses.ts | 6 +- .../ensjs/src/functions/wallet/setFuses.ts | 4 +- .../src/functions/wallet/setPrimaryName.ts | 2 +- .../ensjs/src/functions/wallet/setRecords.ts | 4 +- .../ensjs/src/functions/wallet/setResolver.ts | 2 +- .../src/functions/wallet/transferName.ts | 4 +- .../ensjs/src/functions/wallet/unwrapName.ts | 2 +- .../ensjs/src/functions/wallet/wrapName.ts | 10 +- packages/ensjs/src/test/addTestContracts.ts | 14 +- packages/ensjs/src/test/createHttpServer.ts | 4 +- packages/ensjs/src/test/dns.ts | 3 +- packages/ensjs/src/types.ts | 12 +- .../ensjs/src/utils/ccipBatchRequest.test.ts | 24 +- packages/ensjs/src/utils/ccipBatchRequest.ts | 4 +- packages/ensjs/src/utils/ccipRequest.test.ts | 3 +- packages/ensjs/src/utils/ccipRequest.ts | 4 +- .../checkSafeUniversalResolverData.test.ts | 40 +- .../utils/checkSafeUniversalResolverData.ts | 6 +- packages/ensjs/src/utils/contentHash.ts | 4 +- .../ensjs/src/utils/dns/getDnsTxtRecords.ts | 2 +- .../ensjs/src/utils/encoders/encodeAbi.ts | 2 +- .../src/utils/encoders/encodeClearRecords.ts | 2 +- .../src/utils/encoders/encodeSetAbi.test.ts | 2 +- .../ensjs/src/utils/encoders/encodeSetAbi.ts | 2 +- .../src/utils/encoders/encodeSetAddr.test.ts | 2 +- .../ensjs/src/utils/encoders/encodeSetAddr.ts | 2 +- .../encoders/encodeSetContentHash.test.ts | 7 +- .../utils/encoders/encodeSetContentHash.ts | 2 +- .../src/utils/encoders/encodeSetText.test.ts | 2 +- .../ensjs/src/utils/encoders/encodeSetText.ts | 2 +- packages/ensjs/src/utils/fuses.test.ts | 15 +- packages/ensjs/src/utils/fuses.ts | 5 +- packages/ensjs/src/utils/generateFunction.ts | 4 +- .../src/utils/generateRecordCallArray.test.ts | 2 +- .../src/utils/generateRecordCallArray.ts | 8 +- .../utils/generateSupportedContentTypes.ts | 1 - .../ensjs/src/utils/getRevertErrorData.ts | 2 +- packages/ensjs/src/utils/hexEncodedName.ts | 2 +- packages/ensjs/src/utils/labels.ts | 2 +- packages/ensjs/src/utils/normalise.ts | 27 +- packages/ensjs/src/utils/normaliseCoinId.ts | 6 +- .../ensjs/src/utils/ownerFromContract.test.ts | 15 +- packages/ensjs/src/utils/ownerFromContract.ts | 2 +- .../ensjs/src/utils/registerHelpers.test.ts | 7 +- packages/ensjs/src/utils/registerHelpers.ts | 12 +- packages/ensjs/src/utils/validation.test.ts | 7 +- packages/ensjs/src/utils/validation.ts | 2 +- packages/ensjs/src/utils/wrapper.test.ts | 7 +- packages/ensjs/tsconfig.base.json | 45 + packages/ensjs/tsconfig.build.json | 26 +- packages/ensjs/tsconfig.json | 32 +- packages/ensjs/tsconfig.node.json | 11 + packages/ensjs/utils/legacyNameGenerator.cjs | 73 + packages/ensjs/utils/legacyNameGenerator.ts | 101 - packages/ensjs/utils/nonceManager.cjs | 26 + packages/ensjs/utils/nonceManager.ts | 30 - packages/ensjs/utils/wrappedNameGenerator.cjs | 101 + packages/ensjs/utils/wrappedNameGenerator.ts | 118 - packages/react/.eslintrc.json | 49 + packages/react/package.json | 26 +- packages/react/src/hooks/useDecodedName.ts | 4 +- packages/react/src/hooks/useEnsAvailable.ts | 4 +- packages/react/src/hooks/useEnsCredentials.ts | 2 +- packages/react/src/hooks/useEnsExpiry.ts | 4 +- .../src/hooks/useEnsResolverInterfaces.ts | 6 +- .../react/src/hooks/useNamesForAddress.ts | 6 +- packages/react/src/hooks/useQuery.ts | 4 +- packages/react/tsconfig.base.json | 46 + packages/react/tsconfig.build.json | 17 +- packages/react/tsconfig.json | 17 + packages/react/tsconfig.node.json | 11 + patches/hardhat-deploy.patch | 13 - pnpm-lock.yaml | 17239 +++++++++++----- pnpm-workspace.yaml | 6 +- tsconfig.json | 190 +- 213 files changed, 15206 insertions(+), 8257 deletions(-) create mode 100644 .eslintrc.json create mode 100644 .nvmrc create mode 100644 .prettierrc.json delete mode 100644 biome.json create mode 100644 packages/ens-test-env/.gitignore create mode 100644 packages/ens-test-env/README.md create mode 100644 packages/ens-test-env/package.json create mode 100644 packages/ens-test-env/src/config.d.ts create mode 100644 packages/ens-test-env/src/docker-compose.yml create mode 100644 packages/ens-test-env/src/ens-test-env.example.config.js create mode 100644 packages/ens-test-env/src/fetch-data.js create mode 100644 packages/ens-test-env/src/index.d.ts create mode 100755 packages/ens-test-env/src/index.js create mode 100644 packages/ens-test-env/src/manager.js create mode 100644 packages/ens-test-env/src/subgraph.js create mode 100644 packages/ens-test-env/tsconfig.json create mode 100644 packages/ensjs/.eslintrc.json create mode 100644 packages/ensjs/archive.tar.lz4 delete mode 100644 packages/ensjs/contracts/NoMulticallResolver.json create mode 100644 packages/ensjs/contracts/OldestResolver.json create mode 100644 packages/ensjs/deploy/.eslintrc.json create mode 100644 packages/ensjs/deploy/00_deploy_bulk_renewal.cjs delete mode 100644 packages/ensjs/deploy/00_deploy_bulk_renewal.ts rename packages/ensjs/deploy/{00_deploy_multicall.ts => 00_deploy_multicall.cjs} (66%) create mode 100644 packages/ensjs/deploy/00_legacy_registry.cjs delete mode 100644 packages/ensjs/deploy/00_legacy_registry.ts rename packages/ensjs/deploy/{00_register_concurrently.ts => 00_register_concurrently.cjs} (67%) rename packages/ensjs/deploy/{00_register_legacy.ts => 00_register_legacy.cjs} (75%) rename packages/ensjs/deploy/{00_register_wrapped.ts => 00_register_wrapped.cjs} (72%) create mode 100644 packages/ensjs/deploy/01_delete_names.cjs delete mode 100644 packages/ensjs/deploy/01_delete_names.ts create mode 100644 packages/ensjs/deploy/01_set_legacy_resolver.cjs delete mode 100644 packages/ensjs/deploy/01_set_legacy_resolver.ts create mode 100644 packages/ensjs/deploy/01_set_oldest_resolver.cjs delete mode 100644 packages/ensjs/deploy/01_set_oldest_resolver.ts create mode 100644 packages/ensjs/deploy/01_set_primary.cjs delete mode 100644 packages/ensjs/deploy/01_set_primary.ts create mode 100644 packages/ensjs/deploy/02_get_contract_addresses.cjs delete mode 100644 packages/ensjs/deploy/02_get_contract_addresses.ts rename packages/ensjs/{ens-test-env.config.js => ens-test-env.config.cjs} (79%) rename packages/ensjs/{hardhat.config.cts => hardhat.config.cjs} (54%) create mode 100644 packages/ensjs/tsconfig.base.json create mode 100644 packages/ensjs/tsconfig.node.json create mode 100644 packages/ensjs/utils/legacyNameGenerator.cjs delete mode 100644 packages/ensjs/utils/legacyNameGenerator.ts create mode 100644 packages/ensjs/utils/nonceManager.cjs delete mode 100644 packages/ensjs/utils/nonceManager.ts create mode 100644 packages/ensjs/utils/wrappedNameGenerator.cjs delete mode 100644 packages/ensjs/utils/wrappedNameGenerator.ts create mode 100644 packages/react/.eslintrc.json create mode 100644 packages/react/tsconfig.base.json create mode 100644 packages/react/tsconfig.json create mode 100644 packages/react/tsconfig.node.json delete mode 100644 patches/hardhat-deploy.patch diff --git a/.changeset/config.json b/.changeset/config.json index 8a2b8e1e0..1e4f34ef2 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,13 +1,10 @@ { - "$schema": "https://unpkg.com/@changesets/config@3.0.3/schema.json", - "changelog": [ - "@changesets/changelog-github", - { "repo": "ensdomains/ensjs-v3" } - ], - "commit": false, - "fixed": [], - "linked": [], - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch" + "$schema": "https://unpkg.com/@changesets/config@3.0.3/schema.json", + "changelog": ["@changesets/changelog-github", { "repo": "ensdomains/ensjs-v3" }], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch" } diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3f6587098..ad93c14a0 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,4 +1,5 @@ { - "image": "mcr.microsoft.com/devcontainers/universal:2", - "features": {} + "image": "mcr.microsoft.com/devcontainers/universal:2", + "features": { + } } diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..4deab4548 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,21 @@ +{ + "root": true, + "extends": [ + "airbnb-base", + "airbnb-typescript/base", + "prettier", + "plugin:prettier/recommended" + ], + "plugins": ["@typescript-eslint", "prettier"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "./tsconfig.json" + }, + "rules": { + "no-console": "off", + "prettier/prettier": "error", + "import/prefer-default-export": "off", + "import/extensions": ["off"], + "max-classes-per-file": "off" + } +} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 71dc9e1e0..7d5af147b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/setup-node@v4 with: cache: 'pnpm' - node-version: 22 + node-version: 18 registry-url: 'https://registry.npmjs.org' - name: Install dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fa643dbd5..3d4c149ab 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,23 +8,22 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [22] + node-version: [18] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 + with: + version: 9.4.0 - name: Install Node.js uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - cache: "pnpm" + cache: 'pnpm' - run: pnpm install --frozen-lockfile - - name: Build ensjs - run: pnpm -F @ensdomains/ensjs build - - name: Run tests run: pnpm -F @ensdomains/ensjs tenv start --extra-time 11368000 lint: @@ -34,17 +33,19 @@ jobs: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 + with: + version: 9.4.0 - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: 22 - cache: "pnpm" + node-version: 18 + cache: 'pnpm' - run: pnpm install --frozen-lockfile - name: Lint - run: pnpm lint + run: pnpm -F @ensdomains/ensjs lint - name: Type check run: pnpm -F @ensdomains/ensjs build diff --git a/.npmrc b/.npmrc index 1e31ea269..ca6dc53a8 100644 --- a/.npmrc +++ b/.npmrc @@ -1,4 +1,3 @@ strict-peer-dependencies=false link-workspace-packages=deep -provenance=true -auto-install-peers=false \ No newline at end of file +provenance=true \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..a58d2d2c2 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18.18.2 \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..0f5943609 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,9 @@ +{ + "arrowParens": "always", + "endOfLine": "lf", + "printWidth": 80, + "semi": false, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "all" + } \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 85cba8b79..daaa5ee2e 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,7 @@ { - "recommendations": ["arcanis.vscode-zipfs", "biomejs.biome"] + "recommendations": [ + "arcanis.vscode-zipfs", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode" + ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 91e18d617..a220d6f03 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,14 +1,9 @@ { - "npm.packageManager": "pnpm", - "editor.formatOnSave": true, - "biome.enabled": true, - "eslint.enable": false, - "prettier.enable": false, - "[typescript]": { - "editor.defaultFormatter": "biomejs.biome" - }, - "editor.codeActionsOnSave": { - "source.organizeImports.biome": "explicit", - "quickfix.biome": "explicit" - } + "prettier.enable": true, + "eslint.enable": true, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true } diff --git a/biome.json b/biome.json deleted file mode 100644 index c29ff8f03..000000000 --- a/biome.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "files": { - "ignore": [ - "node_modules", - "package.json", - "dist", - "coverage", - "data", - "cache", - "tsconfig.*.json", - "packages/ensjs/contracts" - ] - }, - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "complexity": { - "noForEach": "off", - "noBannedTypes": "warn" - }, - "style": { - "noNonNullAssertion": "off" - }, - "correctness": { - "noUnusedImports": "error", - "noUnusedVariables": "error", - "noUnusedPrivateClassMembers": "error" - }, - "performance": { - "noAccumulatingSpread": "off" - }, - "suspicious": { - "noAssignInExpressions": "off", - "noExplicitAny": "warn" - } - } - }, - "formatter": { - "enabled": true - }, - "javascript": { - "formatter": { - "enabled": true, - "semicolons": "asNeeded", - "quoteStyle": "single", - "indentWidth": 2, - "indentStyle": "space" - }, - "linter": { - "enabled": true - } - } -} diff --git a/docs/basics/custom-subgraph-uris.md b/docs/basics/custom-subgraph-uris.md index 9da3cfaca..e2996e130 100644 --- a/docs/basics/custom-subgraph-uris.md +++ b/docs/basics/custom-subgraph-uris.md @@ -4,26 +4,26 @@ If you want to use a custom subgraph endpoint for the chain you are using, such Keep in mind though that you can only use custom URIs if not using the default exported ENS clients. ```ts -import { http, createClient } from "viem"; -import { mainnet } from "viem/chains"; -import { addEnsContracts } from "@ensdomains/ensjs"; -import { getSubgraphRecords } from "@ensdomains/ensjs/subgraph"; +import { http, createClient } from 'viem' +import { mainnet } from 'viem/chains' +import { addEnsContracts } from '@ensdomains/ensjs' +import { getSubgraphRecords } from '@ensdomains/ensjs/subgraph' -const mainnetWithEns = addEnsContracts(mainnet); +const mainnetWithEns = addEnsContracts(mainnet) const chain = { ...mainnetWithEns, subgraphs: { ens: { - url: "http://localhost:42069/subgraph", + url: 'http://localhost:8000/subgraphs/name/ensdomains/ens', }, }, -}; +} const client = createClient({ chain, transport: http(), -}); +}) -const subgraphRecords = await getSubgraphRecords(client, { name: "ens.eth" }); +const subgraphRecords = await getSubgraphRecords(client, { name: 'ens.eth' }) ``` diff --git a/docs/wallet/function.setContentHashRecord.md b/docs/wallet/function.setContentHashRecord.md index 26046f36a..c34e0b1ae 100644 --- a/docs/wallet/function.setContentHashRecord.md +++ b/docs/wallet/function.setContentHashRecord.md @@ -24,7 +24,7 @@ const wallet = createWalletClient({ }) const hash = await setContentHashRecord(wallet, { name: 'ens.eth', - contentHash: + value: 'ipns://k51qzi5uqu5djdczd6zw0grmo23j2vkj9uzvujencg15s5rlkq0ss4ivll8wqw', resolverAddress: '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41', }) diff --git a/examples/basic-esm/package.json b/examples/basic-esm/package.json index 9ee083d4e..a40a12c44 100644 --- a/examples/basic-esm/package.json +++ b/examples/basic-esm/package.json @@ -8,6 +8,6 @@ }, "dependencies": { "@ensdomains/ensjs": "workspace:*", - "viem": "^2.30.6" + "viem": "^1.2.9" } } diff --git a/examples/basic-esm/src/index.js b/examples/basic-esm/src/index.js index aa1d89877..dd82f4e64 100644 --- a/examples/basic-esm/src/index.js +++ b/examples/basic-esm/src/index.js @@ -5,17 +5,19 @@ import { mainnet } from 'viem/chains' const client = createEnsPublicClient({ chain: mainnet, - transport: http('https://web3.euc.li/v1/mainnet'), + transport: http('https://web3.ens.domains/v1/mainnet'), }) const main = async () => { const records = await client.getSubgraphRecords({ name: 'ens.eth' }) const recordData = await client.getRecords({ name: 'ens.eth', - coins: [...(records?.coins || []), 'BTC', 'ETH', 'ETC', 'SOL'], - texts: [...(records?.texts || []), 'avatar', 'email', 'description'], - contentHash: true, - abi: true, + records: { + coins: [...(records?.coins || []), 'BTC', 'ETH', 'ETC', 'SOL'], + texts: [...(records?.texts || []), 'avatar', 'email', 'description'], + contentHash: true, + abi: true, + }, }) console.log(recordData) diff --git a/examples/basic-tsnode-esm/package.json b/examples/basic-tsnode-esm/package.json index b97f2c981..9e40a7dee 100644 --- a/examples/basic-tsnode-esm/package.json +++ b/examples/basic-tsnode-esm/package.json @@ -10,6 +10,6 @@ "@ensdomains/ensjs": "workspace:*", "ts-node": "^10.9.2", "typescript": "^5.6.2", - "viem": "^2.30.6" + "viem": "^2.21.9" } } diff --git a/examples/basic-tsnode-esm/src/index.ts b/examples/basic-tsnode-esm/src/index.ts index 6b3fb4263..57f919a0f 100644 --- a/examples/basic-tsnode-esm/src/index.ts +++ b/examples/basic-tsnode-esm/src/index.ts @@ -5,16 +5,18 @@ import { mainnet } from 'viem/chains' const client = createEnsPublicClient({ chain: mainnet, - transport: http('https://web3.euc.li/v1/mainnet'), + transport: http('https://web3.ens.domains/v1/mainnet'), }) const main = async () => { const records = await client.getSubgraphRecords({ name: 'ens.eth' }) const recordData = await client.getRecords({ name: 'ens.eth', - abi: true, - contentHash: true, - ...records, + records: { + abi: true, + contentHash: true, + ...(records || {}), + }, }) console.log(recordData) diff --git a/examples/basic-tsnode-esm/tsconfig.json b/examples/basic-tsnode-esm/tsconfig.json index 292a1522c..992788fc0 100644 --- a/examples/basic-tsnode-esm/tsconfig.json +++ b/examples/basic-tsnode-esm/tsconfig.json @@ -1,10 +1,10 @@ { - "extends": "../../tsconfig.json", - "ts-node": { - "compilerOptions": { - "target": "es2020", - "esModuleInterop": true - } - }, - "include": ["src/**/*.ts"] + "extends": "../../tsconfig.json", + "ts-node": { + "compilerOptions": { + "target": "es2020", + "esModuleInterop": true + } + }, + "include": ["src/**/*.ts"] } diff --git a/package.json b/package.json index da28262eb..52198bd57 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,23 @@ "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", - "lint": "biome check" + "chgset": "pnpm chgset:run && pnpm chgset:version" }, "devDependencies": { - "@biomejs/biome": "^1.9.4", "@changesets/changelog-github": "^0.5.0", "@changesets/cli": "^2.27.8", + "@typescript-eslint/eslint-plugin": "^6.7.5", + "@typescript-eslint/parser": "^6.7.5", + "eslint": "^8.51.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^16.1.2", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-prettier": "^4.0.0", + "prettier": "^2.8.8", "ts-node": "^10.7.0", - "typescript": "^5.8.3" + "typescript": "^5.3.2" }, "resolutions": { "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@0.3.0-beta.13" @@ -30,5 +38,5 @@ "unplugged": true } }, - "packageManager": "pnpm@10.10.0" + "packageManager": "pnpm@9.4.0" } diff --git a/packages/ens-test-env/.gitignore b/packages/ens-test-env/.gitignore new file mode 100644 index 000000000..7a694c969 --- /dev/null +++ b/packages/ens-test-env/.gitignore @@ -0,0 +1 @@ +LICENSE \ No newline at end of file diff --git a/packages/ens-test-env/README.md b/packages/ens-test-env/README.md new file mode 100644 index 000000000..55f383f83 --- /dev/null +++ b/packages/ens-test-env/README.md @@ -0,0 +1,140 @@ +# ens-test-env + +## How it works + +The testing environment used here is implemented in the stateless and stateful tests for ENS app. +The environment consists of two parts: the ganache Ethereum node, and the docker graph instance. +Which environment type you use is dependent on your testing circumstances. + +## Configuration + +There should be a file named `ens-test-env.config.js` in your project's root directory. +You can add a JSDoc type import to import the config type. + +```js +/** + * @type {import('@ensdomains/ens-test-env').ENSTestEnvConfig} + **/ +module.exports = { + deployCommand: 'yarn hardhat deploy', + tenderly: { + user: 'ens', + project: 'core', + key: 'tenderly-key', + }, + archive: { + subgraphId: 'QmXxAE7Urtv6TPa8o8XmPwLVQNbH6r35hRKHP63udTxTNa', + epochTime: 1646894980, + blockNumber: 12066620, + baseUrl: 'https://storage.googleapis.com/ens-manager-build-data', + network: 'mainnet', + }, + docker: { + file: './docker-compose.yml', + sudo: false, + }, + ethereum: { + chain: { + chainId: 0, + }, + fork: { + url: 'https://example.com', + }, + wallet: { + mnemonic: 'test test test test test test test test test test test junk', + unlockedAccounts: ['0x0000000000000000000000000000000000000000'], + }, + }, + graph: { + bypassLocal: false, + }, + scripts: [ + { + command: 'example', + name: 'example', + prefixColor: 'blue.bold', + cwd: path.resolve('./'), + finishOnExit: true, + waitForGraph: true, + }, + ], + paths: { + archives: './archives', + data: './data', + }, +} +``` + +## Environment Types + +### Stateless + +For most testing situations you can use the default settings, which will create a fresh mainnet +fork from a specified block as well as deploying a fresh subgraph with the same specified block +as it's start block. + +Tests should ideally be designed to be stateless where possible, which entails not using hardcoded +addresses and not relying on any specific blockchain/graph state. This allows for a much higher +test reliability and low maintenance. + +### Stateful + +Some tests may require a specific existing state, for example if a test relies on an old deployment +of a contract which can no longer be accurately replicated from a fresh mainnet fork. The stateful +environment uses pre-existing subgraph data at a specified block to allow full state access prior +to the mainnet fork. + +The stateful environment can also be used to more closely replicate a production environment for +true full end-to-end tests. You may also want to use this environment for testing with your own +personal wallet without using mainnet. + +The downside of using the stateful environment is that a test can potentially become unreliable if +one of it's dependencies changes. Alongside reliability, running a stateful test most of the time +will require access to a specific private key. Given this, you should try to avoid writing stateful +tests wherever possible. + +## Contract deployments + +Contract deployments are a small but necessary part of testing, you can deploy contracts to +both stateless and stateful environments. After the locally tested contract is deployed, the +deployment script should be left in the repo to serve as an archive. + +## Updating the graph-node dataset + +Generally, you will want to set a graft variable in the `subgraph.yaml` file for the subgraph. You +can find more about the ENS subgraph [here](https://github.com/ensdomains/ens-subgraph). You'll also +documentation for grafting available [here](https://thegraph.com/docs/en/developer/create-subgraph-hosted/#grafting-onto-existing-subgraphs). + +To update the graph-node dataset, the BLOCK_HEIGHT variable must be changed within the `.env` file. +It should be set to the same value as the graft block. + +If the dataset is a dependency for a local test, you will need to first let your local graph-node +dataset update so that your test can pass. + +Once your data is up to date, you can run + +```bash +yarn ens-test-env data --compress +``` + +in this directory, which will give you a archive file for your dataset. + +### Dataset naming scheme + +```js +const file = `data_${BLOCK_HEIGHT}_${SUBGRAPH_ID}_${EPOCH_TIME}_${NETWORK}.archive` +// e.g. data_14119046_QmTmU4syjQb8gfNq8TCQGv441qp2zQMNKnQ4smjKhpLQ6F_1643850493_ropsten.archive.tar.lz4 +``` + +## Running the environment + +After this you can run: + +```bash +# Start +yarn ens-test-env start +# Load data only +yarn ens-test-env data --load +# Export generated data +yarn ens-test-env data --compress +``` diff --git a/packages/ens-test-env/package.json b/packages/ens-test-env/package.json new file mode 100644 index 000000000..d9ca2d4c1 --- /dev/null +++ b/packages/ens-test-env/package.json @@ -0,0 +1,32 @@ +{ + "name": "@ensdomains/ens-test-env", + "type": "module", + "version": "0.5.0-beta.1", + "files": [ + "src" + ], + "types": "src/index.d.ts", + "scripts": { + "prepublish": "cp ../../LICENSE ./", + "ver": "pnpm version --no-workspaces-update" + }, + "engines": { + "node": ">=18" + }, + "dependencies": { + "@ethersproject/wallet": "^5.6.0", + "ansi-colors": "^4.1.1", + "cli-progress": "^3.10.0", + "commander": "^9.3.0", + "concurrently": "^7.1.0", + "docker-compose": "^0.24.7", + "dotenv": "^16.0.1", + "js-yaml": "^4.1.0", + "lz4": "^0.6.5", + "progress-stream": "^2.0.0", + "tar-fs": "^2.1.1", + "wait-on": "^6.0.1" + }, + "preferUnplugged": true, + "bin": "./src/index.js" +} diff --git a/packages/ens-test-env/src/config.d.ts b/packages/ens-test-env/src/config.d.ts new file mode 100644 index 000000000..69bafd9f3 --- /dev/null +++ b/packages/ens-test-env/src/config.d.ts @@ -0,0 +1,19 @@ +import type { ConcurrentlyCommandInput } from 'concurrently' + +/** + * ens-test-env configuration object + * @see [configuration documentation](https://github.com/ensdomains/ensjs-v3/tree/main/packages/ens-test-env/) + */ +export interface ENSTestEnvConfig { + deployCommand?: string + buildCommand?: string + labelHashes?: { hash: string; label: string }[] + scripts?: (ConcurrentlyCommandInput & { + finishOnExit?: boolean + })[] + paths?: { + data?: string + archive?: string + composeFile?: string + } +} diff --git a/packages/ens-test-env/src/docker-compose.yml b/packages/ens-test-env/src/docker-compose.yml new file mode 100644 index 000000000..d5fd8b85d --- /dev/null +++ b/packages/ens-test-env/src/docker-compose.yml @@ -0,0 +1,63 @@ +version: '3' +services: + anvil: + image: ghcr.io/ensdomains/anvil:next + ports: + - '8545:8545' + entrypoint: /bin/sh -c 'anvil --chain-id 1337 --gas-limit 50000000 --timestamp 1640995200 $ANVIL_EXTRA_ARGS' + environment: + ANVIL_IP_ADDR: '0.0.0.0' + graph-node: + image: graphprotocol/graph-node:v0.30.0 + ports: + - '8000:8000' + - '8001:8001' + - '8020:8020' + - '8030:8030' + - '8040:8040' + depends_on: + - ipfs + - postgres + - anvil + environment: + postgres_host: postgres + postgres_user: graph-node + postgres_pass: let-me-in + postgres_db: graph-node + ipfs: 'ipfs:5001' + ethereum: 'mainnet:http://anvil:8545' + GRAPH_LOG: $GRAPH_LOG_LEVEL + GRAPH_ALLOW_NON_DETERMINISTIC_IPFS: 'true' + GRAPH_ETHEREUM_CLEANUP_BLOCKS: 'true' + extra_hosts: + - 'host.docker.internal:host-gateway' + ipfs: + image: ipfs/kubo:v0.16.0 + ports: + - '5001:5001' + volumes: + - $DATA_FOLDER/ipfs:/data/ipfs + postgres: + image: postgres:14-alpine + ports: + - '5432:5432' + command: ['postgres', '-cshared_preload_libraries=pg_stat_statements'] + environment: + POSTGRES_USER: graph-node + POSTGRES_PASSWORD: let-me-in + POSTGRES_DB: graph-node + POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" + volumes: + - $DATA_FOLDER/postgres:/var/lib/postgresql/data + metadata: + image: ghcr.io/ensdomains/ens-metadata-service:latest + depends_on: + - anvil + - graph-node + ports: + - '8080:8080' + environment: + - ADDRESS_ETH_REGISTRAR=$ADDRESS_ETH_REGISTRAR + - ADDRESS_NAME_WRAPPER=$ADDRESS_NAME_WRAPPER + - RPC_PROVIDER=http://anvil:8545 + - SUBGRAPH_URL=http://graph-node:8000/subgraphs/name/graphprotocol/ens \ No newline at end of file diff --git a/packages/ens-test-env/src/ens-test-env.example.config.js b/packages/ens-test-env/src/ens-test-env.example.config.js new file mode 100644 index 000000000..5bbe08d96 --- /dev/null +++ b/packages/ens-test-env/src/ens-test-env.example.config.js @@ -0,0 +1,28 @@ +const path = require('path') + +/** + * @type {import('./config').ENSTestEnvConfig} + * */ +module.exports = { + deployCommand: 'yarn hardhat deploy', + buildCommand: 'yarn build', + labelHashes: [ + { + hash: '0x4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0', + label: 'eth', + }, + ], + scripts: [ + { + command: 'example', + name: 'example', + prefixColor: 'blue.bold', + cwd: path.resolve('./'), + finishOnExit: true, + }, + ], + paths: { + data: './data', + composeFile: './docker-compose.yml', + }, +} diff --git a/packages/ens-test-env/src/fetch-data.js b/packages/ens-test-env/src/fetch-data.js new file mode 100644 index 000000000..0d674cd2f --- /dev/null +++ b/packages/ens-test-env/src/fetch-data.js @@ -0,0 +1,150 @@ +#!/usr/bin/env node + +/* eslint-disable */ +import colors from 'ansi-colors' +import cliProgress from 'cli-progress' +import 'dotenv/config' +import fs from 'node:fs' +import lz4 from 'lz4' +import progress from 'progress-stream' +import { pipeline } from 'stream' +import tar from 'tar-fs' +import { promisify } from 'node:util' + +const createProgressBar = (name, hasSpeed) => + new cliProgress.SingleBar({ + format: + `${name} Progress |` + + colors.cyan('{bar}') + + '| {percentage}% || {value}/{total} GB' + + (hasSpeed ? ' || Speed: {speed} MB/s' : ''), + barCompleteChar: '\u2588', + barIncompleteChar: '\u2591', + hideCursor: true, + fps: 5, + formatValue: (value, _, type) => { + switch (type) { + case 'value': + return bytesToGb(value).toFixed(2) + case 'total': + return bytesToGb(value).toFixed(2) + default: + return value + } + }, + }) + +const extractProgressBar = createProgressBar('Extract', true) +const compressProgressBar = createProgressBar('Compress', false) + +let localPath, dataPath + +const streamPipeline = promisify(pipeline) +const streamOpts = { + highWaterMark: 67108864, // 64MB +} + +const bytesToGb = (bytes) => bytes * 9.3132257461548e-10 +const bytesToMb = (bytes) => bytes * 9.5367431640625e-7 + +async function compressToArchive() { + return new Promise(async (resolve, reject) => { + let initial = true + const encoder = lz4.createEncoderStream({}) + const output = fs.createWriteStream(localPath + '.tar.lz4', streamOpts) + const archive = tar.pack(dataPath) + const progressStream = progress({}) + + progressStream.on('progress', (progress) => { + if (initial) { + compressProgressBar.start(progress.length, 0, { + speed: 'N/A', + }) + initial = false + } else { + compressProgressBar.update(progress.transferred, { + speed: bytesToMb(progress.speed).toFixed(2), + }) + } + }) + + compressProgressBar.start() + await streamPipeline(archive, encoder, output) + .then(() => { + compressProgressBar.stop() + resolve() + }) + .catch((err) => { + compressProgressBar.stop() + reject(err.message) + }) + }) +} + +async function decompressToOutput() { + return new Promise(async (resolve, reject) => { + if (fs.existsSync(dataPath)) + await fs.promises.rm(dataPath, { recursive: true, force: true }) + + const archiveSize = fs.statSync(localPath + '.tar.lz4').size + const unarchiver = tar.extract(dataPath) + const decoder = lz4.createDecoderStream() + const input = fs.createReadStream(localPath + '.tar.lz4', streamOpts) + const progressStream = progress({}) + + extractProgressBar.start(archiveSize, 0, { + speed: 'N/A', + }) + + progressStream.on('progress', (progress) => { + extractProgressBar.update(progress.transferred, { + speed: bytesToMb(progress.speed).toFixed(2), + }) + }) + + await streamPipeline(input, progressStream, decoder, unarchiver) + .then(() => { + extractProgressBar.stop() + resolve() + }) + .catch((err) => { + extractProgressBar.stop() + reject(err.message) + }) + + const readMePath = `${dataPath}/ipfs/blocks/_README` + if (fs.existsSync(readMePath)) { + await fs.promises.rm(readMePath, {force: true}) + } + }) +} + +export const main = async (arg, config) => { + let time = Date.now() + + localPath = config.paths.archive + dataPath = config.paths.data + + const logTime = (message) => + console.log(`${message} ${(Date.now() - time) / 1000}s`) + + switch (arg) { + case 'load': { + await decompressToOutput().then(() => + logTime('Decompressed and copied in'), + ) + return + } + case 'compress': { + console.log('Compressing /data to archive.tar.lz4...') + await compressToArchive().then(() => logTime('Compressed archive in')) + return + } + case 'clean': { + console.log('Cleaning data directory...') + await fs.promises.rm(dataPath, { force: true, recursive: true }) + await fs.promises.mkdir(dataPath) + return + } + } +} diff --git a/packages/ens-test-env/src/index.d.ts b/packages/ens-test-env/src/index.d.ts new file mode 100644 index 000000000..f934b01b6 --- /dev/null +++ b/packages/ens-test-env/src/index.d.ts @@ -0,0 +1 @@ +export * from './config' diff --git a/packages/ens-test-env/src/index.js b/packages/ens-test-env/src/index.js new file mode 100755 index 000000000..3162d1e53 --- /dev/null +++ b/packages/ens-test-env/src/index.js @@ -0,0 +1,139 @@ +#!/usr/bin/env node + +/* eslint-disable */ + +import { Command, Option } from 'commander' +import path from 'node:path' +import { emitKeypressEvents } from 'node:readline' +import { main as fetchData } from './fetch-data.js' +import { main as manager } from './manager.js' +import { main as subgraph } from './subgraph.js' + +let config +const program = new Command() + +const __dirname = new URL('.', import.meta.url).pathname +const cwd = process.cwd() + +program + .name('ens-test-env') + .description('A testing environment for everything ENS') + .version(process.env.npm_package_version || '0.1.0') + .option('-c, --config ', 'Specify config directory') + .option('-a, --always-cleanup', 'Always cleanup after running') + .hook('preAction', async () => { + if (program.optsWithGlobals().alwaysCleanup) { + emitKeypressEvents(process.stdin) + if (process.stdin.isTTY) process.stdin.setRawMode(true) + process.stdin.on('keypress', (char, key) => { + if (key.ctrl && key.name === 'c') { + process.kill(process.pid, 'SIGINT') + } + }) + } + // if config arg supplied, get config path as next arg + const configDir = program.optsWithGlobals().config + // if config arg, try load config + if (configDir) { + try { + config = (await import(path.join(process.cwd(), configDir))).default + } catch { + program.error(`Config file ${configDir} not found`) + } + } else { + config = ( + await import(path.join(process.cwd(), 'ens-test-env.config.js')) + ).default + } + // if config doesn't have all data, throw error + if (!config) { + program.error('No valid config found') + return help() + } + // add default paths to config, and let them be replaced by specified vars + const paths = { + data: path.resolve(cwd, './data'), + archive: path.resolve(cwd, './archive'), + composeFile: path.resolve(__dirname, './docker-compose.yml'), + } + const configPaths = config.paths || {} + for (const [key, value] of Object.entries(configPaths)) { + if (typeof value === 'string') { + paths[key] = path.resolve(cwd, value) + } + } + config.paths = paths + }) + +program + .command('start') + .description('Starts the test environment') + .addOption(new Option('-nr, --no-reset', "Don't reset the data folder")) + .addOption( + new Option('-s, --save', 'Save data when exiting').implies({ + killGracefully: true, + verbosity: 1, + }), + ) + .addOption( + new Option( + '--extra-time