resolution api: support contenthash, pubkey, abi, interfaces, dnszonehash, version#1967
resolution api: support contenthash, pubkey, abi, interfaces, dnszonehash, version#1967
Conversation
- operations array with optional `result` sentinel; passes layer transforms
- split ENSIP-19 and static-indexed accelerators into dedicated pass helpers
- abi becomes a bitmask (contract-equivalent), single `{ contentType, data } | null` response
- ContentType + InterfaceId land in enssdk
- resolveCallByIndex returns `unknown | undefined` (undefined = not accelerable)
- executeResolveCalls becomes terminal pass over operations, per-call interpret
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 6dd481d The changes in this PR will be included in the next version bump. This PR includes changesets to release 23 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR extends ENS resolver to support resolving additional record types (contenthash, pubkey, ABI, interfaces, dnszonehash, version) through acceleration and RPC pathways. It refactors the resolution pipeline from call-based to operation-based architecture, updates database schemas to store indexed resolver values, and introduces new semantic types. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR extends the Resolution API from Confidence Score: 5/5Safe to merge; all prior P0/P1 issues addressed, remaining finding is a P2 style suggestion. The pipeline architecture is sound, the No files require special attention; the Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[resolveForward] --> B{ENSv2 active?}
B -- yes --> C[executeOperations via UniversalResolver]
B -- no --> D[findResolver]
D --> E{activeResolver found?}
E -- no --> Z[makeRecordsResponse - empty]
E -- yes --> F{isBridgedResolver?}
F -- yes --> G[_resolveForward recursive]
F -- no --> H{accelerate and canAccelerate?}
H -- yes --> I{isKnownENSIP19ReverseResolver?}
I -- yes and name selected --> J[accelerateENSIP19ReverseResolver]
I -- no or name not selected --> K[skip pass]
J --> L{isStaticResolver + records indexed?}
K --> L
L -- yes --> M[accelerateKnownOnchainStaticResolver\nname addr text contenthash pubkey zonehash recordVersions\nABI + interfaceImplementer pass-through to RPC]
L -- no --> N[skip pass]
M --> O{all ops resolved?}
N --> O
H -- no --> O
O -- yes --> Z2[makeRecordsResponse]
O -- no --> P[isExtendedResolver?]
P --> Q[executeOperations via RPC\nsingle readContract per op multicalled by viem]
Q --> R[invariant: all resolved]
R --> Z2
Reviews (3): Last reviewed commit: "accelerate-ensip19: no-op on non-name se..." | Re-trigger Greptile |
There was a problem hiding this comment.
Pull request overview
Extends the Resolution API and protocol-acceleration/indexing pipeline to support additional resolver record types (contenthash, pubkey, abi, interfaces, dnszonehash, version) by introducing a typed Operation[] resolution pipeline, new interpretation helpers, and additive schema/indexing changes (including proper handling of VersionChanged).
Changes:
- Add new resolver record selection/response fields and new semantic types (
ContentType,InterfaceId,RecordVersion). - Restructure ENSAPI forward resolution into a linear
Operation[]pipeline with acceleration passes and a single RPC tail (executeOperations). - Extend protocol-acceleration schema + handlers to index additional scalar resolver records and clear records on
VersionChanged.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/enssdk/src/lib/types/resolver.ts | Adds new semantic types for resolver records (ABI bitmask, ERC-165 interface id, record version). |
| packages/enssdk/src/lib/types/index.ts | Re-exports new resolver types from the enssdk types barrel. |
| packages/ensnode-sdk/src/shared/interpretation/interpret-resolver-values.ts | Adds interpreters for contenthash/pubkey/dnszonehash deletion sentinels. |
| packages/ensnode-sdk/src/shared/interpretation/interpret-resolver-values.test.ts | Unit tests for the new resolver value interpreters. |
| packages/ensnode-sdk/src/shared/interpretation/index.ts | Exposes new interpretation utilities via the shared barrel. |
| packages/ensnode-sdk/src/rpc/eip-165.ts | Migrates EIP-165 reader types to InterfaceId. |
| packages/ensnode-sdk/src/resolution/resolver-records-selection.ts | Extends selection surface to include new record types. |
| packages/ensnode-sdk/src/resolution/resolver-records-response.ts | Extends response surface and selection→response typing (abi/interfaces/version/etc.). |
| packages/ensnode-sdk/src/internal.ts | Re-exports new internal interpretation helpers for ENSAPI/Indexer use. |
| packages/ensdb-sdk/src/lib/drizzle.ts | Makes schema checksum stringification bigint-safe. |
| packages/ensdb-sdk/src/ensindexer-abstract/protocol-acceleration.schema.ts | Adds new indexed resolver scalar columns + version default. |
| apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts | Updates subgraph handler event arg types to new semantic types. |
| apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts | Registers new resolver event handlers and consolidates setup via ensureResolverAndRecords. |
| apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts | Adds helpers to update new records and handles VersionChanged bulk delete/reset. |
| apps/ensapi/src/lib/resolution/resolve-with-universal-resolver.integration.test.ts | Removes old integration test (related logic moved/renamed). |
| apps/ensapi/src/lib/resolution/resolve-calls-and-results.ts | Deletes old call/result model in favor of Operation[]. |
| apps/ensapi/src/lib/resolution/operations.ts | Introduces typed Operation discriminated union + selection→ops builder + logging helpers. |
| apps/ensapi/src/lib/resolution/make-records-response.ts | Replaces multiple response builders with a single fold over Operation[]. |
| apps/ensapi/src/lib/resolution/make-records-response.test.ts | Rewrites unit tests around Operation[] folding + defaults for unresolved ops. |
| apps/ensapi/src/lib/resolution/forward-resolution.ts | Refactors forward resolution into linear Operation[] pipeline + acceleration passes + single RPC tail. |
| apps/ensapi/src/lib/resolution/execute-operations.ts | Adds core RPC executor for unresolved operations + per-op interpretation. |
| apps/ensapi/src/lib/resolution/execute-operations-with-universal-resolver.ts | Updates ENSv2 bailout universal-resolver path to operate on Operation[]. |
| apps/ensapi/src/lib/resolution/accelerate-known-onchain-static-resolver.ts | Adds index-backed acceleration pass for static resolvers (fills indexable ops only). |
| apps/ensapi/src/lib/resolution/accelerate-ensip19-reverse-resolver.ts | Adds ENSIP-19 reverse-resolver acceleration pass (fills name op from index). |
| apps/ensapi/src/lib/protocol-acceleration/get-records-from-index.ts | Returns full resolverRecords row shape (now includes new scalar columns) and preserves address-defaulting behavior. |
| apps/ensapi/src/lib/protocol-acceleration/get-primary-name-from-index.ts | Tightens reverse-name return type to `InterpretedName |
| .changeset/extend-resolver-records.md | Adds changeset documenting the expanded resolution surface + indexing behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/ensapi/src/lib/protocol-acceleration/get-records-from-index.ts`:
- Around line 40-41: The comment above the null-check in
get-records-from-index.ts no longer matches the code; update or remove the
comment that currently reads "coalesce undefined to null" sitting above the line
"if (!row) return null;". Replace it with a concise, accurate note such as
"findFirst returns undefined when no row matches; return null" or simply drop
the comment so the null-guard stands alone; apply this change in the
get-records-from-index file near the if (!row) return null check.
In `@apps/ensapi/src/lib/resolution/accelerate-ensip19-reverse-resolver.ts`:
- Around line 29-44: The loop calls parseReverseName(name) and
getENSIP19ReverseNameRecordFromIndex for each operation, causing redundant work
and repeated invariant errors; hoist parsing and the index lookup out of the
operations.map() so they run once before Promise.all: call
parseReverseName(name) once, validate and throw the invariant if invalid, then
(if valid) call getENSIP19ReverseNameRecordFromIndex(parsed.address,
parsed.coinType) once to get the result, and inside the map (used with
isOperationResolved and op.functionName checks) simply reuse that parsed/result
when returning the updated op.
In `@apps/ensapi/src/lib/resolution/accelerate-known-onchain-static-resolver.ts`:
- Around line 51-55: The addr branch currently converts both sides with
bigintToCoinType and compares the results, which can throw for non-standard coin
types; change the predicate in the records?.addressRecords.find call to compare
the bigints directly (r.coinType === op.args[1]) and return found?.value ?? null
as before, and remove the bigintToCoinType import if it becomes unused; update
any references in the case "addr" block to rely on op.args[1] (bigint) and
r.coinType (bigint) without conversion.
In `@apps/ensapi/src/lib/resolution/operations.ts`:
- Around line 14-18: The JSDoc in operations.ts refers to a stale symbol name
interpretRawRpcCallAndResult; update that comment to reference the actual
exported interpreter interpretOperationWithRawResult so maintainers can find the
implementation; ensure the comment still mentions Operation and makeOperations
to preserve context about the canonical mapping contract.
In `@apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts`:
- Around line 172-177: Rename the handler function handleResolverVersionChange
to handleResolverVersionUpdate to match the existing *Update naming convention;
update the call site in addOnchainEventListener (where
handleResolverVersionChange is invoked), rename the actual function
declaration/definition to handleResolverVersionUpdate, and adjust any
exports/imports or references (e.g., tests or other modules) that mention
handleResolverVersionChange so they point to handleResolverVersionUpdate.
In `@packages/ensnode-sdk/src/resolution/resolver-records-selection.ts`:
- Around line 57-66: isSelectionEmpty incorrectly treats selection.abi (a
ContentType bigint) as falsy (so 0n is "empty") while makeOperations uses the
predicate selection.abi !== undefined; update isSelectionEmpty in
resolver-records-selection.ts to check abi using selection.abi !== undefined
(not !selection.abi) so the ResolverRecordsSelection/abi semantics match
makeOperations and a selection with abi: 0n is not considered empty.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: ff5bc5da-3288-45d9-998b-742f1c6f0881
📒 Files selected for processing (27)
.changeset/extend-resolver-records.mdapps/ensapi/src/lib/protocol-acceleration/get-primary-name-from-index.tsapps/ensapi/src/lib/protocol-acceleration/get-records-from-index.tsapps/ensapi/src/lib/resolution/accelerate-ensip19-reverse-resolver.tsapps/ensapi/src/lib/resolution/accelerate-known-onchain-static-resolver.tsapps/ensapi/src/lib/resolution/execute-operations-with-universal-resolver.tsapps/ensapi/src/lib/resolution/execute-operations.tsapps/ensapi/src/lib/resolution/forward-resolution.tsapps/ensapi/src/lib/resolution/make-records-response.test.tsapps/ensapi/src/lib/resolution/make-records-response.tsapps/ensapi/src/lib/resolution/operations.tsapps/ensapi/src/lib/resolution/resolve-calls-and-results.tsapps/ensapi/src/lib/resolution/resolve-with-universal-resolver.integration.test.tsapps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.tsapps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.tsapps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.tspackages/ensdb-sdk/src/ensindexer-abstract/protocol-acceleration.schema.tspackages/ensdb-sdk/src/lib/drizzle.tspackages/ensnode-sdk/src/internal.tspackages/ensnode-sdk/src/resolution/resolver-records-response.tspackages/ensnode-sdk/src/resolution/resolver-records-selection.tspackages/ensnode-sdk/src/rpc/eip-165.tspackages/ensnode-sdk/src/shared/interpretation/index.tspackages/ensnode-sdk/src/shared/interpretation/interpret-resolver-values.test.tspackages/ensnode-sdk/src/shared/interpretation/interpret-resolver-values.tspackages/enssdk/src/lib/types/index.tspackages/enssdk/src/lib/types/resolver.ts
💤 Files with no reviewable changes (2)
- apps/ensapi/src/lib/resolution/resolve-with-universal-resolver.integration.test.ts
- apps/ensapi/src/lib/resolution/resolve-calls-and-results.ts
- params.schema.ts: parse contenthash/pubkey/dnszonehash/version/abi/interfaces from query - zod-schemas.ts: describe wire shape (bigints serialized as strings) - client.ts: encode new selection fields into URL - resolution-api.ts: replaceBigInts on response to avoid JSON.stringify crash Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- forward-resolution: typo foward→forward, bigint-safe stringify in invariant error message and tracing selectionString - accelerate-ensip19: bigint-safe stringify on selection; hoist parseReverseName out of the per-op loop - isSelectionEmpty: abi uses === undefined to match makeOperations - accelerate-known-onchain-static-resolver: compare addr coinType bigints directly (bigintToCoinType throws on non-standard coinTypes stored in the index, would crash the accelerator) - operations.ts: fix stale JSDoc reference to interpretRawRpcCallAndResult Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
apps/ensapi/src/lib/resolution/execute-operations-with-universal-resolver.ts:50
- The previous integration test for UniversalResolver resolution was deleted, and there doesn't appear to be a replacement covering
executeOperationsWithUniversalResolver(used in the ENSv2 bailout path). Please add an integration test that exercises at least one successful resolution and one unresolvable/empty-bytes case to avoid regressions in this critical fallback path.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
single call site — the helper didn't pull its weight. scalar reset + raw sql bulk deletes now live directly next to the event registration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@greptile please re-review — addressed the P1 on the ENSIP-19 accelerator (5cd5444). |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/ensapi/src/lib/handlers/params.schema.ts`:
- Around line 73-99: The interfaces pipeline currently allows case-variants to
pass because interfaceId lowercases during transform, so deduplicate the array
after normalization: update the selectionFields.interfaces schema (the branch
using stringarray.pipe(z.array(interfaceId))) to apply a transform that removes
duplicate InterfaceId values (e.g., Array.from(new Set(...)) or equivalent)
after the z.array(interfaceId) normalization so only unique lowercased interface
IDs remain; keep the rest of the pipeline intact and ensure the transformed type
stays InterfaceId[].
In `@apps/ensapi/src/lib/resolution/accelerate-ensip19-reverse-resolver.ts`:
- Around line 29-35: The code currently throws when parseReverseName(name)
returns falsy; change this to treat non-reverse names as a cache-miss by
returning the unchanged operations instead of throwing. Locate the
parseReverseName(name) call and the falsy check (the parsed variable) in
accelerate-ensip19-reverse-resolver and replace the throw block with a simple
return of the existing operations (preserving the original operations
array/object), so non-reverse names fall back to the unaccelerated RPC path.
In `@packages/ensnode-sdk/src/resolution/resolver-records-response.ts`:
- Around line 90-104: The mapped type key predicate in ResolverRecordsResponse
currently checks T[K] extends true | any[] | bigint which fails for readonly
tuple selections; update that predicate to include readonly arrays (e.g. change
to T[K] extends true | readonly any[] | bigint) so readonly selections like as
const tuples are accepted; modify the condition in the ResolverRecordsResponse
mapped type (the key remapping that uses T[K] extends ...) to use readonly any[]
instead of any[] and keep the existing branch logic (addresses/texts/interfaces)
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2752c441-08c3-48bc-97fb-dbbf677768db
📒 Files selected for processing (17)
apps/ensapi/src/handlers/api/resolution/resolution-api.tsapps/ensapi/src/lib/handlers/params.schema.tsapps/ensapi/src/lib/resolution/accelerate-ensip19-reverse-resolver.tsapps/ensapi/src/lib/resolution/accelerate-known-onchain-static-resolver.tsapps/ensapi/src/lib/resolution/execute-operations.tsapps/ensapi/src/lib/resolution/forward-resolution.tsapps/ensapi/src/lib/resolution/make-records-response.test.tsapps/ensapi/src/lib/resolution/make-records-response.tsapps/ensapi/src/lib/resolution/operations.tsdocs/ensnode.io/ensapi-openapi.jsonpackages/ensdb-sdk/src/ensindexer-abstract/protocol-acceleration.schema.tspackages/ensnode-sdk/src/ensapi/api/resolution/zod-schemas.tspackages/ensnode-sdk/src/ensapi/client.tspackages/ensnode-sdk/src/resolution/resolver-records-response.tspackages/enssdk/src/lib/index.tspackages/enssdk/src/lib/interface-id.tspackages/enssdk/src/lib/types/resolver.ts
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 34 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
tsup's dts rollup can't portably name the inferred ReactElement return type on OmnigraphProvider — the @types/react symlink path in pnpm is non-deterministic, so the build fails intermittently depending on link-resolution order. explicit return type makes it deterministic. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
the key-remap predicate checked \`T[K] extends true | any[] | bigint\`, which excluded \`readonly\` tuples. \`as const satisfies ResolverRecordsSelection\` selections with \`addresses: readonly [60, 1001]\` got their keys dropped from the mapped type. widen to \`readonly any[]\`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 35 out of 35 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
lightwalker-eth
left a comment
There was a problem hiding this comment.
@shrugs Love the abstractions introduced here. Looks super! Some very small comments please take the lead to merge when ready 👍
…resolution # Conflicts: # apps/ensapi/src/handlers/api/resolution/resolution-api.ts # apps/ensapi/src/lib/handlers/params.schema.ts # docs/ensnode.io/ensapi-openapi.json
There was a problem hiding this comment.
♻️ Duplicate comments (1)
apps/ensapi/src/lib/handlers/params.schema.ts (1)
103-106:⚠️ Potential issue | 🟡 MinorReject duplicate interface IDs after normalization.
stringarraychecks uniqueness beforeinterfaceIdlowercases, so0x01FFC9A7,0x01ffc9a7passes validation and becomes duplicateInterfaceIdentries.🛡️ Proposed fix
const interfaceId = z .string() .refine(isInterfaceId, "Must be a 4-byte hex (0x + 8 hex chars)") .transform((val) => val.toLowerCase() as InterfaceId); + +const interfaceIds = stringarray + .pipe(z.array(interfaceId)) + .refine((values) => new Set(values).size === values.length, { + message: "Must be a set of unique entries.", + }); const rawSelectionParams = z.object({ @@ version: z.optional(boolstring), abi: z.optional(contentTypeBitmask), - interfaces: z.optional(stringarray.pipe(z.array(interfaceId))), + interfaces: z.optional(interfaceIds), });Also applies to: 145-145
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/ensapi/src/lib/handlers/params.schema.ts` around lines 103 - 106, The current schema lowercases values in the interfaceId transform (interfaceId) after uniqueness was already enforced by stringarray, allowing duplicates like "0x01FFC9A7,0x01ffc9a7"; fix by performing uniqueness checking after normalization: update the array schema (stringarray) to map/transform each entry to the normalized InterfaceId (use interfaceId.parse/transform or a .transform on the array elements) before enforcing uniqueness, or add a .superRefine on the array that lowercases all entries and rejects duplicates (compare normalized values) so duplicate InterfaceId entries are rejected post-normalization.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@apps/ensapi/src/lib/handlers/params.schema.ts`:
- Around line 103-106: The current schema lowercases values in the interfaceId
transform (interfaceId) after uniqueness was already enforced by stringarray,
allowing duplicates like "0x01FFC9A7,0x01ffc9a7"; fix by performing uniqueness
checking after normalization: update the array schema (stringarray) to
map/transform each entry to the normalized InterfaceId (use
interfaceId.parse/transform or a .transform on the array elements) before
enforcing uniqueness, or add a .superRefine on the array that lowercases all
entries and rejects duplicates (compare normalized values) so duplicate
InterfaceId entries are rejected post-normalization.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e773a47f-cadc-45fe-8172-c3ab9430af3c
📒 Files selected for processing (9)
apps/ensapi/src/handlers/api/resolution/resolution-api.tsapps/ensapi/src/lib/handlers/params.schema.tsapps/ensapi/src/lib/resolution/execute-operations.integration.test.tsdocs/ensnode.io/ensapi-openapi.jsonpackages/enskit/src/react/omnigraph/provider.tsxpackages/ensnode-sdk/src/ensnode/api/resolution/zod-schemas.tspackages/ensnode-sdk/src/ensnode/client.tspackages/ensnode-sdk/src/internal.tspackages/ensnode-sdk/src/resolution/resolver-records-response.ts
closes #1505
Reviewer Focus (Read This First)
Operation[]pipeline inforward-resolution.ts— each acceleration strategy is a pass; unresolved ops flow to a single final RPC callsiteOperationdiscriminated union inoperations.ts— per-variant result typing drives the rest of the pipeline (executeOperations,makeRecordsResponse, acceleration passes).handleResolverVersionChangeuses rawcontext.ensDb.sql.delete(...)to bulk-delete child records onVersionChanged— this forces a ponder cache flush. accepted because the event is rare, but worth a sanity check.Problem & Motivation
name,addresses,texts. callers need contenthash, pubkey, abi, interfaces, dnszonehash, version to support Portal app featuresABIChangedomits data (would require a follow-upreadContractper event), andinterfaceImplementerhas an ERC-165 fallback that can't be replicated offline. both remain selectable but are always resolved via RPC. support for indexing could be trivially added in the future if desiredVersionChangedsemantics weren't handled: prior records stayed queryable after a version bump.What Changed (Concrete)
ContentType,InterfaceId,RecordVersiontypes inpackages/enssdk/src/lib/types/resolver.ts.eip-165.ts+ subgraphhandleInterfaceChangedmigrated toInterfaceId.@ensnode/ensnode-sdk/internal:interpretContenthashValue,interpretPubkeyValue,interpretDnszonehashValue(empty-bytes / zero-pair → null).protocol-acceleration.schema.ts#resolverRecordsextended withcontenthash,pubkeyX,pubkeyY,dnszonehash,version(defaults to0n).ensureResolverAndRecords(context, event)helper, plus 4 new per-record update helpers (handleResolverContenthashUpdate,handleResolverPubkeyUpdate,handleResolverDnszonehashUpdate,handleResolverVersionChange).ContenthashChanged,PubkeyChanged,DNSZonehashChanged,VersionChanged.ABIChanged+InterfaceChangedintentionally unregistered (comment explains).ResolverRecordsSelection+ResolverRecordsResponseBaseextended withcontenthash,pubkey,abi,interfaces,dnszonehash,version.Operationdiscriminated union inapps/ensapi/src/lib/resolution/operations.ts, driven by anOperationMap{functionName → {args, result}}. each variant'sresultis typed per-variant (e.g.name→InterpretedName | null | undefined).execute-operations.ts—executeOperations(wasexecuteResolveCalls) +interpretOperationWithRawResult. onereadContractcall in the direct-resolve path, withas unknown as …cast to bypass viem's narrowing.execute-operations-with-universal-resolver.ts(wasresolve-with-universal-resolver.ts) — returns resolvedOperations<SELECTION>directly, no separate interpret pass.forward-resolution.tsrestructured: linear pipeline overOperation[], each acceleration strategy a pass, single final RPC execution.accelerate-ensip19-reverse-resolver.tsandaccelerate-known-onchain-static-resolver.ts.resolveOperationWithIndexis colocated with the static-resolver accelerator.make-records-response.ts—makeRecordsResponse<SELECTION>(operations). single-pass reduce, lazy map init.SELECTIONis a type-only generic.makeEmptyResolverRecordsResponsedeleted (empty ops + empty selection collapses to{}, which matchesResolverRecordsResponse<{}>).safeStringifyDrizzleSchemapatched to handlebigintdefaults (schema'sversion.default(0n)crashedJSON.stringifyat startup).operations.ts:isOperationResolved,logOperations,tablifyOperations.Design & Planning
SPEC-resolver-records.mdon original commit on this branch — drove the architecture (hybrid acceleration, linear Operation passes, ABI/interfaces as RPC-only).interfaceImplementer— ERC-165 fallback was annoying to implement offline, + low usagePlanning artifacts:
SPEC-resolver-records.mdin first commit on this branchSelf-Review
A lot changed after the initial pass via the
/simplifyreview cycle.Bugs caught:
safeStringifyDrizzleSchemacrashed onversion: bigintdefault at startup — patched to serialize bigints.op.result as X | nullcasts inmake-records-response.ts— replaced with a typed reduce.Naming / terminology improved:
executeResolveCalls → executeOperations,makeResolveCalls → makeOperations,resolveCallByIndex → resolveOperationWithIndex,interpretRawRpcCallAndResult → interpretOperationWithRawResult.resolve-calls-and-results.ts → operations.ts,resolve-with-universal-resolver.ts → execute-operations-with-universal-resolver.ts,resolve-call-by-index.ts(deleted; inlined intoaccelerate-known-onchain-static-resolver.ts).Dead code removed:
interpretRawCallsAndResults,tablifyCallResults,ResolveCallsAndRawResults,ResolveCallsAndResults,makeEmptyResolverRecordsResponse,findOp,ResolveCall(absorbed intoOperation),IndexedResolverRecords.Cross-Codebase Alignment
InterfaceId,interfaceID,Resolver:ContenthashChanged,newVersion: bigint,interpretNameRecordValue,ResolverRecordsSelection,makeEmptyResolverRecordsResponse.subgraph.schema.ts. the subgraph plugin indexes its ownsubgraph_*tables; that surface is untouched.forward-resolution.tsstill short-circuits toexecuteOperationsWithUniversalResolverinstead of flowing through the linearOperation[]pipeline. follow-up once ENSv2 acceleration is implemented.Search terms used: as above.
Reviewed but unchanged: subgraph plugin's Resolver handlers,
subgraph.schema.ts.Deferred alignment: ENSv2 linear-pipeline integration.
Downstream & Consumer Impact
ResolverRecordsSelection+ResolverRecordsResponse<T>gain 6 new optional fields. existing callers are unaffected; response shape only grows.Operation(formerly conceptuallyResolveCall+ result) is the single discriminated union that drives the resolution pipeline. internal consumers will see this rename.ensureResolverAndRecordsreplaces the three-step setup handlers used to call manually.ContentType,InterfaceId,RecordVersion.Public APIs affected:
ResolverRecordsSelection,ResolverRecordsResponse<T>, newenssdktypes.Docs updated: yes
Naming decisions worth calling out:
Operationas the unified pipeline type;ensureResolverAndRecords.Testing Evidence
Risk Analysis
Pre-Review Checklist (Blocking)