From 856a2b4a9c7bb2bb2a0d531a466b3caf1618588a Mon Sep 17 00:00:00 2001 From: shrugs Date: Fri, 5 Jun 2026 15:51:19 -0500 Subject: [PATCH 1/3] feat(datasources): consolidate UniversalResolver onto IUniversalResolver proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each ENSRoot Datasource now exposes a single `UniversalResolver` contract pointing at the proxy address (0xeeee…eeee on mainnet/sepolia, the ENSv2 deployment on sepolia-v2, UpgradableUniversalResolverProxy on devnet), replacing the separate UniversalResolver (V1) and UniversalResolverV2 contracts. `UniversalResolverABI` is now `mergeAbis([IUniversalResolver, IMulticallable])`. ENSApi forward-resolution and the execute-operations integration test are updated to the single contract. --- .changeset/universal-resolver-proxy.md | 5 + .../execute-operations.integration.test.ts | 8 +- .../src/lib/resolution/forward-resolution.ts | 13 +- .../src/abis/ensv2/UniversalResolverV2.ts | 876 ------------------ .../src/abis/root/UniversalResolverV1.ts | 789 ---------------- .../src/abis/shared/IMulticallable.ts | 12 + .../src/abis/shared/IUniversalResolver.ts | 361 ++++++++ .../src/abis/shared/UniversalResolver.ts | 6 +- packages/datasources/src/ens-test-env.ts | 13 +- packages/datasources/src/mainnet.ts | 8 +- packages/datasources/src/sepolia-v2.ts | 14 +- packages/datasources/src/sepolia.ts | 8 +- .../src/seed/resolver-records.ts | 2 +- 13 files changed, 403 insertions(+), 1712 deletions(-) create mode 100644 .changeset/universal-resolver-proxy.md delete mode 100644 packages/datasources/src/abis/ensv2/UniversalResolverV2.ts delete mode 100644 packages/datasources/src/abis/root/UniversalResolverV1.ts create mode 100644 packages/datasources/src/abis/shared/IMulticallable.ts create mode 100644 packages/datasources/src/abis/shared/IUniversalResolver.ts diff --git a/.changeset/universal-resolver-proxy.md b/.changeset/universal-resolver-proxy.md new file mode 100644 index 0000000000..d6d4517c20 --- /dev/null +++ b/.changeset/universal-resolver-proxy.md @@ -0,0 +1,5 @@ +--- +"@ensnode/datasources": patch +--- + +Consolidate UniversalResolver onto the `IUniversalResolver` proxy. Each ENSRoot Datasource now exposes a single `UniversalResolver` contract pointing at the proxy address (`0xeeeeeeee14d718c2b47d9923deab1335e144eeee` on mainnet/sepolia), replacing the separate `UniversalResolver` (V1) and `UniversalResolverV2` contracts. The exported `UniversalResolverABI` is now `IUniversalResolver` merged with `IMulticallable`. diff --git a/apps/ensapi/src/lib/resolution/execute-operations.integration.test.ts b/apps/ensapi/src/lib/resolution/execute-operations.integration.test.ts index 9e80098553..aae1caf883 100644 --- a/apps/ensapi/src/lib/resolution/execute-operations.integration.test.ts +++ b/apps/ensapi/src/lib/resolution/execute-operations.integration.test.ts @@ -46,10 +46,10 @@ const EXPECTED_DESCRIPTION = "example.eth"; const publicClient = di.context.rootChainPublicClient; -const UniversalResolverV2 = getDatasourceContract( +const UniversalResolver = getDatasourceContract( ENSNamespaceIds.EnsTestEnv, DatasourceNames.ENSRoot, - "UniversalResolverV2", + "UniversalResolver", ); describe("executeOperations against UniversalResolver", () => { @@ -58,7 +58,7 @@ describe("executeOperations against UniversalResolver", () => { await expect( executeOperations({ name: NAME, - resolverAddress: UniversalResolverV2.address, + resolverAddress: UniversalResolver.address, useENSIP10Resolve: true, operations: makeOperations(node, { texts: ["description"] }), publicClient, @@ -82,7 +82,7 @@ describe("executeOperations against UniversalResolver", () => { await expect( executeOperations({ name: NAME_WITH_ENCODED_LABELHASHES, - resolverAddress: UniversalResolverV2.address, + resolverAddress: UniversalResolver.address, useENSIP10Resolve: true, operations: makeOperations(node, { texts: ["description"] }), publicClient, diff --git a/apps/ensapi/src/lib/resolution/forward-resolution.ts b/apps/ensapi/src/lib/resolution/forward-resolution.ts index 7d7e9dd409..02bf83a5a3 100644 --- a/apps/ensapi/src/lib/resolution/forward-resolution.ts +++ b/apps/ensapi/src/lib/resolution/forward-resolution.ts @@ -16,7 +16,6 @@ import { type ForwardResolutionResult, getDatasourceContract, getENSv1RootRegistry, - maybeGetDatasourceContract, type ResolverRecordsSelection, TraceableENSProtocol, toJson, @@ -167,20 +166,12 @@ async function _resolveForward( // plugin being configured — a namespace may be ENSv1-only even when the Unigraph plugin is // defined, and forward resolution must follow the ENSv1 path in that case. if (maybeGetDatasource(di.context.namespace, DatasourceNames.ENSv2Root)) { - const universalResolverV1 = getDatasourceContract( + const universalResolver = getDatasourceContract( di.context.namespace, DatasourceNames.ENSRoot, "UniversalResolver", ); - const universalResolverV2 = maybeGetDatasourceContract( - di.context.namespace, - DatasourceNames.ENSRoot, - "UniversalResolverV2", - ); - - const UniversalResolverAddress = - universalResolverV2?.address ?? universalResolverV1.address; operations = await withEnsProtocolStep( TraceableENSProtocol.ForwardResolution, ForwardResolutionProtocolStep.ExecuteResolveCalls, @@ -188,7 +179,7 @@ async function _resolveForward( () => executeOperations({ name, - resolverAddress: UniversalResolverAddress, + resolverAddress: universalResolver.address, operations, publicClient, useENSIP10Resolve: true, diff --git a/packages/datasources/src/abis/ensv2/UniversalResolverV2.ts b/packages/datasources/src/abis/ensv2/UniversalResolverV2.ts deleted file mode 100644 index 827cac3f3c..0000000000 --- a/packages/datasources/src/abis/ensv2/UniversalResolverV2.ts +++ /dev/null @@ -1,876 +0,0 @@ -import type { Abi } from "viem"; - -export const UniversalResolverV2 = [ - { - type: "constructor", - inputs: [ - { - name: "root", - type: "address", - internalType: "contract IRegistry", - }, - { - name: "batchGatewayProvider", - type: "address", - internalType: "contract IGatewayProvider", - }, - ], - stateMutability: "nonpayable", - }, - { - type: "function", - name: "ROOT_REGISTRY", - inputs: [], - outputs: [ - { - name: "", - type: "address", - internalType: "contract IRegistry", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "batchGatewayProvider", - inputs: [], - outputs: [ - { - name: "", - type: "address", - internalType: "contract IGatewayProvider", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "ccipBatch", - inputs: [ - { - name: "batch", - type: "tuple", - internalType: "struct CCIPBatcher.Batch", - components: [ - { - name: "lookups", - type: "tuple[]", - internalType: "struct CCIPBatcher.Lookup[]", - components: [ - { - name: "target", - type: "address", - internalType: "address", - }, - { - name: "call", - type: "bytes", - internalType: "bytes", - }, - { - name: "data", - type: "bytes", - internalType: "bytes", - }, - { - name: "flags", - type: "uint256", - internalType: "uint256", - }, - ], - }, - { - name: "gateways", - type: "string[]", - internalType: "string[]", - }, - ], - }, - ], - outputs: [ - { - name: "", - type: "tuple", - internalType: "struct CCIPBatcher.Batch", - components: [ - { - name: "lookups", - type: "tuple[]", - internalType: "struct CCIPBatcher.Lookup[]", - components: [ - { - name: "target", - type: "address", - internalType: "address", - }, - { - name: "call", - type: "bytes", - internalType: "bytes", - }, - { - name: "data", - type: "bytes", - internalType: "bytes", - }, - { - name: "flags", - type: "uint256", - internalType: "uint256", - }, - ], - }, - { - name: "gateways", - type: "string[]", - internalType: "string[]", - }, - ], - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "ccipBatchCallback", - inputs: [ - { - name: "response", - type: "bytes", - internalType: "bytes", - }, - { - name: "extraData", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "batch", - type: "tuple", - internalType: "struct CCIPBatcher.Batch", - components: [ - { - name: "lookups", - type: "tuple[]", - internalType: "struct CCIPBatcher.Lookup[]", - components: [ - { - name: "target", - type: "address", - internalType: "address", - }, - { - name: "call", - type: "bytes", - internalType: "bytes", - }, - { - name: "data", - type: "bytes", - internalType: "bytes", - }, - { - name: "flags", - type: "uint256", - internalType: "uint256", - }, - ], - }, - { - name: "gateways", - type: "string[]", - internalType: "string[]", - }, - ], - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "ccipReadCallback", - inputs: [ - { - name: "response", - type: "bytes", - internalType: "bytes", - }, - { - name: "extraData", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [], - stateMutability: "view", - }, - { - type: "function", - name: "findCanonicalName", - inputs: [ - { - name: "registry", - type: "address", - internalType: "contract IRegistry", - }, - ], - outputs: [ - { - name: "", - type: "bytes", - internalType: "bytes", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "findCanonicalRegistry", - inputs: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "", - type: "address", - internalType: "contract IRegistry", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "findExactRegistry", - inputs: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "", - type: "address", - internalType: "contract IRegistry", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "findRegistries", - inputs: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "", - type: "address[]", - internalType: "contract IRegistry[]", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "findResolver", - inputs: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "resolver", - type: "address", - internalType: "address", - }, - { - name: "node", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "offset", - type: "uint256", - internalType: "uint256", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "requireResolver", - inputs: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "info", - type: "tuple", - internalType: "struct AbstractUniversalResolver.ResolverInfo", - components: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - { - name: "offset", - type: "uint256", - internalType: "uint256", - }, - { - name: "node", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "resolver", - type: "address", - internalType: "address", - }, - { - name: "extended", - type: "bool", - internalType: "bool", - }, - ], - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "resolve", - inputs: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - { - name: "data", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "", - type: "bytes", - internalType: "bytes", - }, - { - name: "", - type: "address", - internalType: "address", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "resolveBatchCallback", - inputs: [ - { - name: "response", - type: "bytes", - internalType: "bytes", - }, - { - name: "extraData", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [], - stateMutability: "view", - }, - { - type: "function", - name: "resolveCallback", - inputs: [ - { - name: "response", - type: "bytes", - internalType: "bytes", - }, - { - name: "extraData", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "", - type: "bytes", - internalType: "bytes", - }, - { - name: "", - type: "address", - internalType: "address", - }, - ], - stateMutability: "pure", - }, - { - type: "function", - name: "resolveDirectCallback", - inputs: [ - { - name: "response", - type: "bytes", - internalType: "bytes", - }, - { - name: "extraData", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [], - stateMutability: "view", - }, - { - type: "function", - name: "resolveDirectCallbackError", - inputs: [ - { - name: "response", - type: "bytes", - internalType: "bytes", - }, - { - name: "", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [], - stateMutability: "pure", - }, - { - type: "function", - name: "resolveWithGateways", - inputs: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - { - name: "data", - type: "bytes", - internalType: "bytes", - }, - { - name: "gateways", - type: "string[]", - internalType: "string[]", - }, - ], - outputs: [ - { - name: "result", - type: "bytes", - internalType: "bytes", - }, - { - name: "resolver", - type: "address", - internalType: "address", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "resolveWithResolver", - inputs: [ - { - name: "resolver", - type: "address", - internalType: "address", - }, - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - { - name: "data", - type: "bytes", - internalType: "bytes", - }, - { - name: "gateways", - type: "string[]", - internalType: "string[]", - }, - ], - outputs: [ - { - name: "", - type: "bytes", - internalType: "bytes", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "reverse", - inputs: [ - { - name: "lookupAddress", - type: "bytes", - internalType: "bytes", - }, - { - name: "coinType", - type: "uint256", - internalType: "uint256", - }, - ], - outputs: [ - { - name: "", - type: "string", - internalType: "string", - }, - { - name: "", - type: "address", - internalType: "address", - }, - { - name: "", - type: "address", - internalType: "address", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "reverseAddressCallback", - inputs: [ - { - name: "response", - type: "bytes", - internalType: "bytes", - }, - { - name: "extraData", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "primary", - type: "string", - internalType: "string", - }, - { - name: "resolver", - type: "address", - internalType: "address", - }, - { - name: "reverseResolver", - type: "address", - internalType: "address", - }, - ], - stateMutability: "pure", - }, - { - type: "function", - name: "reverseNameCallback", - inputs: [ - { - name: "response", - type: "bytes", - internalType: "bytes", - }, - { - name: "extraData", - type: "bytes", - internalType: "bytes", - }, - ], - outputs: [ - { - name: "primary", - type: "string", - internalType: "string", - }, - { - name: "", - type: "address", - internalType: "address", - }, - { - name: "", - type: "address", - internalType: "address", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "reverseWithGateways", - inputs: [ - { - name: "lookupAddress", - type: "bytes", - internalType: "bytes", - }, - { - name: "coinType", - type: "uint256", - internalType: "uint256", - }, - { - name: "gateways", - type: "string[]", - internalType: "string[]", - }, - ], - outputs: [ - { - name: "primary", - type: "string", - internalType: "string", - }, - { - name: "resolver", - type: "address", - internalType: "address", - }, - { - name: "reverseResolver", - type: "address", - internalType: "address", - }, - ], - stateMutability: "view", - }, - { - type: "function", - name: "supportsInterface", - inputs: [ - { - name: "interfaceId", - type: "bytes4", - internalType: "bytes4", - }, - ], - outputs: [ - { - name: "", - type: "bool", - internalType: "bool", - }, - ], - stateMutability: "view", - }, - { - type: "error", - name: "DNSDecodingFailed", - inputs: [ - { - name: "dns", - type: "bytes", - internalType: "bytes", - }, - ], - }, - { - type: "error", - name: "DNSEncodingFailed", - inputs: [ - { - name: "ens", - type: "string", - internalType: "string", - }, - ], - }, - { - type: "error", - name: "EmptyAddress", - inputs: [], - }, - { - type: "error", - name: "HttpError", - inputs: [ - { - name: "status", - type: "uint16", - internalType: "uint16", - }, - { - name: "message", - type: "string", - internalType: "string", - }, - ], - }, - { - type: "error", - name: "InvalidBatchGatewayResponse", - inputs: [], - }, - { - type: "error", - name: "LabelIsEmpty", - inputs: [], - }, - { - type: "error", - name: "LabelIsTooLong", - inputs: [ - { - name: "label", - type: "string", - internalType: "string", - }, - ], - }, - { - type: "error", - name: "OffchainLookup", - inputs: [ - { - name: "sender", - type: "address", - internalType: "address", - }, - { - name: "urls", - type: "string[]", - internalType: "string[]", - }, - { - name: "callData", - type: "bytes", - internalType: "bytes", - }, - { - name: "callbackFunction", - type: "bytes4", - internalType: "bytes4", - }, - { - name: "extraData", - type: "bytes", - internalType: "bytes", - }, - ], - }, - { - type: "error", - name: "OffsetOutOfBoundsError", - inputs: [ - { - name: "offset", - type: "uint256", - internalType: "uint256", - }, - { - name: "length", - type: "uint256", - internalType: "uint256", - }, - ], - }, - { - type: "error", - name: "ResolverError", - inputs: [ - { - name: "errorData", - type: "bytes", - internalType: "bytes", - }, - ], - }, - { - type: "error", - name: "ResolverNotContract", - inputs: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - { - name: "resolver", - type: "address", - internalType: "address", - }, - ], - }, - { - type: "error", - name: "ResolverNotFound", - inputs: [ - { - name: "name", - type: "bytes", - internalType: "bytes", - }, - ], - }, - { - type: "error", - name: "ReverseAddressMismatch", - inputs: [ - { - name: "primary", - type: "string", - internalType: "string", - }, - { - name: "primaryAddress", - type: "bytes", - internalType: "bytes", - }, - ], - }, - { - type: "error", - name: "UnsupportedResolverProfile", - inputs: [ - { - name: "selector", - type: "bytes4", - internalType: "bytes4", - }, - ], - }, -] as const satisfies Abi; diff --git a/packages/datasources/src/abis/root/UniversalResolverV1.ts b/packages/datasources/src/abis/root/UniversalResolverV1.ts deleted file mode 100644 index 93d7b943c7..0000000000 --- a/packages/datasources/src/abis/root/UniversalResolverV1.ts +++ /dev/null @@ -1,789 +0,0 @@ -import type { Abi } from "viem"; - -export const UniversalResolverV1 = [ - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address", - }, - { - internalType: "contract ENS", - name: "ens", - type: "address", - }, - { - internalType: "contract IGatewayProvider", - name: "batchGatewayProvider", - type: "address", - }, - ], - stateMutability: "nonpayable", - type: "constructor", - }, - { - inputs: [ - { - internalType: "bytes", - name: "dns", - type: "bytes", - }, - ], - name: "DNSDecodingFailed", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "ens", - type: "string", - }, - ], - name: "DNSEncodingFailed", - type: "error", - }, - { - inputs: [], - name: "EmptyAddress", - type: "error", - }, - { - inputs: [ - { - internalType: "uint16", - name: "status", - type: "uint16", - }, - { - internalType: "string", - name: "message", - type: "string", - }, - ], - name: "HttpError", - type: "error", - }, - { - inputs: [], - name: "InvalidBatchGatewayResponse", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "sender", - type: "address", - }, - { - internalType: "string[]", - name: "urls", - type: "string[]", - }, - { - internalType: "bytes", - name: "callData", - type: "bytes", - }, - { - internalType: "bytes4", - name: "callbackFunction", - type: "bytes4", - }, - { - internalType: "bytes", - name: "extraData", - type: "bytes", - }, - ], - name: "OffchainLookup", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "offset", - type: "uint256", - }, - { - internalType: "uint256", - name: "length", - type: "uint256", - }, - ], - name: "OffsetOutOfBoundsError", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes", - name: "errorData", - type: "bytes", - }, - ], - name: "ResolverError", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - { - internalType: "address", - name: "resolver", - type: "address", - }, - ], - name: "ResolverNotContract", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - ], - name: "ResolverNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "primary", - type: "string", - }, - { - internalType: "bytes", - name: "primaryAddress", - type: "bytes", - }, - ], - name: "ReverseAddressMismatch", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes4", - name: "selector", - type: "bytes4", - }, - ], - name: "UnsupportedResolverProfile", - type: "error", - }, - { - inputs: [], - name: "batchGatewayProvider", - outputs: [ - { - internalType: "contract IGatewayProvider", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - components: [ - { - components: [ - { - internalType: "address", - name: "target", - type: "address", - }, - { - internalType: "bytes", - name: "call", - type: "bytes", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "uint256", - name: "flags", - type: "uint256", - }, - ], - internalType: "struct CCIPBatcher.Lookup[]", - name: "lookups", - type: "tuple[]", - }, - { - internalType: "string[]", - name: "gateways", - type: "string[]", - }, - ], - internalType: "struct CCIPBatcher.Batch", - name: "batch", - type: "tuple", - }, - ], - name: "ccipBatch", - outputs: [ - { - components: [ - { - components: [ - { - internalType: "address", - name: "target", - type: "address", - }, - { - internalType: "bytes", - name: "call", - type: "bytes", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "uint256", - name: "flags", - type: "uint256", - }, - ], - internalType: "struct CCIPBatcher.Lookup[]", - name: "lookups", - type: "tuple[]", - }, - { - internalType: "string[]", - name: "gateways", - type: "string[]", - }, - ], - internalType: "struct CCIPBatcher.Batch", - name: "", - type: "tuple", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "response", - type: "bytes", - }, - { - internalType: "bytes", - name: "extraData", - type: "bytes", - }, - ], - name: "ccipBatchCallback", - outputs: [ - { - components: [ - { - components: [ - { - internalType: "address", - name: "target", - type: "address", - }, - { - internalType: "bytes", - name: "call", - type: "bytes", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "uint256", - name: "flags", - type: "uint256", - }, - ], - internalType: "struct CCIPBatcher.Lookup[]", - name: "lookups", - type: "tuple[]", - }, - { - internalType: "string[]", - name: "gateways", - type: "string[]", - }, - ], - internalType: "struct CCIPBatcher.Batch", - name: "batch", - type: "tuple", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "response", - type: "bytes", - }, - { - internalType: "bytes", - name: "extraData", - type: "bytes", - }, - ], - name: "ccipReadCallback", - outputs: [], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - ], - name: "findResolver", - outputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - { - internalType: "bytes32", - name: "", - type: "bytes32", - }, - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "registry", - outputs: [ - { - internalType: "contract ENS", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - ], - name: "requireResolver", - outputs: [ - { - components: [ - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - { - internalType: "uint256", - name: "offset", - type: "uint256", - }, - { - internalType: "bytes32", - name: "node", - type: "bytes32", - }, - { - internalType: "address", - name: "resolver", - type: "address", - }, - { - internalType: "bool", - name: "extended", - type: "bool", - }, - ], - internalType: "struct AbstractUniversalResolver.ResolverInfo", - name: "info", - type: "tuple", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - name: "resolve", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes", - }, - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "response", - type: "bytes", - }, - { - internalType: "bytes", - name: "extraData", - type: "bytes", - }, - ], - name: "resolveBatchCallback", - outputs: [], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "response", - type: "bytes", - }, - { - internalType: "bytes", - name: "extraData", - type: "bytes", - }, - ], - name: "resolveCallback", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes", - }, - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "pure", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "response", - type: "bytes", - }, - { - internalType: "bytes", - name: "extraData", - type: "bytes", - }, - ], - name: "resolveDirectCallback", - outputs: [], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "response", - type: "bytes", - }, - { - internalType: "bytes", - name: "", - type: "bytes", - }, - ], - name: "resolveDirectCallbackError", - outputs: [], - stateMutability: "pure", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "string[]", - name: "gateways", - type: "string[]", - }, - ], - name: "resolveWithGateways", - outputs: [ - { - internalType: "bytes", - name: "result", - type: "bytes", - }, - { - internalType: "address", - name: "resolver", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "resolver", - type: "address", - }, - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "string[]", - name: "gateways", - type: "string[]", - }, - ], - name: "resolveWithResolver", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "lookupAddress", - type: "bytes", - }, - { - internalType: "uint256", - name: "coinType", - type: "uint256", - }, - ], - name: "reverse", - outputs: [ - { - internalType: "string", - name: "", - type: "string", - }, - { - internalType: "address", - name: "", - type: "address", - }, - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "response", - type: "bytes", - }, - { - internalType: "bytes", - name: "extraData", - type: "bytes", - }, - ], - name: "reverseAddressCallback", - outputs: [ - { - internalType: "string", - name: "primary", - type: "string", - }, - { - internalType: "address", - name: "resolver", - type: "address", - }, - { - internalType: "address", - name: "reverseResolver", - type: "address", - }, - ], - stateMutability: "pure", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "response", - type: "bytes", - }, - { - internalType: "bytes", - name: "extraData", - type: "bytes", - }, - ], - name: "reverseNameCallback", - outputs: [ - { - internalType: "string", - name: "primary", - type: "string", - }, - { - internalType: "address", - name: "", - type: "address", - }, - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes", - name: "lookupAddress", - type: "bytes", - }, - { - internalType: "uint256", - name: "coinType", - type: "uint256", - }, - { - internalType: "string[]", - name: "gateways", - type: "string[]", - }, - ], - name: "reverseWithGateways", - outputs: [ - { - internalType: "string", - name: "primary", - type: "string", - }, - { - internalType: "address", - name: "resolver", - type: "address", - }, - { - internalType: "address", - name: "reverseResolver", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4", - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", - }, -] as const satisfies Abi; diff --git a/packages/datasources/src/abis/shared/IMulticallable.ts b/packages/datasources/src/abis/shared/IMulticallable.ts new file mode 100644 index 0000000000..fa89d2408b --- /dev/null +++ b/packages/datasources/src/abis/shared/IMulticallable.ts @@ -0,0 +1,12 @@ +import type { Abi } from "viem"; + +// function multicall(bytes[] calldata data) external view returns (bytes[] memory); +export const IMulticallable = [ + { + type: "function", + name: "multicall", + stateMutability: "view", + inputs: [{ internalType: "bytes[]", name: "data", type: "bytes[]" }], + outputs: [{ internalType: "bytes[]", name: "", type: "bytes[]" }], + }, +] as const satisfies Abi; diff --git a/packages/datasources/src/abis/shared/IUniversalResolver.ts b/packages/datasources/src/abis/shared/IUniversalResolver.ts new file mode 100644 index 0000000000..e4ec7166d1 --- /dev/null +++ b/packages/datasources/src/abis/shared/IUniversalResolver.ts @@ -0,0 +1,361 @@ +import type { Abi } from "viem"; + +export const IUniversalResolver = [ + { + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "contract ENS", name: "ens", type: "address" }, + { internalType: "contract IGatewayProvider", name: "batchGatewayProvider", type: "address" }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [{ internalType: "bytes", name: "dns", type: "bytes" }], + name: "DNSDecodingFailed", + type: "error", + }, + { + inputs: [{ internalType: "string", name: "ens", type: "string" }], + name: "DNSEncodingFailed", + type: "error", + }, + { inputs: [], name: "EmptyAddress", type: "error" }, + { + inputs: [ + { internalType: "uint16", name: "status", type: "uint16" }, + { internalType: "string", name: "message", type: "string" }, + ], + name: "HttpError", + type: "error", + }, + { inputs: [], name: "InvalidBatchGatewayResponse", type: "error" }, + { + inputs: [ + { internalType: "address", name: "sender", type: "address" }, + { internalType: "string[]", name: "urls", type: "string[]" }, + { internalType: "bytes", name: "callData", type: "bytes" }, + { internalType: "bytes4", name: "callbackFunction", type: "bytes4" }, + { internalType: "bytes", name: "extraData", type: "bytes" }, + ], + name: "OffchainLookup", + type: "error", + }, + { + inputs: [ + { internalType: "uint256", name: "offset", type: "uint256" }, + { internalType: "uint256", name: "length", type: "uint256" }, + ], + name: "OffsetOutOfBoundsError", + type: "error", + }, + { + inputs: [{ internalType: "bytes", name: "errorData", type: "bytes" }], + name: "ResolverError", + type: "error", + }, + { + inputs: [ + { internalType: "bytes", name: "name", type: "bytes" }, + { internalType: "address", name: "resolver", type: "address" }, + ], + name: "ResolverNotContract", + type: "error", + }, + { + inputs: [{ internalType: "bytes", name: "name", type: "bytes" }], + name: "ResolverNotFound", + type: "error", + }, + { + inputs: [ + { internalType: "string", name: "primary", type: "string" }, + { internalType: "bytes", name: "primaryAddress", type: "bytes" }, + ], + name: "ReverseAddressMismatch", + type: "error", + }, + { + inputs: [{ internalType: "bytes4", name: "selector", type: "bytes4" }], + name: "UnsupportedResolverProfile", + type: "error", + }, + { + inputs: [], + name: "batchGatewayProvider", + outputs: [{ internalType: "contract IGatewayProvider", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { internalType: "address", name: "target", type: "address" }, + { internalType: "bytes", name: "call", type: "bytes" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "uint256", name: "flags", type: "uint256" }, + ], + internalType: "struct CCIPBatcher.Lookup[]", + name: "lookups", + type: "tuple[]", + }, + { internalType: "string[]", name: "gateways", type: "string[]" }, + ], + internalType: "struct CCIPBatcher.Batch", + name: "batch", + type: "tuple", + }, + ], + name: "ccipBatch", + outputs: [ + { + components: [ + { + components: [ + { internalType: "address", name: "target", type: "address" }, + { internalType: "bytes", name: "call", type: "bytes" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "uint256", name: "flags", type: "uint256" }, + ], + internalType: "struct CCIPBatcher.Lookup[]", + name: "lookups", + type: "tuple[]", + }, + { internalType: "string[]", name: "gateways", type: "string[]" }, + ], + internalType: "struct CCIPBatcher.Batch", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "bytes", name: "extraData", type: "bytes" }, + ], + name: "ccipBatchCallback", + outputs: [ + { + components: [ + { + components: [ + { internalType: "address", name: "target", type: "address" }, + { internalType: "bytes", name: "call", type: "bytes" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "uint256", name: "flags", type: "uint256" }, + ], + internalType: "struct CCIPBatcher.Lookup[]", + name: "lookups", + type: "tuple[]", + }, + { internalType: "string[]", name: "gateways", type: "string[]" }, + ], + internalType: "struct CCIPBatcher.Batch", + name: "batch", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "bytes", name: "extraData", type: "bytes" }, + ], + name: "ccipReadCallback", + outputs: [], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "bytes", name: "name", type: "bytes" }], + name: "findResolver", + outputs: [ + { internalType: "address", name: "", type: "address" }, + { internalType: "bytes32", name: "", type: "bytes32" }, + { internalType: "uint256", name: "", type: "uint256" }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "registry", + outputs: [{ internalType: "contract ENS", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "bytes", name: "name", type: "bytes" }], + name: "requireResolver", + outputs: [ + { + components: [ + { internalType: "bytes", name: "name", type: "bytes" }, + { internalType: "uint256", name: "offset", type: "uint256" }, + { internalType: "bytes32", name: "node", type: "bytes32" }, + { internalType: "address", name: "resolver", type: "address" }, + { internalType: "bool", name: "extended", type: "bool" }, + ], + internalType: "struct AbstractUniversalResolver.ResolverInfo", + name: "info", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "name", type: "bytes" }, + { internalType: "bytes", name: "data", type: "bytes" }, + ], + name: "resolve", + outputs: [ + { internalType: "bytes", name: "", type: "bytes" }, + { internalType: "address", name: "", type: "address" }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "bytes", name: "extraData", type: "bytes" }, + ], + name: "resolveBatchCallback", + outputs: [], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "bytes", name: "extraData", type: "bytes" }, + ], + name: "resolveCallback", + outputs: [ + { internalType: "bytes", name: "", type: "bytes" }, + { internalType: "address", name: "", type: "address" }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "bytes", name: "extraData", type: "bytes" }, + ], + name: "resolveDirectCallback", + outputs: [], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "bytes", name: "", type: "bytes" }, + ], + name: "resolveDirectCallbackError", + outputs: [], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "name", type: "bytes" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "string[]", name: "gateways", type: "string[]" }, + ], + name: "resolveWithGateways", + outputs: [ + { internalType: "bytes", name: "result", type: "bytes" }, + { internalType: "address", name: "resolver", type: "address" }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "resolver", type: "address" }, + { internalType: "bytes", name: "name", type: "bytes" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { internalType: "string[]", name: "gateways", type: "string[]" }, + ], + name: "resolveWithResolver", + outputs: [{ internalType: "bytes", name: "", type: "bytes" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "lookupAddress", type: "bytes" }, + { internalType: "uint256", name: "coinType", type: "uint256" }, + ], + name: "reverse", + outputs: [ + { internalType: "string", name: "", type: "string" }, + { internalType: "address", name: "", type: "address" }, + { internalType: "address", name: "", type: "address" }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "bytes", name: "extraData", type: "bytes" }, + ], + name: "reverseAddressCallback", + outputs: [ + { internalType: "string", name: "primary", type: "string" }, + { internalType: "address", name: "resolver", type: "address" }, + { internalType: "address", name: "reverseResolver", type: "address" }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "bytes", name: "extraData", type: "bytes" }, + ], + name: "reverseNameCallback", + outputs: [ + { internalType: "string", name: "primary", type: "string" }, + { internalType: "address", name: "", type: "address" }, + { internalType: "address", name: "", type: "address" }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes", name: "lookupAddress", type: "bytes" }, + { internalType: "uint256", name: "coinType", type: "uint256" }, + { internalType: "string[]", name: "gateways", type: "string[]" }, + ], + name: "reverseWithGateways", + outputs: [ + { internalType: "string", name: "primary", type: "string" }, + { internalType: "address", name: "resolver", type: "address" }, + { internalType: "address", name: "reverseResolver", type: "address" }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "bytes4", name: "interfaceId", type: "bytes4" }], + name: "supportsInterface", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, +] as const satisfies Abi; diff --git a/packages/datasources/src/abis/shared/UniversalResolver.ts b/packages/datasources/src/abis/shared/UniversalResolver.ts index 5b9d98fef1..ea03af1fac 100644 --- a/packages/datasources/src/abis/shared/UniversalResolver.ts +++ b/packages/datasources/src/abis/shared/UniversalResolver.ts @@ -1,6 +1,6 @@ import { mergeAbis } from "@ponder/utils"; -import { UniversalResolverV2 } from "../ensv2/UniversalResolverV2"; -import { UniversalResolverV1 } from "../root/UniversalResolverV1"; +import { IMulticallable } from "./IMulticallable"; +import { IUniversalResolver } from "./IUniversalResolver"; -export const UniversalResolverABI = mergeAbis([UniversalResolverV1, UniversalResolverV2]); +export const UniversalResolverABI = mergeAbis([IUniversalResolver, IMulticallable]); diff --git a/packages/datasources/src/ens-test-env.ts b/packages/datasources/src/ens-test-env.ts index f864cd921d..22775bb339 100644 --- a/packages/datasources/src/ens-test-env.ts +++ b/packages/datasources/src/ens-test-env.ts @@ -1,16 +1,15 @@ import { EnhancedAccessControl } from "./abis/ensv2/EnhancedAccessControl"; import { ETHRegistrar } from "./abis/ensv2/ETHRegistrar"; import { Registry } from "./abis/ensv2/Registry"; -import { UniversalResolverV2 } from "./abis/ensv2/UniversalResolverV2"; // ABIs for ENSRoot Datasource import { BaseRegistrar as root_BaseRegistrar } from "./abis/root/BaseRegistrar"; import { LegacyEthRegistrarController as root_LegacyEthRegistrarController } from "./abis/root/LegacyEthRegistrarController"; import { NameWrapper as root_NameWrapper } from "./abis/root/NameWrapper"; import { Registry as root_Registry } from "./abis/root/Registry"; -import { UniversalResolverV1 } from "./abis/root/UniversalResolverV1"; import { UnwrappedEthRegistrarController as root_UnwrappedEthRegistrarController } from "./abis/root/UnwrappedEthRegistrarController"; import { WrappedEthRegistrarController as root_WrappedEthRegistrarController } from "./abis/root/WrappedEthRegistrarController"; import { StandaloneReverseRegistrar } from "./abis/shared/StandaloneReverseRegistrar"; +import { UniversalResolverABI } from "./abis/shared/UniversalResolver"; import { contracts } from "./devnet/constants"; import { ensTestEnvChain } from "./lib/chains"; // Shared ABIs @@ -86,14 +85,8 @@ export default { startBlock: 0, }, UniversalResolver: { - abi: UniversalResolverV1, - address: contracts.UniversalResolver, - startBlock: 0, - }, - // NOTE: named UniversalResolverV2 in devnet - UniversalResolverV2: { - abi: UniversalResolverV2, - address: contracts.UniversalResolverV2, + abi: UniversalResolverABI, + address: contracts.UpgradableUniversalResolverProxy, startBlock: 0, }, }, diff --git a/packages/datasources/src/mainnet.ts b/packages/datasources/src/mainnet.ts index 0e69340380..f3e2a4925d 100644 --- a/packages/datasources/src/mainnet.ts +++ b/packages/datasources/src/mainnet.ts @@ -17,12 +17,12 @@ import { LegacyEthRegistrarController as root_LegacyEthRegistrarController } fro import { NameWrapper as root_NameWrapper } from "./abis/root/NameWrapper"; import { Registry as root_Registry } from "./abis/root/Registry"; import { UniversalRegistrarRenewalWithReferrer as root_UniversalRegistrarRenewalWithReferrer } from "./abis/root/UniversalRegistrarRenewalWithReferrer"; -import { UniversalResolverV1 } from "./abis/root/UniversalResolverV1"; import { UnwrappedEthRegistrarController as root_UnwrappedEthRegistrarController } from "./abis/root/UnwrappedEthRegistrarController"; import { WrappedEthRegistrarController as root_WrappedEthRegistrarController } from "./abis/root/WrappedEthRegistrarController"; import { Seaport as Seaport1_5 } from "./abis/seaport/Seaport1.5"; // Shared ABIs import { StandaloneReverseRegistrar } from "./abis/shared/StandaloneReverseRegistrar"; +import { UniversalResolverABI } from "./abis/shared/UniversalResolver"; import { ThreeDNSToken } from "./abis/threedns/ThreeDNSToken"; import { ResolverABI } from "./lib/ResolverABI"; // Types @@ -86,9 +86,9 @@ export default { startBlock: 16925608, }, UniversalResolver: { - abi: UniversalResolverV1, - address: "0xabd80e8a13596feea40fd26fd6a24c3fe76f05fb", - startBlock: 22671701, + abi: UniversalResolverABI, + address: "0xeeeeeeee14d718c2b47d9923deab1335e144eeee", + startBlock: 23085558, }, BasenamesL1Resolver: { abi: ResolverABI, diff --git a/packages/datasources/src/sepolia-v2.ts b/packages/datasources/src/sepolia-v2.ts index 433e83db89..5fabd01f4c 100644 --- a/packages/datasources/src/sepolia-v2.ts +++ b/packages/datasources/src/sepolia-v2.ts @@ -12,15 +12,14 @@ import { import { EnhancedAccessControl } from "./abis/ensv2/EnhancedAccessControl"; import { ETHRegistrar } from "./abis/ensv2/ETHRegistrar"; import { Registry } from "./abis/ensv2/Registry"; -import { UniversalResolverV2 } from "./abis/ensv2/UniversalResolverV2"; // ABIs for ENSRoot Datasource import { BaseRegistrar as root_BaseRegistrar } from "./abis/root/BaseRegistrar"; import { NameWrapper as root_NameWrapper } from "./abis/root/NameWrapper"; import { Registry as root_Registry } from "./abis/root/Registry"; -import { UniversalResolverV1 } from "./abis/root/UniversalResolverV1"; import { UnwrappedEthRegistrarController as root_UnwrappedEthRegistrarController } from "./abis/root/UnwrappedEthRegistrarController"; // Shared ABIs import { StandaloneReverseRegistrar } from "./abis/shared/StandaloneReverseRegistrar"; +import { UniversalResolverABI } from "./abis/shared/UniversalResolver"; import { ResolverABI } from "./lib/ResolverABI"; // Types import { DatasourceNames, type ENSNamespace } from "./lib/types"; @@ -89,14 +88,9 @@ export default { startBlock: SEPOLIA_ENSV2_DEPLOYMENT_BLOCK, }, UniversalResolver: { - abi: UniversalResolverV1, - address: "0x988061f048e8ff0290dd88ec8afed6b163d7ea76", - startBlock: SEPOLIA_ENSV2_DEPLOYMENT_BLOCK, - }, - UniversalResolverV2: { - abi: UniversalResolverV2, - address: "0x8e4ae9c494a57f15ee19c723c87971c99e014b64", - startBlock: SEPOLIA_ENSV2_DEPLOYMENT_BLOCK, + abi: UniversalResolverABI, + address: "0x651d670ce0d0f1ed0893f39d51fd0dbd4546c9ef", + startBlock: 10893223, }, }, }, diff --git a/packages/datasources/src/sepolia.ts b/packages/datasources/src/sepolia.ts index b335100482..102306020b 100644 --- a/packages/datasources/src/sepolia.ts +++ b/packages/datasources/src/sepolia.ts @@ -24,12 +24,12 @@ import { LegacyEthRegistrarController as root_LegacyEthRegistrarController } fro import { NameWrapper as root_NameWrapper } from "./abis/root/NameWrapper"; import { Registry as root_Registry } from "./abis/root/Registry"; import { UniversalRegistrarRenewalWithReferrer as root_UniversalRegistrarRenewalWithReferrer } from "./abis/root/UniversalRegistrarRenewalWithReferrer"; -import { UniversalResolverV1 } from "./abis/root/UniversalResolverV1"; import { UnwrappedEthRegistrarController as root_UnwrappedEthRegistrarController } from "./abis/root/UnwrappedEthRegistrarController"; import { WrappedEthRegistrarController as root_WrappedEthRegistrarController } from "./abis/root/WrappedEthRegistrarController"; import { Seaport as Seaport1_5 } from "./abis/seaport/Seaport1.5"; // Shared ABIs import { StandaloneReverseRegistrar } from "./abis/shared/StandaloneReverseRegistrar"; +import { UniversalResolverABI } from "./abis/shared/UniversalResolver"; import { ResolverABI } from "./lib/ResolverABI"; // Types import { DatasourceNames, type ENSNamespace } from "./lib/types"; @@ -94,9 +94,9 @@ export default { startBlock: 3790153, }, UniversalResolver: { - abi: UniversalResolverV1, - address: "0xb7b7dadf4d42a08b3ec1d3a1079959dfbc8cffcc", - startBlock: 8515717, + abi: UniversalResolverABI, + address: "0xeeeeeeee14d718c2b47d9923deab1335e144eeee", + startBlock: 8928790, }, BasenamesL1Resolver: { abi: ResolverABI, diff --git a/packages/integration-test-env/src/seed/resolver-records.ts b/packages/integration-test-env/src/seed/resolver-records.ts index 2ee7f3cb3c..1448edcc1b 100644 --- a/packages/integration-test-env/src/seed/resolver-records.ts +++ b/packages/integration-test-env/src/seed/resolver-records.ts @@ -49,7 +49,7 @@ async function seedResolverRecordsForName( async function findResolver(client: DevnetWalletClient, name: string): Promise
{ const [resolver] = await client.readContract({ - address: contracts.UniversalResolverV2, + address: contracts.UpgradableUniversalResolverProxy, abi: UniversalResolverABI, functionName: "findResolver", args: [toHex(packetToBytes(name))], From 631f599dbcac1d94c51403e3e838e237624070dd Mon Sep 17 00:00:00 2001 From: shrugs Date: Fri, 5 Jun 2026 15:57:15 -0500 Subject: [PATCH 2/3] fix(datasources): drop constructor from IUniversalResolver, tidy IMulticallable comment --- packages/datasources/src/abis/shared/IMulticallable.ts | 1 - .../datasources/src/abis/shared/IUniversalResolver.ts | 9 --------- 2 files changed, 10 deletions(-) diff --git a/packages/datasources/src/abis/shared/IMulticallable.ts b/packages/datasources/src/abis/shared/IMulticallable.ts index fa89d2408b..883e26366b 100644 --- a/packages/datasources/src/abis/shared/IMulticallable.ts +++ b/packages/datasources/src/abis/shared/IMulticallable.ts @@ -1,6 +1,5 @@ import type { Abi } from "viem"; -// function multicall(bytes[] calldata data) external view returns (bytes[] memory); export const IMulticallable = [ { type: "function", diff --git a/packages/datasources/src/abis/shared/IUniversalResolver.ts b/packages/datasources/src/abis/shared/IUniversalResolver.ts index e4ec7166d1..a415f8d706 100644 --- a/packages/datasources/src/abis/shared/IUniversalResolver.ts +++ b/packages/datasources/src/abis/shared/IUniversalResolver.ts @@ -1,15 +1,6 @@ import type { Abi } from "viem"; export const IUniversalResolver = [ - { - inputs: [ - { internalType: "address", name: "owner", type: "address" }, - { internalType: "contract ENS", name: "ens", type: "address" }, - { internalType: "contract IGatewayProvider", name: "batchGatewayProvider", type: "address" }, - ], - stateMutability: "nonpayable", - type: "constructor", - }, { inputs: [{ internalType: "bytes", name: "dns", type: "bytes" }], name: "DNSDecodingFailed", From 2066a1d226989202e131ac849d7037ae447c1ad3 Mon Sep 17 00:00:00 2001 From: shrugs Date: Fri, 5 Jun 2026 16:06:32 -0500 Subject: [PATCH 3/3] docs: add ensapi changeset for UniversalResolver proxy resolution --- .changeset/ensapi-universal-resolver-proxy.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/ensapi-universal-resolver-proxy.md diff --git a/.changeset/ensapi-universal-resolver-proxy.md b/.changeset/ensapi-universal-resolver-proxy.md new file mode 100644 index 0000000000..f8d709d42a --- /dev/null +++ b/.changeset/ensapi-universal-resolver-proxy.md @@ -0,0 +1,5 @@ +--- +"ensapi": patch +--- + +Omnigraph API: Resolution now uses the ENSv2-ready stable UniversalResolver proxy address when not accelerated.