Skip to content

fix: derive indexedChainIds from static plugin metadata#1766

Open
shrugs wants to merge 15 commits intomainfrom
fix/indexed-chain-ids
Open

fix: derive indexedChainIds from static plugin metadata#1766
shrugs wants to merge 15 commits intomainfrom
fix/indexed-chain-ids

Conversation

@shrugs
Copy link
Collaborator

@shrugs shrugs commented Mar 13, 2026

Reviewer Focus

  • allDatasourceNames on the plugin interface and how derive_indexedChainIds uses it
  • reordered zod pipeline: .transform() now runs before .check() invariants
  • buildIndexedBlockranges (ensnode-sdk) now skips missing datasources instead of throwing

Problem

derive_indexedChainIds used required (not optional) datasources to determine indexed chains, leading to incorrect indexedChainIds in plugins like protocol-acceleration with optional datasources

What Changed

  1. added allDatasourceNames field to ENSIndexerPlugin — declares all datasources a plugin may index (required + optional)
  2. rewrote derive_indexedChainIds to resolve plugin.allDatasourceNames via maybeGetDatasource
  3. reordered zod pipeline: .transform(derive_indexedChainIds) runs first, then .check() invariants use indexedChainIds directly
  4. simplified invariant_rpcConfigsSpecifiedForIndexedChains and invariant_globalBlockrange to use config.indexedChainIds directly
  5. updated buildIndexedBlockranges + local-ponder-client.ts to use all datasource names (not just required)
  6. added allDatasourceNames to all 8 plugins
  7. removed duplicate test, added cross-namespace derivation test

Testing

  • additional config unit tests

Risk

  • requires plugins to correctly document their allDatasourceNames
  • CI integrity check validates the full startup flow; revert is safe
  • named owner: @shrugs

Checklist

  • reviewed every line of this diff end-to-end
  • changesets included (ensindexer minor, @ensnode/ensnode-sdk patch)

