Conversation
Please consider it still being work in progress. Many more refinements to be applied.
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 12 minutes and 7 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (12)
📝 WalkthroughWalkthroughENSDb documentation transitions from "Coming soon" status to comprehensive "Getting started" content, including concepts, glossaries, architecture diagrams, and quick-start guides. Supporting configuration files for Letta AI integration are added, along with CSS styling updates. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 20
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/ensnode.io/mindmap.md`:
- Line 1: The file violates markdownlint MD041 because it begins with a code
fence (```mermaid) instead of an H1; add a top-level heading above the existing
mermaid block (e.g., a single line starting with "# " with an appropriate title)
so the document starts with an H1, keeping the existing ```mermaid ... mindmap
... ``` block unchanged below it.
In `@docs/ensnode.io/src/content/docs/ensdb/concepts/architecture.mdx`:
- Line 281: The link text "**[Schema
Version](/ensdb/concepts/glossary#schema-version) evolution**" points to a
non-existent anchor "#schema-version"; either update the link to the correct
anchor name used in the glossary (e.g., match the actual heading ID) or add the
corresponding "Schema Version" heading/anchor to the glossary so
"/ensdb/concepts/glossary#schema-version" resolves; locate the link in the
architecture.mdx content and fix the anchor target or glossary heading to make
the anchor valid.
In `@docs/ensnode.io/src/content/docs/ensdb/concepts/database-schemas.mdx`:
- Line 905: The doc text references the camelCase column name `labelName` but
the schema uses snake_case `label_name`; update the documentation sentence that
mentions `labelName` to use the exact `label_name` identifier so the column name
matches the table definition and avoids SQL copy/paste errors (ensure any other
occurrences of `labelName` in this file are replaced with `label_name` for
consistency with the table schema).
- Around line 1142-1146: The table rows mapping domain tables to the
registrations table are pointing to the wrong sub-schema ("registrars"); update
the two rows where From Sub-Schema is "ensv2" and Table is "v1_domains" and
"v2_domains" to set the To Sub-Schema to "ensv2" (so the To Table
"registrations" correctly belongs to the ensv2 sub-schema), leaving the rest of
the row (Relationship and Via) unchanged.
In `@docs/ensnode.io/src/content/docs/ensdb/concepts/glossary.mdx`:
- Around line 146-158: The glossary currently lists a non-existent key
`indexing_metadata_context`; update the table and section to match the actual
implementation in the EnsNodeMetadataKeys enum by replacing that single row with
three rows for the real keys: `ensdb_version`, `ensindexer_public_config`, and
`ensindexer_indexing_status`. Adjust the "Indexing Metadata Context" section
(rename if appropriate) to document each of those three keys individually,
describing their JSON/value shape and how they map to the ENSNode stack (e.g.,
`ensdb_version` = version string for the metadata structure,
`ensindexer_public_config` = public config for the ENSIndexer instance,
`ensindexer_indexing_status` = current indexing status object), and ensure
references to ENSIndexer/ENSDb/ENSRainbow match the writer docs and the
EnsNodeMetadataKeys enum in packages/ensdb-sdk/src/client/ensnode-metadata.ts.
In `@docs/ensnode.io/src/content/docs/ensdb/index.mdx`:
- Around line 41-43: The Mermaid graph incorrectly labels the mainnet API node;
update the label for the ENSApiMainnet node (adjacent to ENSIndexerMainnet) from
"ENSApi Sepolia instances" to a mainnet-appropriate label such as "ENSApi
Mainnet instances" so the node context matches the surrounding mainnet entries.
- Around line 209-215: The SDK snippet has a duplicated .limit(10) call and uses
the wrong schema member name; update the query built from EnsDbReader so it
calls .from(ensDbReader.ensIndexerSchema.v1_domains) (not v1Domain) and remove
the extra .limit(10) so the chain ends with a single .limit(10); ensure the call
chain on ensDbReader.ensDb.select().from(...).limit(10) is syntactically valid
with proper semicolons and line breaks.
In `@docs/ensnode.io/src/content/docs/ensdb/integrations/index.mdx`:
- Line 155: The label ENSDb["ENSDb<br/>(SQLite)"] is inconsistent with the
PostgreSQL model used elsewhere; update the label to match the PostgreSQL
variant (e.g., ENSDb["ENSDb<br/>(PostgreSQL)"] or simply ENSDb["ENSDb"]) so it
aligns with surrounding docs and avoids confusion—locate and edit the
ENSDb["ENSDb<br/>(SQLite)"] entry to the correct PostgreSQL label in the
integrations content.
- Around line 191-197: The diagram currently has Writer pointing to
ReaderGraphQL/ReaderAnalytics/ReaderCLI; change the flow so Writer writes to
ENSDb and each reader queries ENSDb. Replace the three lines "Writer -->
ReaderGraphQL/ReaderAnalytics/ReaderCLI" with a single or three lines "Writer
--> ENSDb" and ensure the reader edges remain or are expressed as "ReaderGraphQL
--> ENSDb", "ReaderAnalytics --> ENSDb", "ReaderCLI --> ENSDb" so the Writer ->
ENSDb and Reader* -> ENSDb directions are correct.
In `@docs/ensnode.io/src/content/docs/ensdb/integrations/reader.mdx`:
- Around line 320-327: The SQL example ends the triple-quoted string incorrectly
with two quotes; update the cursor.execute call (cursor.execute) so the SQL TEXT
block is properly closed with triple quotes (""") and keep the parameters tuple
unchanged; ensure the block reads SELECT ... LIMIT 100 inside a properly started
and terminated triple-quoted string to produce valid Python.
In `@docs/ensnode.io/src/content/docs/ensdb/integrations/writer.mdx`:
- Around line 337-340: The SQL snippet creates an index non-idempotently: change
the CREATE INDEX v1_domains_by_owner ON
ensindexer_mycustom.v1_domains(owner_id); statement to use the idempotent form
supported by PostgreSQL by adding IF NOT EXISTS so repeated runs don’t error;
update the example that references the index name v1_domains_by_owner and the
table ensindexer_mycustom.v1_domains accordingly in the writer.mdx docs.
- Around line 202-237: The three INSERT statements into the ensnode.metadata
table (the ones inserting keys 'ensdb_version', 'ensindexer_public_config', and
'ensindexer_indexing_status') must be made idempotent by adding an ON CONFLICT
clause on the composite primary key (ens_indexer_schema_name, key); update the
statements for the INSERTs that create these rows so they include ON CONFLICT
(ens_indexer_schema_name, key) DO UPDATE SET value = EXCLUDED.value,
value_version = EXCLUDED.value_version (or DO NOTHING if you prefer to keep
existing values), and apply the same pattern to the other two INSERTs so
rerunning the script won’t error on duplicate key violations.
- Around line 246-285: The snippet in Step 6 uses pool.query(...) but doesn't
define pool locally, so make the snippet self-contained by adding a pool
definition (e.g., create a new PG client Pool instance and import it) before its
use; ensure you import Pool from 'pg' (or reference the same pool variable you
defined earlier) and initialize it with the connection env var (e.g.,
process.env.PG_CONNECTION_STRING) so that pool.query in the loop works when the
snippet is copied in isolation.
In `@docs/ensnode.io/src/content/docs/ensdb/operations/index.mdx`:
- Around line 240-243: The metric's SQL uses an invalid call
pg_total_relation_size('ponder_sync.*'); replace it with a query that sums
pg_total_relation_size over all tables in the ponder_sync schema (e.g., select
sum of pg_total_relation_size(...) for tables where schemaname = 'ponder_sync'),
casting each table identifier to regclass (use format('%I.%I', schemaname,
tablename)::regclass) so pg_total_relation_size can accept each table; update
the Ponder Schema size metric to use this aggregated query and present the total
size (optionally formatted with pg_size_pretty) instead of the wildcard
argument.
- Around line 314-323: The Card components inside CardGrid (the entries titled
"Database Schemas", "Architecture", and "ENS Namespaces") are non-navigable and
should be replaced with Starlight's LinkCard so they become actionable; update
the JSX to use LinkCard for those three items (e.g., replace Card elements
referencing the titles "Database Schemas", "Architecture", "ENS Namespaces" with
LinkCard) and add the import for LinkCard from '@astrojs/starlight/components'
at the top of the file, and for the "ENS Namespaces" LinkCard either point it to
an existing documentation path or remove that LinkCard/create the missing doc if
no path exists.
In `@docs/ensnode.io/src/content/docs/ensdb/usage/index.mdx`:
- Line 27: Update the description string that currently reads
description="TypeScript utilities for typing-safe ENSDb access" to use the
correct phrase "type-safe" instead of "typing-safe"; locate the description
attribute in the frontmatter or metadata block and replace "typing-safe" with
"type-safe" so it reads description="TypeScript utilities for type-safe ENSDb
access".
- Around line 66-87: The example mixes CommonJS require('pg') with top-level
await (pool.query), which is invalid; fix by either converting the module to an
ES module (use import { Pool } from 'pg' and ensure the file is an ESM so
top-level await is allowed) or keep CommonJS and wrap the awaits in an async
IIFE (e.g., create an async function that creates const pool = new Pool(...) and
calls await pool.query(...)); update references to Pool, pool, and pool.query
accordingly so the example is syntactically correct for the chosen module
system.
In `@docs/ensnode.io/src/content/docs/ensdb/usage/querying.mdx`:
- Around line 155-159: The SQL example uses a malformed hex literal in the WHERE
clause; update the literal in the query that selects from
ensindexer_mainnet.labels (columns label_hash, interpreted) by removing the
underscore after the \x escape so the hex literal becomes '\xaf2caa...03cc'
instead of '\x_af2caa...03cc'.
In `@docs/ensnode.io/src/content/docs/ensdb/use-cases/index.mdx`:
- Line 73: The WHERE clause uses an invalid bytea literal '\x0x...'; replace it
with valid PostgreSQL bytea syntax such as the hex format '\\x0x...'
(double-escaped backslash in source) or use decode('0x...', 'hex') for
comparisons; update the selector comparison in the query (the WHERE e.selector =
'...') to use either e.selector = '\\x0x...' or e.selector = decode('0x...',
'hex') so PostgreSQL accepts the bytea literal.
- Around line 305-307: The snippet incorrectly treats asyncpg.add_listener as an
async context manager; replace that pattern by registering a callback via
conn.add_listener(channel, callback) where callback(connection, pid, channel,
payload) handles the event (or enqueues it into an asyncio.Queue if you need an
async consumer), and unregister with conn.remove_listener(channel, callback)
when done; update any code that assumed "async with
conn.add_listener('ens_events') as queue" to define a listener function and call
conn.add_listener('ens_events', listener) instead.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 267b8045-48ef-43d5-941e-841f36cdd703
📒 Files selected for processing (19)
docs/ensnode.io/config/integrations/starlight.tsdocs/ensnode.io/mindmap.mddocs/ensnode.io/src/content/docs/ensdb/concepts/architecture.mdxdocs/ensnode.io/src/content/docs/ensdb/concepts/database-schemas.mdxdocs/ensnode.io/src/content/docs/ensdb/concepts/glossary.mdxdocs/ensnode.io/src/content/docs/ensdb/concepts/index.mdxdocs/ensnode.io/src/content/docs/ensdb/concepts/indexing-lifecycle.mdxdocs/ensnode.io/src/content/docs/ensdb/index.mdxdocs/ensnode.io/src/content/docs/ensdb/integrations/index.mdxdocs/ensnode.io/src/content/docs/ensdb/integrations/reader.mdxdocs/ensnode.io/src/content/docs/ensdb/integrations/writer.mdxdocs/ensnode.io/src/content/docs/ensdb/operations/index.mdxdocs/ensnode.io/src/content/docs/ensdb/usage/ensdb-sdk/index.mdxdocs/ensnode.io/src/content/docs/ensdb/usage/ensdb-sdk/reader.mdxdocs/ensnode.io/src/content/docs/ensdb/usage/ensdb-sdk/writer.mdxdocs/ensnode.io/src/content/docs/ensdb/usage/index.mdxdocs/ensnode.io/src/content/docs/ensdb/usage/querying.mdxdocs/ensnode.io/src/content/docs/ensdb/use-cases/index.mdxdocs/ensnode.io/src/styles/starlight.css
| @@ -0,0 +1,80 @@ | |||
| ```mermaid | |||
There was a problem hiding this comment.
Add a top-level heading to satisfy markdownlint MD041.
The file starts with a code fence instead of an H1.
Suggested patch
+# ENSDb Mindmap
+
```mermaid
mindmap📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ```mermaid | |
| # ENSDb Mindmap | |
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/mindmap.md` at line 1, The file violates markdownlint MD041
because it begins with a code fence (```mermaid) instead of an H1; add a
top-level heading above the existing mermaid block (e.g., a single line starting
with "# " with an appropriate title) so the document starts with an H1, keeping
the existing ```mermaid ... mindmap ... ``` block unchanged below it.
| - **Separate indexing per chain** — mainnet, L2s, testnets as independent tenants | ||
| - **Independent operation** — one tenant can restart while others continue unaffected | ||
| - **Custom indexing** — specialized tenants for specific use cases | ||
| - **[Schema Version](/ensdb/concepts/glossary#schema-version) evolution** — different tenants can use different schema versions |
There was a problem hiding this comment.
Fix broken glossary anchor link.
Line 281 links to #schema-version, but the glossary page in this PR does not define that anchor, so the link will not resolve.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/concepts/architecture.mdx` at line
281, The link text "**[Schema Version](/ensdb/concepts/glossary#schema-version)
evolution**" points to a non-existent anchor "#schema-version"; either update
the link to the correct anchor name used in the glossary (e.g., match the actual
heading ID) or add the corresponding "Schema Version" heading/anchor to the
glossary so "/ensdb/concepts/glossary#schema-version" resolves; locate the link
in the architecture.mdx content and fix the anchor target or glossary heading to
make the anchor valid.
| - `byResolvedAddressId`: `resolved_address_id` | ||
|
|
||
| <Aside type="note"> | ||
| String columns `name` and `labelName` use PostgreSQL collation "C" for subgraph compatibility. |
There was a problem hiding this comment.
Use the documented snake_case column name consistently.
Line 905 references labelName, but the table definition uses label_name (Line 881). Keep this exact to avoid copy/paste errors in SQL.
Suggested doc patch
-String columns `name` and `labelName` use PostgreSQL collation "C" for subgraph compatibility.
+String columns `name` and `label_name` use PostgreSQL collation "C" for subgraph compatibility.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| String columns `name` and `labelName` use PostgreSQL collation "C" for subgraph compatibility. | |
| String columns `name` and `label_name` use PostgreSQL collation "C" for subgraph compatibility. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/concepts/database-schemas.mdx` at line
905, The doc text references the camelCase column name `labelName` but the
schema uses snake_case `label_name`; update the documentation sentence that
mentions `labelName` to use the exact `label_name` identifier so the column name
matches the table definition and avoids SQL copy/paste errors (ensure any other
occurrences of `labelName` in this file are replaced with `label_name` for
consistency with the table schema).
| | From Sub-Schema | Table | Relationship | To Sub-Schema | Table | Via | | ||
| |-----------------|-------|--------------|---------------|-------|-----| | ||
| | ensv2 | `v1_domains` | has | registrars | `registrations` | `domain_id` | | ||
| | ensv2 | `v2_domains` | has | registrars | `registrations` | `domain_id` | | ||
| | ensv2 | `v1_domains` | maps to | subgraph | `subgraph_domains` | `id` (node) | |
There was a problem hiding this comment.
Correct sub-schema mapping for registrations.
Lines 1144-1145 map registrations to registrars, but this page defines registrations under the ensv2 sub-schema. This inconsistency can lead readers to query the wrong schema.
Suggested doc patch
-| ensv2 | `v1_domains` | has | registrars | `registrations` | `domain_id` |
-| ensv2 | `v2_domains` | has | registrars | `registrations` | `domain_id` |
+| ensv2 | `v1_domains` | has | ensv2 | `registrations` | `domain_id` |
+| ensv2 | `v2_domains` | has | ensv2 | `registrations` | `domain_id` |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | From Sub-Schema | Table | Relationship | To Sub-Schema | Table | Via | | |
| |-----------------|-------|--------------|---------------|-------|-----| | |
| | ensv2 | `v1_domains` | has | registrars | `registrations` | `domain_id` | | |
| | ensv2 | `v2_domains` | has | registrars | `registrations` | `domain_id` | | |
| | ensv2 | `v1_domains` | maps to | subgraph | `subgraph_domains` | `id` (node) | | |
| | From Sub-Schema | Table | Relationship | To Sub-Schema | Table | Via | | |
| |-----------------|-------|--------------|---------------|-------|-----| | |
| | ensv2 | `v1_domains` | has | ensv2 | `registrations` | `domain_id` | | |
| | ensv2 | `v2_domains` | has | ensv2 | `registrations` | `domain_id` | | |
| | ensv2 | `v1_domains` | maps to | subgraph | `subgraph_domains` | `id` (node) | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/concepts/database-schemas.mdx` around
lines 1142 - 1146, The table rows mapping domain tables to the registrations
table are pointing to the wrong sub-schema ("registrars"); update the two rows
where From Sub-Schema is "ensv2" and Table is "v1_domains" and "v2_domains" to
set the To Sub-Schema to "ensv2" (so the To Table "registrations" correctly
belongs to the ensv2 sub-schema), leaving the rest of the row (Relationship and
Via) unchanged.
| | Key | Description | | ||
| |-----|-------------| | ||
| | `indexing_metadata_context` | [Indexing metadata context](#indexing-metadata-context) of the [ENSIndexer instance](#ensindexer-instance) | | ||
|
|
||
| #### Indexing Metadata Context | ||
|
|
||
| A JSON object that provides context about the ENSNode stack the Indexing Status. It includes: | ||
| - `version`: The version of the Indexing Metadata Context structure | ||
| - `data`: The actual context data, whose structure may evolve over time as the needs of the ENSNode stack evolve. The `data` object may include fields such as: | ||
| - `indexingStatus`: the current Indexing Status of the [ENSIndexer instance](#ensindexer-instance). | ||
| - `ensDbPublicConfig`: the public config of the [ENSDb instance](#ensdb-instance) that this [ENSIndexer instance](#ensindexer-instance) is connected to. | ||
| - `ensIndexerPublicConfig`: the public config of the [ENSIndexer instance](#ensindexer-instance) that this metadata record belongs to. | ||
| - `ensRainbowPublicConfig`: the public config of the ENSRainbow instance that this [ENSIndexer instance](#ensindexer-instance) is connected to. Might be `null` during the ENSNode stack cold start, when the ENSIndexer instance starts before the ENSRainbow instance. |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "ensdb_version|ensindexer_public_config|ensindexer_indexing_status|indexing_metadata_context" \
docs/ensnode.io/src/content/docs/ensdb/concepts/glossary.mdx \
docs/ensnode.io/src/content/docs/ensdb/usage/ensdb-sdk/writer.mdx -C2
rg -n "EnsNodeMetadataKeys\\.(EnsDbVersion|EnsIndexerPublicConfig|EnsIndexerIndexingStatus)" \
packages/ensdb-sdk/src/client/ensdb-writer.ts -C2Repository: namehash/ensnode
Length of output: 3709
🏁 Script executed:
# Search for indexing_metadata_context in the entire codebase
rg -r "indexing_metadata_context" --type typescript --type mdx --type json
# Check the EnsNodeMetadataKeys enum definition
rg -n "enum EnsNodeMetadataKeys|EnsNodeMetadataKeys\s*=" packages/ensdb-sdk/src -A5
# Look at the type definitions for metadata keys
fd -e ts -e tsx packages/ensdb-sdk/src | xargs rg -l "EnsNodeMetadataKeys" | head -5Repository: namehash/ensnode
Length of output: 1632
🏁 Script executed:
# Read the ensnode-metadata.ts file to understand the metadata structure
cat -n packages/ensdb-sdk/src/client/ensnode-metadata.ts
# Check the serialize functions to understand what the values look like
cat -n packages/ensdb-sdk/src/client/serialize/ensnode-metadata.tsRepository: namehash/ensnode
Length of output: 3056
Update the glossary to document the actual metadata keys.
The glossary documents indexing_metadata_context as a metadata key, but it doesn't exist in the implementation. The actual EnsNodeMetadataKeys enum in packages/ensdb-sdk/src/client/ensnode-metadata.ts defines three separate keys: ensdb_version, ensindexer_public_config, and ensindexer_indexing_status—which correctly align with the writer documentation. Replace the single indexing_metadata_context row with entries for these three actual keys, and update the "Indexing Metadata Context" section accordingly to match the implementation.
🧰 Tools
🪛 LanguageTool
[style] ~154-~154: This phrase is redundant. Consider writing “evolve”.
Context: ...ctual context data, whose structure may evolve over time as the needs of the ENSNode stack evolv...
(EVOLVE_OVER_TIME)
[style] ~158-~158: To form a complete sentence, be sure to include a subject.
Context: ...(#ensindexer-instance) is connected to. Might be null during the ENSNode stack cold...
(MISSING_IT_THERE)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/concepts/glossary.mdx` around lines
146 - 158, The glossary currently lists a non-existent key
`indexing_metadata_context`; update the table and section to match the actual
implementation in the EnsNodeMetadataKeys enum by replacing that single row with
three rows for the real keys: `ensdb_version`, `ensindexer_public_config`, and
`ensindexer_indexing_status`. Adjust the "Indexing Metadata Context" section
(rename if appropriate) to document each of those three keys individually,
describing their JSON/value shape and how they map to the ENSNode stack (e.g.,
`ensdb_version` = version string for the metadata structure,
`ensindexer_public_config` = public config for the ENSIndexer instance,
`ensindexer_indexing_status` = current indexing status object), and ensure
references to ENSIndexer/ENSDb/ENSRainbow match the writer docs and the
EnsNodeMetadataKeys enum in packages/ensdb-sdk/src/client/ensnode-metadata.ts.
|
|
||
| <LinkCard | ||
| title="ENSDb SDK" | ||
| description="TypeScript utilities for typing-safe ENSDb access" |
There was a problem hiding this comment.
Fix typo in SDK description.
Line 27 uses “typing-safe”; this should be “type-safe.”
Suggested patch
- description="TypeScript utilities for typing-safe ENSDb access"
+ description="TypeScript utilities for type-safe ENSDb access"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| description="TypeScript utilities for typing-safe ENSDb access" | |
| description="TypeScript utilities for type-safe ENSDb access" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/usage/index.mdx` at line 27, Update
the description string that currently reads description="TypeScript utilities
for typing-safe ENSDb access" to use the correct phrase "type-safe" instead of
"typing-safe"; locate the description attribute in the frontmatter or metadata
block and replace "typing-safe" with "type-safe" so it reads
description="TypeScript utilities for type-safe ENSDb access".
| ```javascript | ||
| const { Pool } = require('pg'); | ||
|
|
||
| const pool = new Pool({ | ||
| host: 'localhost', | ||
| database: 'ensdb', | ||
| user: 'postgres', | ||
| password: 'password', | ||
| }); | ||
|
|
||
| // Discover ENSIndexer Schemas | ||
| const { rows: schemas } = await pool.query(` | ||
| SELECT DISTINCT ens_indexer_schema_name | ||
| FROM ensnode.metadata | ||
| `); | ||
|
|
||
| // Query indexed data | ||
| const { rows: domains } = await pool.query(` | ||
| SELECT * FROM ensindexer_abc123.v1_domains | ||
| LIMIT 10 | ||
| `); | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In Node.js, is top-level awaitvalid in CommonJS files that userequire(...), or only in ES modules?
💡 Result:
Top-level await is valid only in ES modules (.mjs files or with "type": "module" in package.json), not in CommonJS files that use require(...).
Citations:
- 1: https://nodejs.org/docs/latest/api/esm.html
- 2: Why don't CJS modules support "top level await"? nodejs/node#21267
- 3: module: improve error message for top-level await in CommonJS nodejs/node#55874
- 4: https://v8.dev/features/top-level-await
🏁 Script executed:
# Check if the file exists and read lines 66-87
if [ -f "docs/ensnode.io/src/content/docs/ensdb/usage/index.mdx" ]; then
echo "=== File exists, reading lines 66-87 ==="
sed -n '66,87p' "docs/ensnode.io/src/content/docs/ensdb/usage/index.mdx"
else
echo "File not found at expected path. Searching for similar files..."
find . -name "index.mdx" -path "*/ensdb/usage/*" 2>/dev/null | head -5
fiRepository: namehash/ensnode
Length of output: 542
JavaScript example mixes CommonJS with top-level await, which is invalid.
Line 67 uses require(...) (CommonJS), but lines 77 and 83 use top-level await. Top-level await is only valid in ES modules, not in CommonJS files. Wrap the code in an async IIFE or convert to ES module syntax.
Suggested patch
const { Pool } = require('pg');
-const pool = new Pool({
- host: 'localhost',
- database: 'ensdb',
- user: 'postgres',
- password: 'password',
-});
-
-// Discover ENSIndexer Schemas
-const { rows: schemas } = await pool.query(`
- SELECT DISTINCT ens_indexer_schema_name
- FROM ensnode.metadata
-`);
-
-// Query indexed data
-const { rows: domains } = await pool.query(`
- SELECT * FROM ensindexer_abc123.v1_domains
- LIMIT 10
-`);
+(async () => {
+ const pool = new Pool({
+ host: 'localhost',
+ database: 'ensdb',
+ user: 'postgres',
+ password: 'password',
+ });
+
+ // Discover ENSIndexer Schemas
+ const { rows: schemas } = await pool.query(`
+ SELECT DISTINCT ens_indexer_schema_name
+ FROM ensnode.metadata
+ `);
+
+ // Query indexed data
+ const { rows: domains } = await pool.query(`
+ SELECT * FROM ensindexer_abc123.v1_domains
+ LIMIT 10
+ `);
+})();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/usage/index.mdx` around lines 66 - 87,
The example mixes CommonJS require('pg') with top-level await (pool.query),
which is invalid; fix by either converting the module to an ES module (use
import { Pool } from 'pg' and ensure the file is an ESM so top-level await is
allowed) or keep CommonJS and wrap the awaits in an async IIFE (e.g., create an
async function that creates const pool = new Pool(...) and calls await
pool.query(...)); update references to Pool, pool, and pool.query accordingly so
the example is syntactically correct for the chosen module system.
| -- Look up interpreted label for a labelhash | ||
| SELECT label_hash, interpreted | ||
| FROM ensindexer_mainnet.labels | ||
| WHERE label_hash = '\x_af2caa...03cc'; | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "\\\\x_" docs/ensnode.io/src/content/docs/ensdb/usage/querying.mdx -C2Repository: namehash/ensnode
Length of output: 218
Correct the malformed hex literal in the SQL example.
Line 158 contains '\x_af2caa...03cc', which is invalid SQL syntax. Remove the underscore after \x to form a valid hex literal: '\xaf2caa...03cc'.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/usage/querying.mdx` around lines 155 -
159, The SQL example uses a malformed hex literal in the WHERE clause; update
the literal in the query that selects from ensindexer_mainnet.labels (columns
label_hash, interpreted) by removing the underscore after the \x escape so the
hex literal becomes '\xaf2caa...03cc' instead of '\x_af2caa...03cc'.
| FROM ensindexer_mainnet.events e | ||
| JOIN ensindexer_mainnet.domain_events de ON e.id = de.event_id | ||
| JOIN ensindexer_mainnet.v1_domains d ON de.domain_id = d.id | ||
| WHERE e.selector = '\x0x...' -- NewOwner event |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
What is the correct PostgreSQL syntax for comparing a BYTEA column to hex data (e.g., using decode(..., 'hex') or \\x... literals)?
💡 Result:
The correct PostgreSQL syntax for comparing a BYTEA column (e.g., mytable.mybytea) to hex data uses either the \x hex literal or decode('hexstring', 'hex'): 1. Using hex literal (preferred, direct bytea literal): WHERE mytable.mybytea = '\xDEADBEEF'::bytea (Note: In SQL strings, escape the backslash as \x; hex digits are case-insensitive.) 2. Using decode function (for hex strings from variables or longer values): WHERE mytable.mybytea = decode('DEADBEEF', 'hex') Both produce bytea values for direct equality comparison (= operator). The hex literal is faster and recommended by official docs for literals. Examples work in PostgreSQL 9.0+ (hex format introduced then; current as of 2026 is v18). Example query: SELECT * FROM mytable WHERE mybytea = '\xdeadbeef'::bytea; Equivalent: SELECT * FROM mytable WHERE mybytea = decode('deadbeef', 'hex');
Citations:
- 1: http://www.postgresql.org/docs/16/datatype-binary.html
- 2: https://stackoverflow.com/questions/3103242/inserting-text-string-with-hex-into-postgresql-as-a-bytea
- 3: https://www.postgresql.org/docs/current/datatype-binary.html
- 4: https://www.postgresql.org/docs/current/functions-binarystring.html
🏁 Script executed:
fd -t f 'index.mdx' | grep -E 'ensdb/use-cases'Repository: namehash/ensnode
Length of output: 118
🏁 Script executed:
sed -n '70,80p' docs/ensnode.io/src/content/docs/ensdb/use-cases/index.mdxRepository: namehash/ensnode
Length of output: 409
🏁 Script executed:
grep -n "\\\\x0x" docs/ensnode.io/src/content/docs/ensdb/use-cases/index.mdxRepository: namehash/ensnode
Length of output: 109
Replace malformed bytea literal with valid PostgreSQL syntax.
Line 73 uses '\x0x...', which is not valid PostgreSQL bytea syntax. PostgreSQL requires either the \\x hex literal format or the decode() function for bytea comparisons.
Suggested patch
-WHERE e.selector = '\x0x...' -- NewOwner event
+WHERE e.selector = decode('YOUR_EVENT_SELECTOR_HEX', 'hex') -- NewOwner event (no 0x prefix)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| WHERE e.selector = '\x0x...' -- NewOwner event | |
| WHERE e.selector = decode('YOUR_EVENT_SELECTOR_HEX', 'hex') -- NewOwner event (no 0x prefix) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/use-cases/index.mdx` at line 73, The
WHERE clause uses an invalid bytea literal '\x0x...'; replace it with valid
PostgreSQL bytea syntax such as the hex format '\\x0x...' (double-escaped
backslash in source) or use decode('0x...', 'hex') for comparisons; update the
selector comparison in the query (the WHERE e.selector = '...') to use either
e.selector = '\\x0x...' or e.selector = decode('0x...', 'hex') so PostgreSQL
accepts the bytea literal.
| async with conn.add_listener('ens_events') as queue: | ||
| async for event in queue: | ||
| # New event detected |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In asyncpg, what is the correct API pattern for LISTEN/NOTIFY subscriptions—does add_listener return a context manager/queue, or does it require a callback?
💡 Result:
In asyncpg, the correct API pattern for LISTEN/NOTIFY subscriptions is to use Connection.add_listener(channel, callback), which requires a callback function (regular callable or coroutine function since version 0.24.0). The callback receives arguments: connection, pid (sender PID), channel, and payload. It does not return a context manager or queue.
Citations:
- 1: https://magicstack.github.io/asyncpg/current/api/index.html
- 2: [Question] Asynchronous NOTIFY listener MagicStack/asyncpg#567
- 3: Feature Request: better support for LISTEN/NOTIFY? MagicStack/asyncpg#1089
- 4: https://medium.com/@diwasb54/real-time-communication-with-postgresql-listen-notify-and-fastapi-0bfedf66be13
- 5: Documentation for add_listener? MagicStack/asyncpg#905
Use callback-based API for asyncpg.add_listener()—not context manager/stream.
The code attempts to use add_listener as an async context manager that yields a queue, but asyncpg's API requires a callback function. The add_listener(channel, callback) method accepts a regular callable or coroutine function that receives (connection, pid, channel, payload) arguments.
Suggested fix
- async with conn.add_listener('ens_events') as queue:
- async for event in queue:
- # New event detected
- event_data = json.loads(event.payload)
+ async def on_event(_conn, _pid, _channel, payload):
+ # New event detected
+ event_data = json.loads(payload)
+ # process event_data...
+
+ await conn.add_listener('ens_events', on_event)
+ await asyncio.Event().wait() # keep process alive🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/use-cases/index.mdx` around lines 305
- 307, The snippet incorrectly treats asyncpg.add_listener as an async context
manager; replace that pattern by registering a callback via
conn.add_listener(channel, callback) where callback(connection, pid, channel,
payload) handles the event (or enqueues it into an asyncio.Queue if you need an
async consumer), and unregister with conn.remove_listener(channel, callback)
when done; update any code that assumed "async with
conn.add_listener('ens_events') as queue" to define a listener function and call
conn.add_listener('ens_events', listener) instead.
There was a problem hiding this comment.
Pull request overview
Adds an initial ENSDb documentation section to the ensnode.io docs site, including conceptual overviews and practical guides, and wires it into the Starlight sidebar.
Changes:
- Introduces new ENSDb docs pages (Concepts, Usage, Integrations, Use Cases, Operations).
- Updates the ENSDb landing page from “WIP/Coming soon” to a full “Getting started” overview.
- Tweaks Starlight CSS for markdown list rendering and sidebar/pagination selector formatting.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/ensnode.io/src/styles/starlight.css | Adjusts markdown list styling and cleans up selector formatting/spacing. |
| docs/ensnode.io/src/content/docs/ensdb/index.mdx | Replaces the ENSDb placeholder with a full getting-started overview and examples. |
| docs/ensnode.io/src/content/docs/ensdb/concepts/index.mdx | Adds Concepts landing page with links to core conceptual docs. |
| docs/ensnode.io/src/content/docs/ensdb/concepts/architecture.mdx | Documents ENSDb architecture (writer/reader pattern, schemas, server vs instance). |
| docs/ensnode.io/src/content/docs/ensdb/concepts/database-schemas.mdx | Adds comprehensive schema reference and diagrams for ENSDb. |
| docs/ensnode.io/src/content/docs/ensdb/concepts/glossary.mdx | Adds glossary of ENSDb and PostgreSQL terminology. |
| docs/ensnode.io/src/content/docs/ensdb/concepts/indexing-lifecycle.mdx | Documents backfill/following lifecycle and index behavior. |
| docs/ensnode.io/src/content/docs/ensdb/usage/index.mdx | Adds Usage landing page with language examples and links to querying/SDK docs. |
| docs/ensnode.io/src/content/docs/ensdb/usage/querying.mdx | Adds SQL querying guide (schema discovery, status checks, query patterns). |
| docs/ensnode.io/src/content/docs/ensdb/usage/ensdb-sdk/index.mdx | Adds ENSDb SDK overview page with structure and links. |
| docs/ensnode.io/src/content/docs/ensdb/usage/ensdb-sdk/reader.mdx | Adds ENSDb Reader SDK reference and usage examples. |
| docs/ensnode.io/src/content/docs/ensdb/usage/ensdb-sdk/writer.mdx | Adds ENSDb Writer SDK reference (migrations + metadata upserts). |
| docs/ensnode.io/src/content/docs/ensdb/integrations/index.mdx | Adds integrations overview (writer/reader pattern, compliance checklist). |
| docs/ensnode.io/src/content/docs/ensdb/integrations/reader.mdx | Adds “Build a Custom Reader” guide with multi-language examples. |
| docs/ensnode.io/src/content/docs/ensdb/integrations/writer.mdx | Adds “Build a Custom Writer” guide with lifecycle + schema requirements. |
| docs/ensnode.io/src/content/docs/ensdb/use-cases/index.mdx | Adds ENSDb use-cases page with example queries and patterns. |
| docs/ensnode.io/src/content/docs/ensdb/operations/index.mdx | Adds operational guidance (multitenancy, namespace isolation, backups). |
| docs/ensnode.io/mindmap.md | Adds a Mermaid mindmap capturing ENSDb conceptual structure. |
| docs/ensnode.io/config/integrations/starlight.ts | Updates sidebar nav to include ENSDb Concepts/Usage/Use Cases/Integrations/Operations sections. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| |--------|------|---------| | ||
| | `ens_indexer_schema_name` | `text` | References the [ENSIndexer Schema Name](#ensindexer-schema-name) of the ENSIndexer instance that manages this metadata record | | ||
| | `key` | `text` | Type of metadata record | | ||
| | `value` | `jsonb` | The context object (configuration, status, etc.) | |
There was a problem hiding this comment.
The ENSNode metadata table definition here omits the value_version column, but other docs in this PR describe ensnode.metadata as having value_version (e.g. in Database Schemas / Writer docs). Please add value_version to this glossary table (or clarify if the glossary is describing a different/older schema).
| | `value` | `jsonb` | The context object (configuration, status, etc.) | | |
| | `value` | `jsonb` | The context object (configuration, status, etc.) | | |
| | `value_version` | `integer` | Version of the structure stored in `value` | |
| subgraph ENSNodeMainnet["ENSNode 'Mainnet' instance"] | ||
| direction LR | ||
| ENSIndexerMainnet[ENSIndexer 'Mainnet' instance] | ||
| ENSApiMainnet@{ shape: procs, label: "ENSApi Sepolia instances" } |
There was a problem hiding this comment.
The Mermaid diagram node ENSApiMainnet is labeled as “ENSApi Sepolia instances”, which is confusing/misleading in the Mainnet subgraph. Update the label to reflect mainnet (or rename the node) so the diagram matches the surrounding headings.
| ENSApiMainnet@{ shape: procs, label: "ENSApi Sepolia instances" } | |
| ENSApiMainnet@{ shape: procs, label: "ENSApi Mainnet instance" } |
| .from(ensDbReader.ensIndexerSchema.v1Domain) | ||
| .limit(10); | ||
| .limit(10); |
There was a problem hiding this comment.
This TypeScript snippet won’t compile as written: it references ensIndexerSchema.v1Domain (elsewhere the docs use v1_domains), and the chained query is terminated early and then calls .limit(10) again on a new statement. Please update the example to use the correct table property name and a single, properly chained query.
| .from(ensDbReader.ensIndexerSchema.v1Domain) | |
| .limit(10); | |
| .limit(10); | |
| .from(ensDbReader.ensIndexerSchema.v1_domains) | |
| .limit(10); |
|
|
||
| ## ENS Namespace Isolation | ||
|
|
||
| The most critical operational decision is how to handle [ENS Namespaces](/ensindexer/usage/ens-namespaces). An ENS Namespace (like "mainnet" or "sepolia") defines which chains an ENSIndexer instance indexes. |
There was a problem hiding this comment.
This link points to /ensindexer/usage/ens-namespaces, but that page doesn’t exist in the current docs tree (ensindexer/usage only has configuration and management). Please update the link to an existing page/anchor or add the missing ENS Namespaces doc page so readers don’t hit a 404.
| The most critical operational decision is how to handle [ENS Namespaces](/ensindexer/usage/ens-namespaces). An ENS Namespace (like "mainnet" or "sepolia") defines which chains an ENSIndexer instance indexes. | |
| The most critical operational decision is how to handle [ENS Namespaces](/ensindexer/usage/configuration). An ENS Namespace (like "mainnet" or "sepolia") defines which chains an ENSIndexer instance indexes. |
|
|
||
| ### Ponder Schema | ||
|
|
||
| A [database schema](#database-schema) in the [ENSDb instance](#ensdb-instance) following the [Ponder Schema Definition](#ponder-schema-definition). It has a fixed `ponder_sync` name, and it serves as a shared RPC cache for all [ENSIndexer instances](#ensindexer-instance) connected to the [ENSDb instance](#ensdb-instance). It's lifecycle is managed by Ponder runtime. |
There was a problem hiding this comment.
Grammar: “It's lifecycle” should be “Its lifecycle” (possessive, not “it is”).
| A [database schema](#database-schema) in the [ENSDb instance](#ensdb-instance) following the [Ponder Schema Definition](#ponder-schema-definition). It has a fixed `ponder_sync` name, and it serves as a shared RPC cache for all [ENSIndexer instances](#ensindexer-instance) connected to the [ENSDb instance](#ensdb-instance). It's lifecycle is managed by Ponder runtime. | |
| A [database schema](#database-schema) in the [ENSDb instance](#ensdb-instance) following the [Ponder Schema Definition](#ponder-schema-definition). It has a fixed `ponder_sync` name, and it serves as a shared RPC cache for all [ENSIndexer instances](#ensindexer-instance) connected to the [ENSDb instance](#ensdb-instance). Its lifecycle is managed by Ponder runtime. |
| SELECT * FROM "ensnode"."metadata" | ||
| WHERE ens_indexer_schema_name = 'ensindexer_mainnet' | ||
| AND key = 'ensindexer_indexing_status' | ||
| AND value -> 'data' -> 'omnichainSnapshot' ->> 'omnichainStatus' = 'omnichain-following'; |
There was a problem hiding this comment.
The indexing-status query here uses a deeply nested JSON path (value -> 'data' -> 'omnichainSnapshot' ...) and an omnichain-following status string, but other pages in this docs set show the indexing status as value->>'status' with backfill/following (e.g. ensdb/usage/querying.mdx). This inconsistency will confuse readers—please align these examples (or explain the two different formats if both exist).
| AND value -> 'data' -> 'omnichainSnapshot' ->> 'omnichainStatus' = 'omnichain-following'; | |
| AND value->>'status' = 'following'; |
| The `key` column identifies the type of metadata: | ||
|
|
||
| | Key | Description | | ||
| |-----|-------------| | ||
| | `indexing_metadata_context` | [Indexing metadata context](#indexing-metadata-context) of the [ENSIndexer instance](#ensindexer-instance) | | ||
|
|
||
| #### Indexing Metadata Context | ||
|
|
||
| A JSON object that provides context about the ENSNode stack the Indexing Status. It includes: | ||
| - `version`: The version of the Indexing Metadata Context structure | ||
| - `data`: The actual context data, whose structure may evolve over time as the needs of the ENSNode stack evolve. The `data` object may include fields such as: | ||
| - `indexingStatus`: the current Indexing Status of the [ENSIndexer instance](#ensindexer-instance). | ||
| - `ensDbPublicConfig`: the public config of the [ENSDb instance](#ensdb-instance) that this [ENSIndexer instance](#ensindexer-instance) is connected to. | ||
| - `ensIndexerPublicConfig`: the public config of the [ENSIndexer instance](#ensindexer-instance) that this metadata record belongs to. |
There was a problem hiding this comment.
The glossary lists indexing_metadata_context as the only ENSNode metadata key, but the rest of these docs use keys like ensdb_version, ensindexer_public_config, and ensindexer_indexing_status. Please reconcile this section with the keys used elsewhere (either update the list, or explain how indexing_metadata_context relates to those keys).
| The `key` column identifies the type of metadata: | |
| | Key | Description | | |
| |-----|-------------| | |
| | `indexing_metadata_context` | [Indexing metadata context](#indexing-metadata-context) of the [ENSIndexer instance](#ensindexer-instance) | | |
| #### Indexing Metadata Context | |
| A JSON object that provides context about the ENSNode stack the Indexing Status. It includes: | |
| - `version`: The version of the Indexing Metadata Context structure | |
| - `data`: The actual context data, whose structure may evolve over time as the needs of the ENSNode stack evolve. The `data` object may include fields such as: | |
| - `indexingStatus`: the current Indexing Status of the [ENSIndexer instance](#ensindexer-instance). | |
| - `ensDbPublicConfig`: the public config of the [ENSDb instance](#ensdb-instance) that this [ENSIndexer instance](#ensindexer-instance) is connected to. | |
| - `ensIndexerPublicConfig`: the public config of the [ENSIndexer instance](#ensindexer-instance) that this metadata record belongs to. | |
| The `key` column identifies the type of metadata record stored in the table. In the current model documented here, the metadata is stored under a single top-level key: | |
| | Key | Description | | |
| |-----|-------------| | |
| | `indexing_metadata_context` | [Indexing metadata context](#indexing-metadata-context) of the [ENSIndexer instance](#ensindexer-instance) | | |
| Other names used elsewhere in the documentation, such as `ensdb_version`, `ensindexer_public_config`, and `ensindexer_indexing_status`, should be understood as versioned fields or logical sections within the JSON `value` of this metadata record, rather than additional values of the `key` column. | |
| #### Indexing Metadata Context | |
| A JSON object that provides context about the ENSNode stack and the Indexing Status. It includes: | |
| - `version`: The version of the Indexing Metadata Context structure | |
| - `data`: The actual context data, whose structure may evolve over time as the needs of the ENSNode stack evolve. The `data` object may include fields such as: | |
| - `indexingStatus`: the current Indexing Status of the [ENSIndexer instance](#ensindexer-instance). Elsewhere this may be referred to as `ensindexer_indexing_status`. | |
| - `ensDbPublicConfig`: the public config of the [ENSDb instance](#ensdb-instance) that this [ENSIndexer instance](#ensindexer-instance) is connected to. Elsewhere this may be referred to as `ensdb_public_config`, with version information represented by values such as `ensdb_version`. | |
| - `ensIndexerPublicConfig`: the public config of the [ENSIndexer instance](#ensindexer-instance) that this metadata record belongs to. Elsewhere this may be referred to as `ensindexer_public_config`. |
| FROM ensindexer_mainnet.events e | ||
| JOIN ensindexer_mainnet.domain_events de ON e.id = de.event_id | ||
| JOIN ensindexer_mainnet.v1_domains d ON de.domain_id = d.id | ||
| WHERE e.selector = '\x0x...' -- NewOwner event |
There was a problem hiding this comment.
In this SQL example, the bytea literal \x prefix is written as \x0x..., which isn’t valid PostgreSQL input syntax (it will be interpreted as hex starting with 0x...). Use a proper \x... hex string (or show the selector as a normal 0x... string if it’s not meant to be a bytea literal).
| WHERE e.selector = '\x0x...' -- NewOwner event | |
| WHERE e.selector = '\x...' -- NewOwner event |
| Reader["Reader<br/>(API)"] | ||
| end | ||
|
|
||
| ENSDb["ENSDb<br/>(SQLite)"] |
There was a problem hiding this comment.
This architecture diagram labels ENSDb as “SQLite”, but elsewhere (and in the ENSDb definition) ENSDb is explicitly a PostgreSQL database. Using SQLite here is misleading; update the diagram to “PostgreSQL” (or clarify that this pattern is not applicable to ENSDb).
| ENSDb["ENSDb<br/>(SQLite)"] | |
| ENSDb["ENSDb<br/>(PostgreSQL)"] |
|
|
||
| <LinkCard | ||
| title="ENSDb SDK" | ||
| description="TypeScript utilities for typing-safe ENSDb access" |
There was a problem hiding this comment.
Typo in link card description: “typing-safe” should be “type-safe”.
| description="TypeScript utilities for typing-safe ENSDb access" | |
| description="TypeScript utilities for type-safe ENSDb access" |
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (1)
docs/ensnode.io/src/content/docs/ensdb/index.mdx (1)
207-222:⚠️ Potential issue | 🟠 Major
EnsDbReaderconstructor signature doesn't match the actual SDK API.Per
packages/ensdb-sdk/src/client/ensdb-reader.ts, the constructor isnew EnsDbReader(config: EnsDbConfig, abstractEnsIndexerSchema)— it takes two objects ({ connectionString }and an abstract schema), not two bare strings. Users copying this snippet will get type errors. The JSDoc@examplein the SDK source is the authoritative shape.Also,
ensDbReader.ensIndexerSchema.v1Domainshould bev1_domainsto match the schema member used in the SQL examples on line 193 (this was flagged previously and is still present).🛠️ Proposed fix
import { EnsDbReader } from '@ensnode/ensdb-sdk'; +import { EnsIndexerSchema } from '@ensnode/ensdb-sdk/ensindexer-abstract'; // Connect to a specific ENSDb instance by providing its connection string and // the ENSIndexer Schema Name you want to query -const ensDbReader = new EnsDbReader(ensDbConnectionString, ensIndexerSchemaName); +const ensDbReader = new EnsDbReader( + { connectionString: ensDbConnectionString }, + { schemaName: ensIndexerSchemaName }, +); -// Get domains from the ENSIndexer Schema -const v1Domains = await - ensDbReader.ensDb.select() - .from(ensDbReader.ensIndexerSchema.v1Domain) - .limit(10); +// Get domains from the ENSIndexer Schema +const v1Domains = await ensDbReader.ensDb + .select() + .from(ensDbReader.ensIndexerSchema.v1_domains) + .limit(10); // Get indexing status -const indexingStatus = await ensDbReader.getIndexingStatusSnapshot() +const indexingStatus = await ensDbReader.getIndexingStatusSnapshot();#!/bin/bash # Confirm the actual EnsDbReader constructor signature and the schema member name used by EnsIndexer's abstract schema. fd -t f 'ensdb-reader.ts' | xargs -I{} sh -c 'echo "=== {} ==="; sed -n "1,160p" "{}"' echo "---- searching schema member names ----" rg -nP '\b(v1_domains|v1Domain)\b' --type=ts -C1🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/ensnode.io/src/content/docs/ensdb/index.mdx` around lines 207 - 222, The example uses the wrong EnsDbReader signature and schema member names: replace the two-string constructor call with the correct objects (pass an EnsDbConfig-like object, e.g., { connectionString: ... }, as the first argument and the abstractEnsIndexerSchema as the second) and update any schema access from ensDbReader.ensIndexerSchema.v1Domain to ensDbReader.ensIndexerSchema.v1_domains so it matches the actual SDK symbols (refer to EnsDbReader, EnsDbConfig, and abstractEnsIndexerSchema in packages/ensdb-sdk/src/client/ensdb-reader.ts).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.letta/settings.json:
- Line 11: Remove or restrict the overly broad permission rule
"Edit(//Users/tko/dev/github/namehash/**)"; either delete this entry entirely or
replace it with a scoped pattern that only allows edits to the intended
documentation directories (e.g., specific doc paths already listed) so the rule
no longer grants write access to the entire namehash tree.
- Around line 4-6: The three Bash(...) entries containing absolute user-specific
paths should be changed to relative paths or project-root variables so they work
on any machine; update the Bash strings (e.g., the entries starting with
"Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/...") to use relative
equivalents like "Bash(mkdir -p
./docs/ensnode.io/src/content/docs/ensdb/concepts)" or use a
placeholder/project-root variable (e.g., ${PROJECT_ROOT}) consistently for each
of the three lines so they no longer reference a specific home directory.
In @.letta/settings.local.json:
- Around line 1-13: This file (.letta/settings.local.json) contains local user
session state ("lastAgent", "sessionsByServer", "lastSession") and must not be
committed; remove it from version control with git rm --cached
.letta/settings.local.json, add the pattern .letta/settings.local.json (or
.letta/) to .gitignore so it is ignored going forward, and optionally add a
template like .letta/settings.local.json.example containing placeholder keys
("lastAgent", "sessionsByServer", "lastSession") to document the schema for
other developers.
In `@docs/ensnode.io/src/content/docs/ensdb/index.mdx`:
- Around line 95-110: The prose under "Example: Multi-Instance Server" and the
Mermaid diagram use inconsistent environment names (e.g., "sepolia"/"ENSDb
Sepolia instance" and "ens-test-env"/"ENSDb ENS Test Env instance") versus the
Quick Start variable names (`ensdb_mainnet`, `ensdb_testnet`, `ensdb_devnet`);
pick one naming convention (for example: mainnet/sepolia/devnet or
mainnet/testnet/devnet) and make them consistent by updating the paragraph text,
the Mermaid node labels (e.g., change "ENSDb Sepolia instance" and "ENSDb ENS
Test Env instance"), and any Quick Start references (`ensdb_mainnet`,
`ensdb_testnet`, `ensdb_devnet`) so the same names appear everywhere. Ensure the
chosen names are applied to the heading "Example: Multi-Instance Server", the
bulleted examples, and the Mermaid nodes so readers can unambiguously map each
environment to its database instance.
- Line 165: The sentence contains a stray word "you" ("assume you that ENSDb
instances are served") which breaks grammar; remove "you" and change the phrase
to "assume that ENSDb instances are served" so the sentence reads cleanly and
grammatically correct in the ENSDb docs example.
---
Duplicate comments:
In `@docs/ensnode.io/src/content/docs/ensdb/index.mdx`:
- Around line 207-222: The example uses the wrong EnsDbReader signature and
schema member names: replace the two-string constructor call with the correct
objects (pass an EnsDbConfig-like object, e.g., { connectionString: ... }, as
the first argument and the abstractEnsIndexerSchema as the second) and update
any schema access from ensDbReader.ensIndexerSchema.v1Domain to
ensDbReader.ensIndexerSchema.v1_domains so it matches the actual SDK symbols
(refer to EnsDbReader, EnsDbConfig, and abstractEnsIndexerSchema in
packages/ensdb-sdk/src/client/ensdb-reader.ts).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8e7c0404-9c96-4c9d-9365-6e9a52492543
📒 Files selected for processing (4)
.letta/.lettaignore.letta/settings.json.letta/settings.local.jsondocs/ensnode.io/src/content/docs/ensdb/index.mdx
| "Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/docs/ensnode.io/src/content/docs/ensdb/concepts)", | ||
| "Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/docs/ensnode.io/src/content/docs/ensdb/usage)", | ||
| "Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/docs/ensnode.io/src/content/docs/ensdb/usage/sdk)", |
There was a problem hiding this comment.
Replace hardcoded absolute paths with relative paths.
The absolute paths /Users/tko/dev/github/namehash/ensnode/... are specific to your local machine and username. They will fail for other contributors with different usernames or directory structures.
♻️ Proposed fix using relative paths
- "Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/docs/ensnode.io/src/content/docs/ensdb/concepts)",
- "Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/docs/ensnode.io/src/content/docs/ensdb/usage)",
- "Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/docs/ensnode.io/src/content/docs/ensdb/usage/sdk)",
+ "Bash(mkdir -p docs/ensnode.io/src/content/docs/ensdb/concepts)",
+ "Bash(mkdir -p docs/ensnode.io/src/content/docs/ensdb/usage)",
+ "Bash(mkdir -p docs/ensnode.io/src/content/docs/ensdb/usage/sdk)",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/docs/ensnode.io/src/content/docs/ensdb/concepts)", | |
| "Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/docs/ensnode.io/src/content/docs/ensdb/usage)", | |
| "Bash(mkdir -p /Users/tko/dev/github/namehash/ensnode/docs/ensnode.io/src/content/docs/ensdb/usage/sdk)", | |
| "Bash(mkdir -p docs/ensnode.io/src/content/docs/ensdb/concepts)", | |
| "Bash(mkdir -p docs/ensnode.io/src/content/docs/ensdb/usage)", | |
| "Bash(mkdir -p docs/ensnode.io/src/content/docs/ensdb/usage/sdk)", |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.letta/settings.json around lines 4 - 6, The three Bash(...) entries
containing absolute user-specific paths should be changed to relative paths or
project-root variables so they work on any machine; update the Bash strings
(e.g., the entries starting with "Bash(mkdir -p
/Users/tko/dev/github/namehash/ensnode/...") to use relative equivalents like
"Bash(mkdir -p ./docs/ensnode.io/src/content/docs/ensdb/concepts)" or use a
placeholder/project-root variable (e.g., ${PROJECT_ROOT}) consistently for each
of the three lines so they no longer reference a specific home directory.
| "Edit(docs/ensnode.io/src/content/docs/ensdb/**)", | ||
| "Edit(docs/ensdb/concepts/**)", | ||
| "Edit(docs/ensdb/usage/sdk/**)", | ||
| "Edit(//Users/tko/dev/github/namehash/**)" |
There was a problem hiding this comment.
Remove overly permissive edit rule.
The pattern Edit(//Users/tko/dev/github/namehash/**) grants permission to edit any file under the entire namehash directory tree, far beyond the scope of this PR's documentation changes. This violates the principle of least privilege and poses a security risk.
🛡️ Recommended fix
If you need broader edit permissions beyond the specific paths already listed (lines 7-10), scope them to only the documentation directories:
- "Edit(//Users/tko/dev/github/namehash/**)"
+ "Edit(docs/**)"Or remove this line entirely if the specific paths on lines 7-10 are sufficient.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "Edit(//Users/tko/dev/github/namehash/**)" | |
| "Edit(docs/**)" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.letta/settings.json at line 11, Remove or restrict the overly broad
permission rule "Edit(//Users/tko/dev/github/namehash/**)"; either delete this
entry entirely or replace it with a scoped pattern that only allows edits to the
intended documentation directories (e.g., specific doc paths already listed) so
the rule no longer grants write access to the entire namehash tree.
| { | ||
| "lastAgent": "agent-8f1fd90c-1e78-4f11-8a13-d909be3d330b", | ||
| "sessionsByServer": { | ||
| "api.letta.com": { | ||
| "agentId": "agent-8f1fd90c-1e78-4f11-8a13-d909be3d330b", | ||
| "conversationId": "default" | ||
| } | ||
| }, | ||
| "lastSession": { | ||
| "agentId": "agent-8f1fd90c-1e78-4f11-8a13-d909be3d330b", | ||
| "conversationId": "default" | ||
| } | ||
| } |
There was a problem hiding this comment.
Do not commit local state files; add to .gitignore.
This file contains user-specific session state (agent IDs, conversation IDs) that is local to your development environment. Committing it to version control will:
- Cause merge conflicts when other developers' local state differs
- Leak environment-specific runtime state that has no meaning for other contributors
- Override other users' local configuration when they pull changes
🔧 Recommended fix
- Remove this file from version control:
git rm --cached .letta/settings.local.json- Add the pattern to
.gitignore:
+# Letta local state
+.letta/settings.local.json- Optionally, create a
.letta/settings.local.json.exampletemplate file with placeholder values to document the expected schema for other developers.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.letta/settings.local.json around lines 1 - 13, This file
(.letta/settings.local.json) contains local user session state ("lastAgent",
"sessionsByServer", "lastSession") and must not be committed; remove it from
version control with git rm --cached .letta/settings.local.json, add the pattern
.letta/settings.local.json (or .letta/) to .gitignore so it is ignored going
forward, and optionally add a template like .letta/settings.local.json.example
containing placeholder keys ("lastAgent", "sessionsByServer", "lastSession") to
document the schema for other developers.
| ### Example: Multi-Instance Server | ||
|
|
||
| A single PostgreSQL server can serve multiple ENSDb instances for different ENS Namespaces. This allows you to have separate ENSDb instances based on your needs. For example: | ||
| - Your production environment can have a dedicated ENSDb instance for ENS data from the ENS Namespace "mainnet". | ||
| - Your staging environment can have a separate ENSDb instance for ENS data from the ENS Namespace "sepolia". | ||
| - Your local development environment can have its own ENSDb instance for testing with local or ephemeral data from the ENS Namespace "ens-test-env". | ||
|
|
||
| ```mermaid | ||
| flowchart TB | ||
| subgraph PGServer["PostgreSQL Server"] | ||
| direction TB | ||
| Mainnet[(ENSDb Mainnet instance)] | ||
| Testnet[(ENSDb Sepolia instance)] | ||
| Devnet[(ENSDb ENS Test Env instance)] | ||
| end | ||
| ``` |
There was a problem hiding this comment.
Diagram/prose inconsistency: "sepolia" vs. "Testnet" vs. ensdb_testnet.
Lines 97–100 describe three environments keyed by ENS namespace (mainnet, sepolia, ens-test-env), but the diagram below labels the middle instance ENSDb Sepolia instance and the last ENSDb ENS Test Env instance, while the Quick Start block (L169–175) uses ensdb_mainnet/ensdb_testnet/ensdb_devnet. Consider aligning these names (e.g., pick either sepolia/ens-test-env or testnet/devnet consistently) so readers aren't confused about which database corresponds to which environment.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ensnode.io/src/content/docs/ensdb/index.mdx` around lines 95 - 110, The
prose under "Example: Multi-Instance Server" and the Mermaid diagram use
inconsistent environment names (e.g., "sepolia"/"ENSDb Sepolia instance" and
"ens-test-env"/"ENSDb ENS Test Env instance") versus the Quick Start variable
names (`ensdb_mainnet`, `ensdb_testnet`, `ensdb_devnet`); pick one naming
convention (for example: mainnet/sepolia/devnet or mainnet/testnet/devnet) and
make them consistent by updating the paragraph text, the Mermaid node labels
(e.g., change "ENSDb Sepolia instance" and "ENSDb ENS Test Env instance"), and
any Quick Start references (`ensdb_mainnet`, `ensdb_testnet`, `ensdb_devnet`) so
the same names appear everywhere. Ensure the chosen names are applied to the
heading "Example: Multi-Instance Server", the bulleted examples, and the Mermaid
nodes so readers can unambiguously map each environment to its database
instance.
|
|
||
| ### Ponder Schema | ||
|
|
||
| A [database schema](#database-schema) in the [ENSDb instance](#ensdb-instance) following the [Ponder Schema Definition](#ponder-schema-definition). It has a fixed `ponder_sync` name, and it serves as a shared RPC cache for all [ENSIndexer instances](#ensindexer-instance) connected to the [ENSDb instance](#ensdb-instance). It's lifecycle is managed by Ponder runtime. |
|
|
||
| #### Ponder Schema Definition | ||
|
|
||
| A [Schema Definition](#schema-definition) that defines the structure of the [Ponder Schema](#ponder-schema) in the [ENSDb instance](#ensdb-instance). This Schema Definition is an implementation detail of Ponder, so we treat is as an opaque black box in ENSDb documentation. |
| const v1Domains = await | ||
| ensDbReader.ensDb.select() |
| SELECT * FROM "ensnode"."metadata" | ||
| WHERE ens_indexer_schema_name = 'ensindexer_mainnet' | ||
| AND key = 'ensindexer_indexing_status' | ||
| AND value -> 'data' -> 'omnichainSnapshot' ->> 'omnichainStatus' = 'omnichain-following'; |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const ensDbReader = new EnsDbReader(ensDbConnectionString, ensIndexerSchemaName); | ||
|
|
||
| // Get domains from the ENSIndexer Schema | ||
| const v1Domains = await | ||
| ensDbReader.ensDb.select() | ||
| .from(ensDbReader.ensIndexerSchema.v1Domain) | ||
| .limit(10); | ||
|
|
||
| // Get indexing status | ||
| const indexingStatus = await ensDbReader.getIndexingStatusSnapshot() |
There was a problem hiding this comment.
The TypeScript example as written won’t parse/copy-paste cleanly (line break after await, inconsistent indentation, missing semicolon at the end). Consider formatting this snippet as valid TypeScript so users can run it directly.
| const ensDbReader = new EnsDbReader(ensDbConnectionString, ensIndexerSchemaName); | |
| // Get domains from the ENSIndexer Schema | |
| const v1Domains = await | |
| ensDbReader.ensDb.select() | |
| .from(ensDbReader.ensIndexerSchema.v1Domain) | |
| .limit(10); | |
| // Get indexing status | |
| const indexingStatus = await ensDbReader.getIndexingStatusSnapshot() | |
| const ensDbReader = new EnsDbReader(ensDbConnectionString, ensIndexerSchemaName); | |
| // Get domains from the ENSIndexer Schema | |
| const v1Domains = await ensDbReader.ensDb | |
| .select() | |
| .from(ensDbReader.ensIndexerSchema.v1Domain) | |
| .limit(10); | |
| // Get indexing status | |
| const indexingStatus = await ensDbReader.getIndexingStatusSnapshot(); |
|
|
||
| ### Connect with Any PostgreSQL Client | ||
|
|
||
| Connect to an ENSDb instance (a PostgreSQL database). The examples below assume you that ENSDb instances are served from a PostgreSQL server at `host:5432` with databases named `ensdb_mainnet`, `ensdb_testnet`, and `ensdb_devnet`: |
There was a problem hiding this comment.
Grammar: “assume you that” reads incorrectly. Consider changing to “assume that” (or rephrasing the sentence).
| Connect to an ENSDb instance (a PostgreSQL database). The examples below assume you that ENSDb instances are served from a PostgreSQL server at `host:5432` with databases named `ensdb_mainnet`, `ensdb_testnet`, and `ensdb_devnet`: | |
| Connect to an ENSDb instance (a PostgreSQL database). The examples below assume that ENSDb instances are served from a PostgreSQL server at `host:5432` with databases named `ensdb_mainnet`, `ensdb_testnet`, and `ensdb_devnet`: |
| SELECT * FROM "ensnode"."metadata" | ||
| WHERE ens_indexer_schema_name = 'ensindexer_mainnet' | ||
| AND key = 'ensindexer_indexing_status' | ||
| AND value -> 'data' -> 'omnichainSnapshot' ->> 'omnichainStatus' = 'omnichain-following'; |
There was a problem hiding this comment.
The JSON path in this SQL example doesn’t match the serialized shape used by the SDK for ensindexer_indexing_status (it’s not wrapped under data). Based on serializeCrossChainIndexingStatusSnapshot, omnichainStatus lives under value -> 'omnichainSnapshot' ->> 'omnichainStatus'. Updating the query will prevent users from copying an example that returns no rows.
| AND value -> 'data' -> 'omnichainSnapshot' ->> 'omnichainStatus' = 'omnichain-following'; | |
| AND value -> 'omnichainSnapshot' ->> 'omnichainStatus' = 'omnichain-following'; |
| - All [ENSIndexer instances](#ensindexer-instance) share the [Ponder Schema](#ponder-schema), including the RPC cache. | ||
| - Metadata of all [ENSIndexer instances](#ensindexer-instance) is tracked in the [ENSNode Schema](#ensnode-schema) | ||
|
|
||
| This enables separate indexing by multiple [ENSIndexer instance](#ensindexer-instance) with different configs. The configs may require indexing just certain chains. For example, one [ENSIndexer instance](#ensindexer-instance) is configured to index data just from the Ethereum Mainnet, while another [ENSIndexer instance](#ensindexer-instance) is configured to index data from both, Ethereum Mainnet, and Base Mainnet. Each of these [ENSIndexer instances](#ensindexer-instance) would have its own [ENSIndexer Schema](#ensindexer-schema) in the same [ENSDb instance](#ensdb-instance). |
There was a problem hiding this comment.
Grammar: “multiple ENSIndexer instance” should be plural (“instances”).
| This enables separate indexing by multiple [ENSIndexer instance](#ensindexer-instance) with different configs. The configs may require indexing just certain chains. For example, one [ENSIndexer instance](#ensindexer-instance) is configured to index data just from the Ethereum Mainnet, while another [ENSIndexer instance](#ensindexer-instance) is configured to index data from both, Ethereum Mainnet, and Base Mainnet. Each of these [ENSIndexer instances](#ensindexer-instance) would have its own [ENSIndexer Schema](#ensindexer-schema) in the same [ENSDb instance](#ensdb-instance). | |
| This enables separate indexing by multiple [ENSIndexer instances](#ensindexer-instance) with different configs. The configs may require indexing just certain chains. For example, one [ENSIndexer instance](#ensindexer-instance) is configured to index data just from the Ethereum Mainnet, while another [ENSIndexer instance](#ensindexer-instance) is configured to index data from both, Ethereum Mainnet, and Base Mainnet. Each of these [ENSIndexer instances](#ensindexer-instance) would have its own [ENSIndexer Schema](#ensindexer-schema) in the same [ENSDb instance](#ensdb-instance). |
| | `indexing_metadata_context` | [Indexing metadata context](#indexing-metadata-context) of the [ENSIndexer instance](#ensindexer-instance) | | ||
|
|
||
| #### Indexing Metadata Context | ||
|
|
||
| A JSON object that provides context about the ENSNode stack the Indexing Status. It includes: | ||
| - `version`: The version of the Indexing Metadata Context structure | ||
| - `data`: The actual context data, whose structure may evolve over time as the needs of the ENSNode stack evolve. The `data` object may include fields such as: | ||
| - `indexingStatus`: the current Indexing Status of the [ENSIndexer instance](#ensindexer-instance). | ||
| - `ensDbPublicConfig`: the public config of the [ENSDb instance](#ensdb-instance) that this [ENSIndexer instance](#ensindexer-instance) is connected to. | ||
| - `ensIndexerPublicConfig`: the public config of the [ENSIndexer instance](#ensindexer-instance) that this metadata record belongs to. | ||
| - `ensRainbowPublicConfig`: the public config of the ENSRainbow instance that this [ENSIndexer instance](#ensindexer-instance) is connected to. Might be `null` during the ENSNode stack cold start, when the ENSIndexer instance starts before the ENSRainbow instance. | ||
|
|
There was a problem hiding this comment.
The metadata key list here doesn’t match the keys used by the ENSDb SDK (ensdb_version, ensindexer_public_config, ensindexer_indexing_status). Using a different key name (indexing_metadata_context) will mislead readers and conflicts with the SQL example in /ensdb/usage/sql.
| | `indexing_metadata_context` | [Indexing metadata context](#indexing-metadata-context) of the [ENSIndexer instance](#ensindexer-instance) | | |
| #### Indexing Metadata Context | |
| A JSON object that provides context about the ENSNode stack the Indexing Status. It includes: | |
| - `version`: The version of the Indexing Metadata Context structure | |
| - `data`: The actual context data, whose structure may evolve over time as the needs of the ENSNode stack evolve. The `data` object may include fields such as: | |
| - `indexingStatus`: the current Indexing Status of the [ENSIndexer instance](#ensindexer-instance). | |
| - `ensDbPublicConfig`: the public config of the [ENSDb instance](#ensdb-instance) that this [ENSIndexer instance](#ensindexer-instance) is connected to. | |
| - `ensIndexerPublicConfig`: the public config of the [ENSIndexer instance](#ensindexer-instance) that this metadata record belongs to. | |
| - `ensRainbowPublicConfig`: the public config of the ENSRainbow instance that this [ENSIndexer instance](#ensindexer-instance) is connected to. Might be `null` during the ENSNode stack cold start, when the ENSIndexer instance starts before the ENSRainbow instance. | |
| | `ensdb_version` | Version metadata for the connected [ENSDb instance](#ensdb-instance) | | |
| | `ensindexer_public_config` | Public configuration metadata for the [ENSIndexer instance](#ensindexer-instance) | | |
| | `ensindexer_indexing_status` | Current indexing status metadata for the [ENSIndexer instance](#ensindexer-instance) | | |
| #### ENSDb Version | |
| A JSON object describing the version information for the connected [ENSDb instance](#ensdb-instance). As with other metadata records, the object is versioned and includes a top-level `version` field so its structure can evolve safely over time. | |
| #### ENSIndexer Public Config | |
| A JSON object containing the public configuration of the [ENSIndexer instance](#ensindexer-instance) that owns the metadata record. The object is versioned and includes a top-level `version` field. | |
| #### ENSIndexer Indexing Status | |
| A JSON object containing the current indexing status of the [ENSIndexer instance](#ensindexer-instance). The object is versioned and includes a top-level `version` field. |
| #starlight__sidebar>div>ul>li:not(:first-child):not(:last-child)::before { | ||
| content: ""; | ||
| position: absolute; | ||
| left: 8px; /* X-position of the vertical line */ | ||
| left: 8px; | ||
| /* X-position of the vertical line */ | ||
| top: 0; |
There was a problem hiding this comment.
The same selector #starlight__sidebar>div>ul>li:not(:first-child):not(:last-child)::before is defined twice (here and again a few lines below) just to override height. Consider merging into a single rule to avoid duplication and make future edits less error-prone.
| title: ENSNode Reference Implementation | ||
| description: Overview of ENSNode, the reference implementation of the ENSDb standard, including its components and architecture. | ||
| sidebar: | ||
| label: ENSNode Reference Implementation |
There was a problem hiding this comment.
Frontmatter label has an extra leading space, which will likely show up in the rendered sidebar label.
| label: ENSNode Reference Implementation | |
| label: ENSNode Reference Implementation |
| Primary key: (`ens_indexer_schema_name`, `key`) | ||
|
|
||
| The `value` column stores a JSON object which structure may evolve over time. To track this, the JSON object is guaranteed to always include a `version` field indicating the version of the structure. This allows for future-proofing as the metadata needs evolve. | ||
|
|
There was a problem hiding this comment.
This claims the value column always stores a JSON object with a guaranteed version field. In the current SDK, ensdb_version is stored as a JSON string, and other records (e.g. indexing status snapshot) serialize without a {version, data} wrapper. Consider revising this to describe the actual per-key value shapes rather than guaranteeing an object with version.
Lite PR
Tip: Review docs on the ENSNode PR process
Summary
Why
Testing
Notes for Reviewer (Optional)
Pre-Review Checklist (Blocking)