Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tasty-pigs-shine.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ensnode/ensdb-sdk": minor
---

Introduced toolkit for managing ENSDb migrations for ENSNode Schema.
Comment thread
tk-o marked this conversation as resolved.
52 changes: 51 additions & 1 deletion packages/ensdb-sdk/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
# ENSDb SDK

This package is a utility library for interacting with ENSDb.
This package defines the database schema used by ENSDb.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

?? We spoke about how this package has the responsibility to hold more than database schemas but also to hold a growing set of utility functions.

Additionally, it's wrong to write "defines the database schema used by ENSDb.":

  1. You wrote "schema" singular. It should be plural.
  2. It's not "used by" ENSDb. That's communicating the wrong idea. These are the schemas that form an ENSDb instance. ENSDb doesn't use anything.


It exposes two schema modules because `ENSIndexer` needs two different kinds of tables:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

?? what is a "schema module".

Suggested change
It exposes two schema modules because `ENSIndexer` needs two different kinds of tables:
It exposes two schemas because `ENSIndexer` needs two different kinds of tables:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

?? Why are we talking about ENSIndexer here? You do understand that multiple services interface with ENSDb, right? Not just ENSIndexer? Why are you writing this as if only ENSIndexer uses it?

Suggested change
It exposes two schema modules because `ENSIndexer` needs two different kinds of tables:
Each ENSDb instance is formed from the following schemas:


- ENSIndexer Schema for indexing onchain data
- ENSNode Schema for indexing offchain data

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why are you using the word "indexing" here? In my mind, not all data stored in a database represents "indexing". The metadata stored about ENSNode services doesn't qualify as "indexing" in my mind.

Additionally, why are we not referencing how we are also storing metadata about ENSNode services using the ENSDb?


## ENSIndexer Schema

Source: `packages/ensdb-sdk/src/ensindexer`

This database schema is required by the Ponder app that powers `ENSIndexer`.

Ponder requires `ponder.schema.ts` to follow specific rules: `https://ponder.sh/docs/api-reference/ponder/schema#file-requirements`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider formatting the URL as a markdown link.

The Ponder documentation URL is currently plain text. Formatting it as a proper markdown link would improve readability and make it clickable for users.

