Skip to content

Comments

ENSDb data model#1660

Open
tk-o wants to merge 10 commits intomainfrom
feat/ensdb-data-model
Open

ENSDb data model#1660
tk-o wants to merge 10 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: 07033c5

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 21, 2026 4:59pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
ensnode.io Skipped Skipped Feb 21, 2026 4:59pm
ensrainbow.io Skipped Skipped Feb 21, 2026 4:59pm

@coderabbitai
Copy link

coderabbitai bot commented Feb 21, 2026

Warning

Rate limit exceeded

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

⌛ 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.

📝 Walkthrough

Walkthrough

This PR introduces the ENSDb module with metadata storage schema, client interfaces for querying and mutating ENSNode metadata, and compatibility validation for ENSIndexer public configurations. It defines strongly-typed representations for metadata records and exposes these through new barrel exports across multiple packages.

Changes

Cohort / File(s) Summary
Changeset Declarations
.changeset/fresh-adults-decide.md, .changeset/itchy-clubs-repeat.md, .changeset/short-buttons-burn.md
Three changeset files declaring minor version bumps for @ensnode/ensnode-sdk and @ensnode/ensnode-schema packages with descriptions of new ENSDb module, ENSIndexer compatibility check, and ENSNodeMetadata schema additions.
ENSNode Metadata Schema
packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts, packages/ensnode-schema/src/ponder.schema.ts
Introduces onchain metadata table with text key and JSONB value fields; adds re-export to expose schema in public API.
ENSDb Client Interfaces
packages/ensnode-sdk/src/ensdb/client.ts
Defines EnsDbClientQuery and EnsDbClientMutation interfaces with read/write operations for ENSDb version, indexer public config, and indexing status snapshot.
ENSDb Data Models & Serialization
packages/ensnode-sdk/src/ensdb/ensnode-metadata.ts, packages/ensnode-sdk/src/ensdb/serialize/ensnode-metadata.ts
Defines metadata key constants, typed interfaces for three metadata record variants, and corresponding serialized representations using external type dependencies.
ENSIndexer Config Compatibility
packages/ensnode-sdk/src/ensindexer/config/compatibility.ts, packages/ensnode-sdk/src/ensindexer/config/compatibility.test.ts
Introduces validateEnsIndexerPublicConfigCompatibility function enforcing that one config is a subset of another across chain IDs, namespace, compatibility flag, and plugins; includes comprehensive validation tests.
Module Exports
packages/ensnode-sdk/src/ensdb/index.ts, packages/ensnode-sdk/src/ensindexer/config/index.ts, packages/ensnode-sdk/src/indexing-status/index.ts, packages/ensnode-sdk/src/index.ts
Adds barrel export statements to expose ensdb client/metadata/serialization, ensindexer config compatibility, and cross-chain indexing status serializer modules in public API surface.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 ✨ A metadata home takes shape, stored neat,
Keys and values in JSONB's beat,
Compatibility checks ensure all align,
As ENSDb's foundations intertwine!
New exports bloom from barrel files bright,
Our database structure now feels just right! 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'ENSDb data model' clearly and concisely summarizes the main change: introduction of the ENSDb data model, which is the primary objective of this PR.
Description check ✅ Passed The PR description follows the template structure, includes all required sections with substantive content: Summary (3 bullets covering main changes), Why (linked to issue #1252), Testing (describes test types performed), Notes for Reviewer, and completed Pre-Review Checklist.
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 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

@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
@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, 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

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


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

@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

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.

1 participant