shrugs added 2 commits March 13, 2026 12:04
…exedChainIds` in plugins that conditionally index multiple chains (ex: 'protocol-acceleration').
@shrugs shrugs requested a review from a team as a code owner March 13, 2026 17:20
Copilot AI review requested due to automatic review settings March 13, 2026 17:20
@vercel
Copy link
Contributor

vercel bot commented Mar 13, 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 Mar 15, 2026 10:10am
ensnode.io Ready Ready Preview, Comment Mar 15, 2026 10:10am
ensrainbow.io Ready Ready Preview, Comment Mar 15, 2026 10:10am

@changeset-bot
Copy link

changeset-bot bot commented Mar 13, 2026

🦋 Changeset detected

Latest commit: 0ad286b

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

This PR includes changesets to release 19 packages
Name Type
ensindexer Major
@ensnode/ensnode-sdk Major
ensadmin Major
ensapi Major
ensrainbow Major
fallback-ensapi Major
@namehash/ens-referrals Major
@ensnode/ensnode-react Major
@ensnode/ensrainbow-sdk Major
@ensnode/integration-test-env Patch
@namehash/namehash-ui Major
@ensnode/datasources Major
@ensnode/ensnode-schema 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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Derives indexedChainIds by iterating each plugin's declared datasource names (using maybeGetDatasource) instead of namespace-only datasources; exposes allDatasourceNames on plugins, renames public type to EnsIndexerConfig in schema/validation, adds test helpers, and adds a changeset for a minor release.

Changes

Cohort / File(s) Summary
Changeset
/.changeset/tiny-friends-lie.md
Adds changelog entry for a minor release and documents fix to EnsIndexerConfig.indexedChainIds derivation.
Derivation & Config Schema
apps/ensindexer/src/config/derived-params.ts, apps/ensindexer/src/config/config.schema.ts, apps/ensindexer/src/config/validations.ts
Derivation of indexedChainIds now iterates plugin.allDatasourceNames and resolves via maybeGetDatasource; public type renamed to EnsIndexerConfig; invariant checks moved to post-transform and adjusted to use indexedChainIds.
Plugin Types & Helpers
apps/ensindexer/src/lib/plugin-helpers.ts
Adds ALL_DATASOURCE_NAMES generic and public allDatasourceNames to plugin types/BuildPluginOptions; adds getPluginsAllDatasourceNames; removes exported getRequiredDatasourceNames; updates createPlugin signatures.
Plugin Exports (expose allDatasourceNames)
apps/ensindexer/src/plugins/.../plugin.ts
apps/ensindexer/src/plugins/ensv2/plugin.ts, .../protocol-acceleration/plugin.ts, .../registrars/plugin.ts, .../subgraph/plugins/*/plugin.ts, .../tokenscope/plugin.ts
Expose allDatasourceNames (reusing existing ALL/REQUIRED_DATASOURCE_NAMES) on plugin exports.
Local Ponder Client
apps/ensindexer/src/lib/local-ponder-client.ts
Replaces usage of getPluginsRequiredDatasourceNames with getPluginsAllDatasourceNames; passes pluginsAllDatasourceNames to buildIndexedBlockranges; LocalPonderClient invoked with config.indexedChainIds and publicClients.
Indexed Blockranges (SDK)
packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts, packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts
Renames param to pluginsDatasourceNames; skips missing datasources instead of throwing; tests updated to expect empty Map when datasources absent.
Tests
apps/ensindexer/src/config/config.test.ts
Adds stubRpcUrlsForNamespace(namespace) helper to stub RPC_URL_ for all chains in a namespace; refactors tests to use helper and expands protocol-acceleration vs mainnet/sepolia cases.

Sequence Diagram(s)

sequenceDiagram
  participant ConfigBuilder as Config Builder
  participant PluginRegistry as Plugin Registry
  participant DatasourceResolver as maybeGetDatasource
  participant Datasource as Datasource (chain.id)

  ConfigBuilder->>PluginRegistry: for each configured plugin\nread plugin.allDatasourceNames
  loop per datasourceName
    PluginRegistry->>DatasourceResolver: maybeGetDatasource(namespace, datasourceName)
    DatasourceResolver-->>Datasource: resolve datasource or undefined
    alt datasource exists
      Datasource-->>ConfigBuilder: return chain.id
    else datasource missing
      DatasourceResolver-->>ConfigBuilder: return undefined (skip)
    end
  end
  Note right of ConfigBuilder: collect unique chain.ids\nset config.indexedChainIds
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Poem

🐰
I hop through plugins, sniff each name,
maybeGetDatasource helps me find chain.
Tests get a helper, schemas get precise,
a tiny changeset—configs slice by slice. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: derive indexedChainIds from static plugin metadata' directly describes the main fix—deriving indexedChainIds from plugin metadata instead of only required datasources—and aligns with the core changeset objective.
Description check ✅ Passed The PR description includes a structured summary of changes, explains the problem and solution, lists testing and risk considerations, and notes changesets included. All key sections from the template are addressed with substantive detail.
Docstring Coverage ✅ Passed Docstring coverage is 91.67% 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 fix/indexed-chain-ids
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

CodeRabbit can use OpenGrep to find security vulnerabilities and bugs across 17+ programming languages.

OpenGrep is compatible with Semgrep configurations. Add an opengrep.yml or semgrep.yml configuration file to your project to enable OpenGrep analysis.

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 fixes how EnsIndexerConfig.indexedChainIds is derived by switching from “required datasource names” to the plugin’s actual generated Ponder config, which better reflects chains indexed via optional/conditional datasources (notably protocol-acceleration).

Changes:

  • Update derive_indexedChainIds to call plugin.createPonderConfig(config) and extract chain IDs from ponderConfig.chains.
  • Update plugin helper typings around createPonderConfig and remove an unused helper.
  • Add/refactor config tests to stub RPC URLs per-namespace and add explicit .indexedChainIds coverage; add a changeset.

Reviewed changes

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

File Description
apps/ensindexer/src/lib/plugin-helpers.ts Adjusts plugin helper typing surface for createPonderConfig and removes old required-datasource helper.
apps/ensindexer/src/config/derived-params.ts Changes indexedChainIds derivation to use the plugin’s Ponder config chains as source of truth.
apps/ensindexer/src/config/config.test.ts Adds stubRpcUrlsForNamespace and new .indexedChainIds test coverage, plus RPC stub fixes.
.changeset/tiny-friends-lie.md Declares a minor release for the indexedChainIds derivation fix.

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

You can also share your feedback on Copilot code review. Take the survey.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 13, 2026

Greptile Summary

This PR fixes a correctness bug in derive_indexedChainIds: the previous implementation iterated only requiredDatasourceNames, which caused plugins with optional datasources (e.g. protocol-acceleration) to produce an incomplete indexedChainIds set — omitting chains like Base, Linea, and Optimism that the plugin actually indexes.

The fix introduces a new allDatasourceNames field on ENSIndexerPlugin (required + optional datasources), rewrites the derivation to use it via maybeGetDatasource, and reorders the Zod schema pipeline so that .transform(derive_indexedChainIds) executes before all .check() invariants — enabling those invariants to consume the fully-derived indexedChainIds directly rather than re-deriving it themselves. buildIndexedBlockranges is also updated to accept all datasource names and silently skip missing ones, mirroring the new derivation semantics.

Key changes:

  • allDatasourceNames field added to ENSIndexerPlugin and BuildPluginOptions interfaces, wired into all 8 plugins
  • New invariant_requiredDatasourcesSubsetOfAll runtime guard ensures plugin authors declare required datasources as a subset of all datasources
  • invariant_rpcConfigsSpecifiedForIndexedChains and invariant_globalBlockrange simplified to consume config.indexedChainIds directly — note: this is a breaking behavioral change for users of protocol-acceleration, who now need RPC configs for all optional chain IDs (Base, Linea, Optimism, Arbitrum, Scroll) that previously were not validated
  • Three existing test cases in indexed-blockranges.test.ts still use the stale local variable name pluginsRequiredDatasourceNames, which no longer accurately describes the parameter (all datasources, not just required ones)
  • ALL_DATASOURCE_NAMES in protocol-acceleration/plugin.ts contains a pre-existing redundancy: DATASOURCE_NAMES_WITH_ENSv2_CONTRACTS is spread once via DATASOURCE_NAMES_WITH_RESOLVERS and once directly — functionally harmless due to Set deduplication in derive_indexedChainIds, but worth cleaning up for clarity

Confidence Score: 4/5

  • Safe to merge; the architectural change is sound and well-tested, with only minor naming and pre-existing redundancy issues.
  • The core logic change (using allDatasourceNames via maybeGetDatasource) is correct and directly addresses the bug. The Zod pipeline reordering is clean and all invariants that previously re-derived chain IDs now consume the pre-derived value. Test coverage was meaningfully improved with dynamic expected-set computation. The only issues are: stale pluginsRequiredDatasourceNames variable names in three test cases that weren't touched by the diff, and a pre-existing DATASOURCE_NAMES_WITH_ENSv2_CONTRACTS duplication in protocol-acceleration's ALL_DATASOURCE_NAMES. Neither is a runtime bug. The RPC config validation tightening is intentional and documented under Risk.
  • apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts (pre-existing ALL_DATASOURCE_NAMES duplication now surfaced) and packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts (stale local variable names in three test cases).

Important Files Changed

Filename Overview
apps/ensindexer/src/config/derived-params.ts Core fix: rewrites derive_indexedChainIds to iterate plugin.allDatasourceNames via maybeGetDatasource instead of requiredDatasourceNames + getENSNamespace; correctly handles optional datasources.
apps/ensindexer/src/config/config.schema.ts Pipeline reordered: .transform(derive_indexedChainIds) now runs before all .check() invariants, enabling invariants to consume indexedChainIds directly. Adds invariant_requiredDatasourcesSubsetOfAll and removes the now-redundant old check ordering.
apps/ensindexer/src/config/validations.ts New invariant_requiredDatasourcesSubsetOfAll added; invariant_rpcConfigsSpecifiedForIndexedChains and invariant_globalBlockrange simplified to consume pre-derived indexedChainIds, eliminating duplicated resolution logic.
apps/ensindexer/src/lib/plugin-helpers.ts Adds allDatasourceNames generic type parameter and field to ENSIndexerPlugin and BuildPluginOptions; replaces getPluginsRequiredDatasourceNames with getPluginsAllDatasourceNames; removes now-unused getRequiredDatasourceNames helper and uniq import.
apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts Wires in pre-existing ALL_DATASOURCE_NAMES constant as allDatasourceNames; note that ALL_DATASOURCE_NAMES spreads DATASOURCE_NAMES_WITH_ENSv2_CONTRACTS twice (once via DATASOURCE_NAMES_WITH_RESOLVERS, once directly) — a pre-existing redundancy that is functionally harmless but worth cleaning up.
packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts Changes from throwing on missing datasources to silently skipping them, mirroring derive_indexedChainIds semantics; parameter renamed from pluginsRequiredDatasourceNames to pluginsDatasourceNames; plugin name loop variable correctly unused ([, datasourceNames]).
packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts Test for missing datasource correctly updated from "throws" to "skips"; three existing test cases still use the stale local variable name pluginsRequiredDatasourceNames which no longer accurately describes the parameter semantics.
apps/ensindexer/src/config/config.test.ts New stubRpcUrlsForNamespace helper makes RPC-stubbing self-maintaining; new .indexedChainIds suite tests chain-ID derivation for subgraph, basenames, and protocol-acceleration with a dynamic expected-set computed from plugin metadata; subset-relationship test guards plugin author correctness.
apps/ensindexer/src/lib/local-ponder-client.ts Switches from getPluginsRequiredDatasourceNames to getPluginsAllDatasourceNames so that buildIndexedBlockranges receives all datasource names, consistent with the rest of the fix.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ENSIndexerConfigSchema.parse] --> B[.transform: derive_indexedChainIds]
    B --> C{For each active plugin}
    C --> D[plugin.allDatasourceNames\nrequired + optional]
    D --> E{maybeGetDatasource\nnamespace, name}
    E -->|exists| F[indexedChainIds.add\ndatasource.chain.id]
    E -->|undefined| G[skip — optional\ndatasource missing]
    F --> H[return config + indexedChainIds]
    G --> H
    H --> I[.check: invariant_requiredDatasourcesSubsetOfAll\nrequiredDatasourceNames ⊆ allDatasourceNames]
    I --> J[.check: invariant_requiredDatasources\nrequired DSs present in namespace]
    J --> K[.check: invariant_rpcConfigsSpecifiedForRootChain]
    K --> L[.check: invariant_validContractConfigs]
    L --> M[.check: invariant_isSubgraphCompatibleRequirements]
    M --> N[.check: invariant_rpcConfigsSpecifiedForIndexedChains\nfor each id in indexedChainIds]
    N --> O[.check: invariant_globalBlockrange\nindexedChainIds.size ≤ 1 if blockrange set]
    O --> P[EnsIndexerConfig ✓]
Loading

Comments Outside Diff (1)

  1. apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts, line 50-54 (link)

    DATASOURCE_NAMES_WITH_ENSv2_CONTRACTS duplicated in ALL_DATASOURCE_NAMES

    DATASOURCE_NAMES_WITH_RESOLVERS already spreads DATASOURCE_NAMES_WITH_ENSv2_CONTRACTS at the end of its own array (see datasources-with-resolvers.ts line 23). Spreading DATASOURCE_NAMES_WITH_ENSv2_CONTRACTS again directly in ALL_DATASOURCE_NAMES means every ENSv2 datasource name appears twice.

    There is no runtime bug — indexedChainIds is a Set (deduplication), and buildIndexedBlockranges merges duplicate blockranges into themselves — but the array now silently contains redundant entries. This is a pre-existing issue that this PR first surfaces by using ALL_DATASOURCE_NAMES for derivation purposes.

    If the intent is to track every unique datasource, consider deduplicating the array at definition time:

    const ALL_DATASOURCE_NAMES = [
      ...DATASOURCE_NAMES_WITH_RESOLVERS,  // already includes DATASOURCE_NAMES_WITH_ENSv2_CONTRACTS
      ...DATASOURCE_NAMES_WITH_REVERSE_RESOLVERS,
      // DATASOURCE_NAMES_WITH_ENSv2_CONTRACTS is already included via DATASOURCE_NAMES_WITH_RESOLVERS
    ];

Last reviewed commit: 0ad286b

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: 1

🤖 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/ensindexer/src/lib/plugin-helpers.ts`:
- Around line 70-74: The createPonderConfig parameter types are inconsistent:
ENSIndexerPlugin.createPonderConfig currently takes Omit<EnsIndexerConfig,
"indexedChainIds"> while BuildPluginOptions.createPonderConfig takes the full
EnsIndexerConfig, causing a mismatch when createPlugin returns the options as an
ENSIndexerPlugin. Make both signatures use the same type (pick either
EnsIndexerConfig or Omit<EnsIndexerConfig, "indexedChainIds">) and update the
declaration in ENSIndexerPlugin.createPonderConfig or
BuildPluginOptions.createPonderConfig accordingly so createPonderConfig has the
identical parameter type in both places (references: createPonderConfig,
ENSIndexerPlugin, BuildPluginOptions, createPlugin).
🪄 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: 22a24cfe-1406-42b8-8dff-be5777b673da

