feat(ensapi): add Account.nameReferences Omnigraph field#2292
Conversation
Surface the Names whose indexed addr() record points at an Account
("names pointing to this address") as a cursor-paginated connection over
a new NameReference type, optionally scoped to a single CoinType.
Each NameReference exposes the canonical domain, the matching coinType,
the resolver holding the record, and match (whether the indexed ENSIP-19
reverse shortcut resolves back to that exact name). Reflects literally-
indexed, canonical Domains only: records whose node has no canonical
Domain are omitted, and Forward Resolution / CCIP-Read and ENSIP-19
default-address-record expansion are not applied. Backed by a new
(value, coinType) index on resolver_address_records.
Resolves #1962
🦋 Changeset detectedLatest commit: ff3844d The changes in this PR will be included in the next version bump. This PR includes changesets to release 24 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.
3 Skipped Deployments
|
|
Warning Review limit reached
More reviews will be available in 45 minutes and 41 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds Account.nameReferences: a cursor-paginated GraphQL connection that returns canonical Domains whose indexed addr() records target an account, with optional coinType filtering; includes DB index, keyset resolver, GraphQL types/field, tests, context DataLoader, docs, and TODOs for coinType bigint migration. ChangesAccount.nameReferences GraphQL Feature
Sequence Diagram(s)sequenceDiagram
participant Client
participant GraphQL
participant AccountResolver
participant Pagination
participant DB
participant Loader
Client->>GraphQL: account.nameReferences(where?, first/last, before/after)
GraphQL->>AccountResolver: resolveAccountNameReferences(account, coinType?, pagination args)
AccountResolver->>Pagination: lazyConnection + resolveCursorConnection (decode cursors, build keyset bounds)
Pagination->>DB: Query resolver_address_records WHERE value=account [AND coinType=filter] JOIN domain ON canonicalNode ORDER BY (node, coinType, chainId, address)
DB->>Pagination: Rows + totalCount
Pagination->>AccountResolver: Paginated rows
AccountResolver->>Loader: context.loaders.reverseResolution.load(account, coinType) for each row when resolving `match`
Loader->>AccountResolver: ReverseResolutionResult
AccountResolver->>GraphQL: NameReferenceModel edges with encoded cursors
GraphQL->>Client: NameReferenceConnection (edges, pageInfo)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Pull request overview
Adds Account.nameReferences to the ENSAPI Omnigraph GraphQL API, enabling cursor-paginated lookup of canonical ENS Domains whose indexed addr(coinType) record points to a given Account address (with optional coinType scoping). This supports Portal’s “names pointing to this address” view without relying on the subgraph.
Changes:
- Introduces
NameReference+AccountNameReferencesConnectionand wiresAccount.nameReferencesinto the Omnigraph schema and runtime resolvers. - Implements a keyset-paginated DB resolver that filters
resolver_address_recordsbyvalue(+ optionalcoinType) and inner-joins to canonicalDomainviadomain.canonicalNode. - Adds a
(value, coinType)index onresolver_address_recordsand integration tests covering coinType scoping and “all coinTypes” behavior.
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/ensskills/skills/omnigraph/SKILL.md | Documents the new Account.nameReferences field and adds NameReference to the schema type list. |
| packages/enssdk/src/omnigraph/generated/schema.graphql | Regenerates the GraphQL schema to include nameReferences, connection/input types, and NameReference. |
| packages/enssdk/src/omnigraph/generated/introspection.ts | Updates generated introspection data for the new field and types. |
| packages/ensdb-sdk/src/ensindexer-abstract/protocol-acceleration.schema.ts | Adds (value, coinType) index to support reverse lookup queries on resolver_address_records. |
| apps/ensapi/src/omnigraph-api/schema/name-reference.ts | Adds the NameReference GraphQL type (domain/coinType/resolver/match). |
| apps/ensapi/src/omnigraph-api/schema/account.ts | Exposes Account.nameReferences connection field and defines AccountNameReferencesWhereInput. |
| apps/ensapi/src/omnigraph-api/schema/account.integration.test.ts | Adds integration tests validating scoping and omission behavior for nameReferences. |
| apps/ensapi/src/omnigraph-api/schema.ts | Ensures the new schema module is registered. |
| apps/ensapi/src/omnigraph-api/lib/find-name-references/find-name-references-resolver.ts | Implements the DB-backed, keyset-paginated resolver powering Account.nameReferences. |
| .changeset/account-name-references.md | Adds Changeset entries bumping ensapi, enssdk, and @ensnode/ensdb-sdk. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/ensapi/src/omnigraph-api/lib/find-name-references/find-name-references-resolver.ts`:
- Line 144: The current cast "canonicalName: row.canonicalName as
InterpretedName" in find-name-references-resolver.ts is relying on join
semantics; replace this implicit assertion with a small runtime guard: check
row.canonicalName for null/undefined and either throw a descriptive error or
handle the unexpected case (e.g., return/skip the row), then safely cast/assign
to InterpretedName; reference the 'row' object and the 'canonicalName' property
in your fix so the behavior is explicit and robust at runtime.
🪄 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: ec0c018f-6793-40e1-8212-2e8e89d65e49
⛔ Files ignored due to path filters (2)
packages/enssdk/src/omnigraph/generated/introspection.tsis excluded by!**/generated/**packages/enssdk/src/omnigraph/generated/schema.graphqlis excluded by!**/generated/**
📒 Files selected for processing (8)
.changeset/account-name-references.mdapps/ensapi/src/omnigraph-api/lib/find-name-references/find-name-references-resolver.tsapps/ensapi/src/omnigraph-api/schema.tsapps/ensapi/src/omnigraph-api/schema/account.integration.test.tsapps/ensapi/src/omnigraph-api/schema/account.tsapps/ensapi/src/omnigraph-api/schema/name-reference.tspackages/ensdb-sdk/src/ensindexer-abstract/protocol-acceleration.schema.tspackages/ensskills/skills/omnigraph/SKILL.md
…Type bigint sites - Document NameReference.match's indexed-shortcut limitation (no full ENSIP-19 reverse walk; Primary Names set via legacy L1 addr.reverse may read match=false), keeping it consistent with the literally-indexed, exact-match nature of nameReferences. - Split the nameReferences changeset into per-package changesets (ensdb-sdk / ensapi / enssdk) and document the per-service changeset convention in AGENTS.md. - Add @todo(cointype-bigint) breadcrumbs at the indexed coinType bigint<->number round-trip sites (schema columns + indexer write sites + ENSApi read sites), tracked by #2293.
- match: resolve via full ENSIP-19 reverse resolution (always accelerated, index-only, no memo/trace) instead of the StandaloneReverseRegistrar shortcut, covering legacy addr.reverse Primary Names. - reframe "default-address-record expansion" -> "address record defaulting" in all PR prose/comments. - rewrite the ensapi changeset copy; drop the enssdk changeset. - clarify the cursor/keyset doc comments (`value` is the constant filter, not a primary-key column).
|
@greptile review |
|
@greptile review |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/ensapi/src/omnigraph-api/context.ts`:
- Around line 34-47: The reverse-resolution DataLoader currently hardcodes
canAccelerate: true which bypasses request-scoped gating; update
createReverseResolutionLoader to accept a canAccelerate boolean (thread
serverContext.canAccelerate into its caller) and pass that value into
resolveReverse instead of true so resolveReverse respects per-request
acceleration gating; locate createReverseResolutionLoader and its callers (and
NameReference.match usage) and propagate serverContext.canAccelerate through to
the DataLoader and then into resolveReverse.
🪄 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: 459a7152-e022-4a26-88b4-ad45ada5374e
⛔ Files ignored due to path filters (1)
packages/enssdk/src/omnigraph/generated/schema.graphqlis excluded by!**/generated/**
📒 Files selected for processing (2)
apps/ensapi/src/omnigraph-api/context.tsapps/ensapi/src/omnigraph-api/schema/name-reference.ts
…on loader Thread serverContext.canAccelerate into the NameReference.match reverse-resolution DataLoader instead of hardcoding true — matching every other resolution call in the codebase and avoiding stale/empty index reads when the indexer cannot safely accelerate (non-realtime, no ProtocolAcceleration plugin).
|
@greptile review |
resolveReverse's internal protocol-step tracing requires the trace context that runWithTrace establishes; the captured trace is discarded here (match only needs the resolved name).
|
@greptile review |
A bare toSorted() ordered CoinTypes (numbers) lexicographically (e.g. [137, 60]); add a numeric comparator so they sort ascending ([60, 137]). Pre-existing issue surfaced during review of the nameReferences change.
|
@greptile review |
Resolves #1962.
Adds
Account.nameReferencesto the Omnigraph API: the Names whose indexedaddr()record points at an Account ("names pointing to this address"), as a cursor-paginated Relay connection over a newNameReferencetype, optionally scoped to a singleCoinType.This replaces Portal's reliance on ensjs subgraph
getResolvedNamesForAddressfor/addr/$addr/resolution. Unblocked by thecanonicalNodematerialization.API
Design notes
name: String!+ flatresolverAddress/resolverChainId/normalized. Sincedomain.canonicalNodeis now materialized, the node returns the realdomain: Domain!(free interpreted/beautified names, ownership, navigation) andresolver: Resolver!(contractcarries address + chainId). Dropped the redundantnormalized(already first-class viaCanonicalName).resolver_address_records WHERE value = <addr> [AND coin_type = ?]INNER JOINdomain ON domain.canonicalNode = rar.node. Backed by a new(value, coinType)index onresolver_address_records; the join rides the existingbyCanonicalNodehash index.matchresolves via full ENSIP-19 reverse resolution (resolveReverse) — covering both the legacyaddr.reverseand StandaloneReverseRegistrar (default.reverse/[coinType].reverse) mechanisms, with forward verification. Accelerated from the index where supported; batched per(account, coinType)within a request via a dataloader.resolver_address_recordsPK.v1 scope (per issue)
matchis the exception — it performs reverse resolution.)Tests / validation
pnpm generate(idempotent), root typecheck, lint, andpnpm test --project ensapi(293) all green onmainbase.Account.nameReferencesintegration tests (coinType scoping, isolation, all-coinTypes) using the seededtest.ethrootstock addr record. These require the devnet stack (pnpm test:integration:ci) and were not run locally.Follow-ups
coinTypecolumns as CoinType end-to-end (drop bigint round-trips) #2293 (type indexedcoinTypecolumns asCoinTypeend-to-end), Omnigraph: ENSIP-19 default-coinType expansion for Account.nameReferences scoped queries #2294 (ENSIP-19 address record defaulting for chain-scopednameReferencesqueries).