Skip to content

ENSDb data model#1660

Merged
tk-o merged 11 commits intomainfrom
feat/ensdb-data-model
Feb 23, 2026
Merged

ENSDb data model#1660
tk-o merged 11 commits intomainfrom
feat/ensdb-data-model

Conversation

@tk-o
Copy link
Contributor

@tk-o tk-o commented Feb 21, 2026

Lite PR

Tip: Review docs on the ENSNode PR process

Summary

  • Creates ensdb module in ENSNode SDK. The module includes data model describing ENSDb client interactions and ENSNode metadata vartiants to be stored in ENSDb.
  • Updates ensindexer module in ENSNode SDK with functionality to perform compatibility check between two instances of ENSIndexer public config.
  • Creates a new schema for ENSNode Metadata in ENSNode Schema package.

Why


Testing

  • Performed static code analysis (lint, typecheck).
  • Ran extended testing suite.
  • Created initial integration with ENSIndexer (not part of this PR) to check how data model proposed in this PR would work in practice. It works well 👍

Notes for Reviewer (Optional)

  • This PR includes additive updates only.
  • This PR is a small slice from PR feat(ensindexer): ENSDb Writer Worker #1406.
  • There were no particular rules made for ENSIndexer public config compatibility check, so I came up with my interpretaiton for what it might be. I appreciate if the propsed compatibility rules requires updates. Please let me know if so. The rules are located in packages/ensnode-sdk/src/ensindexer/config/compatibility.ts file.

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)

tk-o added 6 commits February 21, 2026 17:15
Include relevant data model definitions for `EnsNodeMetadata`, `EnsDbClientQuery`, and `EnsDbClientMutation`.
Introduces validation function which allows checking compatibility between two instances of `EnsIndexerPublicConfig` type.
…g compatibility check between two instances of ENSIndexer public config.
Extends ENSNode Schemas definitions to make room for ENSNode metadata that will be written from ENSIndexer in order to be read from ENSDb clients, for example, ENSApi service.
@tk-o tk-o requested a review from a team as a code owner February 21, 2026 16:33
Copilot AI review requested due to automatic review settings February 21, 2026 16:33
@changeset-bot
Copy link

changeset-bot bot commented Feb 21, 2026

🦋 Changeset detected

Latest commit: 1f475c5

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

This PR includes changesets to release 19 packages
Name Type
@ensnode/ensnode-sdk Major
@ensnode/ensnode-schema Major
ensadmin Major
ensapi Major
ensindexer Major
ensrainbow Major
fallback-ensapi Major
@namehash/ens-referrals Major
@ensnode/ensnode-react Major
@ensnode/ensrainbow-sdk Major
@namehash/namehash-ui Major
@ensnode/datasources Major
@ensnode/ponder-metadata Major
@ensnode/ponder-sdk Major
@ensnode/ponder-subgraph Major
@ensnode/shared-configs Major
@docs/ensnode Major
@docs/ensrainbow Major
@docs/mintlify Major

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

@vercel
Copy link
Contributor

vercel bot commented Feb 21, 2026

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

Project Deployment Actions Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment Feb 23, 2026 1:47pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
ensnode.io Skipped Skipped Feb 23, 2026 1:47pm
ensrainbow.io Skipped Skipped Feb 23, 2026 1:47pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 21, 2026

📝 Walkthrough

Walkthrough

Adds ENSDb metadata model + schema, ENSDb client query/mutation interfaces and serializers, an EnsIndexer public-config compatibility validator with tests, and updates barrel exports to expose the new ENSDb and indexing-status surfaces.

Changes

Cohort / File(s) Summary
Changesets
.changeset/fresh-adults-decide.md, .changeset/itchy-clubs-repeat.md, .changeset/short-buttons-burn.md
Adds three changeset files declaring minor version bumps and describing ENSDb, ENSIndexer compatibility, and ENSNodeMetadata schema additions.
Schema & Re-exports
packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts, packages/ensnode-schema/src/ponder.schema.ts
Adds ensnode_metadata onchain table (text key, jsonb value) and re-exports the new schema.
ENSDb API Surface
packages/ensnode-sdk/src/ensdb/client.ts, packages/ensnode-sdk/src/ensdb/index.ts
Introduces EnsDbClientQuery/EnsDbClientMutation interfaces and re-exports ensdb modules from the ensdb index.
ENSDb Models & Serialization
packages/ensnode-sdk/src/ensdb/ensnode-metadata.ts, packages/ensnode-sdk/src/ensdb/serialize/ensnode-metadata.ts
Defines EnsNodeMetadataKeys, typed metadata record interfaces/unions, and corresponding serialized types.
Compatibility Validator & Tests
packages/ensnode-sdk/src/ensindexer/config/compatibility.ts, packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts, packages/ensnode-sdk/src/ensindexer/config/index.ts
Adds EnsIndexerPublicConfigCompatibilityCheck type, validateEnsIndexerPublicConfigCompatibility function, unit tests covering key incompatibilities, and re-exports the compatibility module.
Public Barrel Updates
packages/ensnode-sdk/src/index.ts, packages/ensnode-sdk/src/indexing-status/index.ts
Re-exports ./ensdb from SDK root and the cross-chain indexing status serializer from indexing-status barrel.