📥 Commits

Reviewing files that changed from the base of the PR and between 337ef4b and 63ae91d.

📒 Files selected for processing (4)
  • .changeset/tiny-friends-lie.md
  • apps/ensindexer/src/config/config.test.ts
  • apps/ensindexer/src/config/derived-params.ts
  • apps/ensindexer/src/lib/plugin-helpers.ts

@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io March 13, 2026 18:07 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 13, 2026 18:07 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 13, 2026 18:07 Inactive
Copilot AI review requested due to automatic review settings March 13, 2026 19:01
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 13, 2026 19:01 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 13, 2026 19:01 Inactive
@shrugs
Copy link
Collaborator Author

shrugs commented Mar 13, 2026

@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

Fixes EnsIndexerConfig.indexedChainIds derivation so it accounts for chains indexed via optional datasources (not just “required” ones), and updates related helpers/tests to reflect the broader datasource set.

Changes:

  • Introduces allDatasourceNames on plugins and derives indexedChainIds by resolving those datasources against the active namespace.
  • Updates indexed blockrange derivation to accept (required + optional) datasource names and skip datasources not present in the namespace.
  • Expands config tests with .indexedChainIds coverage and adds a namespace-based RPC_URL stubbing helper.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts Accepts broader datasource sets and skips namespace-missing datasources when deriving per-chain blockranges.
packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts Updates expectations to match “skip missing datasource” behavior.
apps/ensindexer/src/plugins/tokenscope/plugin.ts Adds allDatasourceNames metadata for chain derivation.
apps/ensindexer/src/plugins/subgraph/plugins/threedns/plugin.ts Adds allDatasourceNames metadata for chain derivation.
apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts Adds allDatasourceNames metadata for chain derivation.
apps/ensindexer/src/plugins/subgraph/plugins/lineanames/plugin.ts Adds allDatasourceNames metadata for chain derivation.
apps/ensindexer/src/plugins/subgraph/plugins/basenames/plugin.ts Adds allDatasourceNames metadata for chain derivation.
apps/ensindexer/src/plugins/registrars/plugin.ts Adds allDatasourceNames metadata for chain derivation.
apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts Sets allDatasourceNames to include optional multi-chain datasources (bug driver).
apps/ensindexer/src/plugins/ensv2/plugin.ts Adds allDatasourceNames metadata for chain derivation.
apps/ensindexer/src/lib/plugin-helpers.ts Extends plugin typing/factory to require allDatasourceNames; adds getPluginsAllDatasourceNames.
apps/ensindexer/src/lib/local-ponder-client.ts Uses all datasource names when building indexed blockranges.
apps/ensindexer/src/config/validations.ts Validates RPC configs using derived indexedChainIds; updates global blockrange invariant to use the set.
apps/ensindexer/src/config/derived-params.ts Derives indexedChainIds via allDatasourceNames + namespace datasource resolution.
apps/ensindexer/src/config/config.test.ts Adds .indexedChainIds tests and stubRpcUrlsForNamespace() helper.
apps/ensindexer/src/config/config.schema.ts Moves derived-param transform earlier so later invariants can depend on indexedChainIds.
.changeset/tiny-friends-lie.md Adds a changeset entry describing the indexedChainIds fix.

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

