From d942f49dadf3b737b383a455a21724b2fbcd638f Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Wed, 9 Jul 2025 01:02:50 +0530 Subject: [PATCH 1/8] migrate setResolver --- .../ensjs/src/actions/wallet/setResolver.ts | 281 ++++++++++-------- 1 file changed, 163 insertions(+), 118 deletions(-) diff --git a/packages/ensjs/src/actions/wallet/setResolver.ts b/packages/ensjs/src/actions/wallet/setResolver.ts index 814626b0..a92e8b13 100644 --- a/packages/ensjs/src/actions/wallet/setResolver.ts +++ b/packages/ensjs/src/actions/wallet/setResolver.ts @@ -1,119 +1,164 @@ import type { - Account, - Address, - Chain, - GetChainContractAddressErrorType, - WriteContractErrorType, - WriteContractParameters, - WriteContractReturnType, -} from 'viem' -import { writeContract } from 'viem/actions' -import { getAction } from 'viem/utils' + Account, + Address, + Chain, + GetChainContractAddressErrorType, + WriteContractErrorType, + WriteContractParameters, + WriteContractReturnType, +} from "viem"; +import { labelhash } from "viem"; +import { writeContract } from "viem/actions"; +import { getAction } from "viem/utils"; import { - type ChainWithContracts, - getChainContractAddress, - type RequireClientContracts, -} from '../../clients/chain.js' -import { nameWrapperSetResolverSnippet } from '../../contracts/nameWrapper.js' -import { registrySetResolverSnippet } from '../../contracts/registry.js' -import type { ErrorType } from '../../errors/utils.js' -import type { Prettify, WriteTransactionParameters } from '../../types/index.js' -import { ASSERT_NO_TYPE_ERROR } from '../../types/internal.js' + type ChainWithContracts, + getChainContractAddress, + type RequireClientContracts, +} from "../../clients/chain.js"; +import { nameWrapperSetResolverSnippet } from "../../contracts/nameWrapper.js"; +import { registrySetResolverSnippet } from "../../contracts/registry.js"; +import type { ErrorType } from "../../errors/utils.js"; +import type { + Prettify, + WriteTransactionParameters, +} from "../../types/index.js"; +import { ASSERT_NO_TYPE_ERROR } from "../../types/internal.js"; import { - type ClientWithOverridesErrorType, - clientWithOverrides, -} from '../../utils/clientWithOverrides.js' -import { type NamehashErrorType, namehash } from '../../utils/name/namehash.js' + type ClientWithOverridesErrorType, + clientWithOverrides, +} from "../../utils/clientWithOverrides.js"; +import { type NamehashErrorType, namehash } from "../../utils/name/namehash.js"; export type SetResolverWriteParametersParameters = { - /** Name to set resolver for */ - name: string - /** Contract to set resolver on */ - contract: 'registry' | 'nameWrapper' - /** Resolver address to set */ - resolverAddress: Address -} + /** Name to set resolver for */ + name: string; + /** Contract to set resolver on - can be 'registry', 'nameWrapper', or an address of a namechain registry */ + contract: "registry" | "nameWrapper" | Address; + /** Resolver address to set */ + resolverAddress: Address; +}; export type SetResolverWriteParametersReturnType = ReturnType< - typeof setResolverWriteParameters -> + typeof setResolverWriteParameters +>; export type SetResolverWriteParametersErrorType = - | ErrorType - | GetChainContractAddressErrorType - | NamehashErrorType + | ErrorType + | GetChainContractAddressErrorType + | NamehashErrorType; // ================================ // Write parameters // ================================ export const setResolverWriteParameters = < - chain extends Chain, - account extends Account, + chain extends Chain, + account extends Account, >( - client: RequireClientContracts< - chain, - 'ensNameWrapper' | 'ensRegistry', - account - >, - { name, contract, resolverAddress }: SetResolverWriteParametersParameters, + client: RequireClientContracts< + chain, + "ensNameWrapper" | "ensRegistry", + account + >, + { name, contract, resolverAddress }: SetResolverWriteParametersParameters, ) => { - ASSERT_NO_TYPE_ERROR(client) - - if (contract !== 'registry' && contract !== 'nameWrapper') - throw new Error(`Unknown contract: ${contract}`) - - const address = getChainContractAddress({ - chain: client.chain, - contract: contract === 'nameWrapper' ? 'ensNameWrapper' : 'ensRegistry', - }) - - const args = [namehash(name), resolverAddress] as const - const functionName = 'setResolver' - - const baseParams = { - address, - functionName, - args, - chain: client.chain, - account: client.account, - } as const - - if (contract === 'nameWrapper') - return { - ...baseParams, - abi: nameWrapperSetResolverSnippet, - } as const satisfies WriteContractParameters< - typeof nameWrapperSetResolverSnippet - > - - return { - ...baseParams, - abi: registrySetResolverSnippet, - } as const satisfies WriteContractParameters< - typeof registrySetResolverSnippet - > -} + ASSERT_NO_TYPE_ERROR(client); + + // Handle legacy contracts + if (contract === "registry" || contract === "nameWrapper") { + const address = getChainContractAddress({ + chain: client.chain, + contract: contract === "nameWrapper" ? "ensNameWrapper" : "ensRegistry", + }); + + const args = [namehash(name), resolverAddress] as const; + const functionName = "setResolver"; + + const baseParams = { + address, + functionName, + args, + chain: client.chain, + account: client.account, + } as const; + + if (contract === "nameWrapper") + return { + ...baseParams, + abi: nameWrapperSetResolverSnippet, + } as const satisfies WriteContractParameters< + typeof nameWrapperSetResolverSnippet + >; + + return { + ...baseParams, + abi: registrySetResolverSnippet, + } as const satisfies WriteContractParameters< + typeof registrySetResolverSnippet + >; + } + + // Handle namechain contracts + const label = name.split(".")[0]; + const tokenId = BigInt(labelhash(label)); + + const args = [tokenId, resolverAddress] as const; + const functionName = "setResolver"; + + const baseParams = { + address: contract as Address, + functionName, + args, + chain: client.chain, + account: client.account, + } as const; + + const namechainSetResolverSnippet = [ + { + inputs: [ + { + name: "tokenId", + type: "uint256", + }, + { + name: "resolver", + type: "address", + }, + ], + name: "setResolver", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + ] as const; + + return { + ...baseParams, + abi: namechainSetResolverSnippet, + } as const satisfies WriteContractParameters< + typeof namechainSetResolverSnippet + >; +}; // ================================ // Action // ================================ export type SetResolverParameters< - chain extends Chain, - account extends Account, - chainOverride extends ChainWithContracts<'ensNameWrapper' | 'ensRegistry'>, + chain extends Chain, + account extends Account, + chainOverride extends ChainWithContracts<"ensNameWrapper" | "ensRegistry">, > = Prettify< - SetResolverWriteParametersParameters & - WriteTransactionParameters -> + SetResolverWriteParametersParameters & + WriteTransactionParameters +>; -export type SetResolverReturnType = WriteContractReturnType +export type SetResolverReturnType = WriteContractReturnType; export type SetResolverErrorType = - | SetResolverWriteParametersErrorType - | ClientWithOverridesErrorType - | WriteContractErrorType + | SetResolverWriteParametersErrorType + | ClientWithOverridesErrorType + | WriteContractErrorType; /** * Sets a resolver for a name. @@ -139,35 +184,35 @@ export type SetResolverErrorType = * // 0x... */ export async function setResolver< - chain extends Chain, - account extends Account, - chainOverride extends ChainWithContracts<'ensNameWrapper' | 'ensRegistry'>, + chain extends Chain, + account extends Account, + chainOverride extends ChainWithContracts<"ensNameWrapper" | "ensRegistry">, >( - client: RequireClientContracts< - chain, - 'ensNameWrapper' | 'ensRegistry', - account - >, - { - name, - contract, - resolverAddress, - ...txArgs - }: SetResolverParameters, + client: RequireClientContracts< + chain, + "ensNameWrapper" | "ensRegistry", + account + >, + { + name, + contract, + resolverAddress, + ...txArgs + }: SetResolverParameters, ): Promise { - ASSERT_NO_TYPE_ERROR(client) - - const writeParameters = setResolverWriteParameters( - clientWithOverrides(client, txArgs), - { - name, - contract, - resolverAddress, - }, - ) - const writeContractAction = getAction(client, writeContract, 'writeContract') - return writeContractAction({ - ...writeParameters, - ...txArgs, - } as WriteContractParameters) + ASSERT_NO_TYPE_ERROR(client); + + const writeParameters = setResolverWriteParameters( + clientWithOverrides(client, txArgs), + { + name, + contract, + resolverAddress, + }, + ); + const writeContractAction = getAction(client, writeContract, "writeContract"); + return writeContractAction({ + ...writeParameters, + ...txArgs, + } as WriteContractParameters); } From 87aa5b9452ae8960498fc9e92ee2dba0e1d2d666 Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Wed, 9 Jul 2025 19:00:14 +0530 Subject: [PATCH 2/8] export abi from separate file --- packages/ensjs/src/contracts/index.ts | 1 + packages/ensjs/src/contracts/namechain.ts | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 packages/ensjs/src/contracts/namechain.ts diff --git a/packages/ensjs/src/contracts/index.ts b/packages/ensjs/src/contracts/index.ts index 9783f207..2a2bb51e 100644 --- a/packages/ensjs/src/contracts/index.ts +++ b/packages/ensjs/src/contracts/index.ts @@ -96,3 +96,4 @@ export { universalResolverResolveSnippet, universalResolverReverseSnippet, } from './universalResolver.js' +export { namechainSetResolverSnippet } from './namechain.js' diff --git a/packages/ensjs/src/contracts/namechain.ts b/packages/ensjs/src/contracts/namechain.ts new file mode 100644 index 00000000..776317a8 --- /dev/null +++ b/packages/ensjs/src/contracts/namechain.ts @@ -0,0 +1,20 @@ +// Namechain contract ABI snippets + +export const namechainSetResolverSnippet = [ + { + inputs: [ + { + name: 'tokenId', + type: 'uint256', + }, + { + name: 'resolver', + type: 'address', + }, + ], + name: 'setResolver', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const From d0f9c45610095a95ce5daa8e7bee5119de0b9fe4 Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Wed, 9 Jul 2025 19:00:45 +0530 Subject: [PATCH 3/8] add checks for address --- .../ensjs/src/actions/wallet/setResolver.ts | 312 +++++++++--------- 1 file changed, 149 insertions(+), 163 deletions(-) diff --git a/packages/ensjs/src/actions/wallet/setResolver.ts b/packages/ensjs/src/actions/wallet/setResolver.ts index a92e8b13..8134069c 100644 --- a/packages/ensjs/src/actions/wallet/setResolver.ts +++ b/packages/ensjs/src/actions/wallet/setResolver.ts @@ -1,164 +1,150 @@ import type { - Account, - Address, - Chain, - GetChainContractAddressErrorType, - WriteContractErrorType, - WriteContractParameters, - WriteContractReturnType, -} from "viem"; -import { labelhash } from "viem"; -import { writeContract } from "viem/actions"; -import { getAction } from "viem/utils"; + Account, + Address, + Chain, + GetChainContractAddressErrorType, + WriteContractErrorType, + WriteContractParameters, + WriteContractReturnType, +} from 'viem' +import { labelhash, isAddress } from 'viem' +import { writeContract } from 'viem/actions' +import { getAction } from 'viem/utils' import { - type ChainWithContracts, - getChainContractAddress, - type RequireClientContracts, -} from "../../clients/chain.js"; -import { nameWrapperSetResolverSnippet } from "../../contracts/nameWrapper.js"; -import { registrySetResolverSnippet } from "../../contracts/registry.js"; -import type { ErrorType } from "../../errors/utils.js"; -import type { - Prettify, - WriteTransactionParameters, -} from "../../types/index.js"; -import { ASSERT_NO_TYPE_ERROR } from "../../types/internal.js"; + type ChainWithContracts, + getChainContractAddress, + type RequireClientContracts, +} from '../../clients/chain.js' +import { nameWrapperSetResolverSnippet } from '../../contracts/nameWrapper.js' +import { registrySetResolverSnippet } from '../../contracts/registry.js' +import type { ErrorType } from '../../errors/utils.js' +import type { Prettify, WriteTransactionParameters } from '../../types/index.js' +import { ASSERT_NO_TYPE_ERROR } from '../../types/internal.js' import { - type ClientWithOverridesErrorType, - clientWithOverrides, -} from "../../utils/clientWithOverrides.js"; -import { type NamehashErrorType, namehash } from "../../utils/name/namehash.js"; + type ClientWithOverridesErrorType, + clientWithOverrides, +} from '../../utils/clientWithOverrides.js' +import { type NamehashErrorType, namehash } from '../../utils/name/namehash.js' +import { namechainSetResolverSnippet } from '../../contracts/namechain.js' export type SetResolverWriteParametersParameters = { - /** Name to set resolver for */ - name: string; - /** Contract to set resolver on - can be 'registry', 'nameWrapper', or an address of a namechain registry */ - contract: "registry" | "nameWrapper" | Address; - /** Resolver address to set */ - resolverAddress: Address; -}; + /** Name to set resolver for */ + name: string + /** Contract to set resolver on - can be 'registry', 'nameWrapper', or an address of a namechain registry */ + contract: 'registry' | 'nameWrapper' | Address + /** Resolver address to set */ + resolverAddress: Address +} export type SetResolverWriteParametersReturnType = ReturnType< - typeof setResolverWriteParameters ->; + typeof setResolverWriteParameters +> export type SetResolverWriteParametersErrorType = - | ErrorType - | GetChainContractAddressErrorType - | NamehashErrorType; + | ErrorType + | GetChainContractAddressErrorType + | NamehashErrorType // ================================ // Write parameters // ================================ export const setResolverWriteParameters = < - chain extends Chain, - account extends Account, + chain extends Chain, + account extends Account, >( - client: RequireClientContracts< - chain, - "ensNameWrapper" | "ensRegistry", - account - >, - { name, contract, resolverAddress }: SetResolverWriteParametersParameters, + client: RequireClientContracts< + chain, + 'ensNameWrapper' | 'ensRegistry', + account + >, + { name, contract, resolverAddress }: SetResolverWriteParametersParameters, ) => { - ASSERT_NO_TYPE_ERROR(client); - - // Handle legacy contracts - if (contract === "registry" || contract === "nameWrapper") { - const address = getChainContractAddress({ - chain: client.chain, - contract: contract === "nameWrapper" ? "ensNameWrapper" : "ensRegistry", - }); - - const args = [namehash(name), resolverAddress] as const; - const functionName = "setResolver"; - - const baseParams = { - address, - functionName, - args, - chain: client.chain, - account: client.account, - } as const; - - if (contract === "nameWrapper") - return { - ...baseParams, - abi: nameWrapperSetResolverSnippet, - } as const satisfies WriteContractParameters< - typeof nameWrapperSetResolverSnippet - >; - - return { - ...baseParams, - abi: registrySetResolverSnippet, - } as const satisfies WriteContractParameters< - typeof registrySetResolverSnippet - >; - } - - // Handle namechain contracts - const label = name.split(".")[0]; - const tokenId = BigInt(labelhash(label)); - - const args = [tokenId, resolverAddress] as const; - const functionName = "setResolver"; - - const baseParams = { - address: contract as Address, - functionName, - args, - chain: client.chain, - account: client.account, - } as const; - - const namechainSetResolverSnippet = [ - { - inputs: [ - { - name: "tokenId", - type: "uint256", - }, - { - name: "resolver", - type: "address", - }, - ], - name: "setResolver", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - ] as const; - - return { - ...baseParams, - abi: namechainSetResolverSnippet, - } as const satisfies WriteContractParameters< - typeof namechainSetResolverSnippet - >; -}; + ASSERT_NO_TYPE_ERROR(client) + + if (!isAddress(resolverAddress)) { + throw new Error(`Invalid resolver address: ${resolverAddress}`) + } + + // Handle legacy contracts + if (contract === 'registry' || contract === 'nameWrapper') { + const address = getChainContractAddress({ + chain: client.chain, + contract: contract === 'nameWrapper' ? 'ensNameWrapper' : 'ensRegistry', + }) + + const args = [namehash(name), resolverAddress] as const + const functionName = 'setResolver' + + const baseParams = { + address, + functionName, + args, + chain: client.chain, + account: client.account, + } as const + + if (contract === 'nameWrapper') + return { + ...baseParams, + abi: nameWrapperSetResolverSnippet, + } as const satisfies WriteContractParameters< + typeof nameWrapperSetResolverSnippet + > + + return { + ...baseParams, + abi: registrySetResolverSnippet, + } as const satisfies WriteContractParameters< + typeof registrySetResolverSnippet + > + } + + // Handle namechain contracts + if (!isAddress(contract)) { + throw new Error(`Invalid contract address: ${contract}`) + } + + const label = name.split('.')[0] + const tokenId = BigInt(labelhash(label)) + + const args = [tokenId, resolverAddress] as const + + const baseParams = { + address: contract as Address, + functionName: 'setResolver', + args, + chain: client.chain, + account: client.account, + } as const + + return { + ...baseParams, + abi: namechainSetResolverSnippet, + } as const satisfies WriteContractParameters< + typeof namechainSetResolverSnippet + > +} // ================================ // Action // ================================ export type SetResolverParameters< - chain extends Chain, - account extends Account, - chainOverride extends ChainWithContracts<"ensNameWrapper" | "ensRegistry">, + chain extends Chain, + account extends Account, + chainOverride extends ChainWithContracts<'ensNameWrapper' | 'ensRegistry'>, > = Prettify< - SetResolverWriteParametersParameters & - WriteTransactionParameters ->; + SetResolverWriteParametersParameters & + WriteTransactionParameters +> -export type SetResolverReturnType = WriteContractReturnType; +export type SetResolverReturnType = WriteContractReturnType export type SetResolverErrorType = - | SetResolverWriteParametersErrorType - | ClientWithOverridesErrorType - | WriteContractErrorType; + | SetResolverWriteParametersErrorType + | ClientWithOverridesErrorType + | WriteContractErrorType /** * Sets a resolver for a name. @@ -184,35 +170,35 @@ export type SetResolverErrorType = * // 0x... */ export async function setResolver< - chain extends Chain, - account extends Account, - chainOverride extends ChainWithContracts<"ensNameWrapper" | "ensRegistry">, + chain extends Chain, + account extends Account, + chainOverride extends ChainWithContracts<'ensNameWrapper' | 'ensRegistry'>, >( - client: RequireClientContracts< - chain, - "ensNameWrapper" | "ensRegistry", - account - >, - { - name, - contract, - resolverAddress, - ...txArgs - }: SetResolverParameters, + client: RequireClientContracts< + chain, + 'ensNameWrapper' | 'ensRegistry', + account + >, + { + name, + contract, + resolverAddress, + ...txArgs + }: SetResolverParameters, ): Promise { - ASSERT_NO_TYPE_ERROR(client); - - const writeParameters = setResolverWriteParameters( - clientWithOverrides(client, txArgs), - { - name, - contract, - resolverAddress, - }, - ); - const writeContractAction = getAction(client, writeContract, "writeContract"); - return writeContractAction({ - ...writeParameters, - ...txArgs, - } as WriteContractParameters); + ASSERT_NO_TYPE_ERROR(client) + + const writeParameters = setResolverWriteParameters( + clientWithOverrides(client, txArgs), + { + name, + contract, + resolverAddress, + }, + ) + const writeContractAction = getAction(client, writeContract, 'writeContract') + return writeContractAction({ + ...writeParameters, + ...txArgs, + } as WriteContractParameters) } From 5f97f9dac31e71b51efd96202ae7579f1680296e Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Thu, 10 Jul 2025 11:54:42 +0530 Subject: [PATCH 4/8] fix failing test --- packages/ensjs/src/actions/wallet/setResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ensjs/src/actions/wallet/setResolver.ts b/packages/ensjs/src/actions/wallet/setResolver.ts index 8134069c..326b79a6 100644 --- a/packages/ensjs/src/actions/wallet/setResolver.ts +++ b/packages/ensjs/src/actions/wallet/setResolver.ts @@ -102,7 +102,7 @@ export const setResolverWriteParameters = < // Handle namechain contracts if (!isAddress(contract)) { - throw new Error(`Invalid contract address: ${contract}`) + throw new Error(`Unknown contract: ${contract}`) } const label = name.split('.')[0] From c67abf379f799acb2aecbcfebb720a8c19dd475b Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Thu, 10 Jul 2025 12:14:47 +0530 Subject: [PATCH 5/8] organise imports --- packages/ensjs/src/actions/wallet/setResolver.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ensjs/src/actions/wallet/setResolver.ts b/packages/ensjs/src/actions/wallet/setResolver.ts index 326b79a6..f0868505 100644 --- a/packages/ensjs/src/actions/wallet/setResolver.ts +++ b/packages/ensjs/src/actions/wallet/setResolver.ts @@ -7,7 +7,7 @@ import type { WriteContractParameters, WriteContractReturnType, } from 'viem' -import { labelhash, isAddress } from 'viem' +import { isAddress, labelhash } from 'viem' import { writeContract } from 'viem/actions' import { getAction } from 'viem/utils' import { @@ -15,6 +15,7 @@ import { getChainContractAddress, type RequireClientContracts, } from '../../clients/chain.js' +import { namechainSetResolverSnippet } from '../../contracts/namechain.js' import { nameWrapperSetResolverSnippet } from '../../contracts/nameWrapper.js' import { registrySetResolverSnippet } from '../../contracts/registry.js' import type { ErrorType } from '../../errors/utils.js' @@ -25,7 +26,6 @@ import { clientWithOverrides, } from '../../utils/clientWithOverrides.js' import { type NamehashErrorType, namehash } from '../../utils/name/namehash.js' -import { namechainSetResolverSnippet } from '../../contracts/namechain.js' export type SetResolverWriteParametersParameters = { /** Name to set resolver for */ From 0f730bafd8653494a84562b98a6b37362bebacd2 Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Thu, 10 Jul 2025 16:20:33 +0530 Subject: [PATCH 6/8] fix formatting --- 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 2a2bb51e..7df4aed8 100644 --- a/packages/ensjs/src/contracts/index.ts +++ b/packages/ensjs/src/contracts/index.ts @@ -46,6 +46,7 @@ export { multicallGetCurrentBlockTimestampSnippet, multicallTryAggregateSnippet, } from './multicall.js' +export { namechainSetResolverSnippet } from './namechain.js' export { nameWrapperErrors, nameWrapperGetDataSnippet, @@ -96,4 +97,3 @@ export { universalResolverResolveSnippet, universalResolverReverseSnippet, } from './universalResolver.js' -export { namechainSetResolverSnippet } from './namechain.js' From c42aa3b017871f32f8b3246401954d41dee539cb Mon Sep 17 00:00:00 2001 From: v1rtl Date: Tue, 15 Jul 2025 16:32:26 +0300 Subject: [PATCH 7/8] rename namechain registry to standard registry, add a test for the future and better types --- .../src/actions/wallet/setResolver.test.ts | 14 ++++++++- .../ensjs/src/actions/wallet/setResolver.ts | 29 +++++++++++++------ packages/ensjs/src/contracts/index.ts | 2 +- .../standardRegistry.ts} | 2 +- 4 files changed, 35 insertions(+), 12 deletions(-) rename packages/ensjs/src/contracts/{namechain.ts => namechain/standardRegistry.ts} (85%) diff --git a/packages/ensjs/src/actions/wallet/setResolver.test.ts b/packages/ensjs/src/actions/wallet/setResolver.test.ts index 5c9e9e33..8c53eab1 100644 --- a/packages/ensjs/src/actions/wallet/setResolver.test.ts +++ b/packages/ensjs/src/actions/wallet/setResolver.test.ts @@ -1,4 +1,4 @@ -import type { Address, Hex } from 'viem' +import { zeroAddress, type Address, type Hex } from 'viem' import { afterEach, beforeAll, beforeEach, expect, it } from 'vitest' import { publicClient, @@ -67,6 +67,18 @@ it('should error if unknown contract', async () => { ).rejects.toThrow('Unknown contract: random') }) +it.skip('should allow specifying a custom registry address', async () => { + const tx = await setResolver(walletClient, { + name: 'wrapped.eth', + registryAddress: zeroAddress, + resolverAddress: '0xAEfF4f4d8e2cB51854BEa2244B3C5Fb36b41C7fC', + account: accounts[1], + }) + expect(tx).toBeTruthy() + const receipt = await waitForTransaction(tx) + expect(receipt.status).toBe('success') +}) + // it('should return a transaction for a name and set successfully', async () => { // const tx = await setName(walletClient, { // name: 'test123.eth', diff --git a/packages/ensjs/src/actions/wallet/setResolver.ts b/packages/ensjs/src/actions/wallet/setResolver.ts index f0868505..4d573093 100644 --- a/packages/ensjs/src/actions/wallet/setResolver.ts +++ b/packages/ensjs/src/actions/wallet/setResolver.ts @@ -15,7 +15,7 @@ import { getChainContractAddress, type RequireClientContracts, } from '../../clients/chain.js' -import { namechainSetResolverSnippet } from '../../contracts/namechain.js' +import { standardRegistrySetResolverSnippet } from '../../contracts/namechain/standardRegistry.js' import { nameWrapperSetResolverSnippet } from '../../contracts/nameWrapper.js' import { registrySetResolverSnippet } from '../../contracts/registry.js' import type { ErrorType } from '../../errors/utils.js' @@ -27,14 +27,25 @@ import { } from '../../utils/clientWithOverrides.js' import { type NamehashErrorType, namehash } from '../../utils/name/namehash.js' +type SetResolverContractParameters = { + /** Contract to set resolver on - can be 'registry', 'nameWrapper', or an address of a namechain registry */ + contract?: 'registry' | 'nameWrapper' + registryAddress?: never +} + +type SetResolverRegistryAddressParameters = { + /** Contract to set resolver on - can be 'registry', 'nameWrapper', or an address of a namechain registry */ + contract?: never + registryAddress: Address +} + export type SetResolverWriteParametersParameters = { /** Name to set resolver for */ name: string - /** Contract to set resolver on - can be 'registry', 'nameWrapper', or an address of a namechain registry */ - contract: 'registry' | 'nameWrapper' | Address + /** Resolver address to set */ resolverAddress: Address -} +} & (SetResolverContractParameters | SetResolverRegistryAddressParameters) export type SetResolverWriteParametersReturnType = ReturnType< typeof setResolverWriteParameters @@ -58,7 +69,7 @@ export const setResolverWriteParameters = < 'ensNameWrapper' | 'ensRegistry', account >, - { name, contract, resolverAddress }: SetResolverWriteParametersParameters, + { name, contract, resolverAddress, registryAddress }: SetResolverWriteParametersParameters, ) => { ASSERT_NO_TYPE_ERROR(client) @@ -101,7 +112,7 @@ export const setResolverWriteParameters = < } // Handle namechain contracts - if (!isAddress(contract)) { + if (registryAddress && !isAddress(registryAddress)) { throw new Error(`Unknown contract: ${contract}`) } @@ -111,7 +122,7 @@ export const setResolverWriteParameters = < const args = [tokenId, resolverAddress] as const const baseParams = { - address: contract as Address, + address: registryAddress!, functionName: 'setResolver', args, chain: client.chain, @@ -120,9 +131,9 @@ export const setResolverWriteParameters = < return { ...baseParams, - abi: namechainSetResolverSnippet, + abi: standardRegistrySetResolverSnippet, } as const satisfies WriteContractParameters< - typeof namechainSetResolverSnippet + typeof standardRegistrySetResolverSnippet > } diff --git a/packages/ensjs/src/contracts/index.ts b/packages/ensjs/src/contracts/index.ts index 7df4aed8..357b383c 100644 --- a/packages/ensjs/src/contracts/index.ts +++ b/packages/ensjs/src/contracts/index.ts @@ -46,7 +46,7 @@ export { multicallGetCurrentBlockTimestampSnippet, multicallTryAggregateSnippet, } from './multicall.js' -export { namechainSetResolverSnippet } from './namechain.js' +export { standardRegistrySetResolverSnippet } from './namechain/standardRegistry.js' export { nameWrapperErrors, nameWrapperGetDataSnippet, diff --git a/packages/ensjs/src/contracts/namechain.ts b/packages/ensjs/src/contracts/namechain/standardRegistry.ts similarity index 85% rename from packages/ensjs/src/contracts/namechain.ts rename to packages/ensjs/src/contracts/namechain/standardRegistry.ts index 776317a8..4a2c45be 100644 --- a/packages/ensjs/src/contracts/namechain.ts +++ b/packages/ensjs/src/contracts/namechain/standardRegistry.ts @@ -1,6 +1,6 @@ // Namechain contract ABI snippets -export const namechainSetResolverSnippet = [ +export const standardRegistrySetResolverSnippet = [ { inputs: [ { From 3cf1a3589b71b4a96b2ff6863fd8a7c0ec361243 Mon Sep 17 00:00:00 2001 From: v1rtl Date: Tue, 15 Jul 2025 16:34:57 +0300 Subject: [PATCH 8/8] fmt --- packages/ensjs/src/actions/wallet/setResolver.test.ts | 2 +- packages/ensjs/src/actions/wallet/setResolver.ts | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/ensjs/src/actions/wallet/setResolver.test.ts b/packages/ensjs/src/actions/wallet/setResolver.test.ts index 8c53eab1..08807698 100644 --- a/packages/ensjs/src/actions/wallet/setResolver.test.ts +++ b/packages/ensjs/src/actions/wallet/setResolver.test.ts @@ -1,4 +1,4 @@ -import { zeroAddress, type Address, type Hex } from 'viem' +import { type Address, type Hex, zeroAddress } from 'viem' import { afterEach, beforeAll, beforeEach, expect, it } from 'vitest' import { publicClient, diff --git a/packages/ensjs/src/actions/wallet/setResolver.ts b/packages/ensjs/src/actions/wallet/setResolver.ts index 4d573093..fba87511 100644 --- a/packages/ensjs/src/actions/wallet/setResolver.ts +++ b/packages/ensjs/src/actions/wallet/setResolver.ts @@ -69,7 +69,12 @@ export const setResolverWriteParameters = < 'ensNameWrapper' | 'ensRegistry', account >, - { name, contract, resolverAddress, registryAddress }: SetResolverWriteParametersParameters, + { + name, + contract, + resolverAddress, + registryAddress, + }: SetResolverWriteParametersParameters, ) => { ASSERT_NO_TYPE_ERROR(client)