Skip to content

Extend stack info data model#1988

Merged
tk-o merged 22 commits intomainfrom
feat/extend-stack-info-data-model
Apr 24, 2026
Merged

Extend stack info data model#1988
tk-o merged 22 commits intomainfrom
feat/extend-stack-info-data-model

Conversation

@tk-o
Copy link
Copy Markdown
Member

@tk-o tk-o commented Apr 23, 2026

Lite PR

Tip: Review docs on the ENSNode PR process

Summary

  • Extended the stack info data model
    • Introduced EnsIndexerStackInfo data model which includes ensDbPublicConfig, ensIndexerPublicConfig and ensRainbowPublicConfig.
    • Updated EnsNodeStackInfo data model which extends EnsIndexerStackInfo, and includes ensApiPublicConfig.
  • The ensRainbow: EnsRainbowPublicConfig is now required field across all stack info data models
    • Please note we don't write the EnsNodeStackInfo object into ENSNode Metadata table in ENSDb yet, so we while creating EnsNodeStackInfo object in ENSApi runtime, we leverege the fact that ensIndexerPublicConfig.ensIndexerPublicConfig is always present.
  • Updated core data models (as per changesets info)
    • Dropped recordsCount field from EnsRainbowPublicConfig data model.
    • Replaced version field with versionInfo.

Why

  • Why this change exists. Link to related GitHub issues where relevant.

Testing

  • Tested by running ENSNode locally, and going though ENSAdmin views (including mocked ones).
    • Feel free to give it a try yourself: click here to see the preview of the changes

Notes for Reviewer (Optional)

  • Please review commit-by-commit.
  • No visual updates were intended.
  • This is prep PR to enable introduction of the IndexingMetadataContext data model.
  • Out-of-scope (will be done in the PR introducing IndexingMetadataContext data model).
    • Dropping ensIndexerPublicConfig field from EnsApiPublicConfig data model.
    • Dropping ensRainbowPublicConfig field from EnsIndexerPublicConfig data model.

Pre-Review Checklist (Blocking)

  • This PR does not introduce significant changes and is low-risk to review quickly.
  • Relevant changesets are included (or are not required)

Copilot AI review requested due to automatic review settings April 23, 2026 15:54
@tk-o tk-o requested a review from a team as a code owner April 23, 2026 15:54
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ensnode.io Ready Ready Preview, Comment Apr 24, 2026 0:45am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped Apr 24, 2026 0:45am
ensrainbow.io Skipped Skipped Apr 24, 2026 0:45am

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 23, 2026

🦋 Changeset detected

Latest commit: 7c11fc3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 23 packages
Name Type
@ensnode/ensrainbow-sdk Major
@ensnode/ensnode-sdk Major
ensadmin Major
ensindexer Major
ensrainbow Major
ensapi Major
fallback-ensapi Major
@namehash/ens-referrals Major
@ensnode/ensdb-sdk Major
@ensnode/ensnode-react Major
@ensnode/integration-test-env Major
@namehash/namehash-ui Major
@docs/ensnode Major
@docs/ensrainbow Major
enssdk Major
enscli Major
enskit Major
ensskills Major
@ensnode/datasources Major
@ensnode/ponder-sdk Major
@ensnode/ponder-subgraph Major
@ensnode/shared-configs Major
@ensnode/enskit-react-example Patch

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

Warning

Rate limit exceeded

@tk-o has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 28 minutes and 45 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 28 minutes and 45 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 83dfb86d-67a9-48eb-a664-1a64a3789f8a

📥 Commits

Reviewing files that changed from the base of the PR and between 73a15bc and 7c11fc3.

📒 Files selected for processing (13)
  • .changeset/all-kids-smash.md
  • .changeset/calm-ravens-feel.md
  • apps/ensadmin/src/app/mock/indexing-status-api.mock.ts
  • apps/ensadmin/src/app/mock/stack-info/page.tsx
  • apps/ensadmin/src/components/connection/cards/ensnode-stack-info.tsx
  • apps/ensindexer/src/config/types.ts
  • apps/ensindexer/src/ponder/indexing-behavior-injection-contract.ts
  • apps/ensrainbow/src/commands/server-command.test.ts
  • docs/ensnode.io/src/content/docs/ensrainbow/concepts/typescript-interfaces.mdx
  • docs/ensnode.io/src/content/docs/ensrainbow/usage/client-sdk.mdx
  • packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts
  • packages/ensnode-sdk/src/ensindexer/config/types.ts
  • packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts
📝 Walkthrough

Walkthrough

The PR introduces a new EnsIndexerStackInfo data model, restructures public configurations with nested versionInfo objects, renames label-set fields (clientLabelSet for client config, serverLabelSet for server config), and updates the admin UI to use a new /mock/stack-info route with corresponding component and mock data changes.

Changes