You can also share your feedback on Copilot code review. Take the survey.

- use Omit<EnsIndexerConfig, "indexedChainIds"> for createPonderConfig param
- update config.schema.ts inline docs to reflect new pipeline order
- rephrase RPC validation error message
- add @ensnode/ensnode-sdk patch to changeset

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io March 13, 2026 21:12 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 13, 2026 21:12 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 13, 2026 21:12 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

This PR fixes incorrect derivation of EnsIndexerConfig.indexedChainIds by switching from “required datasources only” to “all datasources a plugin may index (required + optional)” via new static plugin metadata, and updates downstream logic to align with that derivation across namespaces.

Changes:

  • Add allDatasourceNames to the plugin interface and update plugins to declare it.
  • Update derive_indexedChainIds to resolve allDatasourceNames via maybeGetDatasource, and reorder the Zod pipeline so derivation happens before invariant checks.
  • Update buildIndexedBlockranges / local-ponder-client to use all datasource names and skip namespace-missing datasources; adjust unit tests accordingly.

Reviewed changes

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

Show a summary per file
File Description
packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts Accepts “all datasource names” and skips datasources missing from a namespace instead of throwing.
packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts Updates expectations to validate “skip missing datasource” behavior.
apps/ensindexer/src/lib/plugin-helpers.ts Extends plugin interface/options with allDatasourceNames and renames helper to return all datasource names.
apps/ensindexer/src/lib/local-ponder-client.ts Uses getPluginsAllDatasourceNames() when building indexed blockranges.
apps/ensindexer/src/config/derived-params.ts Re-derives indexedChainIds using plugin.allDatasourceNames + maybeGetDatasource.
apps/ensindexer/src/config/validations.ts Simplifies invariants to operate directly on config.indexedChainIds.
apps/ensindexer/src/config/config.schema.ts Reorders Zod pipeline: .transform(derive_indexedChainIds) before .check() invariants.
apps/ensindexer/src/config/config.test.ts Adds/updates tests for cross-namespace indexedChainIds derivation and stubs RPC URLs by namespace.
apps/ensindexer/src/plugins/**/plugin.ts Adds allDatasourceNames declarations to plugins (required-only for most; full set for multi/optional plugins).
.changeset/tiny-friends-lie.md Publishes changes (ensindexer minor, ensnode-sdk patch).

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