🔗 Proposed formatting improvement
-Ponder requires `ponder.schema.ts` to follow specific rules: `https://ponder.sh/docs/api-reference/ponder/schema#file-requirements`.
+Ponder requires `ponder.schema.ts` to follow [specific rules](https://ponder.sh/docs/api-reference/ponder/schema#file-requirements).
📝 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.

Suggested change
Ponder requires `ponder.schema.ts` to follow specific rules: `https://ponder.sh/docs/api-reference/ponder/schema#file-requirements`.
Ponder requires `ponder.schema.ts` to follow [specific rules](https://ponder.sh/docs/api-reference/ponder/schema#file-requirements).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensdb-sdk/README.md` at line 16, The README currently shows the
Ponder documentation URL as plain text; update that sentence so the URL is a
proper Markdown link (for example replace
"https://ponder.sh/docs/api-reference/ponder/schema#file-requirements" with a
labeled link like "[Ponder schema file
requirements](https://ponder.sh/docs/api-reference/ponder/schema#file-requirements)"),
preserving the referenced code token `ponder.schema.ts` in backticks and
ensuring the link text clearly indicates it points to the Ponder schema file
requirements.


The most important rule here is that tables must be defined with `onchainTable()`, not with Drizzle's `pgSchema(schemaName).table()`.

Both APIs produce Drizzle table objects, but there is one important difference: `onchainTable()` does not hardcode the Postgres schema name up front. Ponder chooses the schema name dynamically from its configuration.

Ponder is also responsible for initializing and migrating the ENSIndexer Schema. It reads this schema through `apps/ensindexer/ponder/ponder.schema.ts`, which re-exports `packages/ensdb-sdk/src/ensindexer`.

### When it changes

Update files in `src/ensindexer`, then start `ENSIndexer`. Ponder handles the rest.

## ENSNode Schema

Source: `packages/ensdb-sdk/src/ensnode`

This schema is also required by `ENSIndexer`, but for offchain data rather than onchain data.

It uses Drizzle's Postgres schema APIs such as `pgSchema("ensnode").table()`. Unlike the ENSIndexer Schema, the database schema name is fixed up front as `ensnode`.

### When it changes

You must generate migration files:

```bash
pnpm -F @ensnode/ensdb-sdk drizzle-kit:generate
```

This updates `packages/ensdb-sdk/migrations`. `ENSIndexer` currently takes responsibility for applying those migrations and initializing the ENSNode Schema.

## Rule of thumb

- `onchainTable()` + schema name chosen by Ponder = ENSIndexer Schema
- `pgSchema().table()` + fixed schema name + generated migrations = ENSNode Schema

## Current transition

`packages/ensdb-sdk/src/ensindexer/index.ts` still re-exports `ensnode-metadata.schema.ts` as a temporary bridge until ENSNode Schema migrations are fully in place.
10 changes: 10 additions & 0 deletions packages/ensdb-sdk/drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from "drizzle-kit";

const ensNodeSchemaPath = "./src/ensnode/index.ts";

export default defineConfig({
casing: "snake_case",
dialect: "postgresql",
out: "migrations",
schema: ensNodeSchemaPath,
Comment thread
tk-o marked this conversation as resolved.
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE SCHEMA IF NOT EXISTS ensnode;

CREATE TABLE "ensnode"."metadata" (
"ens_indexer_schema_name" text NOT NULL,
"key" text NOT NULL,
"value" jsonb NOT NULL,
CONSTRAINT "metadata_pkey" PRIMARY KEY("ens_indexer_schema_name","key")
);
55 changes: 55 additions & 0 deletions packages/ensdb-sdk/migrations/meta/0000_snapshot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"id": "d661dcae-f64d-4ecd-a4da-3d5783e17e2c",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",
"tables": {
"ensnode.metadata": {
"name": "metadata",
"schema": "ensnode",
"columns": {
"ens_indexer_schema_name": {
"name": "ens_indexer_schema_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"key": {
"name": "key",
"type": "text",
"primaryKey": false,
"notNull": true
},
"value": {
"name": "value",
"type": "jsonb",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"metadata_pkey": {
"name": "metadata_pkey",
"columns": ["ens_indexer_schema_name", "key"]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
13 changes: 13 additions & 0 deletions packages/ensdb-sdk/migrations/meta/_journal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "postgresql",
"entries": [
{
"idx": 0,
"version": "7",
"when": 1773743108514,
"tag": "0000_cultured_captain_cross",
"breakpoints": true
}
]
}
8 changes: 6 additions & 2 deletions packages/ensdb-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
"./ensnode": "./src/ensnode/index.ts"
},
"files": [
"dist"
"dist",
"migrations",
"migrations/meta"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

likely not necessary to re-specify the /meta subpath

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Nice catch, will update this 👍

],
"publishConfig": {
"access": "public",
Expand Down Expand Up @@ -52,7 +54,8 @@
"scripts": {
"prepublish": "tsup",
"lint": "biome check --write .",
"lint:ci": "biome ci"
"lint:ci": "biome ci",
"drizzle-kit:generate": "drizzle-kit generate"
},
Comment thread
tk-o marked this conversation as resolved.
"peerDependencies": {
"drizzle-orm": "catalog:",
Expand All @@ -62,6 +65,7 @@
"devDependencies": {
"@ensnode/ensnode-sdk": "workspace:",
"@ensnode/shared-configs": "workspace:*",
"drizzle-kit": "0.31.10",
Comment thread
tk-o marked this conversation as resolved.
Comment thread
tk-o marked this conversation as resolved.
Comment thread
tk-o marked this conversation as resolved.
"drizzle-orm": "catalog:",
"ponder": "catalog:",
"tsup": "catalog:",
Expand Down
Loading
Loading