From e158f8b2506d53cb151e274bc4a7dfc0d8440792 Mon Sep 17 00:00:00 2001
From: shrugs
Date: Mon, 18 May 2026 15:16:47 -0500
Subject: [PATCH 1/9] docs: prune stale reference pages, trim README, link
follow-ups
Per priority docs pass:
- delete reference/{roadmap,what-is-ensnode,ensnode-v2-notes,mainnet-registered-subnames-of-subregistries} and integrate/migrate-from-subgraph (boss called these stale, lower-value, or "less is more")
- remove their sidebar entries + the stale /ensnode/concepts/what-is-ensnode redirect
- drop the now-dangling 'Skip to What is ENSNode?' LinkCard on reference/subgraph-legacy/what-is-the-ens-subgraph
- drop the 'Coming Soon' panel from integrate/ai-llm (existing content is fine)
- rewrite README around docs/quickstart links + an Omnigraph GraphQL example (inlined eth) sourced from examples/omnigraph-graphql-example
- drop the stale 'docs/ensnode/src/content/docs/reference/mainnet-registered-subnames-of-subregistries.mdx' pointers in datasources comments (mainnet.ts, sepolia.ts)
Follow-ups filed as sub-issues of #1360:
- #2138 docs: write Migrate from ENS Subgraph guide
- #2139 docs: capture mainnet-registered subnames of subregistries
Co-Authored-By: Claude Opus 4.7 (1M context)
---
README.md | 169 ++----------------
docs/ensnode.io/astro.config.mjs | 1 -
.../starlight/sidebar-topics/integrate.ts | 4 -
.../starlight/sidebar-topics/reference.ts | 16 --
.../content/docs/docs/integrate/ai-llm.mdx | 4 -
.../docs/integrate/migrate-from-subgraph.mdx | 10 --
.../docs/docs/reference/ensnode-v2-notes.mdx | 105 -----------
...t-registered-subnames-of-subregistries.mdx | 56 ------
.../content/docs/docs/reference/roadmap.mdx | 82 ---------
.../what-is-the-ens-subgraph.mdx | 8 -
.../docs/docs/reference/what-is-ensnode.mdx | 114 ------------
packages/datasources/src/mainnet.ts | 6 -
packages/datasources/src/sepolia.ts | 6 -
13 files changed, 19 insertions(+), 562 deletions(-)
delete mode 100644 docs/ensnode.io/src/content/docs/docs/integrate/migrate-from-subgraph.mdx
delete mode 100644 docs/ensnode.io/src/content/docs/docs/reference/ensnode-v2-notes.mdx
delete mode 100644 docs/ensnode.io/src/content/docs/docs/reference/mainnet-registered-subnames-of-subregistries.mdx
delete mode 100644 docs/ensnode.io/src/content/docs/docs/reference/roadmap.mdx
delete mode 100644 docs/ensnode.io/src/content/docs/docs/reference/what-is-ensnode.mdx
diff --git a/README.md b/README.md
index 721eb1bf79..c5030dce7b 100644
--- a/README.md
+++ b/README.md
@@ -19,75 +19,29 @@
# ENSNode
-ENSNode is the new multichain indexer for ENS, including [ENSv2](https://roadmap.ens.domains/roadmap/).
-
-Full Documentation ➡︎ ensnode.io
-
-[Join us on Telegram](https://t.me/ensnode) to get support, share ideas, and discuss the future of ENSNode.
-
-## The future of ENS indexing
-
-ENSNode provides enhanced ENS indexing capabilities beyond the ENS Subgraph, including faster indexing and simpler self-hosted deployments. Initial multichain capabilities include indexing mainnet, Basenames, Lineanames, 3DNS, and more, providing a unified multichain namespace via a subgraph-compatible GraphQL API. When exclusively activating our subgraph plugin, ENSNode has full data equivalency with the ENS Subgraph.
-
-- Multichain ENS Namespace
- - flattened, unified, multichain and multiregistrar namespace via optional plugins
- - ✅ All names added to the ENS Registry and the ENS NameWrapper
- - ✅ All direct subnames of .eth
- - ✅ [Basenames](https://www.base.org/names) (`.base.eth`)
- - ✅ [Lineanames](https://names.linea.build/) (`.linea.eth`)
- - ✅ [3DNS](https://3dns.box) Support (`.box`, `.xyz`, +more)
- - 🚧 Offchain Names
- - `.cb.id`, `.uni.id`, + more
- - [NameStone](https://namestone.com/) Names
- - [NameSpace](https://namespace.ninja/) Names
- - [Justaname](https://www.justaname.id/) Names
- - 🚧 + more
-- Built on [Ponder](https://ponder.sh)
- - ✅ Rapid Indexing & Backfill
- - 10x faster than ENS Subgraph
- - Mainnet Cached Backfill: **4.5 hours** on M1 Macbook Pro
- - ✅ More efficient than ENS Subgraph
- - 35x less disk space and 35% fewer RPC credits [[source]](https://ponder.sh/docs/why-ponder)
- - ✅ End-to-end type safety
- - ✅ Automatically reconciles chain reorganizations
- - ✅ Deploy anywhere with Node.js & Docker
-- Designed for web developers
- - ✅ [use ENSNode with ENSjs](https://ensnode.io/docs/usage/with-ensjs)
- - ✅ [GraphQL APIs](https://ensnode.io/docs/usage/api)
- - ✅ Custom APIs for your app
-- [1:1 Subgraph Compatibility](https://ensnode.io/docs/concepts/what-is-the-ens-subgraph)
- - ✅ [100% data equivalency](https://github.com/namehash/ens-subgraph-transition-tools) as compared to Subgraph
- - ✅ 100% ensjs test suites passing via [ens-test-env](https://github.com/namehash/ens-test-env)
- - ✅ 100% ens-app-v3 test suites passing via [ens-test-env](https://github.com/namehash/ens-test-env)
-- Own your ENSNode index
- - ✅ [Deploy ENSNode to your own cloud](https://ensnode.io/docs/deploying) for controlling your own uptime guarantees and private queries
-
-## Why Index ENS? Why ENSNode?
-
-The ENS protocol enables resolution of names across multiple chains and, increasingly, offchain data sources. ENS smart contracts optimize for some operations, but not others: for example, if you wanted to list all of a user's owned names, there's no practical way to do this through ENS contracts, and an indexer like ENSNode _must_ be used.
-
-An indexer aggregates and reorganizes the representation of ENS's state to make important queries like that possible, efficient, and convenient:
+[ENSNode](https://ensnode.io) is the multichain indexer for ENS, with first-class support for [ENSv2](https://roadmap.ens.domains/roadmap/). It exposes a unified GraphQL API — the **ENS Omnigraph** — over both ENSv1 and ENSv2.
+
+- 📚 **Docs:** [ensnode.io](https://ensnode.io)
+- 🚀 **Quickstart:** [ensnode.io/docs/integrate](https://ensnode.io/docs/integrate)
+- 💬 **Telegram:** [t.me/ensnode](https://t.me/ensnode)
+
+## Example: query a name via the Omnigraph
```graphql
-# get all of a user's domains by address — not possible on-chain!
-query Domains($adress: String!) {
- domains(where: { owner: $address }) {
- id
- name
- ...
+query HelloWorld {
+ domain(by: { name: "eth" }) {
+ __typename
+ canonical { name { interpreted } }
+ owner { address }
+ subdomains(first: 20) {
+ totalCount
+ edges { node { __typename canonical { name { interpreted } } owner { address } } }
+ }
}
}
```
-Historically the ENS Subgraph has served this purpose, but the Subgraph's limitations are increasingly severe as the ENS protocol grows: the ENS Subgraph can only index a single chain at a time (ex: mainnet) and can't integrate with names or that require [CCIP-Read](https://docs.ens.domains/resolvers/ccip-read), which includes all names stored on L2 chains or offchain.
-
-Given how the majority of ENS names are now issued off of mainnet, only a small percentage of ENS names can be indexed by the ENS Subgraph. This issue will only grow more severe with the launch of [ENSv2](https://roadmap.ens.domains/roadmap/) and [Namechain](https://app.ens.domains/ens-v2).
-
-ENSNode is a modern, multichain indexer for ENS. It supports backwards-compatible Subgraph queries and sets the stage for supporting [ENSv2](https://roadmap.ens.domains/roadmap/), in particular [Namechain](https://app.ens.domains/ens-v2) and the growing set of off-chain ENS names (like `.uni.eth` and `.cb.id`).
-
-## Documentation
-
-Documentation for the ENSNode suite of apps is available at [ensnode.io](https://ensnode.io).
+See [`examples/omnigraph-graphql-example`](examples/omnigraph-graphql-example) for the full runnable script, and the [Quickstart](https://ensnode.io/docs/integrate) for `enskit` (React), `enssdk` (TypeScript), and direct GraphQL integrations.
## Running with Docker
@@ -97,9 +51,9 @@ docker compose -f docker/docker-compose.yml up -d
See [`docker/README.md`](docker/README.md) for all use cases and commands.
-## Contributions
+## Contributing
-We welcome community contributions and feedback—please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
+See [CONTRIBUTING.md](CONTRIBUTING.md).
## Sponsors
@@ -110,93 +64,8 @@ NameHash has received generous support from the [ENS DAO](https://ensdao.org/) a
-
-ENSAdmin is a dashboard for ENSNode and the ENS protocol. See the [ENSAdmin documentation](https://ensnode.io/ensadmin) for more details.
-
-### [`apps/ensindexer`](apps/ensindexer)
-
-
-
-ENSIndexer is a Ponder-powered indexer for ENS across multiple chains. See the [ENSIndexer documentation](https://ensnode.io/ensindexer) for more details.
-
-### [`apps/ensrainbow`](apps/ensrainbow)
-
-
-
-ENSRainbow heals unknown ENS names: it provides a simple API to recover labels from their labelHashes. See the [ENSRainbow documentation](https://ensnode.io/ensrainbow) for more details.
-
-## Packages
-
-### [`packages/ensdb-sdk`](packages/ensdb-sdk)
-
-Software Development Kit for interacting with data in ENSDb.
-
-### [`packages/ensnode-sdk`](packages/ensnode-sdk)
-
-Software Development Kit for interacting with ENSNode services and data. Includes common utilities used across ENSNode applications.
-
-### [`packages/datasources`](packages/datasources)
-
-Convenient catalog of ENSNode-related datasources including chain, contract addresses, start blocks, and event filters.
-
-### [`packages/ensrainbow-sdk`](packages/ensrainbow-sdk)
-
-TypeScript library for interacting with the [ENSRainbow API](apps/ensrainbow).
-
-### [`packages/ponder-sdk`](packages/ponder-sdk)
-
-A utility library for interacting with Ponder apps and data.
-
-### [`packages/ponder-subgraph`](packages/ponder-subgraph)
-
-Subgraph-compatible GraphQL API.
-
-### [`packages/shared-configs`](packages/shared-configs)
-
-Shared internal configuration files.
-
-## Docs
-
-### [`docs/ensnode.io`](docs/ensnode.io/)
-
-Astro/Starlight documentation app for ENSNode, ENSIndexer, ENSAdmin, and ENSRainbow.
-
-### [`docs/ensrainbow.io`](docs/ensrainbow.io/)
-
-Landing page for ENSRainbow.
diff --git a/docs/ensnode.io/astro.config.mjs b/docs/ensnode.io/astro.config.mjs
index 1b04ccc5d2..9a13484154 100644
--- a/docs/ensnode.io/astro.config.mjs
+++ b/docs/ensnode.io/astro.config.mjs
@@ -36,7 +36,6 @@ export default defineConfig({
"/docs": "/docs/integrate",
"/ensnode": "/docs/integrate",
"/ensnode/deploying/railway": "/docs/services/ensrainbow/deploying/railway",
- "/ensnode/concepts/what-is-ensnode": "/docs/reference/what-is-ensnode",
"/ensnode/concepts/what-is-the-ens-subgraph":
"/docs/reference/subgraph-legacy/what-is-the-ens-subgraph",
"/docs/reference/what-is-the-ens-subgraph":
diff --git a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts
index 01b66e1bd2..eb4e37b5c7 100644
--- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts
+++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts
@@ -153,10 +153,6 @@ export const integrateSidebarTopic = {
},
],
},
- {
- label: "Migrate from ENS Subgraph",
- link: "/docs/integrate/migrate-from-subgraph",
- },
{
label: "Hosted Instances",
link: "/docs/integrate/hosted-instances",
diff --git a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/reference.ts b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/reference.ts
index 93f5a4c5fd..36919b1da7 100644
--- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/reference.ts
+++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/reference.ts
@@ -11,22 +11,6 @@ export const referenceSidebarTopic = {
label: "Terminology",
link: "/docs/reference/terminology",
},
- {
- label: "Roadmap",
- link: "/docs/reference/roadmap",
- },
- {
- label: "What is ENSNode?",
- link: "/docs/reference/what-is-ensnode",
- },
- {
- label: "ENSNode V2 Notes",
- link: "/docs/reference/ensnode-v2-notes",
- },
- {
- label: "Mainnet Subnames of Subregistries",
- link: "/docs/reference/mainnet-registered-subnames-of-subregistries",
- },
{
label: "Subgraph API (Legacy)",
collapsed: true,
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx
index 0b2ab17d1a..499b95d541 100644
--- a/docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx
@@ -5,10 +5,6 @@ description: AI and LLM tooling for building on ENSv2.
import { LinkCard } from "@astrojs/starlight/components";
-:::caution[Coming Soon]
-We're actively working on this page right now. Check back by May 18th for full content!
-:::
-
AI and LLM tooling is a key priority for ENSNode, and we're building the infrastructure to make ENS a first-class citizen in the world of AI coding assistants and chat-based interfaces.
Next on the roadmap for this space are [`enscli`](/docs/integrate/integration-options/enscli) and [`ensskills`](/docs/integrate/integration-options/ensskills) — the foundation for how developers and their AI agents will reach for ENS.
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/migrate-from-subgraph.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/migrate-from-subgraph.mdx
deleted file mode 100644
index db3086a6c8..0000000000
--- a/docs/ensnode.io/src/content/docs/docs/integrate/migrate-from-subgraph.mdx
+++ /dev/null
@@ -1,10 +0,0 @@
----
-title: Migrate from ENS Subgraph
-description: Migration guide for developers using the legacy ENS Subgraph.
----
-
-:::caution[Coming Soon]
-We're actively working on this page right now. Check back by May 18th for full content!
-:::
-
-This page will provide a migration guide for developers currently using the legacy ENS Subgraph — why to migrate, query-shape mapping, and step-by-step instructions.
diff --git a/docs/ensnode.io/src/content/docs/docs/reference/ensnode-v2-notes.mdx b/docs/ensnode.io/src/content/docs/docs/reference/ensnode-v2-notes.mdx
deleted file mode 100644
index 7204c67834..0000000000
--- a/docs/ensnode.io/src/content/docs/docs/reference/ensnode-v2-notes.mdx
+++ /dev/null
@@ -1,105 +0,0 @@
----
-title: ENSNode V2 Notes
----
-
-:::caution[Work in Progress]
-This document contains implementation and architectural notes for the evolution of ENSNode. It is very much a work-in-progress and should not be considered definitive or indicative.
-:::
-
-## Goals of ENSNode V2
-
-The original architecture of the ENS Subgraph assumes a single-chain, on-chain namespace. The protocol and ecosystem has since evolved: the ENS namespace now exists across multiple chains and across many possible off-chain datasources. The primary goal of ENSNode v2 is to become a unified multichain & off-chain ENS indexer, capable of representing the full state of the protocol at a given time.
-
-Many of the ENS datasources are _dynamic_ in nature and capable of changing over time. For example, the normalization algorithm may change to produce newly normalized labels, additional labels may be healed over time, and the state of off-chain databases may change incredibly frequently. A new protocol-centric architecture & data structure
-
-Additionally, the original schema proposed in the ENS Subgraph isn't 1:1 with the protocol itself, increasing confusion, and will likely need to be updated in the future for and changes made in ENS Protocol V2. ENSNode v2 of course aims to perfectly support ENS v2 and Namechain as they release.
-
-## Proposed Architecture
-
-```
- ┌──────────────────────────────────────────┐
- │ API Server │
- └──────┬──────────────┬────────────────┬───┘
- │ │ │
-┌──────────▼─┐ ┌────────▼───┐ ┌────────▼────────┐
-│ Ponder │ │ ENSRainbow │ │ CCIP Read │
-└──────────┬─┘ └────────┬───┘ └──────────┬──────┘
- │ │ │
- ┌──────▼──────────────▼──────────────────▼─┐
- │ Postgres (Isolated Schemas) │
- └──────────────────────────────────────────┘
-```
-
-At the top level, an API server that stitches the various datasources together at request-time, likely with lots of semantic caching involved. Likely HTTP-JSON based, perhaps GraphQL-based (but GraphQL comes with so many downsides, should be seriously evaluated). Large opportunity for ENS protocol semantic endpoints (i.e. every well-known query from ensjs and ens-app-v3 could/should be a dedicated endpoint given how specific and important that functionality seems to be).
-
-Each datasource persists its data to postgres, either a separate postgres instance or a separate schema in a shared postgres. No native joins are used to power queries, as that likely gets a little too far into the weeds of syncing ponder state with other tables in the same db between re-indexes, etc.
-
-## Ponder Indexer (currently ENSIndexer)
-
-ponder multichain-indexes all on-chain state and shoves it into the postgres database. our ensnode api server talks to ponder's postgres tables via shared drizzle schema. api server maintains some internal state to persist which ponder schema is 'active' and then talks to that specific schema.
-
-### Indexer Schema & Logic Improvements
-
-the 'empty' domains should be handled more accurately, depending on how important serving empty domains is for people.
-
-- `Domain#subdomainCount` could/should be a computed property by count(children of parent)
- - removes need to recursively update parent records during domain delete
- - removes need to increment during domain creation
- - new impl likely needs to exclude 'empty' domains (see registry notes for context)
-
-domain createdAt should not update on re-registration, should be original createdAt
-
-various resources use both null and zeroAddress to indicate emptiness, this is horrible and creates numerous checks like [this](https://github.com/ensdomains/ensjs/blob/17ab314/packages/ensjs/src/functions/subgraph/getNamesForAddress.ts#L255) where they check for `!== NULL && !== zeroAddress`
-
-wrappedOwnerId should not be materialized onto domain, should just be resolved through wrappedDomain.owner
-
-### Registry
-
-- in `Registry:NewOwner`, the event emits `node` and `label`, `node` should be named `parent` and the computed subnode should be named `node` or `domain`
-- empty domains aren't actually deleted from the index, but if a domain is empty the parent's subdomain count is reduced appropriately. options:
- 1. if historical info not important (still available by blockheight queries), domains should be deleted, and `subdomainCount` computed with a simple count query
- 2. if domain existance is necesssary, make `subdomainCount` computed with a where clause to exclude 'empty' domains
- 3. if filters against subdomainCount are necessary, maybe the current logic works just fine
-
-
-### Resolver
-
-- the local `Resolver` resource should be keyed by `CAIP-10 ID`, not pairwise ala subgraph, to match on-chain datamodel
- - the handlers should persist all keys and values emitted by the resolver in `Records`
- - the `Record` model stores (`node`, `key`, `value`) and is keyed by (`resolverId`, `node`, `key`)
- - on active resolver change, simply point the domain's `resolverId` to the resolver's address
- - any domain's records are computed through the current `resolverId` and querying
-
-any resolver that implements the CCIP Read standard will have to have its records implemented at the API layer which can stitch the indexed data with realtime offchain data via CCIP Reads. if we don't want to implement the CCIP Read proxy as part of this unified api, the api should know if a Resolver defers to CCIP and communicate that effectively in the response so that clients can do it themselves.
-
-in the subgraph implementation, resolver handlers must upsert resolvers because people can set records etc for a node that has not (yet) specified this resolver as active, meaning the create in `Registry:NewResolver` has yet to fire.
-
-resolvers should be keyed by `(chainId, address)` and manage a mapping of records for a node, to be more protocol-centric. `coinTypes` and `texts` keys & values should be fully indexed (if possible — intentionally ignored in the subgraph because of some historical reason...)
-
-> Yes, when it comes to all forms of key -> value pairs that comprise resolver records, the ENS Subgraph only indexes the keys and not the values. The motivation for this comes from a concern that some apps might improperly decide to use the ENS Subgraph as a source of truth for resolver record values, rather than ENS protocol standards for how resolver record values should be dynamically looked up. A naive implementation that considers the ENS Subgraph as a source of truth for these can cause a lot of problems.
-
-### Registrar
-
-the subgraph implements all of the BaseRegistrar, EthRegistrarController, and LegacyEthRegistrarController logic together
-
-## ENSRainbow
-
-ENSRainbow would be extended to handle all possible label healing data sources and provide a labelhash lookup api to the ensnode api service. In order to track on-chain datasources of healed labels (namely NameWrapper wraps [hah]), this service will likely run its own separate ponder indexer to track those events. It should also serve the existing legacy rainbow tables (`ens_names.sql`) along with tracking any other additional sources of healed labels.
-
-It should store all known labels, normalized, healed, or otherwise, and then over time (cron? on-demand?) attempt to normalize any yet-normalized labels and add them to the set of healed labels. This ensures that changes in unicode and the normalization algorithm are represented in real-time.
-
-It should also filter out any labels that are not indexable
-- i.e. null byte https://ens.mirror.xyz/9GN77d-MqGvRypm72FcwgxlUnPSuKWhG3rWxddHhRwM
-- or other invalid characters (see `isLabelIndexable`)
-
-In theory (and likely in practice) any normalized name will never become invalid, so once added to the set of healed labels it can live there forever.
-
-# ENSIP Ideas
-
-- unable to automatically identify subname registries via onchain event, CCIP standard dosn't include any info about data source, so we'll need to encode manually for now
-- ENSIP - shared interface for subdomain registrars
-- ENSIP — standard for how a resolver on L1 can (optionally) emit an event specifying contract on an L2 that it proxies records from
- - optional, in the popular case of L2-managed subnames
- - removes centralized dependency on the CCIP Gateway
- - flaky test experience with .cb.id name gateway
- - also helps indexer discovery
diff --git a/docs/ensnode.io/src/content/docs/docs/reference/mainnet-registered-subnames-of-subregistries.mdx b/docs/ensnode.io/src/content/docs/docs/reference/mainnet-registered-subnames-of-subregistries.mdx
deleted file mode 100644
index d3e5a6a635..0000000000
--- a/docs/ensnode.io/src/content/docs/docs/reference/mainnet-registered-subnames-of-subregistries.mdx
+++ /dev/null
@@ -1,56 +0,0 @@
----
-title: Mainnet-Registered Subnames of Subregistries
-sidebar:
- order: 4
----
-
-:::caution[Work in Progress]
-This documentation is under active development. Some sections may be incomplete or out of date.
-:::
-
-This reference discusses the situation in which a name is registered on multiple chains (ex. `example.base.eth` being registered on both the mainnet Registry and Basenames [**Shadow Registry**](/docs/reference/terminology#shadow-registry)).
-
-## ENSNode Architecture Background
-
-The current architecture ('v1') of ENSNode derives from that of the ENS Subgraph which was not architected with multi-chain multi-registry use in mind. When running ENSNode with a single-plugin enabled, only the subnames registered in the plugin's indexed subregistry are included in the index, as designed.
-
-When running ENSNode **with multiple plugins enabled**, however, the behavior of mainnet-registered subnames of subregistries managed by the additional plugins should be considered undefined. The specific names that are registered on mainnet for these subregistries as of a given date are listed below.
-
-## ENS Protocol Context
-
-Based on the ENSIP-10 (Wildcard Resolution) standard, any subnames of subregistries (i.e. `.base.eth`, `.linea.eth`) that exist in the ENS Registry on the mainnet ENS namespace will NOT have the forward resolution of their data delegated to the subregistry defined below. Instead their forward resolution will be managed according to the state defined in the ENS Registry.
-
-These subnames (and any others added beneath `base.eth` or `.linea.eth` in the mainnet ENS Registry) may or may not be properly represented during indexing until futher enhancements are made to ENSNode ('v2').
-
-## Current Behavior
-
-Imagine the situation in which a name (i.e. `gov.base.eth`) is registered on both ETH Mainnet and Base and certain records are set for the name on each chain.
-
-ENSNode currently uses ponder in `omnichain` mode, processing all events across all chains in serial order by timestamp. This means that in that scenario the state of `gov.base.eth` in the resulting index will be determined by the order of the events in time, regardless which chain they occurred on.
-
-In the near future, ENSNode will operate in ponder's `multichain` mode, processing events in parallel by chain. With that same scenario, the state of `gov.base.eth` depends on the (unknown) order in which ponder processes backfill events, and could differ from expectations.
-
-v2 of ENSNode will handle this behavior accurately.
-
-## Mainnet-Registered Subnames of .base.eth
-
-As of 9-Feb-2025 a number of subnames of 'base.eth' exist in the ENS Registry on mainnet.
-
-This includes:
-- gov.base.eth
-- bootcamp.base.eth
-- grants.base.eth
-- bridge.base.eth
-- portal.base.eth
-- faucet.base.eth
-- bonjour.base.eth
-- gm.base.eth
-- mint.base.eth
-
-## Mainnet-Registered Subnames of .linea.eth
-
-As of 9-Feb-2025 a number of subnames of 'linea.eth' exist in the ENS Registry on mainnet.
-
-This includes:
-- bridge.linea.eth
-- devconnect.linea.eth
diff --git a/docs/ensnode.io/src/content/docs/docs/reference/roadmap.mdx b/docs/ensnode.io/src/content/docs/docs/reference/roadmap.mdx
deleted file mode 100644
index 39a3554943..0000000000
--- a/docs/ensnode.io/src/content/docs/docs/reference/roadmap.mdx
+++ /dev/null
@@ -1,82 +0,0 @@
----
-title: ENSNode Roadmap
-sidebar:
- order: 3
----
-
-## First-Class ENS v2 Support
-
-With the launch of [ENSv2](https://roadmap.ens.domains/roadmap/), ENS names will increasingly live across multiple chains and require at-request-time resolution via [CCIP-Read](https://docs.ens.domains/resolvers/ccip-read). The ENS Subgraph, which can only index a single chain and lacks support for resolution of offchain names, is unable to meet these emerging needs.
-
-Built on [Ponder](https://ponder.sh), ENSNode provides multichain indexing and at-request-time resolution capabilities that are essential for ENSv2. It maintains backwards compatibility with Subgraph queries while enabling support for [Namechain](https://app.ens.domains/ens-v2) and offchain names like `.uni.eth` and `.cb.id`.
-
-ENSNode will introduce an ENSv2-optimized schema and custom API endpoints specifically designed for common ENSjs operations.
-
-## Additional Chain / Integration Support
-
-- Offchain Names
- - `.cb.id`, `.uni.id`, + more
- - [NameStone](https://namestone.com/) Names
- - [NameSpace](https://namespace.ninja/) Names
- - [Justaname](https://www.justaname.id/) Names
-
-:::tip[Contribute]
-Want support for a specific chain/integration? Contribute to this documentation by [opening a Pull Request](https://github.com/namehash/ensnode).
-:::
-
-## ENS Protocol Accelerator
-
-ENSNode v2 could introduce a custom HTTP/JSON API layer that would allow for performing additional logic at request time, reducing client-side workload and latency, and accelerating common ENS protocol operations like name/record lookups.
-
-In particular, when records are indexed by ENSIndexer, ENSNode could directly query name records without relying on UniversalResolver or CCIP-Read, significantly reducing latency and avoiding unnecessary HTTP requests. For names that aren't directly indexed, ENSNode can implement CCIP-Read, ensuring clients only need a single lightweight HTTP/2 request to confidently resolve records for a given name.
-
-ENSNode could handle CCIP-Read logic internally, batch multiple requests to reduce RPC calls, and cache CCIP-Read and NFT metadata results. Utilizing HTTP/2 multiplexing and optional batch endpoints could ensure efficient server-side deduplication. To minimize latency in cases like lengthy CCIP-Read or NFT resolution, ENSNode could deliver partial JSON objects over Server-Sent Events (SSE), enabling immediate client updates for critical data like Primary Names while background tasks like avatar resolution complete.
-
-Besides dramatically decreasing latency for client applications, the Protocol Accelerator is also a key step forward in decentralization, away from reliance on centralized offchain gateway servers. This is a big win for the ENS protocol!
-
-## ENSDb CLI & Snapshots
-
-We're investing in [ENSDb](/docs/services/ensdb) as a first-class integration point - and the next big step is making it trivial *and inexpensive* to **operate** an ENSDb and to **share state** across instances. See the full teaser at [ensdb-cli & ENSDb snapshots](/docs/integrate/integration-options/ensdb-cli).
-
-Goals on this roadmap stream include:
-
-- **Snapshot creation & consumption** - publish a portable, versioned package of an ENSDb instance to a destination like Cloudflare R2, and pull it down to bootstrap a new ENSNode instance in minutes instead of waiting on a full historical backfill. Saves **both time and RPC cost** - consumers don't need to replay 9+ years of ENS history through their own RPC provider to catch up.
-- **Snapshot metadata** - record which ENSIndexer config, version, and chains a snapshot was produced from, so consumers can pick the right one and trust it for their use case.
-- **Snapshot diffing** - compare snapshots produced before and after an indexing change to confirm the change didn't unexpectedly alter indexed data. A powerful safety net for release reviews.
-- **Operational ENSNode CLI** - list indexer instances tracked in an ENSDb, inspect their configuration and indexing status, and clean up schemas that are no longer in use.
-- **Snapshot verification (exploratory)** - strategies for letting third parties confirm a snapshot's integrity, such as multi-publisher hash consensus or signed attestations. Open research, not a commitment.
-
-These capabilities will unlock dramatically faster - and cheaper - iteration for hackathon teams, self-hosters, marketplaces, and anyone building custom services on top of ENSDb.
-
-## ENS TokenScope: ENS NFT Marketplace Data API
-
-With Reservoir shutting down in the coming months, ENSNode aims to provide replacement infrastructure for tokenized ENS name market data. This includes:
-
-- past sales history
-- active buy/sell orders (on-chain and off-chain)
-
-This capability could be implemented as an optional ENSNode service, providing free and open source infrastructure for marketplaces platforms that support the name market.
-
-By enabling robust secondary markets through this infrastructure, we aim to strengthen both secondary and primary markets for tokenized names, benefiting registrars and the broader ENS ecosystem.
-
-## Label Healing 'Protocol'
-
-ENSRainbow could establish a (decentralized?) protocol for sharing healed ENS labels, enabling community-driven expansion of the rainbow tables. This protocol would:
-
-- allow anyone to contribute newly healed labels to a shared dataset
-- perhaps use a DHT-like peer-to-peer network for label distribution
-- implement verification and validation of contributed labels
-- enable automatic synchronization between ENSNode/ENSRainbow & other network participants
-
-By decentralizing label healing contributions, the protocol would accelerate the growth of available rainbow tables while maintaining data quality through consensus mechanisms. Participants could run lightweight nodes that selectively replicate subsets of the dataset based on their needs. Registration apps could submit healed values of registered names to the protocol, ensuring users' names show up correctly across web3.
-
-## ENS Protocol Inspector & Developer Tools
-
-ENSNode aims to build out the ENS Protocol Inspector and Developer PowerTools in [ENSAdmin](/ensadmin/), including:
-
-- Visual inspection tools for understanding ENS Protocol behavior
-- Testing and debugging capabilities for protocol interactions
-- Edge case exploration and documentation
-- Best practices validation for ENS integrations
-
-Rather than relying solely on historical documentation, the Protocol Inspector will provide an interactive way to understand how the ENS Protocol handles various scenarios, helping developers build more robust integrations.
diff --git a/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/what-is-the-ens-subgraph.mdx b/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/what-is-the-ens-subgraph.mdx
index ca3bc97969..333603bffb 100644
--- a/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/what-is-the-ens-subgraph.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/what-is-the-ens-subgraph.mdx
@@ -4,18 +4,10 @@ sidebar:
order: 1
---
-import { LinkCard } from "@astrojs/starlight/components";
-
:::note
The following serves as background information regarding the ENS Subgraph and describes the ecosystem & context in which ENSNode was developed. It is not necessary for running ENSNode.
:::
-
-
## The Graph & Graph Node
[The Graph](https://thegraph.com/) leads development of [Graph Node](https://thegraph.com/docs/en/indexing/tooling/graph-node/), an [open source software application](https://github.com/graphprotocol/graph-node) for indexing blockchain data.
diff --git a/docs/ensnode.io/src/content/docs/docs/reference/what-is-ensnode.mdx b/docs/ensnode.io/src/content/docs/docs/reference/what-is-ensnode.mdx
deleted file mode 100644
index 0764f9b9af..0000000000
--- a/docs/ensnode.io/src/content/docs/docs/reference/what-is-ensnode.mdx
+++ /dev/null
@@ -1,114 +0,0 @@
----
-title: Understanding ENSNode V1
-sidebar:
- order: 2
----
-
-import { LinkCard } from "@astrojs/starlight/components";
-
-:::note
-This document assumes general knowledge of the ENS protocol and the ENS Subgraph.
-:::
-
-### What is ENSNode
-
-ENSNode is the new multichain indexer for ENS and ENSv2. It is built on [Ponder](https://ponder.sh/) and provides enhanced capabilities over the ENS Subgraph, as well as being more efficient, flexible, and maintainable. ENSNode's enhanced capabilities include multichain and multiregistrar indexing while maintaining backwards compatibility with existing ENS Subgraph APIs.
-
-### ENSNode Version 1
-
-ENSNode version 1 (`V1`), discussed here, prioritizes equivalency with the [ENS Subgraph](/docs/reference/subgraph-legacy/what-is-the-ens-subgraph), which drove many architectural decisions.
-
-
-
-## Core Design Principles
-
-1. **Full Backwards Compatibility w/ ENS Subgraph**
- - Full support for existing ENS Subgraph queries used by [`ensjs`](https://github.com/ensdomains/ensjs/) and [`ens-app-v3`](https://github.com/ensdomains/ens-app-v3)
- - Drop-in replacement for applications using the ENS Subgraph
- - Verified compatibility through extensive testing with [`ens-test-env`](https://github.com/namehash/ens-test-env/) and [ens-subgraph-transition-tools](https://github.com/namehash/ens-subgraph-transition-tools) (see [Subgraph Compatibility](/docs/reference/subgraph-legacy/what-is-the-ens-subgraph))
-2. **Multi-Registry Plugin Architecture**
- - Support for indexing ENS data across multiple chains & subregistries (i.e. mainnet, Base, Linea)
- - Plugins can be activated independently or in combination
-3. **Built on Ponder**
- - Improved indexing speed (>10x faster than ENS Subgraph)
- - Isolated indexing schemas (supporting branches, staging environments)
- - Access your indexed data directly from Postgres
-4. **Self-hostable Decentralization Approach**
- - Self-hostable infrastructure
- - Bring-your-own Postgres
- - Bring-your-own ENSRainbow
-
-## Execution Order
-
-ENSIndexer is a Ponder application, so its execution order is that of a Ponder application. First the `ponder.config.ts` is executed, and then `ponder.schema.ts` and finally all files in `src/` are executed in order to register indexing event handlers via `ponder.on`.
-
-We place all of our application code into the `src/` directory, so it's all eligible for hot-reloading, and event handler registration occurs in each plugin's `event-handlers.ts` file.
-
-## Plugins
-
-ENSIndexer implements the indexing logic for each plugin inside event handlers. Event handlers may optionally be shared across plugins. For example, see the shared event handler functions in `apps/ensindexer/src/handlers/*.ts` which are shared by multiple plugins such as the `subgraph`, `basenames`, and `lineanames` plugins.
-
-Each plugin requires two files:
-
-- `plugin.ts` defines the plugin's overall indexing configuration. See `apps/ensindexer/src/plugins/basenames/plugin.ts` and `apps/ensindexer/src/plugins/lineanames/plugin.ts` for examples.
-- `event-handlers.ts` registers the event handler functions with Ponder at runtime. See `apps/ensindexer/src/plugins/basenames/event-handlers.ts` and `apps/ensindexer/src/plugins/lineanames/event-handlers.ts` for examples.
-
-### Plugin-Scoping
-
-Because plugins indexing subregistries use the shared handlers and may clobber entities created by the `subgraph` plugin—which didn't expect multichain or multi-source entities—, id-generating code is abstracted to be plugin-specific. See the helpers in `apps/ensindexer/src/lib/ids.ts`. In these cases, for the `subgraph` plugin, the original behavior is left un-modified to facilitate 1:1 responses from the subgraph-compatible api.
-
-This scoping also applies to the concept of a "Managed Name" (see `apps/ensindexer/src/lib/managed-names.ts`): some contracts (like Registrars and RegistrarControllers) operate in the context of a Managed Name (like 'eth', 'base.eth', or 'linea.eth'). In the original subgraph implementation, this was hardcoded for the .eth Registrar/RegistrarControllers as the `eth` name, but because ENSNode shares indexing logic between these similar contracts across `.eth` names, `.base.eth` names, etc, we introduce the concept of a contract's "Managed Name" within the context of which it operates.
-
-### Ponder Plugin Integration
-
-#### Contract Namespace
-
-Ponder, by default, does not have the concept of plugins — it assumes that a config is static and that all contract names are known at compile-time. In ENSIndexer, multiple plugins reference contracts of the same name, and further namespacing is required. We namespace plugin-specific contract definitions with a prefix (namely `PluginName`) to avoid collisions (see `apps/ensindexer/src/lib/plugin-helpers.ts` for reference).
-
-#### Contract & Event Typing
-
-Ponder uses the type information of contracts and their abis in the provided config to power the `ponder.on('MyContract:MyEvent', ...)` api, including inferred types for contract names, event names, and event arguments.
-
-In order to replicate this experience with plugins selected at runtime, we use some creative typing in `apps/ensindexer/src/plugins/index.ts` to merge the possible plugin types for Ponder. With this approach we have full type inference for contract and event names/args across the app regardless of which plugins are activated at runtime.
-
-#### Plugin Execution
-
-When ENSIndexer is run, the configs for all of the active plugins (those selected by the user) are merged and ponder runs in `omnichain` (perhaps later: `multichain`) mode to produce the resulting index. The relevant event handlers are attached in each plugin's `event-handlers.ts` which conditionally executes if the plugin is activated in the ENSIndexerConfig.
-
-## @ensnode/datasources
-
-This package provides configurations for each known ENS namespace. An ENS namespace represents a single, unified set of ENS names with a distinct onchain root Registry and the capability to span across multiple chains, subregistries, and offchain resources.
-
-Each namespace is logically independent - for instance, the Sepolia namespace is entirely separate from the canonical mainnet namespace. This package centralizes the contract addresses, start blocks, and other configuration needed to interact with each namespace.
-
-ENSIndexer uses `@ensnode/datasources` to configure its plugins and determine which are available for a given target namespace.
-
-See the [`@ensnode/datasources` README](https://github.com/namehash/ensnode/blob/main/packages/datasources/README.md) for more context on this package & its responsibilities.
-
-## General Execution Flow
-
-The subgraph's codebase is not exhaustively documented or trivially readable. In some cases we've decided to simplify the implementation (ensuring accuracy via [ens-subgraph-transition-tools](https://github.com/namehash/ens-subgraph-transition-tools)) and in others we've elected to match the subgraph's logic closer to 1:1.
-
-In general, however, each handler is written in a more ponder-native way, using ponder's drizzle-inspired entity CRUD apis, rather than the subgraph's active-record-inspired api. It uses minimial branched or nested logic, resulting in code that is much more readable. Along the way we've also documented the purpose of these handlers more exhaustively, which should promote understanding and readability.
-
-## API Layer
-
-ENSIndexer exposes the following API endpoint:
-
-- **Subgraph-Compatible GraphQL** (`/subgraph`)
-
- - Implements the ENS Subgraph schema and query patterns
- - Enables gradual migration from existing Subgraph implementations
- - Maintains compatibility with `ensjs` client library — just replace
-
-## Label Healing with ENSRainbow
-
-ENSIndexer depends on ENSRainbow at runtime to handle the healing of unknown labels. This parallels the ENS Subgraph's reliance on the graph-node's `ens.nameByHash` function.
-
-## Additional Notes in Comments
-
-Additional implementation & background context for certain decisions are included throughout the codebase where relevant, and we encourage curious readers to browse the comments and general structure of the shared handlers & helper libs for further background.
diff --git a/packages/datasources/src/mainnet.ts b/packages/datasources/src/mainnet.ts
index db9b385a31..70fa9b6de0 100644
--- a/packages/datasources/src/mainnet.ts
+++ b/packages/datasources/src/mainnet.ts
@@ -135,9 +135,6 @@ export default {
*
* The owner of 'base.eth' in the ENS Registry in the mainnet ENS namespace (e.g. Coinbase)
* has the ability to change this configuration at any time.
- *
- * See the reference documentation for additional context:
- * docs/ensnode/src/content/docs/reference/mainnet-registered-subnames-of-subregistries.mdx
*/
chain: base,
contracts: {
@@ -214,9 +211,6 @@ export default {
*
* The owner of 'linea.eth' in the ENS Registry in the mainnet ENS namespace (e.g. Consensys)
* has the ability to change this configuration at any time.
- *
- * See the reference documentation for additional context:
- * docs/ensnode/src/content/docs/reference/mainnet-registered-subnames-of-subregistries.mdx
*/
chain: linea,
contracts: {
diff --git a/packages/datasources/src/sepolia.ts b/packages/datasources/src/sepolia.ts
index ec6a8e44f2..b335100482 100644
--- a/packages/datasources/src/sepolia.ts
+++ b/packages/datasources/src/sepolia.ts
@@ -129,9 +129,6 @@ export default {
*
* The owner of 'basetest.eth' in the ENS Registry on the Sepolia ENS namespace
* (e.g. Coinbase) has the ability to change this configuration at any time.
- *
- * See the reference documentation for additional context:
- * docs/ensnode/src/content/docs/reference/mainnet-registered-subnames-of-subregistries.mdx
*/
chain: baseSepolia,
contracts: {
@@ -190,9 +187,6 @@ export default {
*
* The owner of 'linea-sepolia.eth' in the ENS Registry on the Sepolia ENS namespace
* (e.g. Consensys) has the ability to change this configuration at any time.
- *
- * See the reference documentation for additional context:
- * docs/ensnode/src/content/docs/reference/mainnet-registered-subnames-of-subregistries.mdx
*/
chain: lineaSepolia,
contracts: {
From 0748c7e849a4a9b56a017fbe5ece8ae9ca443511 Mon Sep 17 00:00:00 2001
From: shrugs
Date: Mon, 18 May 2026 15:20:04 -0500
Subject: [PATCH 2/9] docs: rewrite why-ensnode for app-developer audience
Lead with what ENSNode is for app developers (unified API, multichain,
full-stack integration surfaces), not what it is for ENS-the-protocol.
Keep the macro arguments (close infra gaps, decentralization) below the
fold as supporting context. Drop the Coming Soon banner and the Season 2
video embed. Anchor the "Subgraph won't work for ENSv2" thesis without a
feature-comparison table.
Co-Authored-By: Claude Opus 4.7 (1M context)
---
.../docs/docs/integrate/why-ensnode.mdx | 111 +++++++++++++-----
1 file changed, 83 insertions(+), 28 deletions(-)
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/why-ensnode.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/why-ensnode.mdx
index b0d8b9560a..46d93f0f66 100644
--- a/docs/ensnode.io/src/content/docs/docs/integrate/why-ensnode.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/integrate/why-ensnode.mdx
@@ -2,47 +2,102 @@
title: Why ENSNode?
description: Why ENSNode is the best way to build ENSv2 apps.
---
+
+import { LinkCard, CardGrid } from "@astrojs/starlight/components";
import LostENSNamesImage from "@workspace/docs/ensnode.io/src/components/atoms/images/astro/LostENSNamesImage.astro";
import ENSAdminImage from "@workspace/docs/ensnode.io/src/components/atoms/images/astro/ENSAdminImage.astro";
-:::caution[Coming Soon]
-We're actively working on this page right now. Check back by May 18th for full content!
-:::
+ENSNode is the full-stack ENSv2 development platform — a single, unified API over **both ENSv1 and ENSv2**, with first-class multichain support and the integration surfaces (React, TypeScript, GraphQL, Postgres) you need to ship.
+
+## Built for ENSv2 from day one
+
+[ENSv2](https://roadmap.ens.domains/roadmap/) is a fundamental change to ENS's onchain data model. The legacy ENS Subgraph wasn't designed for it, and it never will be — single-chain, no resolution, no understanding of the new Namegraph. Apps that stay on the Subgraph will be left behind the moment ENSv2 launches.
+
+ENSNode is built around ENSv2 from the ground up. The same query works against an ENSv1 name today and an ENSv2 name the moment it goes live — with **zero downtime or code changes** in your app.
+
+
+
+## One unified API over ENSv1 + ENSv2
+
+The [ENS Omnigraph](/docs/integrate/omnigraph) is a single GraphQL API that returns a polymorphic, unified view of every ENS Domain — regardless of whether it lives in the ENSv1 nametree, the ENSv2 Namegraph, on mainnet, or on an L2 subregistry.
+
+
-This page will explain why ENSNode is the best way to build ENSv2 applications — including ENSNode's ENSv2 readiness, multichain support, how it compares to the legacy ENS Subgraph, and much more.
+ENSv1 and ENSv2 coexist after the ENSv2 launch. The Omnigraph hides that split: your code asks for `domain(by: { name: "vitalik.eth" })` and gets a typed result, whether the underlying record is V1 or V2.
-## Why it's important for ENS?
+## Multichain by default
-ENSv2 introduces a completely new onchain data model we refer to as the ENS Namegraph.
-Additionally, when ENSv2 launches, ENSv1 continues to exist in parallel.
-The legacy ENS Subgraph cannot support ENSv2.
-Apps building on ENSv2 need a simple and powerful solution for querying the full unified state of ENSv1 and ENSv2.
-ENSNode delivers this as a full-stack of integration points for developers building on the future of ENS.
-Learn more
+ENSNode indexes the full ENS namespace across every chain that matters, all from one query:
-
+- **Mainnet** — the canonical ENS root and `.eth` registrations
+- **Basenames** (`.base.eth`) on Base
+- **Lineanames** (`.linea.eth`) on Linea
+- **3DNS** names (`.box`, tokenized DNS) on Optimism
+- **ENSv2** Namechain (at launch)
+
+No more wiring up a per-chain Subgraph, reconciling overlapping namespaces, or writing CCIP-Read logic in your app — ENSNode handles forward and reverse resolution, including offchain gateways, server-side.
+
+## Full-stack integration surfaces
+
+Whatever your stack looks like, there's an ENSNode integration shaped for it:
+
+
+
+
+
+
+
+
+## Why it matters beyond your app
### Close critical ENS infrastructure gaps
-Indexed ENS data is vital for the upcoming launch of ENSv2.
-Existing ENS indexed data providers (the ENS Subgraph) are fundamentally unsuitable for ENSv2
-and a replacement is critically required for many of ENS’s most important apps,
-including the official ENS Manager App among many others.
+Indexed ENS data is vital for the upcoming launch of ENSv2. The legacy ENS Subgraph is fundamentally unsuitable for ENSv2, and a replacement is critically required for many of ENS's most important apps — including the official ENS Manager App.
-### Strengthen the decentralization and "unstoppability" of ENS
+### Strengthen the decentralization and "unstoppability" of ENS
-Our infrastructure under development removes a strict dependency on many centralized
-offchain gateway servers whose downtime would otherwise shut down impacted multichain ENS
-names that are key to the future of ENSv2, such as subnames of base.eth,
-linea.eth, or tokenized DNS names such as .box names or 3DNS names.
+ENSNode removes the strict dependency on centralized offchain gateway servers whose downtime would otherwise shut down impacted multichain ENS names that are key to the future of ENSv2 — subnames of `base.eth`, `linea.eth`, tokenized DNS names like `.box`, and more.
+
+## Next steps
+
+
+
+
+
+
From a752ccb5a9a4c8afed22dbf0c6f8b861a84e69e8 Mon Sep 17 00:00:00 2001
From: shrugs
Date: Mon, 18 May 2026 15:47:49 -0500
Subject: [PATCH 3/9] update readme/contributing
---
CONTRIBUTING.md | 5 +----
README.md | 12 ++----------
2 files changed, 3 insertions(+), 14 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2481304764..9f7f7c544c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -4,10 +4,7 @@ Thank you for your interest in contributing to ENSNode! We welcome contributions
## Documentation
-For detailed contribution guidelines and setup instructions:
-
-- **ENSNode**: Visit [ENSNode Contributing Guide](https://ensnode.io/docs/contributing)
-- **ENSRainbow**: Visit [ENSRainbow Contributing Guide](https://ensnode.io/ensrainbow/contributing)
+For detailed setup instructions, visit the [ENSNode Contributing Guide](https://ensnode.io/docs/reference/contributing).
## Getting Help
diff --git a/README.md b/README.md
index c5030dce7b..21446e1bb2 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@
# ENSNode
-[ENSNode](https://ensnode.io) is the multichain indexer for ENS, with first-class support for [ENSv2](https://roadmap.ens.domains/roadmap/). It exposes a unified GraphQL API — the **ENS Omnigraph** — over both ENSv1 and ENSv2.
+[ENSNode](https://ensnode.io) is the multichain indexer for ENS, with first-class support for [ENSv2](https://roadmap.ens.domains/roadmap/). It exposes a unified GraphQL API — the **ENS Omnigraph API** — over both ENSv1 and ENSv2.
- 📚 **Docs:** [ensnode.io](https://ensnode.io)
- 🚀 **Quickstart:** [ensnode.io/docs/integrate](https://ensnode.io/docs/integrate)
@@ -41,15 +41,7 @@ query HelloWorld {
}
```
-See [`examples/omnigraph-graphql-example`](examples/omnigraph-graphql-example) for the full runnable script, and the [Quickstart](https://ensnode.io/docs/integrate) for `enskit` (React), `enssdk` (TypeScript), and direct GraphQL integrations.
-
-## Running with Docker
-
-```bash
-docker compose -f docker/docker-compose.yml up -d
-```
-
-See [`docker/README.md`](docker/README.md) for all use cases and commands.
+To get started with ENSNode and the Omnigraph API, follow a [Quickstart](https://ensnode.io/docs/integrate).
## Contributing
From 8280336a6e4bfca14d3f869679326f1f382128dd Mon Sep 17 00:00:00 2001
From: shrugs
Date: Mon, 18 May 2026 16:50:27 -0500
Subject: [PATCH 4/9] checkpoint: docs pass
---
README.md | 2 +-
docs/ensnode.io/astro.config.mjs | 1 +
.../sidebar-topics/hosted-instances.ts | 18 ++++
.../starlight/sidebar-topics/index.ts | 4 +-
.../starlight/sidebar-topics/integrate.ts | 6 +-
.../starlight/sidebar-topics/services.ts | 84 +++++++++---------
.../molecules/IntegrateHostedEnsNodeTip.astro | 2 +-
.../docs/{integrate => }/hosted-instances.mdx | 30 ++++---
.../docs/docs/integrate/ensv2-readiness.mdx | 30 +++++--
.../src/content/docs/docs/integrate/index.mdx | 11 +--
.../integration-options/enskit/index.mdx | 2 +-
.../integration-options/enssdk/index.mdx | 4 +-
.../omnigraph-graphql-api.mdx | 2 +-
.../integrate/omnigraph/examples/index.mdx | 2 +-
.../docs/docs/integrate/why-ensnode.mdx | 5 +-
.../src/content/docs/docs/reference/index.mdx | 2 +-
.../subgraph-legacy/subgraph-api.mdx | 10 +++
.../what-is-the-ens-subgraph.mdx | 59 +++++--------
.../reference/subgraph-legacy/with-ensjs.mdx | 2 +-
.../docs/docs/reference/terminology.mdx | 87 ++++++++++---------
.../src/content/docs/docs/self-host/index.mdx | 12 ++-
.../src/lib/playground/constants.ts | 2 +-
docs/ensnode.io/src/lib/playground/utils.ts | 2 +-
examples/enskit-react-example/src/App.tsx | 2 +-
examples/enssdk-example/src/index.ts | 2 +-
.../omnigraph-graphql-example/src/index.ts | 2 +-
26 files changed, 208 insertions(+), 177 deletions(-)
create mode 100644 docs/ensnode.io/config/integrations/starlight/sidebar-topics/hosted-instances.ts
rename docs/ensnode.io/src/content/docs/docs/{integrate => }/hosted-instances.mdx (76%)
diff --git a/README.md b/README.md
index 21446e1bb2..b795d416b1 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@
# ENSNode
-[ENSNode](https://ensnode.io) is the multichain indexer for ENS, with first-class support for [ENSv2](https://roadmap.ens.domains/roadmap/). It exposes a unified GraphQL API — the **ENS Omnigraph API** — over both ENSv1 and ENSv2.
+[ENSNode](https://ensnode.io) is the multichain indexer for ENS, with first-class support for [ENSv2](https://ens.domains/ensv2). It exposes a unified GraphQL API — the **Omnigraph API** — over both ENSv1 and ENSv2.
- 📚 **Docs:** [ensnode.io](https://ensnode.io)
- 🚀 **Quickstart:** [ensnode.io/docs/integrate](https://ensnode.io/docs/integrate)
diff --git a/docs/ensnode.io/astro.config.mjs b/docs/ensnode.io/astro.config.mjs
index 9a13484154..e431c24883 100644
--- a/docs/ensnode.io/astro.config.mjs
+++ b/docs/ensnode.io/astro.config.mjs
@@ -52,6 +52,7 @@ export default defineConfig({
"/ensrainbow/concepts/label-sets-and-versioning":
"/docs/services/ensrainbow/concepts/label-sets-and-versioning",
"/docs/reference/rest-api": "/docs/services/ensapi/reference/api-reference",
+ "/docs/integrate/hosted-instances": "/docs/hosted-instances",
},
env: {
schema: {
diff --git a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/hosted-instances.ts b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/hosted-instances.ts
new file mode 100644
index 0000000000..9b40f1a6bd
--- /dev/null
+++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/hosted-instances.ts
@@ -0,0 +1,18 @@
+export const hostedInstancesSidebarTopic = {
+ label: "Hosted Instances",
+ link: "/docs/hosted-instances",
+ icon: "cloud-download",
+ items: [
+ {
+ label: "Hosted Instances",
+ collapsed: false,
+ items: [
+ { label: "v2 Sepolia", link: "/docs/hosted-instances#ensnode-v2-sepolia" },
+ { label: "Alpha", link: "/docs/hosted-instances#ensnode-alpha" },
+ { label: "Alpha-Sepolia", link: "/docs/hosted-instances#ensnode-alpha-sepolia" },
+ { label: "Mainnet", link: "/docs/hosted-instances#ensnode-mainnet" },
+ { label: "Sepolia", link: "/docs/hosted-instances#ensnode-sepolia" },
+ ],
+ },
+ ],
+};
diff --git a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/index.ts b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/index.ts
index 4a884cf3e3..e9d88537bf 100644
--- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/index.ts
+++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/index.ts
@@ -1,5 +1,6 @@
import type { StarlightSidebarTopicsUserConfig } from "starlight-sidebar-topics";
+import { hostedInstancesSidebarTopic } from "./hosted-instances";
import { integrateSidebarTopic } from "./integrate";
import { servicesSidebarTopic } from "./services";
import { referenceSidebarTopic } from "./reference";
@@ -7,7 +8,8 @@ import { selfHostSidebarTopic } from "./self-host";
export const starlightSidebarTopicsConfig = [
integrateSidebarTopic,
+ hostedInstancesSidebarTopic,
selfHostSidebarTopic,
- referenceSidebarTopic,
servicesSidebarTopic,
+ referenceSidebarTopic,
] satisfies StarlightSidebarTopicsUserConfig;
diff --git a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts
index eb4e37b5c7..cdfb0044e2 100644
--- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts
+++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts
@@ -29,7 +29,7 @@ export const integrateSidebarTopic = {
},
{
label: "Examples",
- collapsed: false,
+ collapsed: true,
items: [
{
label: "Overview",
@@ -153,10 +153,6 @@ export const integrateSidebarTopic = {
},
],
},
- {
- label: "Hosted Instances",
- link: "/docs/integrate/hosted-instances",
- },
{
label: "AI / LLM Tooling",
link: "/docs/integrate/ai-llm",
diff --git a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/services.ts b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/services.ts
index f346f0cbbb..36e0861be0 100644
--- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/services.ts
+++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/services.ts
@@ -5,42 +5,33 @@ export const servicesSidebarTopic = {
items: [
{ label: "Overview", link: "/docs/services" },
{
- label: "ENSApi",
- collapsed: true,
- items: [
- { label: "Overview", link: "/docs/services/ensapi" },
- { label: "Configuration", link: "/docs/services/ensapi/usage/configuration" },
- { label: "API Reference", link: "/docs/services/ensapi/reference/api-reference" },
- { label: "Contributing", link: "/docs/services/ensapi/contributing" },
- ],
- },
- {
- label: "ENSIndexer",
+ label: "ENSAdmin",
collapsed: true,
items: [
- { label: "Overview", link: "/docs/services/ensindexer" },
- { label: "Startup Sequence", link: "/docs/services/ensindexer/concepts/startup-sequence" },
- {
- label: "Usage",
- collapsed: true,
- items: [
- { label: "Configuration", link: "/docs/services/ensindexer/usage/configuration" },
- { label: "Management", link: "/docs/services/ensindexer/usage/management" },
- ],
- },
+ { label: "Overview", link: "/docs/services/ensadmin" },
{
label: "Contributing",
collapsed: true,
items: [
- { label: "Overview", link: "/docs/services/ensindexer/contributing" },
+ { label: "Overview", link: "/docs/services/ensadmin/contributing" },
{
- label: "Creating a Plugin",
- link: "/docs/services/ensindexer/contributing/creating-a-plugin",
+ label: "Using Docker",
+ link: "/docs/services/ensadmin/contributing/docker",
},
],
},
],
},
+ {
+ label: "ENSApi",
+ collapsed: true,
+ items: [
+ { label: "Overview", link: "/docs/services/ensapi" },
+ { label: "Configuration", link: "/docs/services/ensapi/usage/configuration" },
+ { label: "API Reference", link: "/docs/services/ensapi/reference/api-reference" },
+ { label: "Contributing", link: "/docs/services/ensapi/contributing" },
+ ],
+ },
{
label: "ENSDb",
collapsed: true,
@@ -80,6 +71,33 @@ export const servicesSidebarTopic = {
},
],
},
+ {
+ label: "ENSIndexer",
+ collapsed: true,
+ items: [
+ { label: "Overview", link: "/docs/services/ensindexer" },
+ { label: "Startup Sequence", link: "/docs/services/ensindexer/concepts/startup-sequence" },
+ {
+ label: "Usage",
+ collapsed: true,
+ items: [
+ { label: "Configuration", link: "/docs/services/ensindexer/usage/configuration" },
+ { label: "Management", link: "/docs/services/ensindexer/usage/management" },
+ ],
+ },
+ {
+ label: "Contributing",
+ collapsed: true,
+ items: [
+ { label: "Overview", link: "/docs/services/ensindexer/contributing" },
+ {
+ label: "Creating a Plugin",
+ link: "/docs/services/ensindexer/contributing/creating-a-plugin",
+ },
+ ],
+ },
+ ],
+ },
{
label: "ENSRainbow",
collapsed: true,
@@ -168,24 +186,6 @@ export const servicesSidebarTopic = {
},
],
},
- {
- label: "ENSAdmin",
- collapsed: true,
- items: [
- { label: "Overview", link: "/docs/services/ensadmin" },
- {
- label: "Contributing",
- collapsed: true,
- items: [
- { label: "Overview", link: "/docs/services/ensadmin/contributing" },
- {
- label: "Using Docker",
- link: "/docs/services/ensadmin/contributing/docker",
- },
- ],
- },
- ],
- },
{
label: "ENSEngine",
collapsed: true,
diff --git a/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro b/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro
index 99187a3479..4369656c3d 100644
--- a/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro
+++ b/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro
@@ -7,7 +7,7 @@ You don't need to run your own ENSNode to follow this guide — the steps below
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/hosted-instances.mdx b/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx
similarity index 76%
rename from docs/ensnode.io/src/content/docs/docs/integrate/hosted-instances.mdx
rename to docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx
index a85a83e96e..f3a2bc46da 100644
--- a/docs/ensnode.io/src/content/docs/docs/integrate/hosted-instances.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx
@@ -1,10 +1,11 @@
---
-title: Using Hosted ENSNode Instances
+title: Hosted ENSNode Instances
sidebar:
- label: Hosted ENSNode Instances
+ label: Overview
order: 1
---
+import { LinkCard } from "@astrojs/starlight/components";
import HostedEnsNodeInstances from "@components/molecules/HostedEnsNodeInstances.astro";
## Hosted Instances
@@ -15,22 +16,26 @@ These instances are provided free of charge with no API key required, have no ra
### Available instance configurations
-Each ENSNode hosted instance is configured for a specific ENS namespace and activated ENSNode plugins. The ENS namespace is the source of truth for the data indexed by the instance, and the activated ENSNode plugins determine the specific data model produced by indexing and available for querying.
+Each ENSNode hosted instance is configured for a specific ENS **namespace** and activated ENSNode **plugins**. The ENS namespace is the source of truth for ENS protocol deployment indexed by ENSNode, and the activated plugins determine the specific data model produced and which ENSNode APIs are available to query.
-Each ENS namespace is associated with a particular ENS root registry deployment, which may or may not have completed the transition from ENSv1 to ENSv2. Currently, ENSNode supports the following ENS namespaces:
+Each ENS namespace is associated with a particular ENS Root Registry deployment, which may or may not have completed the transition from ENSv1 to ENSv2. Currently, ENSNode supports the following ENS namespaces:
- `mainnet` (ENSv1)
- `sepolia` (ENSv1)
-- `sepolia-v2` (An independent deployment of ENS to Sepolia that is already upgraded to ENSv2)
-- `ens-test-env` (A deployment of ENSv2 to a local Anvil chain for development and testing. For details see https://github.com/ensdomains/ens-test-env and https://github.com/ensdomains/contracts-v2)
+- `sepolia-v2` (ENSv1+ENSv2 — An independent deployment of ENS to Sepolia that is already upgraded to ENSv2)
+- `ens-test-env` (ENSv1+ENSv2 — A deployment of ENSv2 to a local Anvil chain for development and testing. For details see https://github.com/ensdomains/ens-test-env and https://github.com/ensdomains/contracts-v2)
More details about ENS namespaces can be found inside [ENSNode's datasources package](https://github.com/namehash/ensnode/tree/main/packages/datasources).
-### ENSv2 instances
+### ENSv2 Instances
These instances are associated with an ENS namespace that has upgraded to ENSv2 and demonstrate the latest ENSv2 support in ENSNode.
#### ENSNode 'v2 Sepolia'
+:::tip[v2 Sepolia]
+The `sepolia-v2` namespace is undergoing active development by the ENS Team and should be considered highly experimental.
+:::
+
-## Endpoints
+## Start building
-For more details on how to use these instances, refer to the [ENSNode Quickstart](/docs/integrate).
+Pick an instance above, then jump into the Quickstart to point your app, SDK, or GraphQL client at it.
+
+
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/ensv2-readiness.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/ensv2-readiness.mdx
index baf8a2b5ef..5398e91626 100644
--- a/docs/ensnode.io/src/content/docs/docs/integrate/ensv2-readiness.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/integrate/ensv2-readiness.mdx
@@ -18,7 +18,7 @@ Full access to ENS data formerly required two separate data fetching strategies
1. **ENS resolution** — RPC calls with CCIP-read support for offchain data (e.g. via a popular package such as `viem` or `wagmi`) to perform forward or reverse ENS resolution.
2. **Indexed ENS data** — the [ENS Subgraph](/docs/reference/subgraph-legacy/what-is-the-ens-subgraph) for indexed ENS data, such as discovering names owned by an address and all other ENS state outside of ENS resolutions.
-Neither system alone was complete.
+Neither system alone was complete.
- ENS resolution gives you resolver records, but no access to all the other state about ENS! ENS Resolutions as exposed through popular libraries such as `viem` and `wagmi` are also painfully "close to the metal", putting the burden on app developers to learn and carefully implement complex details about interpreting raw values returned by the ENS protocol.
- The Subgraph gives you queryable indexed ENS data but has critical limitations, including:
- The Subgraph is single-chain.
@@ -31,15 +31,27 @@ In the past, apps building on ENS have had to live with these split fetching str
## How ENSNode solves this
-[ENSIndexer](/docs/services/ensindexer) offers the `unigraph` plugin, which builds a **unified** polymorphic indexed data model in [ENSDb](/docs/services/ensdb) of multiple ENSv1 Nametrees (the ENSv1 onchain state model found in the ENS root registry, Basenames on Base, Lineanames on Linea, 3DNS on Optimism, etc.), and the ENSv2 Namegraph (the ENSv2 onchain state model that ENSv1 domains may optionally make a dynamic upgrade to, and may contain cycles, disjoint domains, and allows domains to dynamically reposition themselves across time within the ENSv2 Namegraph).
+**The Unigraph Data Model** — [ENSIndexer](/docs/services/ensindexer) offers the `unigraph` plugin, which builds a **unified** polymorphic indexed data model in [ENSDb](/docs/services/ensdb) of multiple ENSv1 Nametrees (the ENSv1 onchain state model found in the ENS root registry, Basenames on Base, Lineanames on Linea, 3DNS on Optimism, etc.), and the ENSv2 Namegraph (the ENSv2 onchain state model that ENSv1 domains may optionally be upgraded to, which allows for dynamic reconfiguration of the name hierarchy, including possible cycles and infinite aliases).
-The [ENS Omnigraph API](/docs/integrate/omnigraph) is delivered by the [ENSApi](/docs/services/ensapi) service which provides a highly tailored GraphQL API that builds upon and refines the "unigraph" indexed data model held in ENSDb to deliver all your ENS data access needs in a single API endpoint. The ENS Omnigraph API also understands ENS protocol implementation details including ENSIP-15 (ENS name normalization), ENSIP-10, ENSIP-19, and much more so that you can focus on building your app and not all the internal implementation complexities of the ENS protocol.
+**The Omnigraph API** — The [ENS Omnigraph API](/docs/integrate/omnigraph) is delivered by [ENSApi](/docs/services/ensapi) and builds upon and refines the Unigraph data model held in [ENSDb](/docs/services/ensdb). The Omnigraph API provides a highly tailored, fully typed GraphQL API that understands ENS protocol implementation details—including ENSIP-10, ENSIP-15, ENSIP-19, and much more—so that you can focus on building your app (and not all the internal implementation complexities of the ENS protocol).
-- **ENS Resolution** — The ENS Omnigraph API, through ENSApi, internally implements the ENS Universal Resolver on top of the indexed ENS Unigraph datamodel in ENSDb. We refer to this idea as "ENS Protocol Acceleration". For cases where ENS Resolution requires offchain data, ENSApi internally performs the CCIP-read operations on your behalf to ensure every resolution request accurately follows all ENS protocol standards. No need for any RPC calls in your app. Your ENS resolutions may now also be faster than ever!
-- **Indexed ENS data** — Access the multichain indexed "unigraph" state model all within a single unified, polymorphic API-level state model that understands ENS protocol implementation details including ENSIP-15 (ENS name normalization), ENSIP-10, ENSIP-19, and much more so that you can focus on building your app and not all the internal implementation complexities of the ENS protocol.
+**Accelerated ENS Resolution** — The ENS Omnigraph API, through ENSApi, internally implements the ENS Universal Resolver on top of the indexed ENS Unigraph data model in ENSDb. We refer to this idea as "ENS Protocol Acceleration". For cases where ENS Resolution requires offchain data, ENSApi internally performs the CCIP-read operations on your behalf to ensure every resolution request accurately follows all ENS protocol standards. No need for any RPC calls in your app, and your ENS resolutions for indexed names could speed up by an order of magnitude or more!
-## What you need to do
+## What You Need to Do
+
+**Resolving Records** — If you're resolving ENS names, you need to ensure that your `resolve` RPC calls go to the new `UniversalResolverV2` contract, when it is deployed or risk stale and incorrect records. This update is usually handled behind the scenes by updating `viem` or `wagmi`, just make sure to update in time!
+
+Instead, you can _resolve records via ENSNode_, and enjoy automatic support for ENSv2 when it launches while instantly benefitting from **ENS Protocol Acceleration**, dramatically reducing resolution duration for indexed names.
+
+**Querying ENS Data** — If you're querying ENS names via an indexed service like the legacy Subgraph, you need to update to an ENSv2-ready indexer like ENSNode; after ENSv2 launches, data served by the Subgraph (and any ENSv1-only indexers) will be instantly out of date.
+
+## Pick Your Integration
+
+ENSNode meets you wherever you are — drop-in React components, a typed TypeScript SDK, raw GraphQL, direct ENSDb access, CLI tooling, or AI agent integration. Pick the surface that fits your stack and ship ENSv2-ready code today.
+
+
-:::caution[Coming Soon]
-We're actively working on this page right now. Check back by May 18th for full content!
-:::
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx
index f1fee67625..92af867d41 100644
--- a/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx
@@ -11,7 +11,7 @@ import OmnigraphAPIExample from "@components/organisms/OmnigraphAPIExample.astro
## What is ENSv2?
-[ENSv2](https://ens.domains/ensv2) is the next generation of the Ethereum Name Service — a protocol upgrade that fundamentally changes the onchain data model of ENS.
+[ENSv2](https://ens.domains/ensv2) is the next generation of the [Ethereum Name Service](https://ens.domains) — a protocol upgrade that fundamentally changes how the ENS protocol works.
:::tip[Prepare for ENSv2]
The ENSv2 upgrade to the ENS protocol is coming **Summer 2026**! Your app, regardless of how it interacts with names, needs to be updated to avoid being left behind.
@@ -23,15 +23,15 @@ The ENSv2 upgrade to the ENS protocol is coming **Summer 2026**! Your app, regar
## What is the ENS Omnigraph?
-ENSNode fully supports ENSv2 via the [Omnigraph API](/docs/integrate/omnigraph), a _unified_ API over **both ENSv1 and ENSv2**. Note how when ENSv2 launches, ENSv1 continues to exist in parallel. ENSNode takes the guesswork out of building on ENS, whether you need to resolve up-to-date records, search all Domains, or see which Domains a user owns (and much, much more).
+ENSNode fully supports ENSv2 via the [Omnigraph API](/docs/integrate/omnigraph), a _unified_ API over **both ENSv1 and ENSv2**. When ENSv2 launches in **Summer 2026**, ENSv1 continues to exist, and apps _must_ be updated to use the new protocol version. ENSNode takes the guesswork out of building on ENS, whether you need to resolve up-to-date records, search all Domains, or see which Domains a user owns (and much, much more).

-ENS Omnigraph supports both ENSv1 and ENSv2 **concurrently**. This means you can integrate today (before ENSv2 launches) and continue with full ENSv2 support when it goes live with zero downtime!
+ENS Omnigraph supports both ENSv1 and ENSv2 **concurrently** within the **same datamodel**. This means you can integrate today (before ENSv2 launches) and continue with full ENSv2 support when it goes live, with zero downtime!
## ENSNode's Integration Options
-ENSNode supports a full range of different integration options across the stack, whether you're using React, any JavaScript runtime, raw GraphQL, or looking to go deep and build a new and fully custom service on ENS data.
+ENSNode supports a full range of different integration options across the stack, whether you're using React, any JavaScript runtime, raw GraphQL, or looking to go deep and build a fully custom service using indexed ENS data.
-
+
diff --git a/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/subgraph-api.mdx b/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/subgraph-api.mdx
index 1bde89d0e0..1a06028e9d 100644
--- a/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/subgraph-api.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/subgraph-api.mdx
@@ -9,6 +9,16 @@ import { LinkCard } from "@astrojs/starlight/components";
## Subgraph API
ENSNode exposes a Subgraph-Compatible GraphQL endpoint at `/subgraph`.
+:::caution[Subgraph API Deprecation]
+With the launch of ENSv2 in Summer 2026, the Subgraph-compatible API will become out-of-date; ENSNode still maintains support for the Subgraph-compatible API as described below, but integrators should prefer the ENSv2-ready Omnigraph API.
+
+
+:::
+
:::note[Subgraph API Compatibility]
ENSNode provides verified backwards compatibility with the ENS Subgraph. See configuration details below.
diff --git a/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/what-is-the-ens-subgraph.mdx b/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/what-is-the-ens-subgraph.mdx
index 333603bffb..ec71782c2a 100644
--- a/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/what-is-the-ens-subgraph.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/what-is-the-ens-subgraph.mdx
@@ -4,10 +4,22 @@ sidebar:
order: 1
---
+import { LinkCard } from "@astrojs/starlight/components";
+
:::note
The following serves as background information regarding the ENS Subgraph and describes the ecosystem & context in which ENSNode was developed. It is not necessary for running ENSNode.
:::
+:::caution[Subgraph API Deprecation]
+With the launch of ENSv2 in Summer 2026, the Subgraph-compatible API will become out-of-date; ENSNode still maintains support for the Subgraph-compatible API as described below, but integrators should prefer the ENSv2-ready Omnigraph API.
+
+
+:::
+
## The Graph & Graph Node
[The Graph](https://thegraph.com/) leads development of [Graph Node](https://thegraph.com/docs/en/indexing/tooling/graph-node/), an [open source software application](https://github.com/graphprotocol/graph-node) for indexing blockchain data.
@@ -34,7 +46,7 @@ This network provides access to a [semi-decentralized ENS Subgraph](https://theg
To support the ENS ecosystem's transition away from legacy ENS indexing strategies to ENSNode, ENSNode provides a verified backwards compatible ENS Subgraph GraphQL endpoint. This therefore also provides backwards compatibility with `ensjs`.
1. For those that wish to host their own ENS indexer, it is faster and easier to deploy ENSNode than to run an ENS Subgraph instance.
-2. For those building an app that simply want to query the legacy ENS Subgraph API in the easiest way possible, we make this freely available through [our hosted ENSNode instances](/docs/integrate/hosted-instances).
+2. For those building an app that simply want to query the legacy ENS Subgraph API in the easiest way possible, we make this freely available through [our hosted ENSNode instances](/docs/hosted-instances).
## Self-hosted ENSNode instance configuration for ENS Subgraph compatibility
@@ -60,41 +72,6 @@ ENSNode has developed tooling to verify subgraph compatibility and ease migratio
## Subgraph-Compatible GraphQL API Reference
-### Supported Features
-
-The feature set used by `ensjs` and `ens-app-v3` is fully supported: see the [well-known queries](#well-known-queries) section below.
-
-### Planned Features
-
-- any open [issues](https://github.com/namehash/ensnode/issues) regarding Subgraph-Compatibility
-- [subgraph `_Meta_` object](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#subgraph-metadata-example)
-
-:::note[Contributions]
-If you'd like to contribute to these features, please [open a Pull Request on GitHub](https://github.com/namehash/ensnode).
-:::
-
-## Possible Features
-
-The following features could be implemented, but are not yet planned.
-
-- [fulltext search queries](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#full-text-search-example)
-
-:::note[Contributions]
-If you'd like to contribute to these features, please [open a Pull Request on GitHub](https://github.com/namehash/ensnode).
-:::
-
-### Unplanned Features
-
-The following features of the subgraph graphql api are explicitly unsupported and are not planned.
-
-- [1-level-nested Entity `_orderBy` param](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#nested-entity-sorting-example)
-- [time travel queries](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#time-travel-queries-example)
-- [\_change_block filtering](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#block-based-filtering-example)
-
-:::note[Contributions]
-If you'd like to discuss these features, please [open an Issue on GitHub](https://github.com/namehash/ensnode/issues).
-:::
-
### Well-Known Queries
These are some of the popular queries we've seen in the wild (namely via ENSjs and ens-app-v3)—the Subgraph-compatible GraphQL API includes full compatibility with these use-cases (and all other possible queries with the exceptions listed above).
@@ -133,3 +110,13 @@ If you'd like to highlight additional query patterns of the ENS Subgraph GraphQL
- [`useResolverExists`](https://github.com/ensdomains/ens-app-v3/blob/328692ae832618f8143916c143b7e4cb9e520811/src/hooks/useResolverExists.ts#L27) — Checks if a resolver exists
- [`useRegistrationData`](https://github.com/ensdomains/ens-app-v3/blob/328692ae832618f8143916c143b7e4cb9e520811/src/hooks/useRegistrationData.ts#L31) — Gets registration by id and nameRegistered events
+
+### Unplanned Features
+
+The following features of the subgraph graphql api are explicitly unsupported and are not planned.
+
+- [1-level-nested Entity `_orderBy` param](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#nested-entity-sorting-example)
+- [time travel queries](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#time-travel-queries-example)
+- [\_change_block filtering](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#block-based-filtering-example)
+- [subgraph `_Meta_` object](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#subgraph-metadata-example)
+- [fulltext search queries](https://thegraph.com/docs/en/subgraphs/querying/graphql-api#full-text-search-example)
diff --git a/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/with-ensjs.mdx b/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/with-ensjs.mdx
index 5e9af70347..04e2eaa6df 100644
--- a/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/with-ensjs.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/reference/subgraph-legacy/with-ensjs.mdx
@@ -10,7 +10,7 @@ import { LinkCard } from '@astrojs/starlight/components';
To use ENSNode with `@ensdomains/ensjs`, follow the [ENSjs documentation for custom subgraph URIs](https://github.com/ensdomains/ensjs/blob/17ab314/docs/basics/custom-subgraph-uris.md), replacing the subgraph URI with your ENSNode's subgraph-compatible api endpoint.
:::note
-You may use the public [NameHash Labs hosted instances](/docs/integrate/hosted-instances).
+You may use the public [NameHash Labs hosted instances](/docs/hosted-instances).
:::
```ts
diff --git a/docs/ensnode.io/src/content/docs/docs/reference/terminology.mdx b/docs/ensnode.io/src/content/docs/docs/reference/terminology.mdx
index d272eb8e78..cc9128108d 100644
--- a/docs/ensnode.io/src/content/docs/docs/reference/terminology.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/reference/terminology.mdx
@@ -6,48 +6,6 @@ sidebar:
New terminology (beyond the [official ENS glossary](https://docs.ens.domains/terminology)) has been needed in the course of building ENSNode. The following should be understood as a draft that is open to community feedback. Each definition below aims to maximize alignment with the official ENS glossary where possible, and reduce instances where a piece of terminology may have multiple meanings in the context of the protocol.
-## Core Protocol Extension Concepts
-
-The following concepts extend the core ENS protocol to handle multichain and off-chain scenarios that arise in modern ENS usage.
-
-### Subregistry
-
-A **Subregistry** is any data structure outside of the [Registry](https://docs.ens.domains/terminology#registry) that manages supplemental state for a set of [subnames](https://docs.ens.domains/terminology#subname-subdomain). Each [name](https://docs.ens.domains/terminology#name) has the potential for association with at least 1 subregistry (through the [Name Wrapper](https://docs.ens.domains/terminology#name-wrapper)) and may optionally be associated with multiple subregistries. When a name is associated with multiple subregistries, this means that the full state of a name must be combined across the Registry and each associated subregistry. For example, the state of all direct subnames of .eth is distributed across the Registry and two subregistries: the BaseRegistrar and the Name Wrapper. The ENS protocol does not currently define standards for subregistries: subregistries currently exist outside the scope of ENS protocol standards. For example, subregistries could live on L1, on L2s, or offchain (in a database or even in a Google Sheet). The ENS protocol currently provides no standardized mechanism to discover subregistries or to interact with subregistries.
-
-Some specific implementations of subregistries include:
-
-- The [BaseRegistrar](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/BaseRegistrarImplementation.sol) that holds supplemental state for direct subnames of .eth. This includes state for ERC721 NFTs and expiry times.
-- The [NameWrapper](https://docs.ens.domains/terminology#name-wrapper), which serves as a subregistry for the entire ENS root (all ENS names). This includes state for ERC1155 NFTs, expiry times, and fuses.
- - Note how direct subnames of .eth are an example of multiple subregistries potentially holding supplemental state for a name outside the Registry.
-- The contracts on Base that manage supplemental state for direct subnames of [base.eth](https://www.base.org/names).
-- The contracts on Linea that manage supplemental state for direct subnames of [linea.eth](https://names.linea.build/).
-- The contracts on Base / Optimism that manage supplemental state for DNS names managed by [3DNS](https://3dns.box/).
-- The offchain databases that manage supplemental state for direct subnames of [uni.eth](https://blog.uniswap.org/introducing-uni-eth-your-unique-web3-username).
-- The offchain databases that manage supplemental state for direct subnames of [cb.id](https://help.coinbase.com/en/wallet/managing-account/coinbase-ens-support).
-- DNS nameservers for (essentially) all DNS names. Since ENS is a superset of DNS, (essentially) any DNS name is an ENS name. Therefore, whenever supplemental state associated with a DNS name is updated in a DNS nameserver, a subregistry is being updated.
-
-### Subregistrar
-
-A **Subregistrar** is any system that is a [Registrar](https://docs.ens.domains/terminology#registrar) or that writes to a subregistry.
-
-This definition expands the definition of Registrar to include cases such as:
-
-- The [ETHRegistrarController](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/ETHRegistrarController.sol) that writes to BaseRegistrar (the owner of the "eth" TLD). Note how the definition of "Registrar" in the official ENS glossary only includes contracts that are pointed to by the owner field of the Registry. Therefore, the BaseRegistrar is a Registrar (and a Subregistry), while the ETHRegistrarController is a Subregistrar.
-- The contracts on Base that write to the Subregistry for direct subnames of base.eth. These contracts live on Base, therefore they cannot meet the definition of Registrar because they can't be set as the owner in the Registry on Ethereum mainnet.
-- The offchain systems that write to the offchain databases associated with direct subnames of uni.eth and cb.id.
-- Any NFT marketplace that supports the exchange of an NFT representing ownership of an ENS name. Each time a NFT is exchanged, state about that NFT must be updated within a related subregistry. Therefore the marketplace enabling that trade is a Subregistrar.
-- Any DNS registrar, as ENS is a superset of DNS.
-
-### Shadow Registry
-
-A **Shadow Registry** is a Subregistry meeting ALL of the following constraints:
-
-1. Not the Registry;
-2. Implemented as a smart contract exposing the same interface as the Registry;
-3. Used as part of the source of truth for a CCIP-Read Gateway Server for ENSIP-10 (wildcard resolution) powered subnames.
-
-A specific implementation of a Shadow Registry can be found in [this contract](https://github.com/base-org/basenames/blob/v1.0.4/src/L2/Registry.sol) storing a subset of the state of base.eth subnames on Base.
-
## ENS Name Resolution Fundamentals
Understanding how ENS names are processed and displayed requires precise terminology around name components and their various states. The following sections build from basic name resolution concepts to the specific classification and encoding systems used in ENSNode.
@@ -74,7 +32,7 @@ ENSNode must process labels from various onchain and offchain sources, each pote
A **Label** is a human-readable string used as a segment of a **name** — i.e. `vitalik` and `eth` are the **Labels** of `vitalik.eth`. Labels are arbitrary unicode strings and may or may not be: _normalized_ or _unnormalized_, _known_ or _unknown_.
-In the ENS `Registry` contract, only the **name**'s **node** is registered on-chain. Because of this there is no guarantee that a registered **node** is composed of _normalized_ Labels or that those Labels are _known_. That is, when observing the `Registry` in isolation, the human-readable **Labels** that make up a **name** are not available (either on-chain or off-chain). That said, in many cases the **Labels** that make up a name can be made **known**: human-readable **Labels** can be emitted by contracts (i.e. the `ETHRegistrarController` or the `NameWrapper`), and in other cases the human-readable **Label** for a given **LabelHash** can be determined via rainbow table lookups and other strategies.
+In the ENSv1 `Registry` contract, only the **name**'s **node** is registered on-chain. Because of this there is no guarantee that a registered **node** is composed of _normalized_ Labels or that those Labels are _known_. That is, when observing the `Registry` in isolation, the human-readable **Labels** that make up a **name** are not available (either on-chain or off-chain). That said, in many cases the **Labels** that make up a name can be made **known**: human-readable **Labels** can be emitted by contracts (i.e. the `ETHRegistrarController` or the `NameWrapper`), and in other cases the human-readable **Label** for a given **LabelHash** can be determined via rainbow table lookups (via [ENSRainbow](/docs/services/ensrainbow)) and other strategies.
#### Rendering _Unknown_ Labels
@@ -212,3 +170,46 @@ A **Subgraph Interpreted Label** is a **Label** that is either:
### Subgraph Interpreted Name
A **Subgraph Interpreted Name** is a name exclusively composed of 0 or more **Subgraph Interpreted Labels**.
+
+
+## Core Protocol Extension Concepts
+
+The following concepts extend the core ENS protocol to handle multichain and off-chain scenarios that arise in modern ENS usage.
+
+### Subregistry
+
+A **Subregistry** is any data structure outside of the [Registry](https://docs.ens.domains/terminology#registry) that manages supplemental state for a set of [subnames](https://docs.ens.domains/terminology#subname-subdomain). Each [name](https://docs.ens.domains/terminology#name) has the potential for association with at least 1 subregistry (through the [Name Wrapper](https://docs.ens.domains/terminology#name-wrapper)) and may optionally be associated with multiple subregistries. When a name is associated with multiple subregistries, this means that the full state of a name must be combined across the Registry and each associated subregistry. For example, the state of all direct subnames of .eth is distributed across the Registry and two subregistries: the BaseRegistrar and the Name Wrapper. The ENS protocol does not currently define standards for subregistries: subregistries currently exist outside the scope of ENS protocol standards. For example, subregistries could live on L1, on L2s, or offchain (in a database or even in a Google Sheet). The ENS protocol currently provides no standardized mechanism to discover subregistries or to interact with subregistries.
+
+Some specific implementations of subregistries include:
+
+- The [BaseRegistrar](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/BaseRegistrarImplementation.sol) that holds supplemental state for direct subnames of .eth. This includes state for ERC721 NFTs and expiry times.
+- The [NameWrapper](https://docs.ens.domains/terminology#name-wrapper), which serves as a subregistry for the entire ENS root (all ENS names). This includes state for ERC1155 NFTs, expiry times, and fuses.
+ - Note how direct subnames of .eth are an example of multiple subregistries potentially holding supplemental state for a name outside the Registry.
+- The contracts on Base that manage supplemental state for direct subnames of [base.eth](https://www.base.org/names).
+- The contracts on Linea that manage supplemental state for direct subnames of [linea.eth](https://names.linea.build/).
+- The contracts on Base / Optimism that manage supplemental state for DNS names managed by [3DNS](https://3dns.box/).
+- The offchain databases that manage supplemental state for direct subnames of [uni.eth](https://blog.uniswap.org/introducing-uni-eth-your-unique-web3-username).
+- The offchain databases that manage supplemental state for direct subnames of [cb.id](https://help.coinbase.com/en/wallet/managing-account/coinbase-ens-support).
+- DNS nameservers for (essentially) all DNS names. Since ENS is a superset of DNS, (essentially) any DNS name is an ENS name. Therefore, whenever supplemental state associated with a DNS name is updated in a DNS nameserver, a subregistry is being updated.
+
+### Subregistrar
+
+A **Subregistrar** is any system that is a [Registrar](https://docs.ens.domains/terminology#registrar) or that writes to a subregistry.
+
+This definition expands the definition of Registrar to include cases such as:
+
+- The [ETHRegistrarController](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/ETHRegistrarController.sol) that writes to BaseRegistrar (the owner of the "eth" TLD). Note how the definition of "Registrar" in the official ENS glossary only includes contracts that are pointed to by the owner field of the Registry. Therefore, the BaseRegistrar is a Registrar (and a Subregistry), while the ETHRegistrarController is a Subregistrar.
+- The contracts on Base that write to the Subregistry for direct subnames of base.eth. These contracts live on Base, therefore they cannot meet the definition of Registrar because they can't be set as the owner in the Registry on Ethereum mainnet.
+- The offchain systems that write to the offchain databases associated with direct subnames of uni.eth and cb.id.
+- Any NFT marketplace that supports the exchange of an NFT representing ownership of an ENS name. Each time a NFT is exchanged, state about that NFT must be updated within a related subregistry. Therefore the marketplace enabling that trade is a Subregistrar.
+- Any DNS registrar, as ENS is a superset of DNS.
+
+### Shadow Registry
+
+A **Shadow Registry** is a Subregistry meeting ALL of the following constraints:
+
+1. Not the Registry;
+2. Implemented as a smart contract exposing the same interface as the Registry;
+3. Used as part of the source of truth for a CCIP-Read Gateway Server for ENSIP-10 (wildcard resolution) powered subnames.
+
+A specific implementation of a Shadow Registry can be found in [this contract](https://github.com/base-org/basenames/blob/v1.0.4/src/L2/Registry.sol) storing a subset of the state of base.eth subnames on Base.
diff --git a/docs/ensnode.io/src/content/docs/docs/self-host/index.mdx b/docs/ensnode.io/src/content/docs/docs/self-host/index.mdx
index 741904cad0..bbed365ce4 100644
--- a/docs/ensnode.io/src/content/docs/docs/self-host/index.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/self-host/index.mdx
@@ -26,15 +26,13 @@ Note that because ENSNode makes many label healing requests to ENSRainbow while
## Bootstrap from a snapshot (coming soon)
-Self-hosting today means standing up a fresh ENSNode instance from zero and waiting on an initial backfill - including the RPC bill that comes with it. **[ENSDb snapshots and `ensdb-cli`](/docs/integrate/integration-options/ensdb-cli)** flatten that ramp.
-
-The headline value props for self-hosters:
+Self-hosting today means standing up a fresh ENSNode instance from zero and waiting on an initial backfill - including the RPC bill that comes with it. **[ENSDb snapshots and `ensdb-cli`](/docs/integrate/integration-options/ensdb-cli)** will make it cheap and easy to begin working with indexed ENS data.
@@ -42,10 +40,10 @@ The headline value props for self-hosters:
The Docker deployment option provides the easiest way to run the full ENSNode suite of services both locally and in the cloud.
-
+
### Deploying with Terraform
An example Terraform deployment reference is available, showing an example of deploying the full ENSNode suite on Render with AWS managed domain names.
-
+
diff --git a/docs/ensnode.io/src/lib/playground/constants.ts b/docs/ensnode.io/src/lib/playground/constants.ts
index 80dc322bcd..b0d41e5701 100644
--- a/docs/ensnode.io/src/lib/playground/constants.ts
+++ b/docs/ensnode.io/src/lib/playground/constants.ts
@@ -3,7 +3,7 @@ import { ENSNamespaceIds } from "@ensnode/ensnode-sdk";
/** TODO: Update all to the latest ENSNode URL */
/** Sepolia v2 namespace — matches the public v2 Sepolia ENSNode URL in docs playgrounds. */
export const DOCS_OMNIGRAPH_NAMESPACE = ENSNamespaceIds.SepoliaV2;
-/** Heading anchor for the docs playground instance (`#### ENSNode 'v2 Sepolia'` on /docs/integrate/hosted-instances). */
+/** Heading anchor for the docs playground instance (`#### ENSNode 'v2 Sepolia'` on /docs/hosted-instances). */
export const DOCS_HOSTED_INSTANCE_ANCHOR = "ensnode-v2-sepolia";
/** Sepolia v2 ENSNode URL — matches the public v2 Sepolia ENSNode URL in docs playgrounds. */
export const ENSNODE_URL = "https://api.v2-sepolia.ensnode.io";
diff --git a/docs/ensnode.io/src/lib/playground/utils.ts b/docs/ensnode.io/src/lib/playground/utils.ts
index 7282c7add4..96bc1b2e08 100644
--- a/docs/ensnode.io/src/lib/playground/utils.ts
+++ b/docs/ensnode.io/src/lib/playground/utils.ts
@@ -46,7 +46,7 @@ export function buildOmnigraphCurlExample(params: {
}
/** Docs path for the hosted ENSNode instances catalog. */
-export const HOSTED_INSTANCES_DOC_PATH = "/docs/integrate/hosted-instances" as const;
+export const HOSTED_INSTANCES_DOC_PATH = "/docs/hosted-instances" as const;
/** Link to a hosted instance section (Starlight heading anchor on the hosted instances page). */
export function getHostedEnsNodeInstanceDocUrl(headingAnchor: string): string {
diff --git a/examples/enskit-react-example/src/App.tsx b/examples/enskit-react-example/src/App.tsx
index 644832aed4..da4e26c1d4 100644
--- a/examples/enskit-react-example/src/App.tsx
+++ b/examples/enskit-react-example/src/App.tsx
@@ -12,7 +12,7 @@ import { SearchView } from "./SearchView";
const EXAMPLE_ACCOUNT_ADDRESS = "0x2f8e8b1126e75fde0b7f731e7cb5847eba2d2574";
// you may use a NameHash Hosted ENSNode instance
-// learn more at https://ensnode.io/docs/integrate/hosted-instances
+// learn more at https://ensnode.io/docs/hosted-instances
const ENSNODE_URL = import.meta.env.VITE_ENSNODE_URL ?? "https://api.v2-sepolia.ensnode.io";
console.log(`Connecting to ENSNode at ${ENSNODE_URL}`);
diff --git a/examples/enssdk-example/src/index.ts b/examples/enssdk-example/src/index.ts
index 1edfca0bf9..57f078f4e7 100644
--- a/examples/enssdk-example/src/index.ts
+++ b/examples/enssdk-example/src/index.ts
@@ -3,7 +3,7 @@ import { createEnsNodeClient } from "enssdk/core";
import { type FragmentOf, graphql, omnigraph, readFragment } from "enssdk/omnigraph";
// you may use a NameHash Hosted ENSNode instance
-// learn more at https://ensnode.io/docs/integrate/hosted-instances
+// learn more at https://ensnode.io/docs/hosted-instances
// biome-ignore lint/style/noNonNullAssertion: invariant
const ENSNODE_URL = process.env.ENSNODE_URL!;
diff --git a/examples/omnigraph-graphql-example/src/index.ts b/examples/omnigraph-graphql-example/src/index.ts
index 5ba09e0fe7..071ac272aa 100644
--- a/examples/omnigraph-graphql-example/src/index.ts
+++ b/examples/omnigraph-graphql-example/src/index.ts
@@ -1,5 +1,5 @@
// you may use a NameHash Hosted ENSNode instance
-// learn more at https://ensnode.io/docs/integrate/hosted-instances
+// learn more at https://ensnode.io/docs/hosted-instances
// biome-ignore lint/style/noNonNullAssertion: invariant
const ENSNODE_URL = process.env.ENSNODE_URL!;
From 2a2d9770d536b7f689b9fa1567c5d937d2358839 Mon Sep 17 00:00:00 2001
From: shrugs
Date: Mon, 18 May 2026 16:54:27 -0500
Subject: [PATCH 5/9] checkpoint: docs pass
---
.../src/content/docs/docs/integrate/index.mdx | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx
index 92af867d41..7af963fd34 100644
--- a/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx
@@ -191,12 +191,18 @@ The ENS Omnigraph API is a GraphQL API following the Relay specification, so you
href="https://github.com/namehash/ensnode/tree/main/examples/omnigraph-graphql-example"
/>
+### 4. Further Integration Options
+
+Beyond `enskit`, `enssdk`, and the Omnigraph GraphQL API, ENSNode exposes a deeper set of integration surfaces for advanced use cases:
+
+- **ENSDb** — query the indexed ENS dataset directly over Postgres for custom analytics or your own service layer.
+- **enscli** — script ENSNode operations from the command line.
+- **ensskills** — AI agent tooling for working with ENS data.
+- **ensdb-cli** — share and load point-in-time ENSDb snapshots.
+- **ENSEngine** (coming soon) — subscribe to ENS-aware webhooks driven by changes in ENSDb.
+
-
-:::tip[Coming soon: accelerated self-hosting]
-Planning to self-host? We're building [**`ensdb-cli` & ENSDb snapshots**](/docs/integrate/integration-options/ensdb-cli) so you can stand up a fresh, nearly-current ENSDb in minutes instead of waiting days and spending big on RPC credits to complete a full historical backfill.
-:::
From c0e9f0f66c1fb316f8ee0e74b3ef7813972c42c3 Mon Sep 17 00:00:00 2001
From: shrugs
Date: Mon, 18 May 2026 17:52:28 -0500
Subject: [PATCH 6/9] fist pass at omnigrpah overview
---
.../docs/docs/integrate/omnigraph/index.mdx | 161 +++++++++++++++++-
1 file changed, 156 insertions(+), 5 deletions(-)
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx
index ebf2f77f26..ca26ec23a7 100644
--- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx
@@ -1,10 +1,161 @@
---
title: ENS Omnigraph API
-description: The ultimate ENSv2 API.
+description: A protocol-native, unified GraphQL API over indexed ENS data — polymorphic across ENSv1 and ENSv2.
---
-:::caution[Coming Soon]
-We're actively working on this page right now. Check back by May 18th for full content!
-:::
+import { LinkCard, CardGrid } from "@astrojs/starlight/components";
-This page will introduce the ENS Omnigraph API — the ultimate ENSv2 API. Includes schema overview, mental model, and how it differs from the legacy ENS Subgraph schema.
+The **ENS Omnigraph API** is the GraphQL API over the indexed Unigraph data model. It's a single, polymorphic schema over **both ENSv1 and ENSv2** — write your query once and get correct, typed results regardless of which protocol version a given Domain lives in.
+
+
+
+The Omnigraph is delivered by [ENSApi](/docs/services/ensapi) on top of the indexed Unigraph in [ENSDb](/docs/services/ensdb). It follows the [Relay specification](https://relay.dev/graphql/connections.htm), abstracts away the most common ENS-protocol footguns, and exposes enough of the underlying protocol for builders who need to go deep.
+
+## One unified API over ENSv1 + ENSv2
+
+Both ENSv1 and ENSv2 Domains are indexed concurrently and exposed through the same schema. When ENSv2 launches in **Summer 2026**, the two protocol versions coexist — and the Omnigraph keeps your app working against both, at the same time, with no code changes.
+
+Addressing a Domain by name (`domain(by: { name: "vitalik.eth" })`) prefers the ENSv2 entity when one exists, and falls back to the ENSv1 entity otherwise. Set-returning queries (`domains(where: { name: ... })`) return both protocol versions, unless explicitly filtered with `version: ENSv1` or `version: ENSv2`.
+
+## What is a Namegraph?
+
+A **Namegraph** is the native data model of ENSv2: it represents names not as a flat mapping of namehashes (as in ENSv1), but as a graph of `Registry → Domain → Registry → Domain → …`. This graph may be cyclic, and within the ENSv2 protocol an unbounded number of _disjoint_ (not connected) Namegraphs may/will exist. Within the unified ENS protocol (v1+v2) there will exist many Namegraphs, at the very least those headed by the ENSv1 Root Registry, Basenames, Lineanames, 3DNS, and the ENSv2 Root Registry.
+
+## What is the Unigraph?
+
+The **Unigraph** is the entire collection of these disjoint namegraphs, indexed and stitched together using ENS Forward Resolution semantics, into a single navigable Namegraph. The result is a single, uniform data model — every ENSv1 query is the same shape as every ENSv2 query. Navigating the Namegraph from `"eth"` down to `"vitalik.eth"` and beyond looks identical regardless of whether the underlying entities are ENSv1 or ENSv2.
+
+The [`unigraph` plugin](/docs/services/ensindexer) in ENSIndexer is what builds this unified model. It's also where multichain coverage lives: Basenames (`.base.eth`), Lineanames (`.linea.eth`), and 3DNS names (`.box`) are all materialized into the same Namegraph as mainnet `.eth`, so a single query covers all indexable names in one shot.
+
+## Canonicality
+
+Given that a Domain entity (say, the `sub` in `sub.example.eth`) can be reached by infinitely many aliases (for example, `sub.other.eth`), it becomes important to determine a _canonical_ reference to the Domain — this is the **Canonical Name**. Canonicality is also connected to nameability; if a Domain exists on-chain but isn't eventually connected to the Root Registry somehow, **it doesn't have a name!**
+
+Within the Omnigraph API the complexity of this is reduced, and all Canonical Domains (those with names) are queryable, searchable, and addressable by said name. Domains that are not canonical are _still_ referenceable by `id` (eg. `domain(by: { id: DomainId! })`).
+
+Canonical Domains have a `Domain.canonical` field hosting the canonicality-derived fields such as `name`, `node`, `depth` (i.e. 2 for `vitalik.eth`), and `path` (i.e. `[Domain("eth"), Domain("vitalik.eth")]`).
+
+## Stable IDs vs. Namegraph addressing
+
+Every entity in the Omnigraph has an `id` — a nominally-typed, stable reference to a specific on-chain entity (`DomainId`, `RegistryId`, `RegistrationId`, etc.). When you already know the entity you mean, address it by `id`: `domain(by: { id: "..." })` always returns the same on-chain Domain.
+
+Addressing a Domain by **name** is a different operation. It's **Namegraph forward traversal**: `domain(by: { name: "vitalik.eth" })` walks from the ENSv2 Root Registry → `"eth"` in that Registry → the Registry that `"eth"` points at (the EthRegistry) → `"vitalik"` in that Registry. The Domain returned is whichever on-chain entity that path currently resolves to.
+
+These two views are not interchangeable:
+
+- The `id` you receive from a name lookup _is_ the stable reference to the on-chain entity that the Namegraph currently resolves `"vitalik.eth"` to.
+- But `"vitalik.eth"` is not a stable reference to that entity. The Namegraph can be re-parented or re-aliased — and tomorrow, `"vitalik.eth"` may resolve to an entirely different on-chain Domain.
+
+**Rule of thumb:** address by `name` when you're answering "which Domain would records come from if resolved right now"; address by `id` when you're answering "what's the latest state of this specific on-chain entity?".
+
+## Polymorphism via GraphQL interfaces
+
+`Domain`, `Registry`, and `Registration` are GraphQL **interfaces**, with concrete types implementing each:
+
+- `Domain` → `ENSv1Domain`, `ENSv2Domain`
+- `Registry` → `ENSv1Registry`, `ENSv1VirtualRegistry`, `ENSv2Registry`
+- `Registration` → `BaseRegistrarRegistration`, `NameWrapperRegistration`, `ThreeDNSRegistration`, `ENSv2RegistryRegistration`, `ENSv2RegistryReservation`
+
+Shared fields are available unconditionally on the interface. Protocol- or implementation-specific fields are reached via typed inline fragments — `... on ENSv1Domain { rootRegistryOwner }`, `... on ENSv2Domain { tokenId }`, `... on BaseRegistrarRegistration { wrapped { fuses } }`, `... on NameWrapperRegistration { fuses }`. The result is a single query that compiles, type-checks, and returns the right fields for whichever concrete type each row turns out to be.
+
+## Interpreted Names everywhere
+
+Every name and label crossing the Omnigraph surface is an **Interpreted Name** (or Interpreted Label). Each label in an Interpreted Name is either a normalized literal label or an Encoded LabelHash (`[abc123…]`) when the literal isn't known. This eliminates the most common ENS UI footguns — unnormalized labels, unhealed hashes, and rendering surprises — at the schema layer, making UI rendering trivial. See [terminology](/docs/reference/terminology#interpreted-label) for the full definition.
+
+## Relay-spec connections
+
+Every list field in the schema is a [Relay-spec Connection](https://relay.dev/graphql/connections.htm) with `edges`, `pageInfo`, and `totalCount`. Cursor-based pagination is idiomatic in urql, Apollo, Relay, and most modern GraphQL clients — infinite scroll and stable pagination work out of the box, with no per-endpoint plumbing.
+
+## A complete audit log of ENS Events
+
+The Omnigraph indexes every onchain Event relevant to ENS and exposes it from the entities each Event relates to:
+
+- `Domain.events` — every Event for a specific Domain
+- `Resolver.events` — every Event emitted by a specific Resolver
+- `Account.events` — every Event for which an Account is the HCA-aware `sender`
+- `Permissions.events`, `PermissionsUser.events` — Permission grant and revocation history
+
+Each `Event` carries chain, block, transaction, and log metadata, plus an HCA-aware `sender` field distinct from the raw `tx.from` for HCA-mediated transactions.
+
+## First-class Permissions
+
+Permissions are modeled as top-level entities. `Permissions` represents a contract that manages role grants; `PermissionsResource` is an addressable resource within that contract; `PermissionsUser` is a specific user's role bitmap on a specific resource.
+
+Registries, Resolvers, and ENSv2 Domains all expose their Permissions directly (`Registry.permissions`, `Resolver.permissions`, `ENSv2Domain.permissions`), and an `Account` can be queried for every Permission it's been granted (`Account.permissions`, `Account.registryPermissions`, `Account.resolverPermissions`). Access-aware UIs — "which Domains can this address manage?", "who can update this Registry?" — become a single query.
+
+## Example
+
+The polymorphism, Namegraph traversal, Canonical Name, Events, and version-specific fragments — all in one query:
+
+```graphql
+query EthAndSubdomains {
+ domains(where: { name: { eq: "eth" } }) {
+ edges {
+ node {
+ __typename
+ id
+ canonical {
+ name { interpreted }
+ depth
+ }
+ events(first: 5) {
+ totalCount
+ edges {
+ node {
+ timestamp
+ transactionHash
+ }
+ }
+ }
+ subdomains(first: 10, order: { by: NAME }) {
+ totalCount
+ edges {
+ node {
+ __typename
+ id
+ canonical { name { interpreted } }
+ ... on ENSv1Domain {
+ rootRegistryOwner { address }
+ }
+ ... on ENSv2Domain {
+ tokenId
+ }
+ }
+ }
+ }
+ ... on ENSv1Domain {
+ rootRegistryOwner { address }
+ }
+ ... on ENSv2Domain {
+ tokenId
+ }
+ }
+ }
+ }
+}
+```
+
+## Next steps
+
+
+
+
+
+
+
From e3805bd9b22b03fb6a3f34978b0c36c3951859e3 Mon Sep 17 00:00:00 2001
From: shrugs
Date: Tue, 19 May 2026 16:17:06 -0500
Subject: [PATCH 7/9] docs: apply lightwalker review suggestions
Co-Authored-By: Claude Opus 4.7 (1M context)
---
README.md | 10 ++++---
.../content/docs/docs/hosted-instances.mdx | 6 ++---
.../docs/docs/integrate/ensv2-readiness.mdx | 8 +++---
.../src/content/docs/docs/integrate/index.mdx | 10 +++----
.../docs/docs/integrate/omnigraph/index.mdx | 26 +++++++++----------
.../docs/docs/integrate/why-ensnode.mdx | 10 +++----
.../subgraph-legacy/subgraph-api.mdx | 2 +-
.../what-is-the-ens-subgraph.mdx | 4 +--
8 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/README.md b/README.md
index b795d416b1..17fb7c5761 100644
--- a/README.md
+++ b/README.md
@@ -19,13 +19,17 @@
# ENSNode
-[ENSNode](https://ensnode.io) is the multichain indexer for ENS, with first-class support for [ENSv2](https://ens.domains/ensv2). It exposes a unified GraphQL API — the **Omnigraph API** — over both ENSv1 and ENSv2.
+[ENSNode](https://ensnode.io) is the full-stack development platform for [ENSv2](https://ens.domains/ensv2). Use ENSNode to achieve full ENSv2 readiness even before ENSv2 launches.
+
+The easiest way to get started is through the new **ENS Omnigraph API** — the world's first and only API to support querying the full state of both ENSv1 and ENSv2 in a single unified API.
- 📚 **Docs:** [ensnode.io](https://ensnode.io)
- 🚀 **Quickstart:** [ensnode.io/docs/integrate](https://ensnode.io/docs/integrate)
- 💬 **Telegram:** [t.me/ensnode](https://t.me/ensnode)
-## Example: query a name via the Omnigraph
+## Example: query the subnames of '.eth' via the ENS Omnigraph API
+
+Note that substantial ENS data is not directly queryable through traditional smart contract RPC calls. Examples include: the subnames of a name, or the names owned by an address. ENSNode is the world's first and only solution that makes the full set of ENS data spanning both ENSv1 and ENSv2 accessible through a single unified API.
```graphql
query HelloWorld {
@@ -41,7 +45,7 @@ query HelloWorld {
}
```
-To get started with ENSNode and the Omnigraph API, follow a [Quickstart](https://ensnode.io/docs/integrate).
+To get started with ENSNode and the ENS Omnigraph API, follow the [Quickstart](https://ensnode.io/docs/integrate).
## Contributing
diff --git a/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx b/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx
index f3a2bc46da..4cdd5bb7d9 100644
--- a/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx
@@ -16,7 +16,7 @@ These instances are provided free of charge with no API key required, have no ra
### Available instance configurations
-Each ENSNode hosted instance is configured for a specific ENS **namespace** and activated ENSNode **plugins**. The ENS namespace is the source of truth for ENS protocol deployment indexed by ENSNode, and the activated plugins determine the specific data model produced and which ENSNode APIs are available to query.
+Each ENSNode hosted instance is configured for a specific ENS **namespace** and activated ENSNode **plugins**. The ENS namespace identifies which ENS protocol deployment will be indexed by ENSNode (ex: mainnet or sepolia). The activated plugins determine the specific indexed data model ENSIndexer will produce in ENSDb and therefore which APIs ENSApi will make available to query.
Each ENS namespace is associated with a particular ENS Root Registry deployment, which may or may not have completed the transition from ENSv1 to ENSv2. Currently, ENSNode supports the following ENS namespaces:
- `mainnet` (ENSv1)
@@ -33,7 +33,7 @@ These instances are associated with an ENS namespace that has upgraded to ENSv2
#### ENSNode 'v2 Sepolia'
:::tip[v2 Sepolia]
-The `sepolia-v2` namespace is undergoing active development by the ENS Team and should be considered highly experimental.
+The `sepolia-v2` namespace is undergoing active development by the ENS Labs team who is continuing to release updated ENSv2 contracts. It should be considered experimental.
:::
Date: Tue, 19 May 2026 16:27:23 -0500
Subject: [PATCH 8/9] docs: address vercel bot feedback
- add redirects for the 5 docs pages removed in this branch
- narrow relay-spec connection claim (Domain.path/Event.topics are plain arrays)
Co-Authored-By: Claude Opus 4.7 (1M context)
---
docs/ensnode.io/astro.config.mjs | 5 +++++
.../src/content/docs/docs/integrate/omnigraph/index.mdx | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/docs/ensnode.io/astro.config.mjs b/docs/ensnode.io/astro.config.mjs
index e431c24883..2631833bfd 100644
--- a/docs/ensnode.io/astro.config.mjs
+++ b/docs/ensnode.io/astro.config.mjs
@@ -53,6 +53,11 @@ export default defineConfig({
"/docs/services/ensrainbow/concepts/label-sets-and-versioning",
"/docs/reference/rest-api": "/docs/services/ensapi/reference/api-reference",
"/docs/integrate/hosted-instances": "/docs/hosted-instances",
+ "/docs/integrate/migrate-from-subgraph": "/docs/integrate/ensv2-readiness",
+ "/docs/reference/ensnode-v2-notes": "/docs/integrate/ensv2-readiness",
+ "/docs/reference/mainnet-registered-subnames-of-subregistries": "/docs/integrate/omnigraph",
+ "/docs/reference/roadmap": "/docs/integrate/ensv2-readiness",
+ "/docs/reference/what-is-ensnode": "/docs/integrate/why-ensnode",
},
env: {
schema: {
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx
index 2bd5e35b37..01b9b5a757 100644
--- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx
@@ -64,7 +64,7 @@ Every name and label crossing the Omnigraph surface is an **Interpreted Name** (
## Relay-spec connections
-Every list field in the schema is a [Relay-spec Connection](https://relay.dev/graphql/connections.htm) with `edges`, `pageInfo`, and `totalCount`. Cursor-based pagination is idiomatic in urql, Apollo, Relay, and most modern GraphQL clients — infinite scroll and stable pagination work out of the box, with no per-endpoint plumbing.
+Collection and paginated relationship fields in the schema follow the [Relay-spec Connection](https://relay.dev/graphql/connections.htm) pattern with `edges`, `pageInfo`, and `totalCount`. Some fields like `DomainCanonical.path` and `Event.topics` are plain arrays without pagination support. Cursor-based pagination is idiomatic in urql, Apollo, Relay, and most modern GraphQL clients — infinite scroll and stable pagination work out of the box, with no per-endpoint plumbing.
## A complete audit log of ENS Events
From 304aab8b044f3be02323ca8682e95452e7394c0d Mon Sep 17 00:00:00 2001
From: shrugs
Date: Tue, 19 May 2026 16:27:44 -0500
Subject: [PATCH 9/9] fix: tighten up
---
.../src/content/docs/docs/integrate/omnigraph/index.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx
index 01b9b5a757..20a7524e0f 100644
--- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/index.mdx
@@ -64,7 +64,7 @@ Every name and label crossing the Omnigraph surface is an **Interpreted Name** (
## Relay-spec connections
-Collection and paginated relationship fields in the schema follow the [Relay-spec Connection](https://relay.dev/graphql/connections.htm) pattern with `edges`, `pageInfo`, and `totalCount`. Some fields like `DomainCanonical.path` and `Event.topics` are plain arrays without pagination support. Cursor-based pagination is idiomatic in urql, Apollo, Relay, and most modern GraphQL clients — infinite scroll and stable pagination work out of the box, with no per-endpoint plumbing.
+Collection and paginated relationship fields in the schema follow the [Relay-spec Connection](https://relay.dev/graphql/connections.htm) pattern with `edges`, `pageInfo`, and `totalCount`. Cursor-based pagination is idiomatic in urql, Apollo, Relay, and most modern GraphQL clients — infinite scroll and stable pagination work out of the box, with no per-endpoint plumbing.
## A complete audit log of ENS Events