You can also share your feedback on Copilot code review. Take the survey.

…asourceNames

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io March 13, 2026 21:15 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 13, 2026 21:15 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 13, 2026 21:15 Inactive
@shrugs
Copy link
Collaborator Author

shrugs commented Mar 13, 2026

@greptile review

…nvariant test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 13, 2026 21:50
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 13, 2026 21:50 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 13, 2026 21:50 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io March 13, 2026 21:50 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

Updates ENSIndexer config derivation to compute indexedChainIds from static plugin metadata (allDatasourceNames, including optional datasources), enabling correct multi-namespace + optional-datasource behavior (notably for protocol-acceleration) without needing to execute createPonderConfig.

Changes:

  • Add allDatasourceNames to the plugin interface and populate it across all plugins.
  • Rework derive_indexedChainIds to resolve chains via maybeGetDatasource(plugin.allDatasourceNames) and reorder the Zod pipeline so derived values exist before invariants.
  • Adjust indexed blockrange calculation to skip missing datasources (matching derivation semantics) and update tests accordingly.

Reviewed changes

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

Show a summary per file
File Description
packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts Skip missing datasources when aggregating blockranges.
packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts Update test expectations to match “skip missing datasource” behavior.
apps/ensindexer/src/lib/plugin-helpers.ts Extend plugin type to require allDatasourceNames; expose helper to map plugins → all datasource names.
apps/ensindexer/src/lib/local-ponder-client.ts Use all datasource names when building indexed blockranges.
apps/ensindexer/src/config/derived-params.ts Derive indexedChainIds from allDatasourceNames via maybeGetDatasource.
apps/ensindexer/src/config/validations.ts Simplify invariants to depend on config.indexedChainIds; add subset invariant for required vs all datasource names.
apps/ensindexer/src/config/config.schema.ts Reorder Zod pipeline: .transform(derive_indexedChainIds) before .check(...) invariants.
apps/ensindexer/src/config/config.test.ts Add/adjust tests for cross-namespace chain derivation + subset invariant; add RPC-url stubbing helper.
apps/ensindexer/src/plugins/**/plugin.ts Populate allDatasourceNames across plugins (required-only for most; expanded for multi-datasource plugins).
.changeset/tiny-friends-lie.md Release notes for ensindexer + ensnode-sdk versions.

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