Cohort / File(s) Summary
Release Management
.changeset/clear-rabbits-punch.md, .changeset/fifty-games-smash.md
Two changelog entries for ensadmin and @ensnode/ensnode-sdk packages documenting minor version bumps and the introduction of new stack-info data models.
Admin UI Routes & Navigation
apps/ensadmin/src/app/mock/page.tsx, apps/ensadmin/src/app/mock/stack-info/page.tsx, apps/ensadmin/src/app/mock/config-info/*
Deleted old /mock/config-info route and mock data; created new /mock/stack-info page component with new mock dataset mockSerializedEnsNodeStackInfo; updated navigation to point to /mock/stack-info with EnsNodeStackInfo label.
Stack Info Component Renames
apps/ensadmin/src/components/connection/cards/ensnode-stack-info.tsx, apps/ensadmin/src/components/connection/index.tsx
Renamed components from ENSNodeConfig* pattern to DisplayEnsNodeStackInfo/EnsNodeStackInfoCardDisplay; updated card field sourcing to use nested config objects; removed "Records Count" field from display.
New EnsIndexerStackInfo Model
packages/ensnode-sdk/src/stack-info/ensindexer-stack-info.ts, packages/ensnode-sdk/src/stack-info/serialize/ensindexer-stack-info.ts, packages/ensnode-sdk/src/stack-info/deserialize/ensindexer-stack-info.ts, packages/ensnode-sdk/src/stack-info/zod-schemas/ensindexer-stack-info.ts
Introduced new EnsIndexerStackInfo interface and factory; added serialization, deserialization, and Zod validation for the model with compatibility checks between indexer and rainbow configs.
Updated EnsNodeStackInfo Structure
packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts, packages/ensnode-sdk/src/stack-info/serialize/ensnode-stack-info.ts, packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts
Refactored EnsNodeStackInfo to extend EnsIndexerStackInfo and updated buildEnsNodeStackInfo signature to accept explicit ensIndexerPublicConfig and ensRainbowPublicConfig parameters; updated serialization and schema validation to delegate indexer portion to new helper functions.
Stack Info Module Exports
packages/ensnode-sdk/src/stack-info/index.ts, packages/ensnode-sdk/src/stack-info/validate/ensindexer-stack-info.ts, packages/ensnode-sdk/src/stack-info/validate/ensnode-stack-info.ts
Expanded public re-exports to include new EnsIndexerStackInfo-related modules; added new validator functions for both stack-info types.
ENSIndexer Config: labelSet → clientLabelSet
apps/ensindexer/src/config/config.schema.ts, apps/ensindexer/src/config/types.ts, apps/ensindexer/src/config/serialized-types.ts, apps/ensindexer/src/config/*.test.ts, apps/ensindexer/src/config/serialize.ts, apps/ensindexer/src/lib/ensrainbow/singleton.ts, apps/ensindexer/src/lib/public-config-builder/*, apps/ensindexer/src/ponder/indexing-behavior-injection-contract.ts
Systematic rename of labelSetclientLabelSet across ENSIndexer configuration, validation, serialization, and ponder integration; updated test fixtures and assertions accordingly.
ENSIndexer SDK Types & Validation
packages/ensnode-sdk/src/ensindexer/config/types.ts, packages/ensnode-sdk/src/ensindexer/config/zod-schemas.ts, packages/ensnode-sdk/src/ensindexer/config/serialize.ts, packages/ensnode-sdk/src/ensindexer/config/compatibility.ts, packages/ensnode-sdk/src/ensindexer/config/is-subgraph-compatible.ts, packages/ensnode-sdk/src/ensindexer/config/*.test.ts
Updated EnsIndexerPublicConfig interface to use clientLabelSet; propagated change through all Zod schemas, serializers, compatibility validators, and test fixtures.
ENSRainbow Config: labelSet → serverLabelSet & Restructure
packages/ensnode-sdk/src/ensrainbow/config.ts, packages/ensnode-sdk/src/ensrainbow/zod-schemas/config.ts, apps/ensrainbow/src/config/types.ts, apps/ensrainbow/src/config/public.ts, apps/ensrainbow/src/lib/database.ts, apps/ensrainbow/src/lib/server.ts
Renamed ENSRainbow's labelSetserverLabelSet; replaced top-level version and recordsCount with nested versionInfo structure containing ensRainbow version; updated public config builder and database validation logic accordingly.
ENSRainbow API Integration
apps/ensrainbow/src/commands/server-command.ts, apps/ensrainbow/src/commands/server-command.test.ts, apps/ensrainbow/src/lib/api.ts
Updated createApi signature to accept dbConfig parameter; changed /v1/labels/count endpoint to source count from dbConfig.recordsCount instead of public config; updated test expectations to match new public config shape.
ENS API Cache & Config Building
apps/ensapi/src/cache/stack-info.cache.ts, apps/ensapi/src/config/validations.ts, apps/ensapi/src/config/config.schema.test.ts
Updated loadEnsNodeStackInfo to extract and pass ensIndexerPublicConfig and ensRainbowPublicConfig to buildEnsNodeStackInfo; updated ENSRainbow version validation path to use versionInfo.ensRainbow; updated test fixtures for new config shape.
ENS SDK Mock Data
apps/ensadmin/src/app/mock/indexing-status-api.mock.ts, packages/ensdb-sdk/src/client/ensdb-client.mock.ts, packages/ensindexer/src/lib/ensdb-writer-worker/ensdb-writer-worker.mock.ts, packages/ensnode-sdk/src/ensindexer/client.mock.ts, packages/ensnode-sdk/src/ensnode/client.test.ts, packages/ensrainbow-sdk/src/client.test.ts
Updated all mock public config fixtures to use new field names (clientLabelSet/serverLabelSet) and nested versionInfo structure across indexer, rainbow, and api configs.
ENS SDK Serialization & Schema
packages/ensnode-sdk/src/ensapi/config/conversions.test.ts, packages/ensnode-sdk/src/ensdb/zod-schemas/config.ts, packages/ensnode-sdk/src/ensindexer/config/conversions.test.ts
Updated test fixtures and schema validation to match restructured config shapes with renamed label-set fields and nested version info.
ENSRainbow SDK Client
packages/ensrainbow-sdk/src/client.ts, packages/ensrainbow-sdk/src/client.test.ts
Renamed EnsRainbowApiClientOptions.labelSetclientLabelSet throughout client construction, validation, state, and query-parameter application; updated test fixtures for new option name.
Documentation & OpenAPI Spec
docs/ensnode.io/ensapi-openapi.json, docs/ensnode.io/src/content/docs/ensrainbow/concepts/typescript-interfaces.mdx, docs/ensnode.io/src/content/docs/ensrainbow/usage/client-sdk.mdx
Updated OpenAPI spec version to 1.10.1 and restructured stackInfo schema to reflect new nested config objects and renamed fields; updated documentation examples and descriptions to use clientLabelSet terminology.
Admin UI Text Update
apps/ensadmin/src/components/require-ensadmin-feature.tsx
Updated button text from "See ENSNode Config" to "See ENSNode Stack Info".

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #1859: Both PRs refactor ENSApi public config to replace version with nested versionInfo, update related schemas/serializers/validators, and adjust admin/indexer code to use the new structure.
  • PR #1715: Both PRs modify the ENSIndexer public-config construction surface, introducing or using a PublicConfigBuilder and adding validators for ENSIndexer public config and version info.
  • PR #1705: Both PRs refactor ENSIndexer/ENSRainbow public config types and schemas, propagating field renames (labelSetclientLabelSet/serverLabelSet) and nested versionInfo changes across types, Zod schemas, serialization, and mocks.

Poem

🐰 With configs restructured and fields refined,
labelSets split by client and server line,
versionInfo nestled so snug and deep,
Stack info models our promises to keep!
Stack by stack, the refactor hops on by.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Extend stack info data model' accurately and concisely summarizes the primary change—extending/restructuring the stack info data models with new interfaces and relationships.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed PR description is well-structured and covers key sections: summary, why, testing, notes, and pre-review checklist. All major changes are documented with appropriate context.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/extend-stack-info-data-model

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR extends the stack info data model by introducing EnsIndexerStackInfo (containing ensDb, ensIndexer, and ensRainbow) as a base for EnsNodeStackInfo (which additionally includes ensApi). It also renames labelSetclientLabelSet / serverLabelSet, replaces version: string with versionInfo: EnsRainbowVersionInfo, and removes recordsCount from EnsRainbowPublicConfig. The previous P1 concern — makeEnsNodeStackInfoSchema missing invariant_ensRainbowCompatibilityWithEnsIndexer — is resolved: the check is now explicitly applied on line 75 of the updated schema file.

Confidence Score: 5/5

Safe to merge — all structural changes are consistent and the previously flagged P1 invariant gap has been explicitly resolved.

The previous P1 finding (missing invariant_ensRainbowCompatibilityWithEnsIndexer in makeEnsNodeStackInfoSchema) is resolved: the check is now explicitly applied via .check(invariant_ensRainbowCompatibilityWithEnsIndexer) on line 75. All renames (labelSet → clientLabelSet/serverLabelSet, version → versionInfo, recordsCount removed from public config) are consistently applied across 68 files with matching test and changeset updates. No remaining P1 or P0 issues identified.

No files require special attention — key schema validation logic in packages/ensnode-sdk/src/stack-info/zod-schemas/ has been verified correct.

Important Files Changed

Filename Overview
packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts Rebuilt to compose from makeEnsIndexerStackInfoSchema + explicit .check(invariant_ensRainbowCompatibilityWithEnsIndexer) — previous P1 concern is now addressed
packages/ensnode-sdk/src/stack-info/zod-schemas/ensindexer-stack-info.ts New file defining makeEnsIndexerStackInfoSchema with invariant_ensRainbowCompatibilityWithEnsIndexer cross-field check — correct and well structured
packages/ensnode-sdk/src/stack-info/ensindexer-stack-info.ts New EnsIndexerStackInfo interface and buildEnsIndexerStackInfo factory — cleanly introduces the base stack info model
packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts EnsNodeStackInfo now extends EnsIndexerStackInfo; ensRainbow is required (not optional); buildEnsNodeStackInfo correctly threads all four configs through validation
apps/ensapi/src/cache/stack-info.cache.ts Correctly extracts ensIndexerPublicConfig and ensRainbowPublicConfig from ensApiPublicConfig and passes them to the updated buildEnsNodeStackInfo
apps/ensrainbow/src/lib/api.ts /v1/labels/count endpoint correctly moved from reading publicConfig.recordsCount (removed) to dbConfig.recordsCount via new parameter
packages/ensrainbow-sdk/src/client.ts Systematic rename of labelSet to clientLabelSet in EnsRainbowApiClientOptions and internal state; consistently applied throughout the class
packages/ensnode-sdk/src/ensrainbow/config.ts Correctly replaces version/labelSet/recordsCount with serverLabelSet and versionInfo: EnsRainbowVersionInfo in EnsRainbowPublicConfig
.changeset/all-kids-smash.md Breaking changes (field renames and removal) are properly documented in the changeset as minor releases

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class EnsIndexerStackInfo {
        +EnsDbPublicConfig ensDb
        +EnsIndexerPublicConfig ensIndexer
        +EnsRainbowPublicConfig ensRainbow
    }

    class EnsNodeStackInfo {
        +EnsApiPublicConfig ensApi
    }

    class EnsRainbowPublicConfig {
        +EnsRainbowServerLabelSet serverLabelSet
        +EnsRainbowVersionInfo versionInfo
    }

    class EnsRainbowVersionInfo {
        +string ensRainbow
    }

    class EnsIndexerPublicConfig {
        +EnsRainbowClientLabelSet clientLabelSet
        +EnsIndexerVersionInfo versionInfo
        +EnsRainbowPublicConfig ensRainbowPublicConfig
    }

    class EnsApiPublicConfig {
        +EnsIndexerPublicConfig ensIndexerPublicConfig
        +EnsApiVersionInfo versionInfo
    }

    class EnsApiVersionInfo {
        +string ensApi
        +string ensNormalize
    }

    EnsNodeStackInfo --|> EnsIndexerStackInfo : extends
    EnsIndexerStackInfo *-- EnsRainbowPublicConfig : ensRainbow
    EnsIndexerStackInfo *-- EnsIndexerPublicConfig : ensIndexer
    EnsIndexerPublicConfig *-- EnsRainbowPublicConfig : ensRainbowPublicConfig
    EnsRainbowPublicConfig *-- EnsRainbowVersionInfo
    EnsNodeStackInfo *-- EnsApiPublicConfig : ensApi
    EnsApiPublicConfig *-- EnsApiVersionInfo
Loading

Reviews (6): Last reviewed commit: "Apply AI PR feedback" | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts (1)

14-34: 🧹 Nitpick | 🔵 Trivial

Consider composing via makeEnsDbStackInfoSchema for consistency.

The serialize/deserialize layer and the SerializedEnsNodeStackInfo type both compose via the new EnsDbStackInfo helpers. These Zod schemas still enumerate all fields directly. For consistency (and to pick up the invariant_ensRainbowCompatibilityWithEnsIndexer check that makeEnsDbStackInfoSchema applies), consider:

♻️ Proposed refactor
 export function makeSerializedEnsNodeStackInfoSchema(valueLabel?: string) {
   const label = valueLabel ?? "ENSNodeStackInfo";
-  return z.object({
-    ensApi: makeSerializedEnsApiPublicConfigSchema(`${label}.ensApi`),
-    ensDb: makeEnsDbPublicConfigSchema(`${label}.ensDb`),
-    ensIndexer: makeSerializedEnsIndexerPublicConfigSchema(`${label}.ensIndexer`),
-    ensRainbow: makeEnsRainbowPublicConfigSchema(`${label}.ensRainbow`),
-  });
+  return makeSerializedEnsDbStackInfoSchema(label).extend({
+    ensApi: makeSerializedEnsApiPublicConfigSchema(`${label}.ensApi`),
+  });
 }

Otherwise, tightening ensRainbow to required is correct given the extended-type hierarchy.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts` around
lines 14 - 34, Replace the explicit field enumeration in
makeSerializedEnsNodeStackInfoSchema and makeEnsNodeStackInfoSchema with
composition via the existing EnsDb stack helpers: use
makeSerializedEnsDbStackInfoSchema(...) inside
makeSerializedEnsNodeStackInfoSchema and makeEnsDbStackInfoSchema(...) inside
makeEnsNodeStackInfoSchema (passing the same composed label) so the schemas pick
up the shared structure and the invariant_ensRainbowCompatibilityWithEnsIndexer
check applied by the EnsDb helpers instead of re-declaring ensApi, ensDb,
ensIndexer, ensRainbow locally.
packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts (1)

17-25: ⚠️ Potential issue | 🟡 Minor

Keep the builder documentation in sync with the expanded signature.

The function now also requires ENSIndexer and ENSRainbow configs, but the summary still says it builds only from ENSApi and ENSDb.

Proposed documentation update
 /**
  * Build a complete {`@link` EnsNodeStackInfo} object from
- * the given public configs of ENSApi and ENSDb.
+ * the given public configs of ENSApi, ENSDb, ENSIndexer, and ENSRainbow.
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts` around lines 17 -
25, Update the JSDoc for buildEnsNodeStackInfo to reflect the expanded
parameters: mention that it builds a complete EnsNodeStackInfo from the public
configs of ENSApi, ENSDb, ENSIndexer, and ENSRainbow; update the `@param` list to
include EnsIndexerPublicConfig and EnsRainbowPublicConfig and adjust the summary
sentence accordingly so it no longer only references ENSApi and ENSDb.
🤖 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/ensadmin/src/app/mock/stack-info/page.tsx`:
- Around line 27-32: The mock error case for "Loading Error" uses stale copy
referring to "ENSNodeConfigInfo" and "ENSIndexer Config"; update the returned
error object inside the case "Loading Error" (the error.title and
error.description strings) to reflect the stack info context — e.g., change
error.title to something like "StackInfo Error" and error.description to a
message about failing to fetch Stack Info — so the mock accurately matches the
stack info flow exercised by this page.tsx case.

In `@apps/ensadmin/src/app/mock/stack-info/stack-info.mock.ts`:
- Around line 7-413: The mock has large duplicated sub-objects
(ensRainbowPublicConfig, ensIndexerPublicConfig, ensIndexer, ensRainbow, ensDb,
versionInfo) inside mockSerializedEnsNodeStackInfo; extract shared fragments
like const baseVersionInfo, baseEnsDb, baseEnsRainbowPublicConfig, and
baseEnsIndexerPublicConfig and then build each variant by composing/spreading
those bases and only overriding the few fields that differ (e.g.
indexedChainIds, namespace, plugins, ensIndexerSchemaName); update
mockSerializedEnsNodeStackInfo to reference those constants so the four "happy
path" variants reuse the same base objects while preserving the final
"Deserialization Error" variant intact, and keep the overall export typed with
as const satisfies Record<string, SerializedEnsNodeStackInfo>.

In `@packages/ensnode-sdk/src/stack-info/deserialize/ensdb-stack-info.ts`:
- Around line 12-18: The JSDoc for the builder of EnsDbStackInfo contains a
redundant "@return" tag that merely repeats the summary; remove the "@return"
line from the JSDoc block that documents the function which constructs an
EnsDbStackInfo (referenced alongside makeEnsDbStackInfoSchema and
EnsDbStackInfo) so the doc only keeps the descriptive summary and parameter docs
without the duplicated return tag.

In `@packages/ensnode-sdk/src/stack-info/deserialize/ensindexer-stack-info.ts`:
- Around line 12-18: Remove the redundant JSDoc `@return` tag from the JSDoc block
that documents the function building an unvalidated EnsIndexerStackInfo (the doc
that references {`@link` EnsIndexerStackInfo} and {`@link`
makeEnsIndexerStackInfoSchema}); keep the summary and the `@param` but delete the
`@return` line so the comment no longer restates the method summary.

In `@packages/ensnode-sdk/src/stack-info/zod-schemas/ensdb-stack-info.ts`:
- Around line 8-24: The label fallback is applied only to the ensDb subpath,
causing inconsistent error path prefixes because
makeSerializedEnsIndexerStackInfoSchema and makeEnsIndexerStackInfoSchema are
called with valueLabel rather than the resolved label; change both calls in
makeSerializedEnsDbStackInfoSchema and makeEnsDbStackInfoSchema to pass the
resolved label variable (label) instead of valueLabel so nested indexer/rainbow
errors use the same unified prefix as ensDb (and keep the rest of each function
unchanged).

---

Outside diff comments:
In `@packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts`:
- Around line 17-25: Update the JSDoc for buildEnsNodeStackInfo to reflect the
expanded parameters: mention that it builds a complete EnsNodeStackInfo from the
public configs of ENSApi, ENSDb, ENSIndexer, and ENSRainbow; update the `@param`
list to include EnsIndexerPublicConfig and EnsRainbowPublicConfig and adjust the
summary sentence accordingly so it no longer only references ENSApi and ENSDb.

In `@packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts`:
- Around line 14-34: Replace the explicit field enumeration in
makeSerializedEnsNodeStackInfoSchema and makeEnsNodeStackInfoSchema with
composition via the existing EnsDb stack helpers: use
makeSerializedEnsDbStackInfoSchema(...) inside
makeSerializedEnsNodeStackInfoSchema and makeEnsDbStackInfoSchema(...) inside
makeEnsNodeStackInfoSchema (passing the same composed label) so the schemas pick
up the shared structure and the invariant_ensRainbowCompatibilityWithEnsIndexer
check applied by the EnsDb helpers instead of re-declaring ensApi, ensDb,
ensIndexer, ensRainbow locally.
🪄 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: 16627062-6551-4ce9-97b8-14f89d71638f

📥 Commits

Reviewing files that changed from the base of the PR and between 44b4385 and 64c4fa8.

📒 Files selected for processing (24)
  • .changeset/clear-rabbits-punch.md
  • .changeset/fifty-games-smash.md
  • apps/ensadmin/src/app/@breadcrumbs/mock/stack-info/page.tsx
  • apps/ensadmin/src/app/mock/config-info/data.json
  • apps/ensadmin/src/app/mock/config-info/page.tsx
  • apps/ensadmin/src/app/mock/page.tsx
  • apps/ensadmin/src/app/mock/stack-info/page.tsx
  • apps/ensadmin/src/app/mock/stack-info/stack-info.mock.ts
  • apps/ensadmin/src/components/connection/cards/ensnode-stack-info.tsx
  • apps/ensadmin/src/components/connection/index.tsx
  • apps/ensapi/src/cache/stack-info.cache.ts
  • packages/ensnode-sdk/src/stack-info/deserialize/ensdb-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/deserialize/ensindexer-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/deserialize/ensnode-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/ensdb-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/ensindexer-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/index.ts
  • packages/ensnode-sdk/src/stack-info/serialize/ensdb-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/serialize/ensindexer-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/serialize/ensnode-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/zod-schemas/ensdb-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/zod-schemas/ensindexer-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts
💤 Files with no reviewable changes (2)
  • apps/ensadmin/src/app/mock/config-info/page.tsx
  • apps/ensadmin/src/app/mock/config-info/data.json

Comment thread apps/ensadmin/src/app/mock/stack-info/page.tsx
Comment thread apps/ensadmin/src/app/mock/stack-info/stack-info.mock.ts Outdated
Comment thread packages/ensnode-sdk/src/stack-info/deserialize/ensdb-stack-info.ts Outdated
Comment thread packages/ensnode-sdk/src/stack-info/zod-schemas/ensdb-stack-info.ts Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends @ensnode/ensnode-sdk’s “stack info” domain model into layered types (EnsIndexerStackInfoEnsDbStackInfoEnsNodeStackInfo), with corresponding zod schemas and (de)serialization helpers, and updates ENSApi + ENSAdmin to consume the updated model and renamed UI components/mocks.

Changes:

  • Added new stack-info models for ENSIndexer and ENSDb, and refactored ENSNode stack info to extend them.
  • Added serialize/deserialize + zod schemas for the new stack-info layers.
  • Updated ENSApi stack-info cache builder and ENSAdmin UI/mocks/routes to use the new stack-info naming and structure.

Reviewed changes

Copilot reviewed 23 out of 24 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts Makes ensRainbow required in ENSNode stack-info zod schemas.
packages/ensnode-sdk/src/stack-info/zod-schemas/ensindexer-stack-info.ts New zod schemas + invariant check for EnsIndexerStackInfo.
packages/ensnode-sdk/src/stack-info/zod-schemas/ensdb-stack-info.ts New zod schemas composing EnsIndexerStackInfo + ENSDb config.
packages/ensnode-sdk/src/stack-info/serialize/ensnode-stack-info.ts Refactors ENSNode stack-info serialization to compose via ENSDb stack-info serializer.
packages/ensnode-sdk/src/stack-info/serialize/ensindexer-stack-info.ts New serializer + serialized type for EnsIndexerStackInfo.
packages/ensnode-sdk/src/stack-info/serialize/ensdb-stack-info.ts New serializer + serialized type for EnsDbStackInfo.
packages/ensnode-sdk/src/stack-info/index.ts Exports new stack-info layers and their (de)serializers.
packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts EnsNodeStackInfo now extends EnsDbStackInfo; builder signature updated.
packages/ensnode-sdk/src/stack-info/ensindexer-stack-info.ts New EnsIndexerStackInfo interface + builder.
packages/ensnode-sdk/src/stack-info/ensdb-stack-info.ts New EnsDbStackInfo interface + builder extending EnsIndexerStackInfo.
packages/ensnode-sdk/src/stack-info/deserialize/ensnode-stack-info.ts EnsNodeStackInfo deserialization now composes through EnsDbStackInfo deserialization.
packages/ensnode-sdk/src/stack-info/deserialize/ensindexer-stack-info.ts New deserializer for EnsIndexerStackInfo.
packages/ensnode-sdk/src/stack-info/deserialize/ensdb-stack-info.ts New deserializer for EnsDbStackInfo.
apps/ensapi/src/cache/stack-info.cache.ts Updates stack-info construction to pass explicit indexer/rainbow configs.
apps/ensadmin/src/components/connection/index.tsx Switches connection details card to the renamed stack-info component.
apps/ensadmin/src/components/connection/cards/ensnode-stack-info.tsx Renames ENSNodeConfig* components to EnsNodeStackInfo* and updates ENSRainbow field access.
apps/ensadmin/src/app/mock/stack-info/stack-info.mock.ts Adds mock SerializedEnsNodeStackInfo variants for UI testing.
apps/ensadmin/src/app/mock/stack-info/page.tsx Adds new UI mock page to render stack-info variants via deserialization.
apps/ensadmin/src/app/mock/page.tsx Updates mock list link to the new /mock/stack-info page.
apps/ensadmin/src/app/mock/config-info/page.tsx Removes old config-info mock page.
apps/ensadmin/src/app/mock/config-info/data.json Removes old config-info mock data.
apps/ensadmin/src/app/@breadcrumbs/mock/stack-info/page.tsx Adds breadcrumbs for the new stack-info mock route.
.changeset/fifty-games-smash.md Changeset for SDK minor bump due to new stack-info models/exports.
.changeset/clear-rabbits-punch.md Changeset for ENSAdmin minor bump due to component renames.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/ensnode-sdk/src/stack-info/zod-schemas/ensdb-stack-info.ts Outdated
Comment thread packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts
Comment thread packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts Outdated
Comment thread packages/ensnode-sdk/src/stack-info/zod-schemas/ensindexer-stack-info.ts Outdated
Comment thread apps/ensadmin/src/app/mock/stack-info/page.tsx Outdated
Comment thread packages/ensnode-sdk/src/stack-info/zod-schemas/ensdb-stack-info.ts Outdated
Comment thread packages/ensnode-sdk/src/stack-info/zod-schemas/ensdb-stack-info.ts Outdated
@tk-o
Copy link
Copy Markdown
Member Author

tk-o commented Apr 23, 2026

@greptile review

Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestions:

  1. Breadcrumb label references old component name "ENSNodeConfigInfo" instead of "EnsNodeStackInfo"
  1. Breadcrumb label displays outdated "ENSNodeConfigInfo" instead of "EnsNodeStackInfo"

Fix on Vercel

Comment thread packages/ensnode-sdk/src/stack-info/zod-schemas/ensindexer-stack-info.ts Outdated
Copy link
Copy Markdown
Member

@lightwalker-eth lightwalker-eth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tk-o Nice updates! Reviewed and shared some feedback. Please take the lead to merge when ready 🫡

Comment thread packages/ensnode-sdk/src/stack-info/ensindexer-stack-info.ts
Comment thread packages/ensnode-sdk/src/stack-info/ensindexer-stack-info.ts Outdated
Comment thread packages/ensnode-sdk/src/stack-info/ensindexer-stack-info.ts
Comment thread packages/ensnode-sdk/src/stack-info/ensindexer-stack-info.ts Outdated
Comment thread packages/ensnode-sdk/src/stack-info/ensdb-stack-info.ts Outdated
Comment thread apps/ensadmin/src/app/mock/stack-info/stack-info.mock.ts Outdated
Comment thread packages/ensnode-sdk/src/stack-info/zod-schemas/ensindexer-stack-info.ts Outdated
Comment thread packages/ensnode-sdk/src/stack-info/zod-schemas/ensindexer-stack-info.ts Outdated

type LoadingVariant = "Loading" | "Loading Error";
type Variants = keyof typeof mockSerializedEnsNodeStackInfo | LoadingVariant;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CleanShot 2026-04-24 at 09 44 02

Unfortunately it seems if we have a breaking change to related data models that it won't be possible to open the /mock page at all inside ENSAdmin Vercel Previews.

If there's an easy fix for this, great!

If not, and a fix for this would need more effort or investigation, then please don't worry about it now. Instead:

  1. Could you please verify the mock UIs look ok in your own local ENSAdmin?
  2. Could you please create a follow-up issue for this?

Thanks!

Copy link
Copy Markdown
Member Author

@tk-o tk-o Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lightwalker-eth please connect to api.alpha-sepolia.blue.ensnode.io as it serves ENSApi v1.10.1 which already includes the stackInfo object in the Indexing Status response 👍

Here's the exact connection link for ENSAdmin:
https://adminensnodeio-git-feat-extend-stack-info-data-model-namehash.vercel.app/mock/stack-info?connection=https%3A%2F%2Fapi.alpha-sepolia.blue.ensnode.io%2F

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 65 out of 66 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

docs/ensnode.io/src/content/docs/ensrainbow/usage/client-sdk.mdx:37

  • The TypeScript usage snippet uses baseUrl and healLabel(...), but EnsRainbowApiClient expects endpointUrl: URL and the method is heal(...). Update the docs example to match the actual SDK API so copy-paste usage typechecks and runs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/ensrainbow-sdk/src/client.ts
Comment thread packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts
Comment thread .changeset/fifty-games-smash.md
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (9)
packages/ensnode-sdk/src/ensindexer/config/conversions.test.ts (1)

93-102: ⚠️ Potential issue | 🟡 Minor

Redundant assignment makes this test a duplicate of the baseline round-trip.

correctSerializedConfig.isSubgraphCompatible is already true (Line 68), so Line 98 is a no-op and this case degenerates into re-testing the happy path already covered by the first it block. Either flip it to false with a plugin set that is subgraph-compatible to actually exercise a distinct invariant path, or remove this case.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-sdk/src/ensindexer/config/conversions.test.ts` around lines
93 - 102, The test "can enforce invariants: expected subgraph-compatibility" is
redundant because correctSerializedConfig.isSubgraphCompatible is already true;
change the test to exercise the alternate path by setting
serializedConfig.isSubgraphCompatible = false and ensure the
serializedConfig.plugins (or whichever field denotes plugin set) contains a
plugin that is subgraph-compatible so
deserializeEnsIndexerPublicConfig(serializedConfig) hits the distinct invariant
branch, or delete the test if you prefer not to cover that case separately;
update only the serializedConfig mutation in this test (referencing
serializedConfig, correctSerializedConfig, isSubgraphCompatible, and
deserializeEnsIndexerPublicConfig).
docs/ensnode.io/ensapi-openapi.json (1)

802-991: ⚠️ Potential issue | 🟡 Minor

EnsIndexerPublicConfig is now duplicated across stackInfo.ensIndexer and stackInfo.ensApi.ensIndexerPublicConfig.

The flattened stackInfo.ensIndexer (lines 802–881) and the nested stackInfo.ensApi.ensIndexerPublicConfig (lines 909–991) describe the same underlying EnsIndexerPublicConfig fields (ensIndexerSchemaName, ensRainbowPublicConfig, indexedChainIds, isSubgraphCompatible, clientLabelSet, namespace, plugins, versionInfo). In addition, stackInfo.ensIndexer.ensRainbowPublicConfig (806–831) duplicates the new stackInfo.ensRainbow (882–905).

Two risks this introduces for consumers:

  1. Divergence — Nothing in the schema constrains the two copies to be equal, so clients can receive conflicting values for the same logical config and won't know which is authoritative.
  2. Payload bloat / ambiguity — Documentation no longer has a single source of truth for the connected indexer's config.

Given the PR description notes this is transitional (ENSApi still relies on ensIndexerPublicConfig.ensIndexerPublicConfig being present), please at least document the canonical source in the schema description fields, and track removal of the nested copies from stackInfo.ensApi in the promised follow-up. Otherwise OpenAPI consumers generating typed clients will end up with two parallel types for the same concept.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ensnode.io/ensapi-openapi.json` around lines 802 - 991, The schema
duplicates the same EnsIndexerPublicConfig across stackInfo.ensIndexer and
stackInfo.ensApi.ensIndexerPublicConfig (and also duplicates ensRainbow in
stackInfo.ensIndexer.ensRainbowPublicConfig vs stackInfo.ensRainbow); replace
these inline copies with a single reusable component (e.g.,
components.schemas.EnsIndexerPublicConfig and components.schemas.EnsRainbow) and
reference it via $ref from both stackInfo.ensIndexer and
stackInfo.ensApi.ensIndexerPublicConfig, and update the description fields on
stackInfo.ensApi.ensIndexerPublicConfig and on the duplicated ensRainbow to
explicitly state the canonical source (stackInfo.ensIndexer /
components.schemas.EnsIndexerPublicConfig) and mark the nested copy as
transitional/deprecated pending removal in the follow-up so generated clients
know which is authoritative.
apps/ensindexer/src/config/types.ts (1)

151-154: ⚠️ Potential issue | 🟡 Minor

Stale reference to labelSet in JSDoc after rename.

Now that the field has been renamed to clientLabelSet (Line 36), the invariant doc on Line 153 should reflect the new name for consistency.

📝 Proposed doc fix
    * If {`@link` isSubgraphCompatible} is true, the following invariants are true for the ENSIndexerConfig:
    * 1. only the 'subgraph' plugin is enabled, and
-   * 2. the labelSet must be { labelSetId: 'subgraph', labelSetVersion: 0 }
+   * 2. the clientLabelSet must be { labelSetId: 'subgraph', labelSetVersion: 0 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensindexer/src/config/types.ts` around lines 151 - 154, The JSDoc
invariant mentions the old field name "labelSet" but the config now uses
clientLabelSet; update the comment under isSubgraphCompatible/ENSIndexerConfig
to reference clientLabelSet (and the expected value { labelSetId: 'subgraph',
labelSetVersion: 0 } if still valid) so the doc matches the renamed property.
packages/ensnode-sdk/src/ensindexer/config/types.ts (1)

128-131: ⚠️ Potential issue | 🟡 Minor

Stale reference to labelSet in JSDoc after rename.

The field was renamed to clientLabelSet (Line 81), but the invariant doc on Line 130 still refers to labelSet.

📝 Proposed doc fix
    * If {`@link` isSubgraphCompatible} is true, the following invariants are true for the ENSIndexerConfig:
    * 1. only the 'subgraph' plugin is enabled, and
-   * 2. the labelSet must be { labelSetId: 'subgraph', labelSetVersion: 0 }
+   * 2. the clientLabelSet must be { labelSetId: 'subgraph', labelSetVersion: 0 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-sdk/src/ensindexer/config/types.ts` around lines 128 - 131,
The JSDoc for ENSIndexerConfig still refers to the old field name "labelSet" in
the invariant for isSubgraphCompatible; update that text to refer to the renamed
field "clientLabelSet" (and the expected value { clientLabelSet: { labelSetId:
'subgraph', labelSetVersion: 0 } }) so the doc matches the actual config shape
and the isSubgraphCompatible contract; check the comment block containing
isSubgraphCompatible and ENSIndexerConfig to replace all occurrences of
"labelSet" with "clientLabelSet".
apps/ensadmin/src/app/mock/indexing-status-api.mock.ts (1)

19-19: 🧹 Nitpick | 🔵 Trivial

Nit: import SerializedEnsRainbowPublicConfig as type.

It is only used as a type annotation (line 80, satisfies SerializedEnsRainbowPublicConfig), so it should be a type-only import like the other sibling imports in this block.

Proposed fix
-  SerializedEnsRainbowPublicConfig,
+  type SerializedEnsRainbowPublicConfig,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensadmin/src/app/mock/indexing-status-api.mock.ts` at line 19, The
import of SerializedEnsRainbowPublicConfig is only used as a type (used in the
`satisfies SerializedEnsRainbowPublicConfig` annotation around line 80), so
change its import to a type-only import to avoid runtime inclusion; update the
import statement that currently lists SerializedEnsRainbowPublicConfig with the
other imports to use the `import type { SerializedEnsRainbowPublicConfig }` form
(matching the style of the sibling type imports) and ensure no runtime usage
remains.
.changeset/fifty-games-smash.md (1)

1-6: ⚠️ Potential issue | 🟡 Minor

Changeset omits breaking SDK field renames/removals.

This PR isn't just additive — on @ensnode/ensnode-sdk it also:

  • renames EnsIndexerPublicConfig.labelSetclientLabelSet,
  • renames EnsRainbowPublicConfig.labelSetserverLabelSet,
  • replaces EnsRainbowPublicConfig.version with versionInfo,
  • removes EnsRainbowPublicConfig.recordsCount.

These are breaking for external SDK consumers and should be called out in the release notes (and, depending on this package's semver policy for 0.x, may warrant major rather than minor).

✍️ Suggested changeset expansion
 ---
 "@ensnode/ensnode-sdk": minor
 ---

-Introduced a set of "stack info" data models: `EnsIndexerStackInfo`, `EnsNodeStackInfo`.
+Introduced a set of "stack info" data models: `EnsIndexerStackInfo`, `EnsNodeStackInfo`.
+
+Breaking changes:
+- `EnsIndexerPublicConfig.labelSet` renamed to `clientLabelSet`.
+- `EnsRainbowPublicConfig.labelSet` renamed to `serverLabelSet`.
+- `EnsRainbowPublicConfig.version` replaced with `versionInfo`.
+- `EnsRainbowPublicConfig.recordsCount` removed.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.changeset/fifty-games-smash.md around lines 1 - 6, The changeset
.changeset/fifty-games-smash.md currently lists only additive model additions
but omits breaking SDK field renames/removals; update the changeset to
explicitly document the breaking changes: rename EnsIndexerPublicConfig.labelSet
→ clientLabelSet, rename EnsRainbowPublicConfig.labelSet → serverLabelSet,
replace EnsRainbowPublicConfig.version with versionInfo, and remove
EnsRainbowPublicConfig.recordsCount; state that these are breaking for external
SDK consumers and adjust the release type from minor to major if your semver
policy for 0.x requires it, and include short migration notes for each symbol
(EnsIndexerPublicConfig, EnsRainbowPublicConfig) so consumers know how to
update.
packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts (1)

70-70: ⚠️ Potential issue | 🟡 Minor

Stale test description still references labelSet instead of clientLabelSet.

The body of this test now mutates clientLabelSet.labelSetId and asserts against a 'clientLabelSet.labelSetId' error, but the it(...) title still reads 'configA.labelSet.labelSetId' / 'configB.labelSet.labelSetId'. The sibling test at line 86 was updated — align this one for consistency.

📝 Proposed description fix
-    it("throws error when 'configA.labelSet.labelSetId' is not same as 'configB.labelSet.labelSetId'", () => {
+    it("throws error when 'configA.clientLabelSet.labelSetId' is not same as 'configB.clientLabelSet.labelSetId'", () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts` at line 70,
The test description is stale: update the it(...) title that currently says
"'configA.labelSet.labelSetId' / 'configB.labelSet.labelSetId'" to reference
clientLabelSet (e.g., "'configA.clientLabelSet.clientLabelSetId' is not same as
'configB.clientLabelSet.clientLabelSetId'") so it matches the test body which
mutates clientLabelSet.labelSetId and asserts the "'clientLabelSet.labelSetId'"
error; ensure the new title mirrors the sibling test's wording for consistency
and clarity.
apps/ensrainbow/src/commands/server-command.test.ts (1)

131-146: ⚠️ Potential issue | 🟡 Minor

Stale test description after removing the /v1/config.recordsCount cross-check.

The test's it title says "(same as /v1/config)", but per this PR recordsCount was removed from EnsRainbowPublicConfig, and the cross-endpoint consistency assertion was dropped. The title now implies a relationship that no longer exists and is likely to confuse future readers.

📝 Proposed title tweak
-    it("should return count snapshot from startup (same as /v1/config)", async () => {
+    it("should return count snapshot from startup (from dbConfig.recordsCount)", async () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensrainbow/src/commands/server-command.test.ts` around lines 131 - 146,
The test title for the "GET /v1/labels/count" spec still says "(same as
/v1/config)" even though the cross-check against /v1/config.recordsCount was
removed; update the it(...) title to accurately reflect the test behavior (e.g.,
change the string in the it call to "should return count snapshot from startup"
or similar) so the description no longer implies a relationship to /v1/config;
locate the spec under the describe("GET /v1/labels/count") block in
server-command.test.ts and edit the it(...) title accordingly.
docs/ensnode.io/src/content/docs/ensrainbow/concepts/typescript-interfaces.mdx (1)

34-34: ⚠️ Potential issue | 🟡 Minor

Stale labelSet reference in the intro sentence.

The prose still shows new EnsRainbowApiClient({ labelSet: … }), but the constructor option was renamed to clientLabelSet (see the updated examples on lines 66 and 72, and the SDK change in packages/ensrainbow-sdk/src/client.ts).

📝 Proposed fix
-Provided when constructing `new EnsRainbowApiClient({ labelSet: … })` to pin client expectations:
+Provided when constructing `new EnsRainbowApiClient({ clientLabelSet: … })` to pin client expectations:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@docs/ensnode.io/src/content/docs/ensrainbow/concepts/typescript-interfaces.mdx`
at line 34, The intro sentence currently references the old constructor option
name labelSet; update that prose to use the new option name clientLabelSet so it
matches the SDK and the examples (ensure the sentence reads something like
"Provided when constructing new EnsRainbowApiClient({ clientLabelSet: … })" and
replace any remaining occurrences of labelSet in this section with
clientLabelSet to keep the docs consistent with the EnsRainbowApiClient
constructor.
🤖 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/ensadmin/src/app/mock/stack-info/page.tsx`:
- Around line 19-21: DEFAULT_VARIANT is currently an untyped string and can
drift out of sync with mockSerializedEnsNodeStackInfo keys; explicitly type it
as the Variants/key type used by mockSerializedEnsNodeStackInfo so the compiler
will catch renames/removals. Change the declaration of DEFAULT_VARIANT to use
the same key type (e.g., keyof typeof mockSerializedEnsNodeStackInfo or
Variants) referenced by useState<Variants>, so MockConfigPage (and calls like
mockSerializedEnsNodeStackInfo[selectedConfig] and deserializeEnsNodeStackInfo)
cannot receive an invalid key at compile time.
- Line 20: Rename the stale default exported component function MockConfigPage
to MockStackInfoPage so the component name matches the route and page content;
update the function declaration (export default function MockConfigPage() ->
export default function MockStackInfoPage()) and any internal/local references
or test imports that reference MockConfigPage to use MockStackInfoPage instead.

In `@apps/ensindexer/src/ponder/indexing-behavior-injection-contract.ts`:
- Around line 49-55: Update the JSDoc to reference the renamed property: replace
the stale `labelSet` mention with `clientLabelSet` in the comment above the
clientLabelSet property (the comment block that describes clientLabelSet and
references "healing" results), so the description and any inline code formatting
match the actual field name `clientLabelSet` and its type
EnsIndexerConfig["clientLabelSet"].

In `@docs/ensnode.io/ensapi-openapi.json`:
- Line 5: The OpenAPI spec version field needs to be updated to reflect the
breaking schema changes to /api/indexing-status: change the "version" value in
ensapi-openapi.json from "1.10.1" to at least "1.11.0" (or "2.0.0" if you decide
to mark this as a major breaking change) so downstream clients and release
tooling see the schema bump; ensure this update accompanies the documented
changes to stackInfo (new top-level children ensDb, ensIndexer, ensRainbow), the
renaming of labelSet → clientLabelSet inside ensIndexerPublicConfig, and the new
ensRainbow shape (serverLabelSet + versionInfo.ensRainbow).

In
`@docs/ensnode.io/src/content/docs/ensrainbow/concepts/typescript-interfaces.mdx`:
- Around line 45-47: Change the inconsistent single-word "labelset" occurrences
in the three bullet points to the two-word form "label set" to match the rest of
the document and glossary, while leaving code identifiers like `labelSetId`
unchanged; update the three bullets so they read "label set" (e.g., "accept any
client label set", "insist on a specific client label set") and ensure
surrounding punctuation/capitalization remains consistent.

In `@packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts`:
- Around line 13-57: The Zod issue paths in
invariant_ensApiCompatibilityWithEnsIndexerAndEnsRainbow are using dotted-string
segments (e.g., path: ["ensIndexer.versionInfo.ensDb"]) which breaks Zod v4 path
handling; update each ctx.issues.push call to use an array of individual
property keys instead (e.g., ["ensIndexer","versionInfo","ensDb"],
["ensIndexer","versionInfo","ensIndexer"],
["ensRainbow","versionInfo","ensRainbow"],
["ensIndexer","versionInfo","ensNormalize"]) so Zod treats them as nested path
segments.

---

Outside diff comments:
In @.changeset/fifty-games-smash.md:
- Around line 1-6: The changeset .changeset/fifty-games-smash.md currently lists
only additive model additions but omits breaking SDK field renames/removals;
update the changeset to explicitly document the breaking changes: rename
EnsIndexerPublicConfig.labelSet → clientLabelSet, rename
EnsRainbowPublicConfig.labelSet → serverLabelSet, replace
EnsRainbowPublicConfig.version with versionInfo, and remove
EnsRainbowPublicConfig.recordsCount; state that these are breaking for external
SDK consumers and adjust the release type from minor to major if your semver
policy for 0.x requires it, and include short migration notes for each symbol
(EnsIndexerPublicConfig, EnsRainbowPublicConfig) so consumers know how to
update.

In `@apps/ensadmin/src/app/mock/indexing-status-api.mock.ts`:
- Line 19: The import of SerializedEnsRainbowPublicConfig is only used as a type
(used in the `satisfies SerializedEnsRainbowPublicConfig` annotation around line
80), so change its import to a type-only import to avoid runtime inclusion;
update the import statement that currently lists
SerializedEnsRainbowPublicConfig with the other imports to use the `import type
{ SerializedEnsRainbowPublicConfig }` form (matching the style of the sibling
type imports) and ensure no runtime usage remains.

In `@apps/ensindexer/src/config/types.ts`:
- Around line 151-154: The JSDoc invariant mentions the old field name
"labelSet" but the config now uses clientLabelSet; update the comment under
isSubgraphCompatible/ENSIndexerConfig to reference clientLabelSet (and the
expected value { labelSetId: 'subgraph', labelSetVersion: 0 } if still valid) so
the doc matches the renamed property.

In `@apps/ensrainbow/src/commands/server-command.test.ts`:
- Around line 131-146: The test title for the "GET /v1/labels/count" spec still
says "(same as /v1/config)" even though the cross-check against
/v1/config.recordsCount was removed; update the it(...) title to accurately
reflect the test behavior (e.g., change the string in the it call to "should
return count snapshot from startup" or similar) so the description no longer
implies a relationship to /v1/config; locate the spec under the describe("GET
/v1/labels/count") block in server-command.test.ts and edit the it(...) title
accordingly.

In `@docs/ensnode.io/ensapi-openapi.json`:
- Around line 802-991: The schema duplicates the same EnsIndexerPublicConfig
across stackInfo.ensIndexer and stackInfo.ensApi.ensIndexerPublicConfig (and
also duplicates ensRainbow in stackInfo.ensIndexer.ensRainbowPublicConfig vs
stackInfo.ensRainbow); replace these inline copies with a single reusable
component (e.g., components.schemas.EnsIndexerPublicConfig and
components.schemas.EnsRainbow) and reference it via $ref from both
stackInfo.ensIndexer and stackInfo.ensApi.ensIndexerPublicConfig, and update the
description fields on stackInfo.ensApi.ensIndexerPublicConfig and on the
duplicated ensRainbow to explicitly state the canonical source
(stackInfo.ensIndexer / components.schemas.EnsIndexerPublicConfig) and mark the
nested copy as transitional/deprecated pending removal in the follow-up so
generated clients know which is authoritative.

In
`@docs/ensnode.io/src/content/docs/ensrainbow/concepts/typescript-interfaces.mdx`:
- Line 34: The intro sentence currently references the old constructor option
name labelSet; update that prose to use the new option name clientLabelSet so it
matches the SDK and the examples (ensure the sentence reads something like
"Provided when constructing new EnsRainbowApiClient({ clientLabelSet: … })" and
replace any remaining occurrences of labelSet in this section with
clientLabelSet to keep the docs consistent with the EnsRainbowApiClient
constructor.

In `@packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts`:
- Line 70: The test description is stale: update the it(...) title that
currently says "'configA.labelSet.labelSetId' / 'configB.labelSet.labelSetId'"
to reference clientLabelSet (e.g., "'configA.clientLabelSet.clientLabelSetId' is
not same as 'configB.clientLabelSet.clientLabelSetId'") so it matches the test
body which mutates clientLabelSet.labelSetId and asserts the
"'clientLabelSet.labelSetId'" error; ensure the new title mirrors the sibling
test's wording for consistency and clarity.

In `@packages/ensnode-sdk/src/ensindexer/config/conversions.test.ts`:
- Around line 93-102: The test "can enforce invariants: expected
subgraph-compatibility" is redundant because
correctSerializedConfig.isSubgraphCompatible is already true; change the test to
exercise the alternate path by setting serializedConfig.isSubgraphCompatible =
false and ensure the serializedConfig.plugins (or whichever field denotes plugin
set) contains a plugin that is subgraph-compatible so
deserializeEnsIndexerPublicConfig(serializedConfig) hits the distinct invariant
branch, or delete the test if you prefer not to cover that case separately;
update only the serializedConfig mutation in this test (referencing
serializedConfig, correctSerializedConfig, isSubgraphCompatible, and
deserializeEnsIndexerPublicConfig).

In `@packages/ensnode-sdk/src/ensindexer/config/types.ts`:
- Around line 128-131: The JSDoc for ENSIndexerConfig still refers to the old
field name "labelSet" in the invariant for isSubgraphCompatible; update that
text to refer to the renamed field "clientLabelSet" (and the expected value {
clientLabelSet: { labelSetId: 'subgraph', labelSetVersion: 0 } }) so the doc
matches the actual config shape and the isSubgraphCompatible contract; check the
comment block containing isSubgraphCompatible and ENSIndexerConfig to replace
all occurrences of "labelSet" with "clientLabelSet".
🪄 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: 8feecd32-3b92-4fa6-85cd-a11467e3cf38

📥 Commits

Reviewing files that changed from the base of the PR and between 64c4fa8 and 73a15bc.

📒 Files selected for processing (59)
  • .changeset/fifty-games-smash.md
  • apps/ensadmin/src/app/mock/indexing-status-api.mock.ts
  • apps/ensadmin/src/app/mock/stack-info/page.tsx
  • apps/ensadmin/src/app/mock/stack-info/stack-info.mock.ts
  • apps/ensadmin/src/components/connection/cards/ensnode-stack-info.tsx
  • apps/ensadmin/src/components/require-ensadmin-feature.tsx
  • apps/ensapi/src/config/config.schema.test.ts
  • apps/ensapi/src/config/validations.ts
  • apps/ensindexer/src/config/config.schema.ts
  • apps/ensindexer/src/config/config.test.ts
  • apps/ensindexer/src/config/environment-defaults.test.ts
  • apps/ensindexer/src/config/serialize.ts
  • apps/ensindexer/src/config/serialized-types.ts
  • apps/ensindexer/src/config/types.ts
  • apps/ensindexer/src/lib/ensdb-writer-worker/ensdb-writer-worker.mock.ts
  • apps/ensindexer/src/lib/ensrainbow/singleton.ts
  • apps/ensindexer/src/lib/public-config-builder/public-config-builder.test.ts
  • apps/ensindexer/src/lib/public-config-builder/public-config-builder.ts
  • apps/ensindexer/src/ponder/indexing-behavior-injection-contract.ts
  • apps/ensrainbow/src/commands/server-command.test.ts
  • apps/ensrainbow/src/commands/server-command.ts
  • apps/ensrainbow/src/config/config.schema.test.ts
  • apps/ensrainbow/src/config/public.ts
  • apps/ensrainbow/src/config/types.ts
  • apps/ensrainbow/src/lib/api.ts
  • apps/ensrainbow/src/lib/database.ts
  • apps/ensrainbow/src/lib/server.ts
  • docs/ensnode.io/ensapi-openapi.json
  • docs/ensnode.io/src/content/docs/ensrainbow/concepts/typescript-interfaces.mdx
  • docs/ensnode.io/src/content/docs/ensrainbow/usage/client-sdk.mdx
  • packages/ensdb-sdk/src/client/ensdb-client.mock.ts
  • packages/ensnode-sdk/src/ensapi/config/conversions.test.ts
  • packages/ensnode-sdk/src/ensdb/zod-schemas/config.ts
  • packages/ensnode-sdk/src/ensindexer/client.mock.ts
  • packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts
  • packages/ensnode-sdk/src/ensindexer/config/compatibility.ts
  • packages/ensnode-sdk/src/ensindexer/config/conversions.test.ts
  • packages/ensnode-sdk/src/ensindexer/config/is-subgraph-compatible.test.ts
  • packages/ensnode-sdk/src/ensindexer/config/is-subgraph-compatible.ts
  • packages/ensnode-sdk/src/ensindexer/config/serialize.ts
  • packages/ensnode-sdk/src/ensindexer/config/types.ts
  • packages/ensnode-sdk/src/ensindexer/config/zod-schemas.test.ts
  • packages/ensnode-sdk/src/ensindexer/config/zod-schemas.ts
  • packages/ensnode-sdk/src/ensnode/client.test.ts
  • packages/ensnode-sdk/src/ensrainbow/config.ts
  • packages/ensnode-sdk/src/ensrainbow/zod-schemas/config.ts
  • packages/ensnode-sdk/src/stack-info/deserialize/ensindexer-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/deserialize/ensnode-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/ensindexer-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/ensnode-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/index.ts
  • packages/ensnode-sdk/src/stack-info/serialize/ensindexer-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/serialize/ensnode-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/validate/ensindexer-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/validate/ensnode-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/zod-schemas/ensindexer-stack-info.ts
  • packages/ensnode-sdk/src/stack-info/zod-schemas/ensnode-stack-info.ts
  • packages/ensrainbow-sdk/src/client.test.ts
  • packages/ensrainbow-sdk/src/client.ts

Comment thread apps/ensadmin/src/app/mock/stack-info/page.tsx Outdated
Comment thread apps/ensadmin/src/app/mock/stack-info/page.tsx Outdated
Comment thread apps/ensindexer/src/ponder/indexing-behavior-injection-contract.ts
Comment thread docs/ensnode.io/ensapi-openapi.json
Comment thread docs/ensnode.io/src/content/docs/ensrainbow/concepts/typescript-interfaces.mdx Outdated
Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestion:

Breadcrumb label displays old name "ENSNodeConfigInfo" instead of "EnsNodeStackInfo"

Fix on Vercel

@tk-o
Copy link
Copy Markdown
Member Author

tk-o commented Apr 24, 2026

@greptile review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 67 out of 68 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/ensnode.io/src/content/docs/ensrainbow/usage/client-sdk.mdx
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io April 24, 2026 12:44 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io April 24, 2026 12:44 Inactive
@tk-o tk-o merged commit 0d8a4b4 into main Apr 24, 2026
19 checks passed
@tk-o tk-o deleted the feat/extend-stack-info-data-model branch April 24, 2026 12:47
@github-actions github-actions Bot mentioned this pull request Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants