Skip to content

Use static import for ENSIndexer Schema used with subgraphGraphQLMidlleware function#1851

Merged
tk-o merged 2 commits intov1.9-patchesfrom
hotfix/subgraph-api
Mar 31, 2026
Merged

Use static import for ENSIndexer Schema used with subgraphGraphQLMidlleware function#1851
tk-o merged 2 commits intov1.9-patchesfrom
hotfix/subgraph-api

Conversation

@tk-o
Copy link
Copy Markdown
Contributor

@tk-o tk-o commented Mar 31, 2026

Lite PR

Tip: Review docs on the ENSNode PR process

Summary

  • Updated ensIndexerSchema value that is passed into subgraphGraphQLMiddleware function.
    • Replaced the value wrapped in lazyProxy with the value read directly from ENSDb SDK.

Why

The lazy-proxy implemented for ensIndexerSchema export is not working with Drizzle ORM in ponder-subgraph package.

What does not work (the current v1.9.0):

export const ensIndexerSchema = lazyProxy<EnsDbReader["ensIndexerSchema"]>(
  () => ensDbClient.ensIndexerSchema,
);

What does work:

export const ensIndexerSchema = ensDbClient.ensIndexerSchema;

However, there would be a problem with generating the OpenAPI spec if we went ahead with just dropping the lazyProxy wrapper. We need something else for the hotfix.


Testing

  • I did test all commits locally between v1.8.1 and v1.9.0.
  • While testing, I was running local ENSApi and local ENSAdmin.
  • The local ENSApi instance was connected to the ENSDb in the Blue env, with the following config ENSINDEXER_SCHEMA_NAME=mainnetSchema1.9.0

Notes for Reviewer (Optional)

  • The branch for this PR created based on v1.9.0 commit.

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 tk-o requested a review from a team as a code owner March 31, 2026 16:05
Copilot AI review requested due to automatic review settings March 31, 2026 16:05
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 31, 2026

🦋 Changeset detected

Latest commit: 3d4a94b

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

This PR includes changesets to release 19 packages
Name Type
ensapi Patch
ensindexer Patch
ensadmin Patch
ensrainbow Patch
fallback-ensapi Patch
@ensnode/datasources Patch
@ensnode/ensrainbow-sdk Patch
@ensnode/ensdb-sdk Patch
@ensnode/ensnode-react Patch
@ensnode/ensnode-sdk Patch
@ensnode/ponder-sdk Patch
@ensnode/ponder-subgraph Patch
@ensnode/shared-configs Patch
@docs/ensnode Patch
@docs/ensrainbow Patch
@docs/mintlify Patch
@namehash/ens-referrals Patch
@namehash/namehash-ui Patch
@ensnode/integration-test-env 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 Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 97a06b51-268d-4d7e-b1b9-aeffea56d6d4

📥 Commits

Reviewing files that changed from the base of the PR and between ab1750c and 3d4a94b.

📒 Files selected for processing (2)
  • .changeset/thin-lemons-type.md
  • apps/ensapi/src/handlers/subgraph/subgraph-api.ts

📝 Walkthrough

Walkthrough

A changeset entry documents a patch-level release for the ensapi package, and the import source of ensIndexerSchema is refactored from a local singleton module to an external SDK package (@ensnode/ensdb-sdk/ensindexer-abstract), maintaining the same downstream schema filtering logic.

Changes

Cohort / File(s) Summary
Changeset Documentation
.changeset/thin-lemons-type.md
Added changeset entry marking ensapi for patch release and documenting the ensIndexerSchema update.
Import Refactoring
apps/ensapi/src/handlers/subgraph/subgraph-api.ts
Replaced local import of ensIndexerSchema from @/lib/ensdb/singleton with namespace import from @ensnode/ensdb-sdk/ensindexer-abstract; downstream schema filtering logic remains unchanged.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Poem