You can also share your feedback on Copilot code review. Take the survey.

…ecification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 13, 2026 22:05 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 13, 2026 22:05 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io March 13, 2026 22:05 Inactive
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.

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

This PR fixes incorrect indexedChainIds derivation for plugins that optionally index additional datasources/chains by introducing static plugin metadata (allDatasourceNames) and using it to derive indexed chains without executing plugin createPonderConfig.

Changes:

  • Add allDatasourceNames (required + optional datasources) to the ENSIndexerPlugin interface and populate it across all plugins.
  • Rework derive_indexedChainIds to resolve allDatasourceNames via maybeGetDatasource, and reorder the config zod pipeline to derive before invariant checks.
  • Update indexed blockrange calculation and config tests to align with the new “skip missing datasource in namespace” behavior.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/ensnode-sdk/src/shared/config/indexed-blockranges.ts Skip missing datasources (namespace-dependent) when building indexed blockranges.
packages/ensnode-sdk/src/shared/config/indexed-blockranges.test.ts Update expectations to match “skip missing datasource” behavior.
apps/ensindexer/src/plugins/tokenscope/plugin.ts Populate allDatasourceNames for TokenScope plugin.
apps/ensindexer/src/plugins/subgraph/plugins/threedns/plugin.ts Populate allDatasourceNames for ThreeDNS plugin.
apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts Populate allDatasourceNames for Subgraph plugin.
apps/ensindexer/src/plugins/subgraph/plugins/lineanames/plugin.ts Populate allDatasourceNames for Lineanames plugin.
apps/ensindexer/src/plugins/subgraph/plugins/basenames/plugin.ts Populate allDatasourceNames for Basenames plugin.
apps/ensindexer/src/plugins/registrars/plugin.ts Populate allDatasourceNames for Registrars plugin.
apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts Populate allDatasourceNames (required + optional) for Protocol Acceleration plugin.
apps/ensindexer/src/plugins/ensv2/plugin.ts Populate allDatasourceNames (required + optional) for ENSv2 plugin.
apps/ensindexer/src/lib/plugin-helpers.ts Extend plugin types/factory to require allDatasourceNames; add helper to fetch all datasource names per plugin.
apps/ensindexer/src/lib/local-ponder-client.ts Use all datasource names when building indexed blockranges.
apps/ensindexer/src/config/validations.ts Add subset invariant and simplify invariants to use config.indexedChainIds directly.
apps/ensindexer/src/config/derived-params.ts Derive indexedChainIds from plugin.allDatasourceNames resolved via maybeGetDatasource.
apps/ensindexer/src/config/config.test.ts Add/adjust tests for indexedChainIds derivation and helper for stubbing RPC env vars by namespace.
apps/ensindexer/src/config/config.schema.ts Run .transform(derive_indexedChainIds) before .check() invariants so checks can use derived values.
.changeset/tiny-friends-lie.md Version bumps and release note for indexedChainIds derivation fix.
Comments suppressed due to low confidence (1)

apps/ensindexer/src/config/validations.ts:96

  • Typo in the global blockrange invariant message: "unintentially" should be "unintentionally". Since this string is surfaced to users during validation failures, fixing the spelling will make the guidance clearer.
        input: config,
        message: `ENSIndexer's behavior when indexing _multiple chains_ with a _specific blockrange_ is considered undefined (for now). If you're using this feature, you're likely interested in snapshotting at a specific END_BLOCK, and may have unintentially activated plugins that source events from multiple chains. The config currently is:


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

@lightwalker-eth
Copy link
Member

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

3 participants