From 82781f3568079ee18e353bcd5d47b39ef58692b0 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Fri, 5 Jun 2026 15:17:58 +0200 Subject: [PATCH 1/7] Apply feedback from Slack and PR 2227 --- .../src/components/molecules/EnsDbReaderIntro.astro | 2 +- docs/ensnode.io/src/content/docs/docs/integrate/index.mdx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/ensnode.io/src/components/molecules/EnsDbReaderIntro.astro b/docs/ensnode.io/src/components/molecules/EnsDbReaderIntro.astro index d1119a101..fa1781b67 100644 --- a/docs/ensnode.io/src/components/molecules/EnsDbReaderIntro.astro +++ b/docs/ensnode.io/src/components/molecules/EnsDbReaderIntro.astro @@ -7,5 +7,5 @@ import { Aside } from "@astrojs/starlight/components"; href="/docs/services/ensdb/concepts/glossary#ensdb-writer-schema" >ensIndexerSchema schema definition in the Connect section if you haven't already. + > in the Connect example if you haven't already. 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 f6b7ad883..6f96a9eb0 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx @@ -155,9 +155,9 @@ The ENS Omnigraph API is a GraphQL API following the Relay specification, so you Beyond [`enssdk`](/docs/integrate/integration-options/enssdk), [`enskit`](/docs/integrate/integration-options/enskit), and the [Omnigraph GraphQL API](/docs/integrate/integration-options/omnigraph-graphql-api), ENSNode exposes a deeper set of integration surfaces for advanced use cases: - **[ENSDb (SQL)](/docs/integrate/integration-options/ensdb)** — query the indexed ENSv1 and ENSv2 datasets directly via SQL for custom analytics or your own service layer, from any language with a Postgres driver. -- **[ENSDb Writers (Indexers)](/docs/integrate/integration-options/ensdb-writers)** — build your own ENSDb Writer to index ENS data into your own ENSDb instance. -- **[ENSDb Readers](/docs/integrate/integration-options/ensdb-readers)** — build your own ENSDb Reader to query your own ENSDb instance through any interface of your choice. -- **[ENSNode Plugins](/docs/integrate/integration-options/ensnode-plugins)** — define how onchain data should be indexed into ENSDb. +- **[ENSDb Writers (Indexers)](/docs/integrate/integration-options/ensdb-writers)** — enable all other layers of the ENSNode stack to build on your custom indexing engine. +- **[ENSDb Readers (Custom APIs)](/docs/integrate/integration-options/ensdb-readers)** — build your own custom APIs and services on top of ENSDb using any programming language or framework. +- **[ENSNode Plugins (Indexed Data Models)](/docs/integrate/integration-options/ensnode-plugins)** — define how onchain data should be indexed into ENSDb. - **[enscli (CLI)](/docs/integrate/integration-options/enscli)** — resolve names, look up records, and run ad-hoc Omnigraph queries from the terminal — built for humans and AI agents alike. - **[ensskills (AI agents)](/docs/integrate/integration-options/ensskills)** — a curated set of skills that gives AI coding agents a well-defined contract for working with ENS. - **[ensdb-cli (ENSDb Snapshots)](/docs/integrate/integration-options/ensdb-cli)** — bootstrap a fresh ENSDb in minutes from portable, versioned snapshots instead of waiting days on a full historical backfill. From a309cb7c6549f4b3865396019a7e4969c227b3cc Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Fri, 5 Jun 2026 15:18:11 +0200 Subject: [PATCH 2/7] Setup ENS Unigraph exmaple files --- .../starlight/sidebar-topics/integrate.ts | 28 ++- .../unigraph/examples/account-domains.mdx | 32 ++-- .../unigraph/examples/account-permissions.mdx | 55 ++++++ .../unigraph/examples/domain-by-name.mdx | 51 +---- .../unigraph/examples/domain-events.mdx | 72 +++++++ .../examples/domains-fuzzy-search-by-name.mdx | 55 ++++++ .../examples/expiring-registrations.mdx | 55 ++++++ .../unigraph/examples/indexing-status.mdx | 2 +- .../examples/latest-registrations.mdx | 55 ++++++ .../examples/subdomains-by-parent-name.mdx | 25 +++ .../data/unigraph-examples/domain-by-name.ts | 56 ++++++ .../domains-fuzzy-search-by-name.ts | 56 ++++++ .../subdomains-by-parent-name.ts | 175 ++++++++++++++++++ .../src/data/unigraph-examples/types.ts | 9 + 14 files changed, 660 insertions(+), 66 deletions(-) create mode 100644 docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-permissions.mdx create mode 100644 docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-events.mdx create mode 100644 docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domains-fuzzy-search-by-name.mdx create mode 100644 docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/expiring-registrations.mdx create mode 100644 docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/latest-registrations.mdx create mode 100644 docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/subdomains-by-parent-name.mdx create mode 100644 docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts create mode 100644 docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts create mode 100644 docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts create mode 100644 docs/ensnode.io/src/data/unigraph-examples/types.ts 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 18b7500aa..9a40dcf4c 100644 --- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts +++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts @@ -175,17 +175,41 @@ export const integrateSidebarTopic = { collapsed: true, items: [ { - label: "Overview", + label: "Connect", link: "/docs/integrate/unigraph/examples", }, { label: "Domain by Name", link: "/docs/integrate/unigraph/examples/domain-by-name", }, + { + label: "Domain Fuzzy Search", + link: "/docs/integrate/unigraph/examples/domains-fuzzy-search-by-name", + }, + { + label: "Domain Events", + link: "/docs/integrate/unigraph/examples/domain-events", + }, + { + label: "Subdomains", + link: "/docs/integrate/unigraph/examples/subdomains-by-parent-name", + }, { label: "Account Domains", link: "/docs/integrate/unigraph/examples/account-domains", }, + { + label: "Account Permissions", + link: "/docs/integrate/unigraph/examples/account-permissions", + }, + { + label: "Latest Registrations", + link: "/docs/integrate/unigraph/examples/latest-registrations", + }, + { + label: "Exipring Registrations", + link: "/docs/integrate/unigraph/examples/expiring-registrations", + }, { label: "Indexing Status", link: "/docs/integrate/unigraph/examples/indexing-status", @@ -231,7 +255,7 @@ export const integrateSidebarTopic = { link: "/docs/integrate/integration-options/ensdb-readers", }, { - label: "ENSNode Plugins (data models)", + label: "ENSNode Plugins (Data Models)", link: "/docs/integrate/integration-options/ensnode-plugins", }, { diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index c157b6595..aea543fd2 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -20,19 +20,25 @@ export const resultJson = [ } ]; -export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains +export const sqlExample = { + codeSnippet: `SELECT type, count(*) FROM ensindexer_0.domains WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' GROUP BY type; -`; +`, + result: resultJson, +}; -export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; +export const tsExample = { + codeSnippet: `import { count, eq } from "drizzle-orm"; const counts = await ensDb -\t.select({ type: ensIndexerSchema.domain.type, count: count() }) -\t.from(ensIndexerSchema.domain) -\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) -\t.groupBy(ensIndexerSchema.domain.type); -` +.select({ type: ensIndexerSchema.domain.type, count: count() }) +.from(ensIndexerSchema.domain) +.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) +.groupBy(ensIndexerSchema.domain.type); +`, +result: resultJson, +}; :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) @@ -41,14 +47,8 @@ Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-permissions.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-permissions.mdx new file mode 100644 index 000000000..dae2c7e60 --- /dev/null +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-permissions.mdx @@ -0,0 +1,55 @@ +--- +title: Fuzzy Search for ENS Names +description: Perform a fuzzy search for ENS names. +sidebar: + label: Fuzzy Search +--- + +import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; +import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; + +export const resultJson = [ + { + type: "ENSv1Domain", + count: 2 + }, + { + type: "ENSv2Domain", + count: 14 + } +]; + +export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains +WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' +GROUP BY type; +`; + +export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; + +const counts = await ensDb +\t.select({ type: ensIndexerSchema.domain.type, count: count() }) +\t.from(ensIndexerSchema.domain) +\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) +\t.groupBy(ensIndexerSchema.domain.type); +` + +:::caution[`unigraph` plugin required] +Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) +::: + +Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. + + + + + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index 5590b6083..05b445a49 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -8,50 +8,7 @@ sidebar: import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; - -export const unigraphSqlResultJson = [ - { - id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - type: "ENSv1Domain", - canonical_name: "vitalik.eth", - canonical_node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - owner_id: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", - }, -]; - -export const ensDbSdkResultJson = [ - { - id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - type: "ENSv1Domain", - canonicalName: "vitalik.eth", - canonicalNode: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - ownerId: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", - }, -]; - -export const sqlExampleSnippet = `SELECT - id, - type, - canonical_name, - canonical_node, - owner_id -FROM ensindexer_0.domains -WHERE canonical_name = 'vitalik.eth';` - -export const tsExampleSnippet = `import { eq } from "drizzle-orm"; - -const [vitalik] = await ensDb -\t.select({ -\t\tid: ensIndexerSchema.domain.id, -\t\ttype: ensIndexerSchema.domain.type, -\t\tcanonicalName: ensIndexerSchema.domain.canonicalName, -\t\tcanonicalNode: ensIndexerSchema.domain.canonicalNode, -\t\townerId: ensIndexerSchema.domain.ownerId, -\t}) -\t.from(ensIndexerSchema.domain) -\t.where(eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth")); - -console.log(vitalik);` +import { exampleDomainByName } from "@data/unigraph-examples/domain-by-name"; :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) @@ -64,9 +21,9 @@ Canonical fields are populated on every Domain reachable from the canonical root ::: - + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-events.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-events.mdx new file mode 100644 index 000000000..5590b6083 --- /dev/null +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-events.mdx @@ -0,0 +1,72 @@ +--- +title: Domain by Name +description: Fetch a Domain from the ENS Unigraph by its canonical name. +sidebar: + label: Domain by Name +--- + +import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; +import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; + +export const unigraphSqlResultJson = [ + { + id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + type: "ENSv1Domain", + canonical_name: "vitalik.eth", + canonical_node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + owner_id: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + }, +]; + +export const ensDbSdkResultJson = [ + { + id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + type: "ENSv1Domain", + canonicalName: "vitalik.eth", + canonicalNode: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + ownerId: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + }, +]; + +export const sqlExampleSnippet = `SELECT + id, + type, + canonical_name, + canonical_node, + owner_id +FROM ensindexer_0.domains +WHERE canonical_name = 'vitalik.eth';` + +export const tsExampleSnippet = `import { eq } from "drizzle-orm"; + +const [vitalik] = await ensDb +\t.select({ +\t\tid: ensIndexerSchema.domain.id, +\t\ttype: ensIndexerSchema.domain.type, +\t\tcanonicalName: ensIndexerSchema.domain.canonicalName, +\t\tcanonicalNode: ensIndexerSchema.domain.canonicalNode, +\t\townerId: ensIndexerSchema.domain.ownerId, +\t}) +\t.from(ensIndexerSchema.domain) +\t.where(eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth")); + +console.log(vitalik);` + +:::caution[`unigraph` plugin required] +Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) +::: + +Fetch a Domain by its canonical name. Because `canonical_name` is materialized across both ENSv1 and ENSv2, the same lookup works regardless of protocol version. See [Connect](/docs/integrate/unigraph/examples) for setup. + +:::note[Canonical fields] +Canonical fields are populated on every Domain reachable from the canonical root, across both ENSv1 and ENSv2 — query them uniformly without branching by `type`. In SQL, these columns are `canonical_name`, `canonical_path`, `canonical_node`, and `canonical_depth`; in `ensdb-sdk`, the corresponding fields are `canonicalName`, `canonicalPath`, `canonicalNode`, and `canonicalDepth`. +::: + + + + + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domains-fuzzy-search-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domains-fuzzy-search-by-name.mdx new file mode 100644 index 000000000..dae2c7e60 --- /dev/null +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domains-fuzzy-search-by-name.mdx @@ -0,0 +1,55 @@ +--- +title: Fuzzy Search for ENS Names +description: Perform a fuzzy search for ENS names. +sidebar: + label: Fuzzy Search +--- + +import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; +import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; + +export const resultJson = [ + { + type: "ENSv1Domain", + count: 2 + }, + { + type: "ENSv2Domain", + count: 14 + } +]; + +export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains +WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' +GROUP BY type; +`; + +export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; + +const counts = await ensDb +\t.select({ type: ensIndexerSchema.domain.type, count: count() }) +\t.from(ensIndexerSchema.domain) +\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) +\t.groupBy(ensIndexerSchema.domain.type); +` + +:::caution[`unigraph` plugin required] +Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) +::: + +Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. + + + + + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/expiring-registrations.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/expiring-registrations.mdx new file mode 100644 index 000000000..dae2c7e60 --- /dev/null +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/expiring-registrations.mdx @@ -0,0 +1,55 @@ +--- +title: Fuzzy Search for ENS Names +description: Perform a fuzzy search for ENS names. +sidebar: + label: Fuzzy Search +--- + +import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; +import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; + +export const resultJson = [ + { + type: "ENSv1Domain", + count: 2 + }, + { + type: "ENSv2Domain", + count: 14 + } +]; + +export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains +WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' +GROUP BY type; +`; + +export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; + +const counts = await ensDb +\t.select({ type: ensIndexerSchema.domain.type, count: count() }) +\t.from(ensIndexerSchema.domain) +\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) +\t.groupBy(ensIndexerSchema.domain.type); +` + +:::caution[`unigraph` plugin required] +Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) +::: + +Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. + + + + + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index 000984ac8..4a6085234 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -121,7 +121,7 @@ export const unigraphSqlResultJson = { export const sqlExampleSnippet = `-- Indexing status snapshot for the \`ensindexer_0\` ENSIndexer Schema SELECT value -> 'indexingStatus' as indexing_status_snapshot -FROM ensnode.metadata +FROM "ensnode".metadata WHERE ens_indexer_schema_name = 'ensindexer_0' AND key = 'indexing_metadata_context'; `; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/latest-registrations.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/latest-registrations.mdx new file mode 100644 index 000000000..dae2c7e60 --- /dev/null +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/latest-registrations.mdx @@ -0,0 +1,55 @@ +--- +title: Fuzzy Search for ENS Names +description: Perform a fuzzy search for ENS names. +sidebar: + label: Fuzzy Search +--- + +import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; +import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; + +export const resultJson = [ + { + type: "ENSv1Domain", + count: 2 + }, + { + type: "ENSv2Domain", + count: 14 + } +]; + +export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains +WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' +GROUP BY type; +`; + +export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; + +const counts = await ensDb +\t.select({ type: ensIndexerSchema.domain.type, count: count() }) +\t.from(ensIndexerSchema.domain) +\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) +\t.groupBy(ensIndexerSchema.domain.type); +` + +:::caution[`unigraph` plugin required] +Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) +::: + +Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. + + + + + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/subdomains-by-parent-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/subdomains-by-parent-name.mdx new file mode 100644 index 000000000..e323095f2 --- /dev/null +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/subdomains-by-parent-name.mdx @@ -0,0 +1,25 @@ +--- +title: Subdomains +description: Subdomains under an ENS name. +sidebar: + label: Subdomains +--- + +import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; +import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; +import { exampleSubdomainsByParentName } from "@data/unigraph-examples/subdomains-by-parent-name"; + +:::caution[`unigraph` plugin required] +Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) +::: + +Get a list of subdomains for the `eth` domain, including their Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. + + + + + diff --git a/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts b/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts new file mode 100644 index 000000000..fb179ea6a --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts @@ -0,0 +1,56 @@ +import type { QueryExample } from "./types"; + +/** + * Example query for fetching a Domain by its canonical name, + * demonstrating the use of canonical fields to query across both ENSv1 and + * ENSv2 domains without branching by protocol version. + */ +export const exampleDomainByName = { + sql: { + codeSnippet: `SELECT + id, + type, + canonical_name, + canonical_node, + owner_id +FROM ensindexer_0.domains +WHERE canonical_name = 'vitalik.eth'; +`, + result: [ + { + id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + type: "ENSv1Domain", + canonical_name: "vitalik.eth", + canonical_node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + owner_id: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + }, + ], + }, + sdk: { + codeSnippet: `import { eq } from "drizzle-orm"; + +const [vitalik] = await ensDb + .select({ + id: ensIndexerSchema.domain.id, + type: ensIndexerSchema.domain.type, + canonicalName: ensIndexerSchema.domain.canonicalName, + canonicalNode: ensIndexerSchema.domain.canonicalNode, + ownerId: ensIndexerSchema.domain.ownerId, + }) + .from(ensIndexerSchema.domain) + .where( + eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth") + ); + +console.log(vitalik);`, + result: [ + { + id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + type: "ENSv1Domain", + canonicalName: "vitalik.eth", + canonicalNode: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + ownerId: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + }, + ], + }, +} satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts b/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts new file mode 100644 index 000000000..fb179ea6a --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts @@ -0,0 +1,56 @@ +import type { QueryExample } from "./types"; + +/** + * Example query for fetching a Domain by its canonical name, + * demonstrating the use of canonical fields to query across both ENSv1 and + * ENSv2 domains without branching by protocol version. + */ +export const exampleDomainByName = { + sql: { + codeSnippet: `SELECT + id, + type, + canonical_name, + canonical_node, + owner_id +FROM ensindexer_0.domains +WHERE canonical_name = 'vitalik.eth'; +`, + result: [ + { + id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + type: "ENSv1Domain", + canonical_name: "vitalik.eth", + canonical_node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + owner_id: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + }, + ], + }, + sdk: { + codeSnippet: `import { eq } from "drizzle-orm"; + +const [vitalik] = await ensDb + .select({ + id: ensIndexerSchema.domain.id, + type: ensIndexerSchema.domain.type, + canonicalName: ensIndexerSchema.domain.canonicalName, + canonicalNode: ensIndexerSchema.domain.canonicalNode, + ownerId: ensIndexerSchema.domain.ownerId, + }) + .from(ensIndexerSchema.domain) + .where( + eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth") + ); + +console.log(vitalik);`, + result: [ + { + id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + type: "ENSv1Domain", + canonicalName: "vitalik.eth", + canonicalNode: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + ownerId: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + }, + ], + }, +} satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts b/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts new file mode 100644 index 000000000..2040f8e2a --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts @@ -0,0 +1,175 @@ +import type { QueryExample } from "./types"; + +/** + * Example query for fetching subdomains by their canonical name of the parent domain. + */ +export const exampleSubdomainsByParentName = { + sql: { + codeSnippet: `WITH parent AS ( + SELECT subregistry_id + FROM "ensindexer_0".domains + WHERE canonical_name = 'eth' + AND canonical = true +) +SELECT + d.type, + d.canonical_name, + d.canonical_node, + d.id +FROM "ensindexer_0".domains d +JOIN parent p ON d.registry_id = p.subregistry_id +WHERE d.canonical = true +ORDER BY d.canonical_name +LIMIT 10; +`, + result: [ + { + type: "ENSv1Domain", + canonical_name: "[52602a50858115661619fb28cf543ee766c182e0be6743c72d5bd674b3d12686].eth", + canonical_node: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + }, + { + type: "ENSv1Domain", + canonical_name: "[d90db363b8bc1371f7d738d264ff7294bfc5636f907c467adf68321a3c6d8188].eth", + canonical_node: "0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + }, + { + type: "ENSv2Domain", + canonical_name: "katrenpadu.eth", + canonical_node: "0xf8ae81127bcd7ff99828b3dbd982a943d6dd961ee3f1a6ca707aa0eea913328e", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-112554048520345018269255786667391470421317806528110367240542760381540064034816", + }, + { + type: "ENSv2Domain", + canonical_name: "roppp.eth", + canonical_node: "0x39095c3dfb872d6441c95547f88591e7fb97014eef30cabe3df12a9b2a64dbe8", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-88275407146030613359050872632052369891139576190404928761656352489271755538432", + }, + { + type: "ENSv1Domain", + canonical_name: "sfmpfv44d0mig.eth", + canonical_node: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + }, + { + type: "ENSv2Domain", + canonical_name: "sfmpfv44d0mig.eth", + canonical_node: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-30078755955643454526763071980293195785165410039216352470119925106082295316480", + }, + { + type: "ENSv2Domain", + canonical_name: "sfmpfv44d0res.eth", + canonical_node: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-37259562946248504018379781627254217478007643438678910837598068740925220192256", + }, + { + type: "ENSv2Domain", + canonical_name: "sfmpfvtoicv2ok.eth", + canonical_node: "0x7d0c27336cf9d51c3fc8f29ef4ef69df9cd4a8ec983e3e17d457a8de6013f3c5", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-49509597771493908415463190501045916291230588437784211605615168713991762477056", + }, + { + type: "ENSv2Domain", + canonical_name: "wrapnation.eth", + canonical_node: "0xc7da9e9ef214b62959a64ba9967cb33a2545a5c0f217d2716474ad1e85fa51fd", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", + }, + ], + }, + sdk: { + codeSnippet: `import { and, eq, asc } from "drizzle-orm"; + +// Two-step: +// 1) find parent domain, +// 2) query children by parent domain's subregistryId. +const [parentDomain] = await ensDb + .select({ subregistryId: ensIndexerSchema.domain.subregistryId }) + .from(ensIndexerSchema.domain) + .where( + and( + eq(ensIndexerSchema.domain.canonicalName, "eth"), + eq(ensIndexerSchema.domain.canonical, true), + ) +); + +if (parentDomain?.subregistryId) { + const subdomains = await ensDb + .select({ + type: ensIndexerSchema.domain.type, + canonicalName: ensIndexerSchema.domain.canonicalName, + canonicalNode: ensIndexerSchema.domain.canonicalNode, + id: ensIndexerSchema.domain.id, + }) + .from(ensIndexerSchema.domain) + .where( + and( + eq(ensIndexerSchema.domain.registryId, parentDomain.subregistryId), + eq(ensIndexerSchema.domain.canonical, true), + ) + ) + .orderBy(asc(ensIndexerSchema.domain.canonicalName)) + .limit(limit); + + console.log(subdomains); +}`, + result: [ + { + type: "ENSv1Domain", + canonicalName: "[52602a50858115661619fb28cf543ee766c182e0be6743c72d5bd674b3d12686].eth", + canonicalNode: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + }, + { + type: "ENSv1Domain", + canonicalName: "[d90db363b8bc1371f7d738d264ff7294bfc5636f907c467adf68321a3c6d8188].eth", + canonicalNode: "0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + }, + { + type: "ENSv2Domain", + canonicalName: "katrenpadu.eth", + canonicalNode: "0xf8ae81127bcd7ff99828b3dbd982a943d6dd961ee3f1a6ca707aa0eea913328e", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-112554048520345018269255786667391470421317806528110367240542760381540064034816", + }, + { + type: "ENSv2Domain", + canonicalName: "roppp.eth", + canonicalNode: "0x39095c3dfb872d6441c95547f88591e7fb97014eef30cabe3df12a9b2a64dbe8", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-88275407146030613359050872632052369891139576190404928761656352489271755538432", + }, + { + type: "ENSv1Domain", + canonicalName: "sfmpfv44d0mig.eth", + canonicalNode: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + }, + { + type: "ENSv2Domain", + canonicalName: "sfmpfv44d0mig.eth", + canonicalNode: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-30078755955643454526763071980293195785165410039216352470119925106082295316480", + }, + { + type: "ENSv2Domain", + canonicalName: "sfmpfv44d0res.eth", + canonicalNode: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-37259562946248504018379781627254217478007643438678910837598068740925220192256", + }, + { + type: "ENSv2Domain", + canonicalName: "sfmpfvtoicv2ok.eth", + canonicalNode: "0x7d0c27336cf9d51c3fc8f29ef4ef69df9cd4a8ec983e3e17d457a8de6013f3c5", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-49509597771493908415463190501045916291230588437784211605615168713991762477056", + }, + { + type: "ENSv2Domain", + canonicalName: "wrapnation.eth", + canonicalNode: "0xc7da9e9ef214b62959a64ba9967cb33a2545a5c0f217d2716474ad1e85fa51fd", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", + }, + ], + }, +} satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/types.ts b/docs/ensnode.io/src/data/unigraph-examples/types.ts new file mode 100644 index 000000000..31605aa9a --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/types.ts @@ -0,0 +1,9 @@ +export interface CodeExample { + codeSnippet: string; + result: unknown; +} + +export interface QueryExample { + sql: CodeExample; + sdk: CodeExample; +} From d4e91df415482090053bb2b1e3932eb0774e825d Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Fri, 5 Jun 2026 16:47:49 +0200 Subject: [PATCH 3/7] Extend ENS Unigraph examples --- .../starlight/sidebar-topics/integrate.ts | 4 - .../unigraph/examples/account-domains.mdx | 36 +--- .../unigraph/examples/account-permissions.mdx | 55 ----- .../unigraph/examples/domain-events.mdx | 59 +----- .../examples/domains-fuzzy-search-by-name.mdx | 38 +--- .../examples/expiring-registrations.mdx | 44 +--- .../unigraph/examples/indexing-status.mdx | 132 +----------- .../examples/latest-registrations.mdx | 44 +--- .../data/unigraph-examples/account-domains.ts | 198 ++++++++++++++++++ .../data/unigraph-examples/domain-by-name.ts | 12 +- .../data/unigraph-examples/domain-events.ts | 168 +++++++++++++++ .../domains-fuzzy-search-by-name.ts | 124 ++++++++--- .../expiring-registrations.ts | 168 +++++++++++++++ .../data/unigraph-examples/indexing-status.ts | 132 ++++++++++++ .../unigraph-examples/latest-registrations.ts | 179 ++++++++++++++++ .../subdomains-by-parent-name.ts | 123 ++++------- 16 files changed, 1024 insertions(+), 492 deletions(-) delete mode 100644 docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-permissions.mdx create mode 100644 docs/ensnode.io/src/data/unigraph-examples/account-domains.ts create mode 100644 docs/ensnode.io/src/data/unigraph-examples/domain-events.ts create mode 100644 docs/ensnode.io/src/data/unigraph-examples/expiring-registrations.ts create mode 100644 docs/ensnode.io/src/data/unigraph-examples/indexing-status.ts create mode 100644 docs/ensnode.io/src/data/unigraph-examples/latest-registrations.ts 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 9a40dcf4c..60af43d51 100644 --- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts +++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts @@ -198,10 +198,6 @@ export const integrateSidebarTopic = { label: "Account Domains", link: "/docs/integrate/unigraph/examples/account-domains", }, - { - label: "Account Permissions", - link: "/docs/integrate/unigraph/examples/account-permissions", - }, { label: "Latest Registrations", link: "/docs/integrate/unigraph/examples/latest-registrations", diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index aea543fd2..65dfe167e 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -8,37 +8,7 @@ sidebar: import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; - -export const resultJson = [ - { - type: "ENSv1Domain", - count: 2 - }, - { - type: "ENSv2Domain", - count: 14 - } -]; - -export const sqlExample = { - codeSnippet: `SELECT type, count(*) FROM ensindexer_0.domains -WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' -GROUP BY type; -`, - result: resultJson, -}; - -export const tsExample = { - codeSnippet: `import { count, eq } from "drizzle-orm"; - -const counts = await ensDb -.select({ type: ensIndexerSchema.domain.type, count: count() }) -.from(ensIndexerSchema.domain) -.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) -.groupBy(ensIndexerSchema.domain.type); -`, -result: resultJson, -}; +import { exampleAccountDomains } from "@data/unigraph-examples/account-domains"; :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) @@ -47,8 +17,8 @@ Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-permissions.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-permissions.mdx deleted file mode 100644 index dae2c7e60..000000000 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-permissions.mdx +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Fuzzy Search for ENS Names -description: Perform a fuzzy search for ENS names. -sidebar: - label: Fuzzy Search ---- - -import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; -import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; -import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; - -export const resultJson = [ - { - type: "ENSv1Domain", - count: 2 - }, - { - type: "ENSv2Domain", - count: 14 - } -]; - -export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains -WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' -GROUP BY type; -`; - -export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; - -const counts = await ensDb -\t.select({ type: ensIndexerSchema.domain.type, count: count() }) -\t.from(ensIndexerSchema.domain) -\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) -\t.groupBy(ensIndexerSchema.domain.type); -` - -:::caution[`unigraph` plugin required] -Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) -::: - -Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. - - - - - diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-events.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-events.mdx index 5590b6083..3ce2a33e8 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-events.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-events.mdx @@ -1,72 +1,29 @@ --- -title: Domain by Name -description: Fetch a Domain from the ENS Unigraph by its canonical name. +title: Domain Events +description: Fetch recent events for a Domain from the ENS Unigraph by its canonical name. sidebar: - label: Domain by Name + label: Domain Events --- import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; - -export const unigraphSqlResultJson = [ - { - id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - type: "ENSv1Domain", - canonical_name: "vitalik.eth", - canonical_node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - owner_id: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", - }, -]; - -export const ensDbSdkResultJson = [ - { - id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - type: "ENSv1Domain", - canonicalName: "vitalik.eth", - canonicalNode: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - ownerId: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", - }, -]; - -export const sqlExampleSnippet = `SELECT - id, - type, - canonical_name, - canonical_node, - owner_id -FROM ensindexer_0.domains -WHERE canonical_name = 'vitalik.eth';` - -export const tsExampleSnippet = `import { eq } from "drizzle-orm"; - -const [vitalik] = await ensDb -\t.select({ -\t\tid: ensIndexerSchema.domain.id, -\t\ttype: ensIndexerSchema.domain.type, -\t\tcanonicalName: ensIndexerSchema.domain.canonicalName, -\t\tcanonicalNode: ensIndexerSchema.domain.canonicalNode, -\t\townerId: ensIndexerSchema.domain.ownerId, -\t}) -\t.from(ensIndexerSchema.domain) -\t.where(eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth")); - -console.log(vitalik);` +import { exampleDomainEvents } from "@data/unigraph-examples/domain-events"; :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) ::: -Fetch a Domain by its canonical name. Because `canonical_name` is materialized across both ENSv1 and ENSv2, the same lookup works regardless of protocol version. See [Connect](/docs/integrate/unigraph/examples) for setup. +Fetch recent events for a Domain by its canonical name. This example joins the `events`, `domain_events`, and `domains` tables to retrieve domain events associated with the `vitalik.eth` name. :::note[Canonical fields] Canonical fields are populated on every Domain reachable from the canonical root, across both ENSv1 and ENSv2 — query them uniformly without branching by `type`. In SQL, these columns are `canonical_name`, `canonical_path`, `canonical_node`, and `canonical_depth`; in `ensdb-sdk`, the corresponding fields are `canonicalName`, `canonicalPath`, `canonicalNode`, and `canonicalDepth`. ::: - + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domains-fuzzy-search-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domains-fuzzy-search-by-name.mdx index dae2c7e60..2d7eacbd3 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domains-fuzzy-search-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domains-fuzzy-search-by-name.mdx @@ -8,47 +8,17 @@ sidebar: import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; - -export const resultJson = [ - { - type: "ENSv1Domain", - count: 2 - }, - { - type: "ENSv2Domain", - count: 14 - } -]; - -export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains -WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' -GROUP BY type; -`; - -export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; - -const counts = await ensDb -\t.select({ type: ensIndexerSchema.domain.type, count: count() }) -\t.from(ensIndexerSchema.domain) -\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) -\t.groupBy(ensIndexerSchema.domain.type); -` +import { exampleDomainsFuzzySearchByName } from "@data/unigraph-examples/domains-fuzzy-search-by-name"; :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) ::: -Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. +Fetch Domains with names similar to a query string, ranked by similarity. This example uses PostgreSQL's `pg_trgm` extension, which provides the `%` operator for fuzzy matching and the `similarity()` function for ranking results. See [Connect](/docs/integrate/unigraph/examples) for setup. diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/expiring-registrations.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/expiring-registrations.mdx index dae2c7e60..c5e59dea9 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/expiring-registrations.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/expiring-registrations.mdx @@ -1,54 +1,24 @@ --- -title: Fuzzy Search for ENS Names -description: Perform a fuzzy search for ENS names. +title: Expiring ENS Registrations +description: Fetch ENS registrations that are about to expire. sidebar: - label: Fuzzy Search + label: Expiring Registrations --- import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; - -export const resultJson = [ - { - type: "ENSv1Domain", - count: 2 - }, - { - type: "ENSv2Domain", - count: 14 - } -]; - -export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains -WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' -GROUP BY type; -`; - -export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; - -const counts = await ensDb -\t.select({ type: ensIndexerSchema.domain.type, count: count() }) -\t.from(ensIndexerSchema.domain) -\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) -\t.groupBy(ensIndexerSchema.domain.type); -` +import { exampleExpiringRegistrations } from "@data/unigraph-examples/expiring-registrations"; :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) ::: -Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. +Fetch Domains with registrations expiring within a certain timeframe. This example uses a simple `WHERE` clause to filter for Domains with `expiry_date` between the current time and a specified future time (e.g., 3 days from now). See [Connect](/docs/integrate/unigraph/examples) for setup. diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index 4a6085234..09a77e5d6 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -8,141 +8,17 @@ sidebar: import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsNodeSchemaIntro from "@components/molecules/EnsNodeSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; - -export const ensDbSdkResultJson = { - indexingStatus: { - strategy: "omnichain", - snapshotTime: 1779795066, - omnichainSnapshot: { - chains: { - 1: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 3327417, - timestamp: 1489165544, - }, - }, - chainStatus: "chain-backfill", - backfillEndBlock: { - number: 25171597, - timestamp: 1779703391, - }, - latestIndexedBlock: { - number: 21224717, - timestamp: 1732054691, - }, - }, - 10: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 110393959, - timestamp: 1696386695, - }, - }, - chainStatus: "chain-backfill", - backfillEndBlock: { - number: 152052671, - timestamp: 1779704119, - }, - latestIndexedBlock: { - number: 128226309, - timestamp: 1732051395, - }, - }, - 8453: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 17522624, - timestamp: 1721834595, - }, - }, - chainStatus: "chain-backfill", - backfillEndBlock: { - number: 46457386, - timestamp: 1779704119, - }, - latestIndexedBlock: { - number: 22632818, - timestamp: 1732054983, - }, - }, - 42161: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 349263357, - timestamp: 1750406457, - }, - }, - chainStatus: "chain-queued", - }, - 59144: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 6682888, - timestamp: 1720768992, - }, - }, - chainStatus: "chain-backfill", - backfillEndBlock: { - number: 30774477, - timestamp: 1779703911, - }, - latestIndexedBlock: { - number: 12280006, - timestamp: 1732054967, - }, - }, - 534352: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 16604272, - timestamp: 1750406415, - }, - }, - chainStatus: "chain-queued", - }, - }, - omnichainStatus: "omnichain-backfill", - omnichainIndexingCursor: 1732054983, - }, - slowestChainIndexingCursor: 1732054983, - } -} - -export const unigraphSqlResultJson = { - indexing_status_snapshot: ensDbSdkResultJson.indexingStatus, -}; - -export const sqlExampleSnippet = `-- Indexing status snapshot for the \`ensindexer_0\` ENSIndexer Schema -SELECT value -> 'indexingStatus' as indexing_status_snapshot -FROM "ensnode".metadata -WHERE ens_indexer_schema_name = 'ensindexer_0' -AND key = 'indexing_metadata_context'; -`; - -export const tsExampleSnippet = `import { IndexingMetadataContextStatusCodes } from "@ensnode/ensdb-sdk"; - -const indexingMetadataContext = await ensDbReader.getIndexingMetadataContext(); -if (indexingMetadataContext.statusCode === IndexingMetadataContextStatusCodes.Initialized) { -\tconst { indexingStatus } = indexingMetadataContext; -\tconsole.log({ indexingStatus }); -}`; +import { exampleIndexingStatus } from "@data/unigraph-examples/indexing-status"; :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) ::: -Read the indexing status snapshot for an ENSIndexer instance from the shared `ensnode.metadata` table. See [Connect](/docs/integrate/unigraph/examples) for setup. +Read the indexing status snapshot for an ENSDb Writer instance from the shared `ensnode.metadata` table. See [Connect](/docs/integrate/unigraph/examples) for setup. diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/latest-registrations.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/latest-registrations.mdx index dae2c7e60..167336fe2 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/latest-registrations.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/latest-registrations.mdx @@ -1,54 +1,24 @@ --- -title: Fuzzy Search for ENS Names -description: Perform a fuzzy search for ENS names. +title: Latest ENS Registrations +description: Fetch the latest ENS registrations. sidebar: - label: Fuzzy Search + label: Latest Registrations --- import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsDbWriterSchemaIntro from "@components/molecules/EnsDbWriterSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; - -export const resultJson = [ - { - type: "ENSv1Domain", - count: 2 - }, - { - type: "ENSv2Domain", - count: 14 - } -]; - -export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains -WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' -GROUP BY type; -`; - -export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; - -const counts = await ensDb -\t.select({ type: ensIndexerSchema.domain.type, count: count() }) -\t.from(ensIndexerSchema.domain) -\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) -\t.groupBy(ensIndexerSchema.domain.type); -` +import { exampleLatestRegistrations } from "@data/unigraph-examples/latest-registrations"; :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) ::: -Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. +Fetch the latest registrations and their associated Domains. See [Connect](/docs/integrate/unigraph/examples) for setup. diff --git a/docs/ensnode.io/src/data/unigraph-examples/account-domains.ts b/docs/ensnode.io/src/data/unigraph-examples/account-domains.ts new file mode 100644 index 000000000..f70b6a900 --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/account-domains.ts @@ -0,0 +1,198 @@ +import type { QueryExample } from "./types"; + +/** + * Example query for fetching Domains by their owner's address, + * demonstrating the use of canonical fields to query across both ENSv1 and + * ENSv2 domains without branching by protocol version. + */ +export const exampleAccountDomains = { + sql: { + codeSnippet: `SELECT + d.type, + d.canonical_name, + d.canonical_node, + d.id, + d.owner_id +FROM "ensindexer_0".domains d +WHERE d.canonical = true +AND d.owner_id = '0xffffffffff52d316b7bd028358089bc8066b8f80' +ORDER BY d.canonical_name +LIMIT 10;`, + result: [ + { + type: "ENSv1Domain", + canonical_name: + "[3ad05e2a5922916840bc1e5e6039f00b27cbabf8d0428abce062aa2011307374].addr.reverse", + canonical_node: "0xd3947f90d04d7f41f973f09ad7dbdb34cb7463359369e6cf1663bbf928d66e53", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xd3947f90d04d7f41f973f09ad7dbdb34cb7463359369e6cf1663bbf928d66e53", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonical_name: "[52602a50858115661619fb28cf543ee766c182e0be6743c72d5bd674b3d12686].eth", + canonical_node: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonical_name: + "[8268685e13ae6bbfa54901f2954f9fcf80839ffa102fe7146b930623ce9bd7f0].addr.reverse", + canonical_node: "0x21c356e778799bfddf59a5683c04f6b08710d7c198fef466cc697563b2210785", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x21c356e778799bfddf59a5683c04f6b08710d7c198fef466cc697563b2210785", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonical_name: "[d90db363b8bc1371f7d738d264ff7294bfc5636f907c467adf68321a3c6d8188].eth", + canonical_node: "0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonical_name: + "[d99fc3d8237200c7122431276a337421cf793f51276873df5a54cc482fdbe685].addr.reverse", + canonical_node: "0x4fc87044c0adc4a0c996b9dafe3a4889e72fe0745fc76f18151b81ed73582218", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x4fc87044c0adc4a0c996b9dafe3a4889e72fe0745fc76f18151b81ed73582218", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv2Domain", + canonical_name: "eth", + canonical_node: "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", + id: "11155111-0x835f0b284e78cd3f358bcf6cba3b53809f09b79e-35894389512221139346028120028875095598761990588366713962827482865183915769856", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv2Domain", + canonical_name: "reverse", + canonical_node: "0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + id: "11155111-0x835f0b284e78cd3f358bcf6cba3b53809f09b79e-100753657518907091865523951670693454610893379027273088370152078482136467767296", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonical_name: "reverse", + canonical_node: "0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv2Domain", + canonical_name: "sfmpfv44d0mig.eth", + canonical_node: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-30078755955643454526763071980293195785165410039216352470119925106082295316480", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv2Domain", + canonical_name: "sfmpfvtoicv2ok.eth", + canonical_node: "0x7d0c27336cf9d51c3fc8f29ef4ef69df9cd4a8ec983e3e17d457a8de6013f3c5", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-49509597771493908415463190501045916291230588437784211605615168713991762477056", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + ], + }, + sdk: { + codeSnippet: `import { and, eq } from "drizzle-orm"; + +const owner = "0xffffffffff52d316b7bd028358089bc8066b8f80"; +const limit = 10; + +const accountDomains = await ensDb + .select({ + canonicalName: ensIndexerSchema.domain.canonicalName, + canonicalNode: ensIndexerSchema.domain.canonicalNode, + type: ensIndexerSchema.domain.type, + id: ensIndexerSchema.domain.id, + ownerId: ensIndexerSchema.domain.ownerId, + }) + .from(ensIndexerSchema.domain) + .where( + and( + eq(ensIndexerSchema.domain.ownerId, owner), + eq(ensIndexerSchema.domain.canonical, true), + ), + ) + .orderBy(asc(ensIndexerSchema.domain.canonicalName)) + .limit(limit); + +console.log(accountDomains);`, + result: [ + { + type: "ENSv1Domain", + canonicalName: + "[3ad05e2a5922916840bc1e5e6039f00b27cbabf8d0428abce062aa2011307374].addr.reverse", + canonicalNode: "0xd3947f90d04d7f41f973f09ad7dbdb34cb7463359369e6cf1663bbf928d66e53", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xd3947f90d04d7f41f973f09ad7dbdb34cb7463359369e6cf1663bbf928d66e53", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonicalName: "[52602a50858115661619fb28cf543ee766c182e0be6743c72d5bd674b3d12686].eth", + canonicalNode: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonicalName: + "[8268685e13ae6bbfa54901f2954f9fcf80839ffa102fe7146b930623ce9bd7f0].addr.reverse", + canonicalNode: "0x21c356e778799bfddf59a5683c04f6b08710d7c198fef466cc697563b2210785", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x21c356e778799bfddf59a5683c04f6b08710d7c198fef466cc697563b2210785", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonicalName: "[d90db363b8bc1371f7d738d264ff7294bfc5636f907c467adf68321a3c6d8188].eth", + canonicalNode: "0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonicalName: + "[d99fc3d8237200c7122431276a337421cf793f51276873df5a54cc482fdbe685].addr.reverse", + canonicalNode: "0x4fc87044c0adc4a0c996b9dafe3a4889e72fe0745fc76f18151b81ed73582218", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x4fc87044c0adc4a0c996b9dafe3a4889e72fe0745fc76f18151b81ed73582218", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv2Domain", + canonicalName: "eth", + canonicalNode: "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", + id: "11155111-0x835f0b284e78cd3f358bcf6cba3b53809f09b79e-35894389512221139346028120028875095598761990588366713962827482865183915769856", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv2Domain", + canonicalName: "reverse", + canonicalNode: "0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + id: "11155111-0x835f0b284e78cd3f358bcf6cba3b53809f09b79e-100753657518907091865523951670693454610893379027273088370152078482136467767296", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv1Domain", + canonicalName: "reverse", + canonicalNode: "0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv2Domain", + canonicalName: "sfmpfv44d0mig.eth", + canonicalNode: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-30078755955643454526763071980293195785165410039216352470119925106082295316480", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + { + type: "ENSv2Domain", + canonicalName: "sfmpfvtoicv2ok.eth", + canonicalNode: "0x7d0c27336cf9d51c3fc8f29ef4ef69df9cd4a8ec983e3e17d457a8de6013f3c5", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-49509597771493908415463190501045916291230588437784211605615168713991762477056", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + }, + ], + }, +} satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts b/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts index fb179ea6a..5fc624f93 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts @@ -13,8 +13,9 @@ export const exampleDomainByName = { canonical_name, canonical_node, owner_id -FROM ensindexer_0.domains -WHERE canonical_name = 'vitalik.eth'; +FROM "ensindexer_0".domains +WHERE canonical_name = 'vitalik.eth' +AND canonical = true; `, result: [ { @@ -27,7 +28,7 @@ WHERE canonical_name = 'vitalik.eth'; ], }, sdk: { - codeSnippet: `import { eq } from "drizzle-orm"; + codeSnippet: `import { and, eq } from "drizzle-orm"; const [vitalik] = await ensDb .select({ @@ -39,7 +40,10 @@ const [vitalik] = await ensDb }) .from(ensIndexerSchema.domain) .where( - eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth") + and( + eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth"), + eq(ensIndexerSchema.domain.canonical, true) + ) ); console.log(vitalik);`, diff --git a/docs/ensnode.io/src/data/unigraph-examples/domain-events.ts b/docs/ensnode.io/src/data/unigraph-examples/domain-events.ts new file mode 100644 index 000000000..82bbdec47 --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/domain-events.ts @@ -0,0 +1,168 @@ +import type { QueryExample } from "./types"; + +/** + * Example query for fetching recent events for a Domain by its canonical name. + */ +export const exampleDomainEvents = { + sql: { + codeSnippet: `SELECT + e.chain_id, + e.block_number, + e.transaction_hash, + e.log_index, + e.address as contract_address, + e.sender, + d.id as domain_id +FROM "ensindexer_0".events e +JOIN "ensindexer_0".domain_events de ON e.id = de.event_id +JOIN "ensindexer_0".domains d ON de.domain_id = d.id +WHERE d.canonical_name = 'vitalik.eth' +AND d.canonical = true +ORDER BY e.block_number DESC, e.log_index DESC +LIMIT 5; +`, + result: [ + { + chain_id: "11155111", + block_number: "6023942", + transaction_hash: "0x6206e95dc5ba5fc8d0804283498f17bac18081437b4198c824b62ee851622ba5", + log_index: 194, + contract_address: "0xfed6a969aaa60e4961fcd3ebf1a2e8913ac65b72", + sender: "0x225f137127d9067788314bc7fcc1f36746a3c3b5", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + { + chain_id: "11155111", + block_number: "6023942", + transaction_hash: "0x6206e95dc5ba5fc8d0804283498f17bac18081437b4198c824b62ee851622ba5", + log_index: 193, + contract_address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85", + sender: "0x225f137127d9067788314bc7fcc1f36746a3c3b5", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + { + chain_id: "11155111", + block_number: "4107392", + transaction_hash: "0xf143118eb4100361f040b1ae5627562125f0cf1717073a8204befe5e512c80d4", + log_index: 22, + contract_address: "0x0635513f179d50a207757e05759cbd106d7dfce8", + sender: "0x179a862703a4adfb29896552df9e307980d19285", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + { + chain_id: "11155111", + block_number: "4107386", + transaction_hash: "0x6410de03e9a2f12543e491d1048209e5638d702948cf23d48a63d96a50efd20d", + log_index: 19, + contract_address: "0xfed6a969aaa60e4961fcd3ebf1a2e8913ac65b72", + sender: "0x179a862703a4adfb29896552df9e307980d19285", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + { + chain_id: "11155111", + block_number: "4107386", + transaction_hash: "0x6410de03e9a2f12543e491d1048209e5638d702948cf23d48a63d96a50efd20d", + log_index: 16, + contract_address: "0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e", + sender: "0x179a862703a4adfb29896552df9e307980d19285", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + ], + }, + sdk: { + codeSnippet: `import { and, desc, eq } from "drizzle-orm"; + +const name = "vitalik.eth"; +const limit = 5; + +const domainEvents = await ensDb + .select({ + chainId: ensIndexerSchema.event.chainId, + blockNumber: ensIndexerSchema.event.blockNumber, + transactionHash: ensIndexerSchema.event.transactionHash, + logIndex: ensIndexerSchema.event.logIndex, + contractAddress: ensIndexerSchema.event.address, + sender: ensIndexerSchema.event.sender, + domainId: ensIndexerSchema.domain.id, + }) + .from(ensIndexerSchema.event) + .innerJoin( + ensIndexerSchema.domainEvent, + eq(ensIndexerSchema.event.id, ensIndexerSchema.domainEvent.eventId), + ) + .innerJoin( + ensIndexerSchema.domain, + eq(ensIndexerSchema.domainEvent.domainId, ensIndexerSchema.domain.id), + ) + .where( + and( + eq(ensIndexerSchema.domain.canonicalName, name), + eq(ensIndexerSchema.domain.canonical, true), + ), + ) + .orderBy( + desc(ensIndexerSchema.event.blockNumber), + desc(ensIndexerSchema.event.logIndex), + ) + .limit(limit); + +console.log(domainEvents);`, + result: [ + { + chainId: 11155111, + blockNumber: "6023942", + transactionHash: "0x6206e95dc5ba5fc8d0804283498f17bac18081437b4198c824b62ee851622ba5", + logIndex: 194, + contractAddress: "0xfed6a969aaa60e4961fcd3ebf1a2e8913ac65b72", + sender: "0x225f137127d9067788314bc7fcc1f36746a3c3b5", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + { + chainId: 11155111, + blockNumber: "6023942", + transactionHash: "0x6206e95dc5ba5fc8d0804283498f17bac18081437b4198c824b62ee851622ba5", + logIndex: 193, + contractAddress: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85", + sender: "0x225f137127d9067788314bc7fcc1f36746a3c3b5", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + { + chainId: 11155111, + blockNumber: "4107392", + transactionHash: "0xf143118eb4100361f040b1ae5627562125f0cf1717073a8204befe5e512c80d4", + logIndex: 22, + contractAddress: "0x0635513f179d50a207757e05759cbd106d7dfce8", + sender: "0x179a862703a4adfb29896552df9e307980d19285", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + { + chainId: 11155111, + blockNumber: "4107386", + transactionHash: "0x6410de03e9a2f12543e491d1048209e5638d702948cf23d48a63d96a50efd20d", + logIndex: 19, + contractAddress: "0xfed6a969aaa60e4961fcd3ebf1a2e8913ac65b72", + sender: "0x179a862703a4adfb29896552df9e307980d19285", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + { + chainId: 11155111, + blockNumber: "4107386", + transactionHash: "0x6410de03e9a2f12543e491d1048209e5638d702948cf23d48a63d96a50efd20d", + logIndex: 16, + contractAddress: "0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e", + sender: "0x179a862703a4adfb29896552df9e307980d19285", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + ], + }, +} satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts b/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts index fb179ea6a..bd33a75c2 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts @@ -1,55 +1,129 @@ import type { QueryExample } from "./types"; /** - * Example query for fetching a Domain by its canonical name, - * demonstrating the use of canonical fields to query across both ENSv1 and - * ENSv2 domains without branching by protocol version. + * Example query for fetching Domains by a fuzzy search on their canonical name. */ -export const exampleDomainByName = { +export const exampleDomainsFuzzySearchByName = { sql: { codeSnippet: `SELECT - id, - type, - canonical_name, - canonical_node, - owner_id -FROM ensindexer_0.domains -WHERE canonical_name = 'vitalik.eth'; + type, + canonical_name, + canonical_node, + owner_id, + similarity(canonical_name, 'vitalik') as name_similarity, + id +FROM "ensindexer_0".domains +-- Use the pg_trgm similarity operator (%) for fuzzy matching on canonical_name +WHERE canonical_name % 'vitalik' +AND canonical = true +ORDER BY name_similarity DESC +LIMIT 5; `, result: [ { - id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", type: "ENSv1Domain", canonical_name: "vitalik.eth", canonical_node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - owner_id: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + owner_id: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", + name_similarity: 0.6666667, + }, + { + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x278adcf079fceb551531f1593deae8891d83bf4708b935d54eda7f8db51ce797", + type: "ENSv1Domain", + canonical_name: "vitalikkk.eth", + canonical_node: "0x278adcf079fceb551531f1593deae8891d83bf4708b935d54eda7f8db51ce797", + owner_id: "0x588f6b3169f60176c1143f8bab47bcf3deebecdc", + name_similarity: 0.46666667, + }, + { + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x55e83f7d37d7cf1f87c40a6bd5fc8e62e8898b327c5a09776596f6efe547349a", + type: "ENSv1Domain", + canonical_name: "vitalik.taars.eth", + canonical_node: "0x55e83f7d37d7cf1f87c40a6bd5fc8e62e8898b327c5a09776596f6efe547349a", + owner_id: "0x5a09e3ec3efdd91205cbb097142a4f4dcefc7f02", + name_similarity: 0.44444445, + }, + { + id: "84532-0x1493b2567056c2181630115660963e13a8e32735-0x97fa42e69feb1d407361108d79ddad705707a16392d7823f8b21b44dabfc4a9d", + type: "ENSv1Domain", + canonical_name: "vitalik.basetest.eth", + canonical_node: "0x97fa42e69feb1d407361108d79ddad705707a16392d7823f8b21b44dabfc4a9d", + owner_id: "0x15378e401f9c3243639c7c3250be0f396a758e40", + name_similarity: 0.3809524, + }, + { + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x117e485acf1ebff586d1382b7689201ce23f7142ae92f4c397849f4b01e6a1cc", + type: "ENSv1Domain", + canonical_name: "vitalikbuterin.eth", + canonical_node: "0x117e485acf1ebff586d1382b7689201ce23f7142ae92f4c397849f4b01e6a1cc", + owner_id: "0x16ecc228f185b084cb884be2d65544f5ca4dd761", + name_similarity: 0.35, }, ], }, sdk: { - codeSnippet: `import { eq } from "drizzle-orm"; + codeSnippet: `import { and, asc, eq, sql } from "drizzle-orm"; -const [vitalik] = await ensDb +const q = "vitalik"; +const limit = 5; + +const domains = await ensDb .select({ - id: ensIndexerSchema.domain.id, - type: ensIndexerSchema.domain.type, canonicalName: ensIndexerSchema.domain.canonicalName, - canonicalNode: ensIndexerSchema.domain.canonicalNode, + canonicalDepth: ensIndexerSchema.domain.canonicalDepth, ownerId: ensIndexerSchema.domain.ownerId, + nameSimilarity: sql\`similarity(\${ensIndexerSchema.domain.canonicalName}, \${q})\`.as( + "name_similarity", + ), + id: ensIndexerSchema.domain.id, }) .from(ensIndexerSchema.domain) .where( - eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth") - ); + and( + sql\`\${ensIndexerSchema.domain.canonicalName} % \${q}\`, + eq(ensIndexerSchema.domain.canonical, true), + ), + ) + .orderBy(sql\`name_similarity DESC\`) + .limit(limit); -console.log(vitalik);`, +console.log(domains);`, result: [ { - id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - type: "ENSv1Domain", canonicalName: "vitalik.eth", - canonicalNode: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - ownerId: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + canonicalDepth: 2, + ownerId: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", + nameSimilarity: 0.6666667, + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + }, + { + canonicalName: "vitalikkk.eth", + canonicalDepth: 2, + ownerId: "0x588f6b3169f60176c1143f8bab47bcf3deebecdc", + nameSimilarity: 0.46666667, + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x278adcf079fceb551531f1593deae8891d83bf4708b935d54eda7f8db51ce797", + }, + { + canonicalName: "vitalik.taars.eth", + canonicalDepth: 3, + ownerId: "0x5a09e3ec3efdd91205cbb097142a4f4dcefc7f02", + nameSimilarity: 0.44444445, + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x55e83f7d37d7cf1f87c40a6bd5fc8e62e8898b327c5a09776596f6efe547349a", + }, + { + canonicalName: "vitalik.basetest.eth", + canonicalDepth: 3, + ownerId: "0x15378e401f9c3243639c7c3250be0f396a758e40", + nameSimilarity: 0.3809524, + id: "84532-0x1493b2567056c2181630115660963e13a8e32735-0x97fa42e69feb1d407361108d79ddad705707a16392d7823f8b21b44dabfc4a9d", + }, + { + canonicalName: "vitalikbuterin.eth", + canonicalDepth: 2, + ownerId: "0x16ecc228f185b084cb884be2d65544f5ca4dd761", + nameSimilarity: 0.35, + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x117e485acf1ebff586d1382b7689201ce23f7142ae92f4c397849f4b01e6a1cc", }, ], }, diff --git a/docs/ensnode.io/src/data/unigraph-examples/expiring-registrations.ts b/docs/ensnode.io/src/data/unigraph-examples/expiring-registrations.ts new file mode 100644 index 000000000..fb13a57db --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/expiring-registrations.ts @@ -0,0 +1,168 @@ +import type { QueryExample } from "./types"; + +/** + * Example query for fetching recent events for a Domain by its canonical name. + */ +export const exampleExpiringRegistrations = { + sql: { + codeSnippet: `SELECT + d.canonical_name, + r.start, + r.expiry, + r.grace_period, + d.owner_id, + d.id as domain_id +FROM "ensindexer_0".registrations r +JOIN "ensindexer_0".latest_registration_index lri + ON r.domain_id = lri.domain_id + AND r.registration_index = lri.registration_index +JOIN "ensindexer_0".domains d ON r.domain_id = d.id +WHERE r.expiry >= EXTRACT(EPOCH FROM NOW()) + AND r.expiry <= EXTRACT(EPOCH FROM NOW() + INTERVAL '3 days') + AND d.canonical = true +ORDER BY r.expiry ASC +LIMIT 5; +`, + result: [ + { + canonical_name: "block-land.eth", + start: "1717602456", + expiry: "1780674456", + grace_period: "7776000", + owner_id: "0x95e488ed0d3497f8cf2392e35c9eb81812ef863c", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x4263eab7cb93cb3161f613e59357fce5de6646c9dab3682c388938231ca16fe6", + }, + { + canonical_name: "hagemz.eth", + start: "1749139932", + expiry: "1780675932", + grace_period: "7776000", + owner_id: "0xeb4bde48fb4ad1ab104eb1ef978fdd24e11d6a28", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x7886dc1e5b637005edf606d9e0f5cee78bd86a57e1378e1c76c3fa7557847659", + }, + { + canonical_name: "leogomez.eth", + start: "1749152664", + expiry: "1780688664", + grace_period: "7776000", + owner_id: "0x2f7970674b6410f90b8bc43d8188ef35ab3f1a9b", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x6c577a69aa94e39ee0ff1beedbd3385f405506bc35d88f47284056c1ceba5759", + }, + { + canonical_name: "ilanklein.eth", + start: "1749156780", + expiry: "1780692780", + grace_period: "7776000", + owner_id: "0x99969df2da9bf780cfd62d7cc22f77e5bdb332df", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x94877f55b294b34b0ac4952ad746f1c163a7e1aba16c41d113c558cd4f2bdff5", + }, + { + canonical_name: "iwms.eth", + start: "1749157272", + expiry: "1780693272", + grace_period: "7776000", + owner_id: "0xa098364308d3e400e2f1199675ac765adac4810f", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x13403c49bb9d168c7f18b830b5dd86f562e3e203fe2fc545927e5f609e3e6417", + }, + ], + }, + sdk: { + codeSnippet: `import { and, asc, eq, gte, lte, sql } from "drizzle-orm"; + +const limit = 5; + +const expiringRegistrations = await ensDb + .select({ + canonicalName: ensIndexerSchema.domain.canonicalName, + expiry: ensIndexerSchema.registration.expiry, + start: ensIndexerSchema.registration.start, + gracePeriod: ensIndexerSchema.registration.gracePeriod, + ownerId: ensIndexerSchema.domain.ownerId, + domainId: ensIndexerSchema.domain.id, + }) + .from(ensIndexerSchema.registration) + .innerJoin( + ensIndexerSchema.latestRegistrationIndex, + and( + eq( + ensIndexerSchema.registration.domainId, + ensIndexerSchema.latestRegistrationIndex.domainId, + ), + eq( + ensIndexerSchema.registration.registrationIndex, + ensIndexerSchema.latestRegistrationIndex.registrationIndex, + ), + ), + ) + .innerJoin( + ensIndexerSchema.domain, + eq(ensIndexerSchema.registration.domainId, ensIndexerSchema.domain.id), + ) + .where( + and( + gte(ensIndexerSchema.registration.expiry, sql\`EXTRACT(EPOCH FROM NOW())\`), + lte( + ensIndexerSchema.registration.expiry, + sql\`EXTRACT(EPOCH FROM NOW() + INTERVAL '3 days')\`, + ), + eq(ensIndexerSchema.domain.canonical, true), + ), + ) + .orderBy(asc(ensIndexerSchema.registration.expiry)) + .limit(limit); + +console.log(expiringRegistrations);`, + result: [ + { + canonicalName: "block-land.eth", + expiry: "1780674456", + start: "1717602456", + gracePeriod: "7776000", + ownerId: "0x95e488ed0d3497f8cf2392e35c9eb81812ef863c", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x4263eab7cb93cb3161f613e59357fce5de6646c9dab3682c388938231ca16fe6", + }, + { + canonicalName: "hagemz.eth", + expiry: "1780675932", + start: "1749139932", + gracePeriod: "7776000", + ownerId: "0xeb4bde48fb4ad1ab104eb1ef978fdd24e11d6a28", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x7886dc1e5b637005edf606d9e0f5cee78bd86a57e1378e1c76c3fa7557847659", + }, + { + canonicalName: "leogomez.eth", + expiry: "1780688664", + start: "1749152664", + gracePeriod: "7776000", + ownerId: "0x2f7970674b6410f90b8bc43d8188ef35ab3f1a9b", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x6c577a69aa94e39ee0ff1beedbd3385f405506bc35d88f47284056c1ceba5759", + }, + { + canonicalName: "ilanklein.eth", + expiry: "1780692780", + start: "1749156780", + gracePeriod: "7776000", + ownerId: "0x99969df2da9bf780cfd62d7cc22f77e5bdb332df", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x94877f55b294b34b0ac4952ad746f1c163a7e1aba16c41d113c558cd4f2bdff5", + }, + { + canonicalName: "iwms.eth", + expiry: "1780693272", + start: "1749157272", + gracePeriod: "7776000", + ownerId: "0xa098364308d3e400e2f1199675ac765adac4810f", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x13403c49bb9d168c7f18b830b5dd86f562e3e203fe2fc545927e5f609e3e6417", + }, + ], + }, +} satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/indexing-status.ts b/docs/ensnode.io/src/data/unigraph-examples/indexing-status.ts new file mode 100644 index 000000000..174dbd085 --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/indexing-status.ts @@ -0,0 +1,132 @@ +import type { QueryExample } from "./types"; + +const indexingStatusSnapshot = { + indexingStatus: { + strategy: "omnichain", + snapshotTime: 1779795066, + omnichainSnapshot: { + chains: { + 1: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 3327417, + timestamp: 1489165544, + }, + }, + chainStatus: "chain-backfill", + backfillEndBlock: { + number: 25171597, + timestamp: 1779703391, + }, + latestIndexedBlock: { + number: 21224717, + timestamp: 1732054691, + }, + }, + 10: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 110393959, + timestamp: 1696386695, + }, + }, + chainStatus: "chain-backfill", + backfillEndBlock: { + number: 152052671, + timestamp: 1779704119, + }, + latestIndexedBlock: { + number: 128226309, + timestamp: 1732051395, + }, + }, + 8453: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 17522624, + timestamp: 1721834595, + }, + }, + chainStatus: "chain-backfill", + backfillEndBlock: { + number: 46457386, + timestamp: 1779704119, + }, + latestIndexedBlock: { + number: 22632818, + timestamp: 1732054983, + }, + }, + 42161: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 349263357, + timestamp: 1750406457, + }, + }, + chainStatus: "chain-queued", + }, + 59144: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 6682888, + timestamp: 1720768992, + }, + }, + chainStatus: "chain-backfill", + backfillEndBlock: { + number: 30774477, + timestamp: 1779703911, + }, + latestIndexedBlock: { + number: 12280006, + timestamp: 1732054967, + }, + }, + 534352: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 16604272, + timestamp: 1750406415, + }, + }, + chainStatus: "chain-queued", + }, + }, + omnichainStatus: "omnichain-backfill", + omnichainIndexingCursor: 1732054983, + }, + slowestChainIndexingCursor: 1732054983, + }, +} as const; + +/** + * Example query for fetching the indexing status snapshot of an ENSDb Writer + */ +export const exampleIndexingStatus = { + sql: { + codeSnippet: `SELECT value -> 'indexingStatus' as indexing_status_snapshot +FROM "ensnode".metadata +WHERE ens_indexer_schema_name = 'ensindexer_0' +AND key = 'indexing_metadata_context'; +`, + result: { indexing_status_snapshot: indexingStatusSnapshot }, + }, + sdk: { + codeSnippet: `import { IndexingMetadataContextStatusCodes } from "@ensnode/ensdb-sdk"; + +const indexingMetadataContext = await ensDbReader.getIndexingMetadataContext(); + +if (indexingMetadataContext.statusCode === IndexingMetadataContextStatusCodes.Initialized) { + const { indexingStatus } = indexingMetadataContext; + console.log({ indexingStatus }); +}`, + result: { indexingStatus: indexingStatusSnapshot }, + }, +} satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/latest-registrations.ts b/docs/ensnode.io/src/data/unigraph-examples/latest-registrations.ts new file mode 100644 index 000000000..1c59c783a --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/latest-registrations.ts @@ -0,0 +1,179 @@ +import type { QueryExample } from "./types"; + +/** + * Example query for fetching the latest registrations for a Domain by its canonical name. + */ +export const exampleLatestRegistrations = { + sql: { + codeSnippet: `SELECT + d.canonical_name, + r.start, + r.expiry, + d.owner_id, + d.id as domain_id +FROM "ensindexer_0".registrations r +JOIN "ensindexer_0".latest_registration_index lri + ON r.domain_id = lri.domain_id + AND r.registration_index = lri.registration_index +JOIN "ensindexer_0".domains d ON r.domain_id = d.id +WHERE r.start <= EXTRACT(EPOCH FROM NOW()) + AND d.canonical = true + AND r.type <> 'NameWrapper' +ORDER BY r.start DESC +LIMIT 15; +`, + result: [ + { + canonical_name: "[67f53c740a0051f85075dc2383fb83a7b48d2984fc9ed9db56b334ca96d1d309].eth", + start: "1779816216", + expiry: "1811352216", + grace_period: "7776000", + base: "3125000000003490", + premium: "0", + registration_type: "BaseRegistrar", + owner_id: "0x205d2686da3bf33f64c17f21462c51b5ead462cf", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x085bfc7f3695efa2e9d3f9717214d85474f40b4b3ef902b67d2bb49654679fa1", + }, + { + canonical_name: "coolorg.eth", + start: "1779794160", + expiry: "1811330160", + grace_period: "7776000", + base: "3125000000003490", + premium: "0", + registration_type: "BaseRegistrar", + owner_id: "0x5f71c6074141d41d0e769689dc9830388a5c7e3e", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xe2a76df5554592c08c28946f750aad17d0c2bb3553c6dd2f0298e0f2fe873be3", + }, + { + canonical_name: "[1d79e56219bd305bbd3fa8ab125997beceebe63b8f6e12d0b6cb956e955549ca].eth", + start: "1779785856", + expiry: "1906016256", + grace_period: "7776000", + base: "12508561643849586", + premium: "0", + registration_type: "BaseRegistrar", + owner_id: "0x07a811c0bd3f46733822df66d7e2d723e6f73fd6", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x8f9e9956842380910d836aa4ac85bc50bee0999824ea8b54412d02bc56d57c6c", + }, + { + canonical_name: "kevin-af.eth", + start: "1779768924", + expiry: "1874463324", + grace_period: "7776000", + base: "9383561643846096", + premium: "0", + registration_type: "BaseRegistrar", + owner_id: "0x6a89280251f72918b6b143817201008b3d99d96e", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x49c87057b1dbe6a6bdfdcf9cc9b2bc12544bc3cd9fd01aa6ea8efb7dab89ca7e", + }, + { + canonical_name: "executor1.eth", + start: "1779743592", + expiry: "1937509992", + grace_period: "7776000", + base: "15633561643853076", + premium: "0", + registration_type: "BaseRegistrar", + owner_id: "0xbb0274908a353d7c37a97ea1ea099352ee39734e", + domain_id: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x56fc11b057812d300b43fd13136ee7e656fa9081e5a3063ed011224302b3658f", + }, + ], + }, + sdk: { + codeSnippet: `import { and, asc, eq, ne, lte, sql } from "drizzle-orm"; + +const limit = 5; + +const recentRegistrations = await ensDb + .select({ + canonicalName: ensIndexerSchema.domain.canonicalName, + expiry: ensIndexerSchema.registration.expiry, + start: ensIndexerSchema.registration.start, + registrationType: ensIndexerSchema.registration.type, + ownerId: ensIndexerSchema.domain.ownerId, + domainId: ensIndexerSchema.domain.id, + }) + .from(ensIndexerSchema.registration) + .innerJoin( + ensIndexerSchema.latestRegistrationIndex, + and( + eq( + ensIndexerSchema.registration.domainId, + ensIndexerSchema.latestRegistrationIndex.domainId, + ), + eq( + ensIndexerSchema.registration.registrationIndex, + ensIndexerSchema.latestRegistrationIndex.registrationIndex, + ), + ), + ) + .innerJoin( + ensIndexerSchema.domain, + eq(ensIndexerSchema.registration.domainId, ensIndexerSchema.domain.id), + ) + .where( + and( + lte(ensIndexerSchema.registration.start, sql\`EXTRACT(EPOCH FROM NOW())\`), + eq(ensIndexerSchema.domain.canonical, true), + ne(ensIndexerSchema.registration.type, "NameWrapper"), + ), + ) + .orderBy(desc(ensIndexerSchema.registration.start)) + .limit(limit); + +console.log(recentRegistrations);`, + result: [ + { + canonicalName: "[67f53c740a0051f85075dc2383fb83a7b48d2984fc9ed9db56b334ca96d1d309].eth", + expiry: "1811352216", + start: "1779816216", + registrationType: "BaseRegistrar", + ownerId: "0x205d2686da3bf33f64c17f21462c51b5ead462cf", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x085bfc7f3695efa2e9d3f9717214d85474f40b4b3ef902b67d2bb49654679fa1", + }, + { + canonicalName: "coolorg.eth", + expiry: "1811330160", + start: "1779794160", + registrationType: "BaseRegistrar", + ownerId: "0x5f71c6074141d41d0e769689dc9830388a5c7e3e", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xe2a76df5554592c08c28946f750aad17d0c2bb3553c6dd2f0298e0f2fe873be3", + }, + { + canonicalName: "[1d79e56219bd305bbd3fa8ab125997beceebe63b8f6e12d0b6cb956e955549ca].eth", + expiry: "1906016256", + start: "1779785856", + registrationType: "BaseRegistrar", + ownerId: "0x07a811c0bd3f46733822df66d7e2d723e6f73fd6", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x8f9e9956842380910d836aa4ac85bc50bee0999824ea8b54412d02bc56d57c6c", + }, + { + canonicalName: "kevin-af.eth", + expiry: "1874463324", + start: "1779768924", + registrationType: "BaseRegistrar", + ownerId: "0x6a89280251f72918b6b143817201008b3d99d96e", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x49c87057b1dbe6a6bdfdcf9cc9b2bc12544bc3cd9fd01aa6ea8efb7dab89ca7e", + }, + { + canonicalName: "executor1.eth", + expiry: "1937509992", + start: "1779743592", + registrationType: "BaseRegistrar", + ownerId: "0xbb0274908a353d7c37a97ea1ea099352ee39734e", + domainId: + "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x56fc11b057812d300b43fd13136ee7e656fa9081e5a3063ed011224302b3658f", + }, + ], + }, +} satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts b/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts index 2040f8e2a..0344f4759 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts @@ -20,68 +20,47 @@ FROM "ensindexer_0".domains d JOIN parent p ON d.registry_id = p.subregistry_id WHERE d.canonical = true ORDER BY d.canonical_name -LIMIT 10; +LIMIT 5; `, result: [ { type: "ENSv1Domain", - canonical_name: "[52602a50858115661619fb28cf543ee766c182e0be6743c72d5bd674b3d12686].eth", - canonical_node: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", - id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + canonical_name: "$2442.eth", + canonical_node: "0x89c28481de9640822dd25f821e341b0304640b9363d419e10b9d6b99f049fc8c", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x89c28481de9640822dd25f821e341b0304640b9363d419e10b9d6b99f049fc8c", }, { type: "ENSv1Domain", - canonical_name: "[d90db363b8bc1371f7d738d264ff7294bfc5636f907c467adf68321a3c6d8188].eth", - canonical_node: "0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", - id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", - }, - { - type: "ENSv2Domain", - canonical_name: "katrenpadu.eth", - canonical_node: "0xf8ae81127bcd7ff99828b3dbd982a943d6dd961ee3f1a6ca707aa0eea913328e", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-112554048520345018269255786667391470421317806528110367240542760381540064034816", - }, - { - type: "ENSv2Domain", - canonical_name: "roppp.eth", - canonical_node: "0x39095c3dfb872d6441c95547f88591e7fb97014eef30cabe3df12a9b2a64dbe8", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-88275407146030613359050872632052369891139576190404928761656352489271755538432", + canonical_name: "$bless.eth", + canonical_node: "0xfca869315283e0747c929ff17f57d6712cf76b372395eef8b770595d393902ea", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xfca869315283e0747c929ff17f57d6712cf76b372395eef8b770595d393902ea", }, { type: "ENSv1Domain", - canonical_name: "sfmpfv44d0mig.eth", - canonical_node: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", - id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", - }, - { - type: "ENSv2Domain", - canonical_name: "sfmpfv44d0mig.eth", - canonical_node: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-30078755955643454526763071980293195785165410039216352470119925106082295316480", + canonical_name: "$pauly.eth", + canonical_node: "0x8254e524ac45f21ce3a3483e52dbedf1aa7bc5d5cff69d4a189df5e369f6eacf", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x8254e524ac45f21ce3a3483e52dbedf1aa7bc5d5cff69d4a189df5e369f6eacf", }, { - type: "ENSv2Domain", - canonical_name: "sfmpfv44d0res.eth", - canonical_node: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-37259562946248504018379781627254217478007643438678910837598068740925220192256", - }, - { - type: "ENSv2Domain", - canonical_name: "sfmpfvtoicv2ok.eth", - canonical_node: "0x7d0c27336cf9d51c3fc8f29ef4ef69df9cd4a8ec983e3e17d457a8de6013f3c5", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-49509597771493908415463190501045916291230588437784211605615168713991762477056", + type: "ENSv1Domain", + canonical_name: "$vince.eth", + canonical_node: "0x1630be8a50ed7d79c1a5510ca7aaf3d6a483596affcc81c2dbaad17262619dcc", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x1630be8a50ed7d79c1a5510ca7aaf3d6a483596affcc81c2dbaad17262619dcc", }, { - type: "ENSv2Domain", - canonical_name: "wrapnation.eth", - canonical_node: "0xc7da9e9ef214b62959a64ba9967cb33a2545a5c0f217d2716474ad1e85fa51fd", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", + type: "ENSv1Domain", + canonical_name: "0000000000000000000000000000000000000000.eth", + canonical_node: "0xc13733debbac0dd0143dddcbfe8fcede7c3405033357f034d8b0779ad85802e1", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xc13733debbac0dd0143dddcbfe8fcede7c3405033357f034d8b0779ad85802e1", }, ], }, sdk: { codeSnippet: `import { and, eq, asc } from "drizzle-orm"; +const name = "eth"; +const limit = 5; + // Two-step: // 1) find parent domain, // 2) query children by parent domain's subregistryId. @@ -90,7 +69,7 @@ const [parentDomain] = await ensDb .from(ensIndexerSchema.domain) .where( and( - eq(ensIndexerSchema.domain.canonicalName, "eth"), + eq(ensIndexerSchema.domain.canonicalName, name), eq(ensIndexerSchema.domain.canonical, true), ) ); @@ -118,57 +97,33 @@ if (parentDomain?.subregistryId) { result: [ { type: "ENSv1Domain", - canonicalName: "[52602a50858115661619fb28cf543ee766c182e0be6743c72d5bd674b3d12686].eth", - canonicalNode: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", - id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + canonicalName: "$2442.eth", + canonicalNode: "0x89c28481de9640822dd25f821e341b0304640b9363d419e10b9d6b99f049fc8c", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x89c28481de9640822dd25f821e341b0304640b9363d419e10b9d6b99f049fc8c", }, { type: "ENSv1Domain", - canonicalName: "[d90db363b8bc1371f7d738d264ff7294bfc5636f907c467adf68321a3c6d8188].eth", - canonicalNode: "0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", - id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", - }, - { - type: "ENSv2Domain", - canonicalName: "katrenpadu.eth", - canonicalNode: "0xf8ae81127bcd7ff99828b3dbd982a943d6dd961ee3f1a6ca707aa0eea913328e", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-112554048520345018269255786667391470421317806528110367240542760381540064034816", - }, - { - type: "ENSv2Domain", - canonicalName: "roppp.eth", - canonicalNode: "0x39095c3dfb872d6441c95547f88591e7fb97014eef30cabe3df12a9b2a64dbe8", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-88275407146030613359050872632052369891139576190404928761656352489271755538432", + canonicalName: "$bless.eth", + canonicalNode: "0xfca869315283e0747c929ff17f57d6712cf76b372395eef8b770595d393902ea", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xfca869315283e0747c929ff17f57d6712cf76b372395eef8b770595d393902ea", }, { type: "ENSv1Domain", - canonicalName: "sfmpfv44d0mig.eth", - canonicalNode: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", - id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", - }, - { - type: "ENSv2Domain", - canonicalName: "sfmpfv44d0mig.eth", - canonicalNode: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-30078755955643454526763071980293195785165410039216352470119925106082295316480", - }, - { - type: "ENSv2Domain", - canonicalName: "sfmpfv44d0res.eth", - canonicalNode: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-37259562946248504018379781627254217478007643438678910837598068740925220192256", + canonicalName: "$pauly.eth", + canonicalNode: "0x8254e524ac45f21ce3a3483e52dbedf1aa7bc5d5cff69d4a189df5e369f6eacf", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x8254e524ac45f21ce3a3483e52dbedf1aa7bc5d5cff69d4a189df5e369f6eacf", }, { - type: "ENSv2Domain", - canonicalName: "sfmpfvtoicv2ok.eth", - canonicalNode: "0x7d0c27336cf9d51c3fc8f29ef4ef69df9cd4a8ec983e3e17d457a8de6013f3c5", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-49509597771493908415463190501045916291230588437784211605615168713991762477056", + type: "ENSv1Domain", + canonicalName: "$vince.eth", + canonicalNode: "0x1630be8a50ed7d79c1a5510ca7aaf3d6a483596affcc81c2dbaad17262619dcc", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x1630be8a50ed7d79c1a5510ca7aaf3d6a483596affcc81c2dbaad17262619dcc", }, { - type: "ENSv2Domain", - canonicalName: "wrapnation.eth", - canonicalNode: "0xc7da9e9ef214b62959a64ba9967cb33a2545a5c0f217d2716474ad1e85fa51fd", - id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", + type: "ENSv1Domain", + canonicalName: "0000000000000000000000000000000000000000.eth", + canonicalNode: "0xc13733debbac0dd0143dddcbfe8fcede7c3405033357f034d8b0779ad85802e1", + id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xc13733debbac0dd0143dddcbfe8fcede7c3405033357f034d8b0779ad85802e1", }, ], }, From 2b41753cafa6c338fcf08ef2950de4ed66e2e588 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Fri, 5 Jun 2026 19:54:58 +0200 Subject: [PATCH 4/7] Apply AI PR feedback --- .../integrations/starlight/sidebar-topics/integrate.ts | 2 +- .../integrate/unigraph/examples/account-domains.mdx | 2 +- .../docs/integrate/unigraph/examples/domain-events.mdx | 2 +- .../unigraph/examples/expiring-registrations.mdx | 2 +- .../src/data/unigraph-examples/account-domains.ts | 2 +- .../data/unigraph-examples/expiring-registrations.ts | 2 +- .../src/data/unigraph-examples/indexing-status.ts | 6 +++--- .../src/data/unigraph-examples/latest-registrations.ts | 10 +++++++--- 8 files changed, 16 insertions(+), 12 deletions(-) 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 60af43d51..c28584288 100644 --- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts +++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts @@ -203,7 +203,7 @@ export const integrateSidebarTopic = { link: "/docs/integrate/unigraph/examples/latest-registrations", }, { - label: "Exipring Registrations", + label: "Expiring Registrations", link: "/docs/integrate/unigraph/examples/expiring-registrations", }, { diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index 65dfe167e..a721b5ccf 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -14,7 +14,7 @@ import { exampleAccountDomains } from "@data/unigraph-examples/account-domains"; Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) ::: -Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. +Fetch the Domains owned by an address (across both ENSv1 and ENSv2), including each Domain's `type` (`ENSv1Domain` vs `ENSv2Domain`). See [Connect](/docs/integrate/unigraph/examples) for setup. 'NameWrapper' ORDER BY r.start DESC -LIMIT 15; +LIMIT 5; `, result: [ { @@ -86,7 +90,7 @@ LIMIT 15; ], }, sdk: { - codeSnippet: `import { and, asc, eq, ne, lte, sql } from "drizzle-orm"; + codeSnippet: `import { and, desc, eq, ne, lte, sql } from "drizzle-orm"; const limit = 5; From 8b2ce94ec2b49d3e22ee5607800ba8a459c45de3 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Fri, 5 Jun 2026 21:11:51 +0200 Subject: [PATCH 5/7] Make examples to use latest indexed columns in domains table --- .../UnigraphStaticExample.astro | 6 +- .../data/unigraph-examples/account-domains.ts | 5 + .../data/unigraph-examples/domain-by-name.ts | 47 ++++-- .../data/unigraph-examples/domain-events.ts | 121 +++++--------- .../domains-fuzzy-search-by-name.ts | 150 ++++++++---------- .../expiring-registrations.ts | 5 + .../data/unigraph-examples/indexing-status.ts | 11 +- .../unigraph-examples/latest-registrations.ts | 5 + .../subdomains-by-parent-name.ts | 98 ++++++------ .../src/data/unigraph-examples/types.ts | 1 + .../src/data/unigraph-examples/utils.ts | 2 + 11 files changed, 222 insertions(+), 229 deletions(-) create mode 100644 docs/ensnode.io/src/data/unigraph-examples/utils.ts diff --git a/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro index a4663d928..093a7e1f6 100644 --- a/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro +++ b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro @@ -38,7 +38,7 @@ const defaultResultNote = - {sql.resultNote ?? defaultResultNote} + @@ -54,8 +54,6 @@ const defaultResultNote = - - {ensDbSdk.resultNote ?? defaultResultNote} - + diff --git a/docs/ensnode.io/src/data/unigraph-examples/account-domains.ts b/docs/ensnode.io/src/data/unigraph-examples/account-domains.ts index 8aa10a7b8..27347cc06 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/account-domains.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/account-domains.ts @@ -1,5 +1,8 @@ +import { outputSource } from "./utils"; import type { QueryExample } from "./types"; +const resultNote = outputSource("V2 Sepolia"); + /** * Example query for fetching Domains by their owner's address, * demonstrating the use of canonical fields to query across both ENSv1 and @@ -93,6 +96,7 @@ LIMIT 10;`, owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", }, ], + resultNote, }, sdk: { codeSnippet: `import { and, eq, asc } from "drizzle-orm"; @@ -194,5 +198,6 @@ console.log(accountDomains);`, ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", }, ], + resultNote, }, } satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts b/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts index 5fc624f93..46ef0ee76 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/domain-by-name.ts @@ -1,7 +1,10 @@ +import { outputSource } from "./utils"; import type { QueryExample } from "./types"; +const resultNote = outputSource("V2 Sepolia"); + /** - * Example query for fetching a Domain by its canonical name, + * Example query for fetching Domains by a canonical name, * demonstrating the use of canonical fields to query across both ENSv1 and * ENSv2 domains without branching by protocol version. */ @@ -14,23 +17,33 @@ export const exampleDomainByName = { canonical_node, owner_id FROM "ensindexer_0".domains -WHERE canonical_name = 'vitalik.eth' +WHERE canonical_name = 'eth' AND canonical = true; `, result: [ { - id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", type: "ENSv1Domain", - canonical_name: "vitalik.eth", - canonical_node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - owner_id: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + canonical_name: "eth", + canonical_node: "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", + owner_id: "0xa51c9e6efe589407c72984e93b45e35a71a398ec", + }, + { + id: "11155111-0x835f0b284e78cd3f358bcf6cba3b53809f09b79e-35894389512221139346028120028875095598761990588366713962827482865183915769856", + type: "ENSv2Domain", + canonical_name: "eth", + canonical_node: "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", }, ], + resultNote, }, sdk: { codeSnippet: `import { and, eq } from "drizzle-orm"; -const [vitalik] = await ensDb +const name = "eth"; + +const domains = await ensDb .select({ id: ensIndexerSchema.domain.id, type: ensIndexerSchema.domain.type, @@ -41,20 +54,28 @@ const [vitalik] = await ensDb .from(ensIndexerSchema.domain) .where( and( - eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth"), + eq(ensIndexerSchema.domain.canonicalName, name), eq(ensIndexerSchema.domain.canonical, true) ) ); -console.log(vitalik);`, +console.log(domains);`, result: [ { - id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", type: "ENSv1Domain", - canonicalName: "vitalik.eth", - canonicalNode: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - ownerId: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", + canonicalName: "eth", + canonicalNode: "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", + ownerId: "0xa51c9e6efe589407c72984e93b45e35a71a398ec", + }, + { + id: "11155111-0x835f0b284e78cd3f358bcf6cba3b53809f09b79e-35894389512221139346028120028875095598761990588366713962827482865183915769856", + type: "ENSv2Domain", + canonicalName: "eth", + canonicalNode: "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", }, ], + resultNote, }, } satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/domain-events.ts b/docs/ensnode.io/src/data/unigraph-examples/domain-events.ts index 82bbdec47..af585abed 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/domain-events.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/domain-events.ts @@ -1,5 +1,8 @@ +import { outputSource } from "./utils"; import type { QueryExample } from "./types"; +const resultNote = outputSource("V2 Sepolia"); + /** * Example query for fetching recent events for a Domain by its canonical name. */ @@ -16,7 +19,7 @@ export const exampleDomainEvents = { FROM "ensindexer_0".events e JOIN "ensindexer_0".domain_events de ON e.id = de.event_id JOIN "ensindexer_0".domains d ON de.domain_id = d.id -WHERE d.canonical_name = 'vitalik.eth' +WHERE d.canonical_name = 'wrapnation.eth' AND d.canonical = true ORDER BY e.block_number DESC, e.log_index DESC LIMIT 5; @@ -24,60 +27,41 @@ LIMIT 5; result: [ { chain_id: "11155111", - block_number: "6023942", - transaction_hash: "0x6206e95dc5ba5fc8d0804283498f17bac18081437b4198c824b62ee851622ba5", - log_index: 194, - contract_address: "0xfed6a969aaa60e4961fcd3ebf1a2e8913ac65b72", - sender: "0x225f137127d9067788314bc7fcc1f36746a3c3b5", - domain_id: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - }, - { - chain_id: "11155111", - block_number: "6023942", - transaction_hash: "0x6206e95dc5ba5fc8d0804283498f17bac18081437b4198c824b62ee851622ba5", - log_index: 193, - contract_address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85", - sender: "0x225f137127d9067788314bc7fcc1f36746a3c3b5", - domain_id: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - }, - { - chain_id: "11155111", - block_number: "4107392", - transaction_hash: "0xf143118eb4100361f040b1ae5627562125f0cf1717073a8204befe5e512c80d4", - log_index: 22, - contract_address: "0x0635513f179d50a207757e05759cbd106d7dfce8", - sender: "0x179a862703a4adfb29896552df9e307980d19285", + block_number: "10918673", + transaction_hash: "0xca5e111932f0b26e1d458c690c5dfe8b2b8165ee2a937c04e4021e93a71954e4", + log_index: 42, + contract_address: "0xb68e594a47fe057bd31e7a8229ffcfd85b2e28af", + sender: "0x801d2e48d378f161dba7ad7ad002ad557714c191", domain_id: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", }, { chain_id: "11155111", - block_number: "4107386", - transaction_hash: "0x6410de03e9a2f12543e491d1048209e5638d702948cf23d48a63d96a50efd20d", - log_index: 19, - contract_address: "0xfed6a969aaa60e4961fcd3ebf1a2e8913ac65b72", - sender: "0x179a862703a4adfb29896552df9e307980d19285", + block_number: "10918673", + transaction_hash: "0xca5e111932f0b26e1d458c690c5dfe8b2b8165ee2a937c04e4021e93a71954e4", + log_index: 38, + contract_address: "0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1", + sender: "0xb68e594a47fe057bd31e7a8229ffcfd85b2e28af", domain_id: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", }, { chain_id: "11155111", - block_number: "4107386", - transaction_hash: "0x6410de03e9a2f12543e491d1048209e5638d702948cf23d48a63d96a50efd20d", - log_index: 16, - contract_address: "0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e", - sender: "0x179a862703a4adfb29896552df9e307980d19285", + block_number: "10918673", + transaction_hash: "0xca5e111932f0b26e1d458c690c5dfe8b2b8165ee2a937c04e4021e93a71954e4", + log_index: 37, + contract_address: "0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1", + sender: "0xb68e594a47fe057bd31e7a8229ffcfd85b2e28af", domain_id: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", }, ], + resultNote, }, sdk: { codeSnippet: `import { and, desc, eq } from "drizzle-orm"; -const name = "vitalik.eth"; +const name = "wrapnation.eth"; const limit = 5; const domainEvents = await ensDb @@ -115,54 +99,35 @@ console.log(domainEvents);`, result: [ { chainId: 11155111, - blockNumber: "6023942", - transactionHash: "0x6206e95dc5ba5fc8d0804283498f17bac18081437b4198c824b62ee851622ba5", - logIndex: 194, - contractAddress: "0xfed6a969aaa60e4961fcd3ebf1a2e8913ac65b72", - sender: "0x225f137127d9067788314bc7fcc1f36746a3c3b5", - domainId: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - }, - { - chainId: 11155111, - blockNumber: "6023942", - transactionHash: "0x6206e95dc5ba5fc8d0804283498f17bac18081437b4198c824b62ee851622ba5", - logIndex: 193, - contractAddress: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85", - sender: "0x225f137127d9067788314bc7fcc1f36746a3c3b5", - domainId: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - }, - { - chainId: 11155111, - blockNumber: "4107392", - transactionHash: "0xf143118eb4100361f040b1ae5627562125f0cf1717073a8204befe5e512c80d4", - logIndex: 22, - contractAddress: "0x0635513f179d50a207757e05759cbd106d7dfce8", - sender: "0x179a862703a4adfb29896552df9e307980d19285", + blockNumber: "10918673", + transactionHash: "0xca5e111932f0b26e1d458c690c5dfe8b2b8165ee2a937c04e4021e93a71954e4", + logIndex: 42, + contractAddress: "0xb68e594a47fe057bd31e7a8229ffcfd85b2e28af", + sender: "0x801d2e48d378f161dba7ad7ad002ad557714c191", domainId: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", }, { chainId: 11155111, - blockNumber: "4107386", - transactionHash: "0x6410de03e9a2f12543e491d1048209e5638d702948cf23d48a63d96a50efd20d", - logIndex: 19, - contractAddress: "0xfed6a969aaa60e4961fcd3ebf1a2e8913ac65b72", - sender: "0x179a862703a4adfb29896552df9e307980d19285", + blockNumber: "10918673", + transactionHash: "0xca5e111932f0b26e1d458c690c5dfe8b2b8165ee2a937c04e4021e93a71954e4", + logIndex: 38, + contractAddress: "0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1", + sender: "0xb68e594a47fe057bd31e7a8229ffcfd85b2e28af", domainId: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", }, { chainId: 11155111, - blockNumber: "4107386", - transactionHash: "0x6410de03e9a2f12543e491d1048209e5638d702948cf23d48a63d96a50efd20d", - logIndex: 16, - contractAddress: "0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e", - sender: "0x179a862703a4adfb29896552df9e307980d19285", + blockNumber: "10918673", + transactionHash: "0xca5e111932f0b26e1d458c690c5dfe8b2b8165ee2a937c04e4021e93a71954e4", + logIndex: 37, + contractAddress: "0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1", + sender: "0xb68e594a47fe057bd31e7a8229ffcfd85b2e28af", domainId: - "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-68387108911874305622019956908914347119991166106996198835225265868637904830464", }, ], + resultNote, }, } satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts b/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts index bd33a75c2..f88aaebe6 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts @@ -1,66 +1,53 @@ +import { outputSource } from "./utils"; import type { QueryExample } from "./types"; +const resultNote = outputSource("V2 Sepolia"); + /** * Example query for fetching Domains by a fuzzy search on their canonical name. */ export const exampleDomainsFuzzySearchByName = { sql: { codeSnippet: `SELECT - type, - canonical_name, - canonical_node, - owner_id, - similarity(canonical_name, 'vitalik') as name_similarity, - id + type, + canonical_name, + canonical_node, + owner_id, + similarity(canonical_name, 'reverse') as name_similarity, + id FROM "ensindexer_0".domains --- Use the pg_trgm similarity operator (%) for fuzzy matching on canonical_name -WHERE canonical_name % 'vitalik' +WHERE __canonicalNamePrefix % 'reverse' AND canonical = true ORDER BY name_similarity DESC LIMIT 5; `, result: [ { - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - type: "ENSv1Domain", - canonical_name: "vitalik.eth", - canonical_node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - owner_id: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", - name_similarity: 0.6666667, - }, - { - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x278adcf079fceb551531f1593deae8891d83bf4708b935d54eda7f8db51ce797", - type: "ENSv1Domain", - canonical_name: "vitalikkk.eth", - canonical_node: "0x278adcf079fceb551531f1593deae8891d83bf4708b935d54eda7f8db51ce797", - owner_id: "0x588f6b3169f60176c1143f8bab47bcf3deebecdc", - name_similarity: 0.46666667, - }, - { - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x55e83f7d37d7cf1f87c40a6bd5fc8e62e8898b327c5a09776596f6efe547349a", type: "ENSv1Domain", - canonical_name: "vitalik.taars.eth", - canonical_node: "0x55e83f7d37d7cf1f87c40a6bd5fc8e62e8898b327c5a09776596f6efe547349a", - owner_id: "0x5a09e3ec3efdd91205cbb097142a4f4dcefc7f02", - name_similarity: 0.44444445, + canonical_name: "reverse", + canonical_node: "0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + name_similarity: 1, + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", }, { - id: "84532-0x1493b2567056c2181630115660963e13a8e32735-0x97fa42e69feb1d407361108d79ddad705707a16392d7823f8b21b44dabfc4a9d", - type: "ENSv1Domain", - canonical_name: "vitalik.basetest.eth", - canonical_node: "0x97fa42e69feb1d407361108d79ddad705707a16392d7823f8b21b44dabfc4a9d", - owner_id: "0x15378e401f9c3243639c7c3250be0f396a758e40", - name_similarity: 0.3809524, + type: "ENSv2Domain", + canonical_name: "reverse", + canonical_node: "0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + owner_id: "0xffffffffff52d316b7bd028358089bc8066b8f80", + name_similarity: 1, + id: "11155111-0x835f0b284e78cd3f358bcf6cba3b53809f09b79e-100753657518907091865523951670693454610893379027273088370152078482136467767296", }, { - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x117e485acf1ebff586d1382b7689201ce23f7142ae92f4c397849f4b01e6a1cc", type: "ENSv1Domain", - canonical_name: "vitalikbuterin.eth", - canonical_node: "0x117e485acf1ebff586d1382b7689201ce23f7142ae92f4c397849f4b01e6a1cc", - owner_id: "0x16ecc228f185b084cb884be2d65544f5ca4dd761", - name_similarity: 0.35, + canonical_name: "addr.reverse", + canonical_node: "0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2", + owner_id: "0x26e5e80e8f36607ef401443fb34eea363c86e8f7", + name_similarity: 0.61538464, + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2", }, ], + resultNote, }, sdk: { codeSnippet: `import { and, asc, eq, sql } from "drizzle-orm"; @@ -70,61 +57,52 @@ const limit = 5; const domains = await ensDb .select({ - canonicalName: ensIndexerSchema.domain.canonicalName, - canonicalDepth: ensIndexerSchema.domain.canonicalDepth, - ownerId: ensIndexerSchema.domain.ownerId, - nameSimilarity: sql\`similarity(\${ensIndexerSchema.domain.canonicalName}, \${q})\`.as( - "name_similarity", - ), - id: ensIndexerSchema.domain.id, - }) - .from(ensIndexerSchema.domain) - .where( - and( - sql\`\${ensIndexerSchema.domain.canonicalName} % \${q}\`, - eq(ensIndexerSchema.domain.canonical, true), - ), - ) - .orderBy(sql\`name_similarity DESC\`) - .limit(limit); + type: ensIndexerSchema.domain.type, + canonicalName: ensIndexerSchema.domain.canonicalName, + canonicalNode: ensIndexerSchema.domain.canonicalNode, + ownerId: ensIndexerSchema.domain.ownerId, + nameSimilarity: sql\`similarity(\${ensIndexerSchema.domain.canonicalName}, \${q})\`.as( + "name_similarity", + ), + id: ensIndexerSchema.domain.id, + }) + .from(ensIndexerSchema.domain) + .where( + and( + sql\`\${ensIndexerSchema.domain.__canonicalNamePrefix} % \${q}\`, + eq(ensIndexerSchema.domain.canonical, true), + ), + ) + .orderBy(sql\`name_similarity DESC\`) + .limit(limit); console.log(domains);`, result: [ { - canonicalName: "vitalik.eth", - canonicalDepth: 2, - ownerId: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", - nameSimilarity: 0.6666667, - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - }, - { - canonicalName: "vitalikkk.eth", - canonicalDepth: 2, - ownerId: "0x588f6b3169f60176c1143f8bab47bcf3deebecdc", - nameSimilarity: 0.46666667, - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x278adcf079fceb551531f1593deae8891d83bf4708b935d54eda7f8db51ce797", - }, - { - canonicalName: "vitalik.taars.eth", - canonicalDepth: 3, - ownerId: "0x5a09e3ec3efdd91205cbb097142a4f4dcefc7f02", - nameSimilarity: 0.44444445, - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x55e83f7d37d7cf1f87c40a6bd5fc8e62e8898b327c5a09776596f6efe547349a", + type: "ENSv1Domain", + canonicalName: "reverse", + canonicalNode: "0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + nameSimilarity: 1, + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", }, { - canonicalName: "vitalik.basetest.eth", - canonicalDepth: 3, - ownerId: "0x15378e401f9c3243639c7c3250be0f396a758e40", - nameSimilarity: 0.3809524, - id: "84532-0x1493b2567056c2181630115660963e13a8e32735-0x97fa42e69feb1d407361108d79ddad705707a16392d7823f8b21b44dabfc4a9d", + type: "ENSv2Domain", + canonicalName: "reverse", + canonicalNode: "0xa097f6721ce401e757d1223a763fef49b8b5f90bb18567ddb86fd205dff71d34", + ownerId: "0xffffffffff52d316b7bd028358089bc8066b8f80", + nameSimilarity: 1, + id: "11155111-0x835f0b284e78cd3f358bcf6cba3b53809f09b79e-100753657518907091865523951670693454610893379027273088370152078482136467767296", }, { - canonicalName: "vitalikbuterin.eth", - canonicalDepth: 2, - ownerId: "0x16ecc228f185b084cb884be2d65544f5ca4dd761", - nameSimilarity: 0.35, - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x117e485acf1ebff586d1382b7689201ce23f7142ae92f4c397849f4b01e6a1cc", + type: "ENSv1Domain", + canonicalName: "addr.reverse", + canonicalNode: "0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2", + ownerId: "0x26e5e80e8f36607ef401443fb34eea363c86e8f7", + nameSimilarity: 0.61538464, + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2", }, ], + resultNote, }, } satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/expiring-registrations.ts b/docs/ensnode.io/src/data/unigraph-examples/expiring-registrations.ts index b924914ce..fbc3d15c5 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/expiring-registrations.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/expiring-registrations.ts @@ -1,5 +1,8 @@ +import { outputSource } from "./utils"; import type { QueryExample } from "./types"; +const resultNote = outputSource("Alpha Sepolia"); + /** * Example query for fetching ENS registrations that are expiring soon. */ @@ -70,6 +73,7 @@ LIMIT 5; "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x13403c49bb9d168c7f18b830b5dd86f562e3e203fe2fc545927e5f609e3e6417", }, ], + resultNote, }, sdk: { codeSnippet: `import { and, asc, eq, gte, lte, sql } from "drizzle-orm"; @@ -164,5 +168,6 @@ console.log(expiringRegistrations);`, "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x13403c49bb9d168c7f18b830b5dd86f562e3e203fe2fc545927e5f609e3e6417", }, ], + resultNote, }, } satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/indexing-status.ts b/docs/ensnode.io/src/data/unigraph-examples/indexing-status.ts index 9e1526228..a8aee98fe 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/indexing-status.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/indexing-status.ts @@ -1,6 +1,9 @@ +import { outputSource } from "@data/unigraph-examples/utils"; import type { QueryExample } from "./types"; -const result = { +const resultNote = outputSource("Alpha"); + +const indexingMetadataContextPartial = { indexingStatus: { strategy: "omnichain", snapshotTime: 1779795066, @@ -116,7 +119,8 @@ FROM "ensnode".metadata WHERE ens_indexer_schema_name = 'ensindexer_0' AND key = 'indexing_metadata_context'; `, - result: { indexing_status_snapshot: result.indexingStatus }, + result: { indexing_status_snapshot: indexingMetadataContextPartial.indexingStatus }, + resultNote, }, sdk: { codeSnippet: `import { IndexingMetadataContextStatusCodes } from "@ensnode/ensdb-sdk"; @@ -127,6 +131,7 @@ if (indexingMetadataContext.statusCode === IndexingMetadataContextStatusCodes.In const { indexingStatus } = indexingMetadataContext; console.log({ indexingStatus }); }`, - result: { indexingStatus: result.indexingStatus }, + result: { indexingStatus: indexingMetadataContextPartial.indexingStatus }, + resultNote, }, } satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/latest-registrations.ts b/docs/ensnode.io/src/data/unigraph-examples/latest-registrations.ts index 786d79433..1e21d43da 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/latest-registrations.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/latest-registrations.ts @@ -1,5 +1,8 @@ +import { outputSource } from "./utils"; import type { QueryExample } from "./types"; +const resultNote = outputSource("Alpha Sepolia"); + /** * Example query for fetching the latest registrations across all Domains. */ @@ -88,6 +91,7 @@ LIMIT 5; "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x56fc11b057812d300b43fd13136ee7e656fa9081e5a3063ed011224302b3658f", }, ], + resultNote, }, sdk: { codeSnippet: `import { and, desc, eq, ne, lte, sql } from "drizzle-orm"; @@ -179,5 +183,6 @@ console.log(recentRegistrations);`, "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x56fc11b057812d300b43fd13136ee7e656fa9081e5a3063ed011224302b3658f", }, ], + resultNote, }, } satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts b/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts index 0344f4759..b3b2a28d6 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/subdomains-by-parent-name.ts @@ -1,5 +1,8 @@ +import { outputSource } from "./utils"; import type { QueryExample } from "./types"; +const resultNote = outputSource("V2 Sepolia"); + /** * Example query for fetching subdomains by their canonical name of the parent domain. */ @@ -25,56 +28,57 @@ LIMIT 5; result: [ { type: "ENSv1Domain", - canonical_name: "$2442.eth", - canonical_node: "0x89c28481de9640822dd25f821e341b0304640b9363d419e10b9d6b99f049fc8c", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x89c28481de9640822dd25f821e341b0304640b9363d419e10b9d6b99f049fc8c", + canonical_name: "[52602a50858115661619fb28cf543ee766c182e0be6743c72d5bd674b3d12686].eth", + canonical_node: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", }, { type: "ENSv1Domain", - canonical_name: "$bless.eth", - canonical_node: "0xfca869315283e0747c929ff17f57d6712cf76b372395eef8b770595d393902ea", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xfca869315283e0747c929ff17f57d6712cf76b372395eef8b770595d393902ea", + canonical_name: "[d90db363b8bc1371f7d738d264ff7294bfc5636f907c467adf68321a3c6d8188].eth", + canonical_node: "0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", }, { - type: "ENSv1Domain", - canonical_name: "$pauly.eth", - canonical_node: "0x8254e524ac45f21ce3a3483e52dbedf1aa7bc5d5cff69d4a189df5e369f6eacf", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x8254e524ac45f21ce3a3483e52dbedf1aa7bc5d5cff69d4a189df5e369f6eacf", + type: "ENSv2Domain", + canonical_name: "katrenpadu.eth", + canonical_node: "0xf8ae81127bcd7ff99828b3dbd982a943d6dd961ee3f1a6ca707aa0eea913328e", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-112554048520345018269255786667391470421317806528110367240542760381540064034816", }, { - type: "ENSv1Domain", - canonical_name: "$vince.eth", - canonical_node: "0x1630be8a50ed7d79c1a5510ca7aaf3d6a483596affcc81c2dbaad17262619dcc", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x1630be8a50ed7d79c1a5510ca7aaf3d6a483596affcc81c2dbaad17262619dcc", + type: "ENSv2Domain", + canonical_name: "roppp.eth", + canonical_node: "0x39095c3dfb872d6441c95547f88591e7fb97014eef30cabe3df12a9b2a64dbe8", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-88275407146030613359050872632052369891139576190404928761656352489271755538432", }, { type: "ENSv1Domain", - canonical_name: "0000000000000000000000000000000000000000.eth", - canonical_node: "0xc13733debbac0dd0143dddcbfe8fcede7c3405033357f034d8b0779ad85802e1", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xc13733debbac0dd0143dddcbfe8fcede7c3405033357f034d8b0779ad85802e1", + canonical_name: "sfmpfv44d0mig.eth", + canonical_node: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", }, ], + resultNote, }, sdk: { - codeSnippet: `import { and, eq, asc } from "drizzle-orm"; + codeSnippet: `import { and, eq, inArray, asc } from "drizzle-orm"; const name = "eth"; const limit = 5; // Two-step: -// 1) find parent domain, -// 2) query children by parent domain's subregistryId. -const [parentDomain] = await ensDb +// 1) find parent domains +// 2) query children by each parent domain's subregistryId. +const parentDomains = await ensDb .select({ subregistryId: ensIndexerSchema.domain.subregistryId }) .from(ensIndexerSchema.domain) .where( and( eq(ensIndexerSchema.domain.canonicalName, name), eq(ensIndexerSchema.domain.canonical, true), - ) -); + ), + ); -if (parentDomain?.subregistryId) { +if (parentDomains.length > 0) { const subdomains = await ensDb .select({ type: ensIndexerSchema.domain.type, @@ -85,11 +89,14 @@ if (parentDomain?.subregistryId) { .from(ensIndexerSchema.domain) .where( and( - eq(ensIndexerSchema.domain.registryId, parentDomain.subregistryId), + inArray( + ensIndexerSchema.domain.registryId, + parentDomains.map((d) => d.subregistryId), + ), eq(ensIndexerSchema.domain.canonical, true), - ) + ), ) - .orderBy(asc(ensIndexerSchema.domain.canonicalName)) + .orderBy(asc(ensIndexerSchema.domain.__canonicalNamePrefix)) .limit(limit); console.log(subdomains); @@ -97,34 +104,35 @@ if (parentDomain?.subregistryId) { result: [ { type: "ENSv1Domain", - canonicalName: "$2442.eth", - canonicalNode: "0x89c28481de9640822dd25f821e341b0304640b9363d419e10b9d6b99f049fc8c", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x89c28481de9640822dd25f821e341b0304640b9363d419e10b9d6b99f049fc8c", + canonicalName: "[52602a50858115661619fb28cf543ee766c182e0be6743c72d5bd674b3d12686].eth", + canonicalNode: "0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0xe91ce3506cd47457c2b3f04c2736875ca1d17ed74bf1a328a7e64cca5ae8c94b", }, { type: "ENSv1Domain", - canonicalName: "$bless.eth", - canonicalNode: "0xfca869315283e0747c929ff17f57d6712cf76b372395eef8b770595d393902ea", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xfca869315283e0747c929ff17f57d6712cf76b372395eef8b770595d393902ea", + canonicalName: "[d90db363b8bc1371f7d738d264ff7294bfc5636f907c467adf68321a3c6d8188].eth", + canonicalNode: "0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", + id: "11155111-0xb6fb46e1458915dd828633d91e1df8e4c3f2d4dd-0x08c0f01c419a8971af6b3eefe2a8bba1556cccf1163df60b1cdbcab632c8ab48", }, { - type: "ENSv1Domain", - canonicalName: "$pauly.eth", - canonicalNode: "0x8254e524ac45f21ce3a3483e52dbedf1aa7bc5d5cff69d4a189df5e369f6eacf", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x8254e524ac45f21ce3a3483e52dbedf1aa7bc5d5cff69d4a189df5e369f6eacf", + type: "ENSv2Domain", + canonicalName: "katrenpadu.eth", + canonicalNode: "0xf8ae81127bcd7ff99828b3dbd982a943d6dd961ee3f1a6ca707aa0eea913328e", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-112554048520345018269255786667391470421317806528110367240542760381540064034816", }, { - type: "ENSv1Domain", - canonicalName: "$vince.eth", - canonicalNode: "0x1630be8a50ed7d79c1a5510ca7aaf3d6a483596affcc81c2dbaad17262619dcc", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x1630be8a50ed7d79c1a5510ca7aaf3d6a483596affcc81c2dbaad17262619dcc", + type: "ENSv2Domain", + canonicalName: "roppp.eth", + canonicalNode: "0x39095c3dfb872d6441c95547f88591e7fb97014eef30cabe3df12a9b2a64dbe8", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-88275407146030613359050872632052369891139576190404928761656352489271755538432", }, { - type: "ENSv1Domain", - canonicalName: "0000000000000000000000000000000000000000.eth", - canonicalNode: "0xc13733debbac0dd0143dddcbfe8fcede7c3405033357f034d8b0779ad85802e1", - id: "11155111-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xc13733debbac0dd0143dddcbfe8fcede7c3405033357f034d8b0779ad85802e1", + type: "ENSv2Domain", + canonicalName: "sfmpfv44d0mig.eth", + canonicalNode: "0x9b365136312d7ee6e232e3c98e459bc8667ec818c47fbbc55bb5e23d0a21e8cc", + id: "11155111-0x64c81210d0e580cfc7746f3fb910bf0e8f6378e1-30078755955643454526763071980293195785165410039216352470119925106082295316480", }, ], + resultNote, }, } satisfies QueryExample; diff --git a/docs/ensnode.io/src/data/unigraph-examples/types.ts b/docs/ensnode.io/src/data/unigraph-examples/types.ts index 31605aa9a..56aebb586 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/types.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/types.ts @@ -1,6 +1,7 @@ export interface CodeExample { codeSnippet: string; result: unknown; + resultNote?: string; } export interface QueryExample { diff --git a/docs/ensnode.io/src/data/unigraph-examples/utils.ts b/docs/ensnode.io/src/data/unigraph-examples/utils.ts new file mode 100644 index 000000000..9935d4e66 --- /dev/null +++ b/docs/ensnode.io/src/data/unigraph-examples/utils.ts @@ -0,0 +1,2 @@ +export const outputSource = (source: "V2 Sepolia" | "Alpha" | "Alpha Sepolia") => + `Output matches a point in time snapshot of ENSDb result from our "${source}" Hosted ENSNode instance. Live output depends on the configuration of your ENSNode instance and also changes that may have happened in ENS since this point in time snapshot example response was captured.`; From 131bc366bea510a9b7f4d6217b19171f6760f26c Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Fri, 5 Jun 2026 21:13:34 +0200 Subject: [PATCH 6/7] Apply AI PR feedback --- .../docs/docs/integrate/unigraph/examples/indexing-status.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index 09a77e5d6..791e9bca6 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -1,6 +1,6 @@ --- title: Indexing Status -description: Read the indexing status snapshot for an ENSIndexer instance from ENSDb. +description: Read the indexing status snapshot for an ENSDb Writer instance from ENSDb. sidebar: label: Indexing Status --- From 0a0b6f24d42dd9b7e05513ca59c32d9f2d2826b4 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Fri, 5 Jun 2026 21:16:00 +0200 Subject: [PATCH 7/7] Apply AI PR feedback --- .../src/data/unigraph-examples/domains-fuzzy-search-by-name.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts b/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts index f88aaebe6..1440e9f42 100644 --- a/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts +++ b/docs/ensnode.io/src/data/unigraph-examples/domains-fuzzy-search-by-name.ts @@ -50,7 +50,7 @@ LIMIT 5; resultNote, }, sdk: { - codeSnippet: `import { and, asc, eq, sql } from "drizzle-orm"; + codeSnippet: `import { and, eq, sql } from "drizzle-orm"; const q = "vitalik"; const limit = 5;