🐰 Schemas hop from home to harbor wide,
From local nests to SDK-provided tide,
One import swapped, the filtering flows on,
A cleaner path where shared sources are drawn! 📚✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly describes the main change: switching from a lazy-proxy import to a static import for the ENSIndexer Schema used in the subgraphGraphQLMiddleware function.
Description check ✅ Passed The PR description follows the required template with all key sections completed: Summary, Why, Testing, Notes for Reviewer, and Pre-Review Checklist all properly filled out with relevant details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/subgraph-api

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.

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 31, 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 31, 2026 4:07pm
ensnode.io Ready Ready Preview, Comment Mar 31, 2026 4:07pm
ensrainbow.io Ready Ready Preview, Comment Mar 31, 2026 4:07pm

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 31, 2026

Greptile Summary

This PR is a targeted hotfix replacing the lazyProxy-wrapped ensIndexerSchema import with a direct static import * as ensIndexerSchema from "@ensnode/ensdb-sdk/ensindexer-abstract" in subgraph-api.ts, resolving a Drizzle ORM incompatibility inside the ponder-subgraph package.

Root cause: ponder-subgraph's makeDrizzle internally calls setDatabaseSchema(schema, databaseSchema) from @ponder/client, which iterates over the schema object and mutates table definitions in-place. This mutation does not work correctly when schema is backed by a JavaScript Proxy (the lazyProxy wrapper), because Proxy-wrapped objects may not correctly forward the property enumeration and internal symbol checks (isTable, isPgEnum) that setDatabaseSchema relies on.

Why the fix works: By importing the abstract schema module directly (import * as ...), subgraphSchema (the filtered subset passed to subgraphGraphQLMiddleware) is a plain object containing real Drizzle table references. setDatabaseSchema can successfully iterate and mutate these in-place. Because filterSchemaByPrefix returns references to the same table objects, the mutation propagates through subgraphSchema correctly.

Correctness observations:

  • The module-level const subgraphSchema = filterSchemaByPrefix("subgraph_", ensIndexerSchema) is computed once, but since filterSchemaByPrefix returns object references, the lazy setDatabaseSchema mutation (triggered on first request via lazy()) is visible through subgraphSchema. ✓
  • buildConcreteEnsIndexerSchema in ensdb-sdk also mutates the same abstract schema objects (for other handlers using ensDbClient). Since both paths use the same ensIndexerSchemaName, this is idempotent and safe. ✓
  • The existing lazy() wrapper around getSubgraphMiddleware preserves the ability to import this module during OpenAPI generation without requiring env vars. ✓
  • The FIXME comment clearly documents the intent to restore the singleton import once lazyProxy is improved to support Drizzle ORM's schema mutation patterns.

Confidence Score: 5/5

This PR is safe to merge — it is a focused hotfix with no functional regressions, proper documentation of the temporary workaround, and preserves all existing lazy-initialization behavior.

The change is minimal, well-reasoned, and directly fixes a concrete runtime failure. No P0/P1 issues found. The mutation semantics of the abstract schema module work correctly with filterSchemaByPrefix's reference-based filtering and the lazy() guard remains intact for OpenAPI generation. The FIXME comment appropriately tracks the follow-up work.

No files require special attention. The only file modified meaningfully is apps/ensapi/src/handlers/subgraph/subgraph-api.ts, and the change is correct.

Important Files Changed

Filename Overview
apps/ensapi/src/handlers/subgraph/subgraph-api.ts Replaces the lazyProxy-wrapped ensIndexerSchema from singleton.ts with a direct static import of the abstract schema module; adds a FIXME comment documenting the intended future fix; maintains lazy() wrapper for OpenAPI generation compatibility.
.changeset/thin-lemons-type.md Adds a patch-level changeset entry for the ensapi package describing the fix to ensIndexerSchema passed into subgraphGraphQLMiddleware.

Sequence Diagram

sequenceDiagram
    participant Mod as subgraph-api.ts (module load)
    participant Abs as @ensnode/ensdb-sdk/ensindexer-abstract
    participant Filter as filterSchemaByPrefix
    participant Lazy as lazy()
    participant MW as subgraphGraphQLMiddleware
    participant Drizzle as makeDrizzle / setDatabaseSchema

    Mod->>Abs: import * as ensIndexerSchema
    Note over Abs: Real module namespace (no Proxy)
    Mod->>Filter: filterSchemaByPrefix("subgraph_", ensIndexerSchema)
    Filter-->>Mod: subgraphSchema (plain object with table refs)

    Note over Mod,Lazy: Module fully loaded — env vars NOT required yet

    rect rgb(200, 230, 200)
        Note over Lazy,Drizzle: First incoming HTTP request
        Lazy->>MW: subgraphGraphQLMiddleware({schema: subgraphSchema, databaseSchema, ...})
        MW->>Drizzle: makeDrizzle({schema: subgraphSchema, databaseSchema})
        Drizzle->>Drizzle: setDatabaseSchema(subgraphSchema, databaseSchema)
        Note over Drizzle: Mutates table objects in-place via Table.Symbol.Schema — works correctly, no Proxy in the way
        Drizzle-->>MW: drizzleClient
        MW-->>Lazy: Hono middleware
    end
Loading

Reviews (1): Last reviewed commit: "docs(changeset): Updated `ensIndexerSche..." | Re-trigger Greptile

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

This PR updates ENSApi’s subgraph handler to use a statically imported ENSIndexer schema (from @ensnode/ensdb-sdk) instead of the lazyProxy-wrapped ensIndexerSchema export, addressing a Drizzle ORM compatibility issue in ponder-subgraph while preserving the ability to import the module during OpenAPI generation without requiring env vars.

Changes:

  • Replaced ensIndexerSchema import from @/lib/ensdb/singleton with a static import from @ensnode/ensdb-sdk/ensindexer-abstract.
  • Kept subgraph schema derivation via filterSchemaByPrefix("subgraph_", ...) but with the new schema source.
  • Added a changeset to ship the fix as an ensapi patch.

Reviewed changes

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

File Description
apps/ensapi/src/handlers/subgraph/subgraph-api.ts Switches schema source to ensdb-sdk’s abstract schema to avoid lazyProxy/Drizzle incompatibility.
.changeset/thin-lemons-type.md Declares a patch release for ensapi describing the schema import adjustment.

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

// import { ensIndexerSchema } from "@/lib/ensdb/singleton";
// Once the lazy proxy implemented for `ensIndexerSchema` export is improved
// to support Drizzle ORM in `ponder-subgraph` package.
import * as ensIndexerSchema from "@ensnode/ensdb-sdk/ensindexer-abstract";
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The identifier ensIndexerSchema is now importing the abstract schema module (@ensnode/ensdb-sdk/ensindexer-abstract), not the concrete EnsDbReader.ensIndexerSchema. Renaming this import to something like abstractEnsIndexerSchema (and updating the filterSchemaByPrefix call) would avoid confusion and make it clear why setDatabaseSchema is needed downstream.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +8
// Once the lazy proxy implemented for `ensIndexerSchema` export is improved
// to support Drizzle ORM in `ponder-subgraph` package.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The FIXME comment is a bit ambiguous about what needs to be “improved”. Consider clarifying that the current lazyProxy implementation doesn’t support key enumeration (e.g. Object.entries/Object.keys/ownKeys), which is what Drizzle (via ponder-subgraph) relies on, so future readers know the precise blocker.

Suggested change
// Once the lazy proxy implemented for `ensIndexerSchema` export is improved
// to support Drizzle ORM in `ponder-subgraph` package.
// once the `lazyProxy` used for the `ensIndexerSchema` export supports key
// enumeration (e.g. Object.keys/Object.entries/Reflect.ownKeys), which Drizzle
// (used by the `@ensnode/ponder-subgraph` package) currently relies on.

Copilot uses AI. Check for mistakes.
@tk-o tk-o merged commit 05bbdb5 into v1.9-patches Mar 31, 2026
30 of 31 checks passed
@tk-o tk-o deleted the hotfix/subgraph-api branch March 31, 2026 17:25
@coderabbitai coderabbitai bot mentioned this pull request Mar 31, 2026
2 tasks
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