Sequence Diagram(s)

sequenceDiagram
  participant Indexer as Indexer
  participant Validator as Validator
  participant Serializer as Serializer
  participant EnsDbClient as EnsDbClient
  participant Database as Database

  Indexer->>Validator: load local EnsIndexerPublicConfig (A)
  Indexer->>EnsDbClient: fetch stored EnsIndexerPublicConfig (B)
  EnsDbClient-->>Validator: return stored config B
  Validator->>Validator: validateEnsIndexerPublicConfigCompatibility(A, B)
  alt compatible
    Indexer->>Serializer: build EnsNodeMetadata (version, config, status)
    Serializer->>EnsDbClient: upsert serialized metadata
    EnsDbClient->>Database: write/merge metadata rows
    Database-->>EnsDbClient: ack
    EnsDbClient-->>Indexer: success
  else incompatible
    Validator-->>Indexer: throw Error (stored vs current details)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰✨ I nibble keys and JSON, neat,
Versions tucked in rows complete,
Validators hop, compare each part,
Clients store the rabbit's art,
Exports bloom — a tiny celebratory beat.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'ENSDb data model' directly summarizes the main change in the PR: introducing a new ENSDb module with its data model, which is the primary objective.
Description check ✅ Passed The PR description follows the required template with all sections completed: Summary (3 bullets covering the main changes), Why (linked to issue #1252), Testing (static analysis, extended suite, integration validation), Notes for Reviewer, and Pre-Review Checklist (both items checked).
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/ensdb-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.

Copy link
Contributor Author

@tk-o tk-o left a comment

Choose a reason for hiding this comment

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

Self-review completed.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 21, 2026

Greptile Summary

Introduces ENSDb data model and ENSIndexer config compatibility checking. Creates new ensdb module with interfaces for reading/writing ENSNode metadata (version, config, indexing status) to ENSDb. Adds compatibility validation ensuring stored configs are subsets of current configs (chain IDs, plugins, namespace, subgraph compatibility flag must match). Defines database schema for key-value metadata storage using Ponder/jsonb.

  • New ensdb module provides clean client interface abstractions for metadata operations
  • Compatibility check validates subset relationships: stored config must be compatible with current config
  • Well-tested with comprehensive unit tests covering all validation branches
  • Type-safe discriminated unions for metadata variants with proper serialization support
  • Schema properly uses jsonb for flexible storage while maintaining type safety in TypeScript layer

Confidence Score: 5/5

  • Safe to merge with no issues found
  • All changes are additive type definitions and interfaces with comprehensive test coverage. No runtime logic changes or breaking modifications. Compatibility validation logic is well-tested and straightforward. Schema definition follows established patterns.
  • No files require special attention

Important Files Changed

Filename Overview
packages/ensnode-sdk/src/ensdb/client.ts Defines ENSDb client interfaces for query and mutation operations
packages/ensnode-sdk/src/ensdb/ensnode-metadata.ts Defines metadata keys and type variants for ENSNode metadata storage
packages/ensnode-sdk/src/ensindexer/config/compatibility.ts Implements subset-based compatibility validation for ENSIndexer public config
packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts Defines Ponder schema for ENSNode metadata key-value table

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class EnsDbClientQuery {
        <<interface>>
        +getEnsDbVersion() Promise
        +getEnsIndexerPublicConfig() Promise
        +getIndexingStatusSnapshot() Promise
    }
    
    class EnsDbClientMutation {
        <<interface>>
        +upsertEnsDbVersion(string) Promise
        +upsertEnsIndexerPublicConfig(config) Promise
        +upsertIndexingStatusSnapshot(snapshot) Promise
    }
    
    class EnsNodeMetadata {
        <<union>>
    }
    
    class EnsNodeMetadataEnsDbVersion {
        +key: string
        +value: string
    }
    
    class EnsNodeMetadataEnsIndexerPublicConfig {
        +key: string
        +value: EnsIndexerPublicConfig
    }
    
    class EnsNodeMetadataEnsIndexerIndexingStatus {
        +key: string
        +value: CrossChainIndexingStatusSnapshot
    }
    
    class EnsIndexerPublicConfig {
        +namespace: ENSNamespaceId
        +indexedChainIds: Set
        +isSubgraphCompatible: boolean
        +plugins: Array
        +labelSet: Object
        +databaseSchemaName: string
        +versionInfo: Object
    }
    
    class ensNodeMetadataSchema {
        +key: text PK
        +value: jsonb
    }
    
    EnsNodeMetadata <|-- EnsNodeMetadataEnsDbVersion
    EnsNodeMetadata <|-- EnsNodeMetadataEnsIndexerPublicConfig
    EnsNodeMetadata <|-- EnsNodeMetadataEnsIndexerIndexingStatus
    
    EnsNodeMetadataEnsIndexerPublicConfig --> EnsIndexerPublicConfig
    EnsDbClientQuery --> EnsIndexerPublicConfig
    EnsDbClientMutation --> EnsIndexerPublicConfig
    ensNodeMetadataSchema ..> EnsNodeMetadata : stores
Loading

Last reviewed commit: 07033c5

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

14 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link
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

This PR creates foundational data model infrastructure for persisting ENSNode metadata to ENSDb. It introduces a new ensdb module in the ENSNode SDK with TypeScript interfaces for ENSDb client interactions, adds ENSIndexer configuration compatibility validation, and defines a new database schema for storing ENSNode metadata. This work is preparatory for issue #1252, which aims to enable ENSApi to survive ENSIndexer crashes by storing indexing status and configuration in the database.

Changes:

  • Added ENSDb client interface definitions for reading/writing ENSNode metadata (ENSDb version, ENSIndexer config, indexing status)
  • Implemented ENSIndexer config compatibility validation with subset semantics for safe configuration updates
  • Created ensnode_metadata schema table using key-value pattern with JSONB storage

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/ensnode-sdk/src/ensdb/client.ts Defines TypeScript interfaces for ENSDb client query and mutation operations
packages/ensnode-sdk/src/ensdb/ensnode-metadata.ts Defines discriminated union types for type-safe metadata storage
packages/ensnode-sdk/src/ensdb/serialize/ensnode-metadata.ts Defines serialized representations of metadata types for database storage
packages/ensnode-sdk/src/ensdb/index.ts Exports ensdb module types
packages/ensnode-sdk/src/ensindexer/config/compatibility.ts Implements config compatibility validation enforcing subset semantics
packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts Tests for config compatibility validation logic
packages/ensnode-sdk/src/ensindexer/config/index.ts Exports compatibility validation
packages/ensnode-sdk/src/index.ts Adds ensdb module to SDK exports
packages/ensnode-sdk/src/indexing-status/index.ts Exports cross-chain indexing status serialization
packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts Defines ensnode_metadata table schema with key-value JSONB pattern
packages/ensnode-schema/src/ponder.schema.ts Exports new ensnode-metadata schema
.changeset/short-buttons-burn.md Documents schema package changes
.changeset/itchy-clubs-repeat.md Documents ENSIndexer compatibility feature
.changeset/fresh-adults-decide.md Documents ENSDb module addition

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

Copy link
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: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/ensnode-sdk/src/ensdb/client.ts`:
- Around line 6-10: The JSDoc comment block for the ENSDb client header ("ENSDb
Client Query") is malformed because one line in the block is missing the leading
" * " prefix; update the top JSDoc block so every interior line begins with " *
" (e.g., ensure the line containing "Includes methods for reading from ENSDb."
is prefixed with " * ") to produce a well-formed JSDoc comment for the ENSDb
client (client.ts) header.
- Around line 1-4: Change the type import in client.ts to a relative import to
avoid a package-level circular dependency: replace the package self-reference
import of CrossChainIndexingStatusSnapshot and EnsIndexerPublicConfig from
"@ensnode/ensnode-sdk" with a relative path to the local module that exports
those types (e.g., import type { CrossChainIndexingStatusSnapshot,
EnsIndexerPublicConfig } from "./index" or the same relative path used in
ensnode-metadata.ts) so client.ts no longer references the package root.

In `@packages/ensnode-sdk/src/ensdb/ensnode-metadata.ts`:
- Around line 7-11: Rename the property EnsNodeMetadataKeys.IndexingStatus to
EnsIndexerIndexingStatus to match the existing prefix convention used by
EnsDbVersion and EnsIndexerPublicConfig; update the object key name in
EnsNodeMetadataKeys and then update all code references (including any
interfaces like EnsNodeMetadataEnsIndexerIndexingStatus and any serialized-types
files that use key: typeof EnsNodeMetadataKeys.IndexingStatus) to use
EnsNodeMetadataKeys.EnsIndexerIndexingStatus while keeping the string value
"ensindexer_indexing_status" unchanged.

In `@packages/ensnode-sdk/src/ensdb/serialize/ensnode-metadata.ts`:
- Around line 3-9: The import list at the top currently brings in
EnsNodeMetadata without the TypeScript-only modifier; change the import to `type
EnsNodeMetadata` to match the other imports (e.g., `type
EnsNodeMetadataEnsDbVersion`, `type EnsNodeMetadataKeys`) so it is a type-only
import; update the import statement that contains EnsNodeMetadata and ensure
references (including the JSDoc usage around line 33) remain valid under
`verbatimModuleSyntax`/`isolatedModules`.

In `@packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts`:
- Around line 20-30: Add a new test that uses structuredClone(config) to create
configA and configB with identical contents (no changes to indexedChainIds or
plugins) and asserts that calling
validateEnsIndexerPublicConfigCompatibility(configA, configB) does not throw;
reference the existing test setup using config, configA, configB,
PluginName.Lineanames, and indexedChainIds so the new test mirrors the
happy-path but with exact-match instead of a superset.

In `@packages/ensnode-sdk/src/ensindexer/config/compatibility.ts`:
- Around line 14-62: The validator validateEnsIndexerPublicConfigCompatibility
currently throws on the first mismatch; update it to accumulate all
incompatibility messages (e.g., collect into an array like errors) while
checking indexedChainIds (configAIndexedChainIds/configBIndexedChainIds),
isSubgraphCompatible, namespace, and plugins, and after all checks, if
errors.length > 0 throw a single Error joining those messages so callers see all
failures at once; keep the same descriptive message fragments for each check but
push them into the errors array instead of throwing immediately.
- Around line 18-23: The subset check converts configB.indexedChainIds to an
array and uses .includes(), which is unnecessary and inefficient; replace the
Array.from + .includes() pattern by using Set.has() directly against
configB.indexedChainIds (e.g. change the check that iterates
configA.indexedChainIds to call configB.indexedChainIds.has(configAChainId)),
and remove the temporary configBIndexedChainIds array so lookups are O(1) and
more idiomatic.

@vercel vercel bot temporarily deployed to Preview – ensrainbow.io February 21, 2026 16:43 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io February 21, 2026 16:43 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io February 21, 2026 16:46 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io February 21, 2026 16:46 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io February 21, 2026 16:58 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io February 21, 2026 16:58 Inactive
@tk-o
Copy link
Contributor Author

tk-o commented Feb 21, 2026

@greptile review

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

14 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link
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 Thank you, looks good 😄

Copy link
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 14 out of 14 changed files in this pull request and generated 3 comments.


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

Copy link
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: 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 `@packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts`:
- Around line 7-37: Remove the duplicated type-name lists from the JSDoc on the
key and value columns of the ensNodeMetadata table: keep the full enumeration
only in the table-level comment (or replace the column-level lists with a short
pointer to the EnsNodeMetadata discriminated-union type), so update the JSDoc
for the key property (symbol: key) and the value property (symbol: value) to
omit the verbatim type names and instead reference EnsNodeMetadata or the
table-level docs.

In `@packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts`:
- Around line 29-38: Add tests verifying the opposite direction: that when
configB has additional entries (not present in configA) the compatibility check
behaves as intended; specifically, create a test where structuredClone(config)
is used for configA and configB then add (not delete) an indexedChainId to
configB and assert validateEnsIndexerPublicConfigCompatibility(configA, configB)
does NOT throw (or throws only if intended), and similarly add a plugin entry to
configB and assert the expected behavior for plugins; reference the existing
test pattern and the function validateEnsIndexerPublicConfigCompatibility, as
well as the properties indexedChainIds and plugins, to mirror the current tests
but with configB having more entries.

In `@packages/ensnode-sdk/src/ensindexer/config/compatibility.ts`:
- Around line 8-26: The function validateEnsIndexerPublicConfigCompatibility
currently uses symmetricDifference which enforces equality but the docstring
requires configA to be a subset of configB; update the checks to enforce subset
semantics by replacing the symmetricDifference-based checks with isSubsetOf
calls (e.g., if (!configA.indexedChainIds.isSubsetOf(configB.indexedChainIds)) {
throw ... } ) and do the same change for the plugins check (replace
symmetricDifference with isSubsetOf), and adjust the thrown error messages to
state that configA must be a subset of configB for those fields.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e92e72b and 1e28b30.

📒 Files selected for processing (6)
  • packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts
  • packages/ensnode-sdk/src/ensdb/client.ts
  • packages/ensnode-sdk/src/ensdb/ensnode-metadata.ts
  • packages/ensnode-sdk/src/ensdb/serialize/ensnode-metadata.ts
  • packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts
  • packages/ensnode-sdk/src/ensindexer/config/compatibility.ts

Copilot AI review requested due to automatic review settings February 23, 2026 13:45
@tk-o tk-o force-pushed the feat/ensdb-data-model branch from 9bdd321 to 1f475c5 Compare February 23, 2026 13:45
@vercel vercel bot temporarily deployed to Preview – ensnode.io February 23, 2026 13:46 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io February 23, 2026 13:46 Inactive
Copy link
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 14 out of 14 changed files in this pull request and generated 2 comments.


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

Copy link
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.

♻️ Duplicate comments (1)
packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts (1)

33-42: 🧹 Nitpick | 🔵 Trivial

Missing tests for the superset direction — required to document equality semantics.

Both the indexedChainIds (Line 37) and plugins (Line 106) tests only mutate configB by removing an entry from configA. There is no test asserting that adding an entry to configB (making it a superset of configA) also throws. Since the implementation uses symmetricDifference (equality semantics), not isSubsetOf (subset semantics), this direction should also be covered — both to document the intent and to guard against any future drift back toward subset semantics.

📝 Suggested additional tests
+    it("throws error when 'configB.indexedChainIds' is a strict superset of 'configA.indexedChainIds'", () => {
+      const configA = structuredClone(config);
+
+      const configB = structuredClone(config);
+      configB.indexedChainIds.add(999 as ChainId);
+
+      expect(() => validateEnsIndexerPublicConfigCompatibility(configA, configB)).toThrowError(
+        /'indexedChainIds' must be compatible/i,
+      );
+    });
+
+    it("throws error when 'configB.plugins' is a strict superset of 'configA.plugins'", () => {
+      const configA = structuredClone(config);
+
+      const configB = {
+        ...structuredClone(config),
+        plugins: [...config.plugins, "extra-plugin"],
+      } satisfies EnsIndexerPublicConfigCompatibilityCheck;
+
+      expect(() => validateEnsIndexerPublicConfigCompatibility(configA, configB)).toThrowError(
+        /'plugins' must be compatible/i,
+      );
+    });

Also applies to: 102-111

🤖 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` around
lines 33 - 42, Add tests covering the superset direction to document equality
semantics: for validateEnsIndexerPublicConfigCompatibility create cases where
configB adds an entry relative to configA (e.g., for indexedChainIds add a new
chain id to configB and assert the same toThrowError message) and similarly for
plugins (add a plugin to configB and assert it throws); reference the existing
test variables configA/configB and the function
validateEnsIndexerPublicConfigCompatibility as the locations to modify so both
the indexedChainIds and plugins tests assert that a superset in configB is also
treated as incompatible.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts`:
- Around line 33-42: Add tests covering the superset direction to document
equality semantics: for validateEnsIndexerPublicConfigCompatibility create cases
where configB adds an entry relative to configA (e.g., for indexedChainIds add a
new chain id to configB and assert the same toThrowError message) and similarly
for plugins (add a plugin to configB and assert it throws); reference the
existing test variables configA/configB and the function
validateEnsIndexerPublicConfigCompatibility as the locations to modify so both
the indexedChainIds and plugins tests assert that a superset in configB is also
treated as incompatible.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e28b30 and 1f475c5.

📒 Files selected for processing (2)
  • packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts
  • packages/ensnode-sdk/src/ensindexer/config/compatibility.ts

@tk-o tk-o merged commit 9bffd55 into main Feb 23, 2026
20 checks passed
@tk-o tk-o deleted the feat/ensdb-data-model branch February 23, 2026 14:03
@github-actions github-actions bot mentioned this pull request Feb 23, 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