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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
}
},
{
"comment": "Walkthroughs mirror the example apps verbatim; don't reflow their embedded GraphQL.",
"files": ["docs/ensnode.io/src/components/walkthroughs/**/*.mdx", "examples/**/*.{ts,tsx}"],
"comment": "Don't reflow embedded code: hand-authored GraphQL examples throughout the docs, and the example apps that walkthroughs mirror verbatim.",
"files": ["docs/ensnode.io/**/*.{md,mdx}", "examples/**/*.{ts,tsx}"],
"options": {
"embeddedLanguageFormatting": "off"
}
Expand Down
2 changes: 1 addition & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"recommendations": ["biomejs.biome"]
"recommendations": ["biomejs.biome", "esbenp.prettier-vscode"]
}
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,14 @@
},
"[terraform]": {
"editor.defaultFormatter": "hashicorp.terraform"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[mdx]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[astro]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const integrateSidebarTopic = {
link: "/docs/integrate/ens-subgraph",
},
{
label: "Key Limitations",
label: "Key Limitations 🚨",
link: "/docs/integrate/ens-subgraph/key-limitations",
},
{
Expand Down Expand Up @@ -72,6 +72,10 @@ export const integrateSidebarTopic = {
label: "Overview",
link: "/docs/integrate/omnigraph",
},
{
label: "Core Concepts",
link: "/docs/integrate/omnigraph/concepts",
},
{
label: "Protocol Acceleration",
link: "/docs/integrate/omnigraph/protocol-acceleration",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { LinkCard, CardGrid, Aside } from "@astrojs/starlight/components";
import HostedInstanceSdkVersionWarning from "@components/molecules/HostedInstanceSdkVersionWarning.astro";
import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro";

## What is ENSv2?
Expand Down Expand Up @@ -30,8 +29,6 @@ Here's a summary of some popular integration strategies:

With `enssdk`, leverage ENSNode and the Omnigraph from any JavaScript runtime to power your frontend or backend apps. `enssdk` comes with built-in type-safety and editor autocomplete for Omnigraph queries.

<HostedInstanceSdkVersionWarning />

```ts title="example.ts"
Comment thread
shrugs marked this conversation as resolved.
// create and extend an EnsNodeClient with Omnigraph API support
const client = createEnsNodeClient({ url: process.env.ENSNODE_URL! }).extend(omnigraph);
Expand Down Expand Up @@ -72,76 +69,34 @@ const result = await client.omnigraph.query({ query: HelloWorldQuery });

With `enskit`, leverage ENSNode and the Omnigraph to power your React components using `useOmnigraphQuery`. `enskit` comes with built-in type-safety, Omnigraph-specific cache directives, easy infinite pagination, and much much more.

<HostedInstanceSdkVersionWarning />
Comment thread
shrugs marked this conversation as resolved.

```tsx title="example.tsx"
// this is fully typechecked and supports editor autocomplete!
const DomainFragment = graphql(`
fragment DomainFragment on Domain {
__typename
id
name
owner { id address }
}
`);

// this is fully typechecked and supports editor autocomplete!
const DomainByNameQuery = graphql(
`
// this query is fully typechecked and supports editor autocomplete!
Comment thread
vercel[bot] marked this conversation as resolved.
const DomainByNameQuery = graphql(`
query DomainByNameQuery($name: InterpretedName!) {
domain(by: { name: $name }) {
...DomainFragment
subdomains {
edges { node { ...DomainFragment } }
Comment thread
vercel[bot] marked this conversation as resolved.
name
owner {
address
}
}
}
`,
[DomainFragment],
);

function RenderDomainFragment({ data }: { data: FragmentOf<typeof DomainFragment> }) {
// type-safe access to fragment data!
const domain = readFragment(DomainFragment, data);

return (
<>
<span>Name: {domain.name ? beautifyInterpretedName(domain.name) : "Unnamed Domain"}</span>
<span>Protocol Version: {domain.__typename === "ENSv1Domain" ? "ENSv1" : "ENSv2"}</span>
<span>Owner: {domain.owner ? domain.owner.address : "Unowned"}</span>
</>
);
}
`);
Comment thread
shrugs marked this conversation as resolved.

export function RenderDomainAndSubdomains({ name }: { name: InterpretedName }) {
export function DomainCard({ name }: { name: InterpretedName }) {
// `result` is fully typed!
const [result] = useOmnigraphQuery({ query: DomainByNameQuery, variables: { name } });
const { data, fetching, error } = result;

// some loading/error handling
if (!data && fetching) return <p>Loading...</p>;
if (fetching) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
if (!data?.domain) return <p>No domain was found with name '{name}'.</p>;
if (!data?.domain) return <p>No domain found for '{name}'.</p>;

// now we have type-safe access to Domain!
const domain = readFragment(DomainFragment, data.domain);
const { subdomains } = data.domain;
const { domain } = data;

return (
<div>
<RenderDomainFragment data={data.domain} />

<h2>Subdomains:</h2>
<ul>
{subdomains?.edges.map((edge) => {
const { id } = readFragment(DomainFragment, edge.node);
return (
<li key={id}>
<RenderDomainFragment data={edge.node} />
</li>
);
})}
</ul>
<p>Name: {domain.name ? beautifyInterpretedName(domain.name) : "Unnamed Domain"}</p>
<p>Owner: {domain.owner?.address ?? "Unowned"}</p>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { LinkCard, CardGrid, Aside } from "@astrojs/starlight/components";
import HostedInstanceSdkVersionWarning from "@components/molecules/HostedInstanceSdkVersionWarning.astro";
import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro";

## What is ENSv2?
Expand Down Expand Up @@ -30,8 +29,6 @@ Here's a summary of some popular integration strategies:

With `enssdk`, leverage ENSNode and the Omnigraph from any JavaScript runtime to power your frontend or backend apps. `enssdk` comes with built-in type-safety and editor autocomplete for Omnigraph queries.

<HostedInstanceSdkVersionWarning />

```ts title="example.ts"
Comment thread
shrugs marked this conversation as resolved.
// create and extend an EnsNodeClient with Omnigraph API support
const client = createEnsNodeClient({ url: process.env.ENSNODE_URL! }).extend(omnigraph);
Expand All @@ -40,7 +37,6 @@ const client = createEnsNodeClient({ url: process.env.ENSNODE_URL! }).extend(omn
const HelloWorldQuery = graphql(`
query HelloWorld {
domain(by: { name: "eth" }) {
id
canonical { name { beautified } }
owner { address }
}
Expand Down Expand Up @@ -72,76 +68,32 @@ const result = await client.omnigraph.query({ query: HelloWorldQuery });

With `enskit`, leverage ENSNode and the Omnigraph to power your React components using `useOmnigraphQuery`. `enskit` comes with built-in type-safety, Omnigraph-specific cache directives, easy infinite pagination, and much much more.

<HostedInstanceSdkVersionWarning />

```tsx title="example.tsx"
// this is fully typechecked and supports editor autocomplete!
const DomainFragment = graphql(`
fragment DomainFragment on Domain {
__typename
id
canonical { name { beautified } }
owner { id address }
}
`);

// this is fully typechecked and supports editor autocomplete!
const DomainByNameQuery = graphql(
`
// this query is fully typechecked and supports editor autocomplete!
const DomainByNameQuery = graphql(`
Comment thread
shrugs marked this conversation as resolved.
query DomainByNameQuery($name: InterpretedName!) {
domain(by: { name: $name }) {
...DomainFragment
subdomains {
edges { node { ...DomainFragment } }
}
canonical { name { beautified } }
owner { address }
}
}
`,
[DomainFragment],
);

function RenderDomainFragment({ data }: { data: FragmentOf<typeof DomainFragment> }) {
// type-safe access to fragment data!
const domain = readFragment(DomainFragment, data);

return (
<>
<span>Name: {domain.canonical ? domain.canonical.name.beautified : "Unnamed Domain"}</span>
<span>Protocol Version: {domain.__typename === "ENSv1Domain" ? "ENSv1" : "ENSv2"}</span>
<span>Owner: {domain.owner ? domain.owner.address : "Unowned"}</span>
</>
);
}
`);

export function RenderDomainAndSubdomains({ name }: { name: InterpretedName }) {
export function DomainCard({ name }: { name: InterpretedName }) {
// `result` is fully typed!
const [result] = useOmnigraphQuery({ query: DomainByNameQuery, variables: { name } });
const { data, fetching, error } = result;

// some loading/error handling
if (!data && fetching) return <p>Loading...</p>;
if (fetching) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
if (!data?.domain) return <p>No domain was found with name '{name}'.</p>;
if (!data?.domain) return <p>No domain found for '{name}'.</p>;

// now we have type-safe access to Domain!
const domain = readFragment(DomainFragment, data.domain);
const { subdomains } = data.domain;
const { domain } = data;

return (
<div>
<RenderDomainFragment data={data.domain} />

<h2>Subdomains:</h2>
<ul>
{subdomains?.edges.map((edge) => {
const { id } = readFragment(DomainFragment, edge.node);
return (
<li key={id}>
<RenderDomainFragment data={edge.node} />
</li>
);
})}
</ul>
<p>Name: {domain.canonical?.name.beautified ?? "Unnamed Domain"}</p>
Comment thread
shrugs marked this conversation as resolved.
<p>Owner: {domain.owner?.address ?? "Unowned"}</p>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ sidebar:

import { LinkCard } from "@astrojs/starlight/components";

:::danger[The ENS Subgraph is legacy — do not build new ENS apps on it!]
The ENS Subgraph predates ENSv2 and **cannot** carry your app into it. Three reasons it falls short:
:::danger[🚨 The ENS Subgraph is not ENSv2 compatible]
The ENS Subgraph **fundamentally fails as a source of ENS data as soon as ENSv2 launches.**

- **ENSv1 only — instantly out of date.** The Subgraph data model has no concept of ENSv2. The moment ENSv2 launches (Summer 2026), apps still reading the Subgraph are looking at a stale, partial view of ENS.
- **Single-chain only — misses most names.** The Subgraph indexes a single chain, so it never sees Basenames (`.base.eth`), Lineanames (`.linea.eth`), or 3DNS names (`.box`).
- **No resolution — and slow when you bolt it on.** The Subgraph doesn't resolve names; you're left making your own RPC calls, which are slow, hard to batch, and easy to get wrong.

These are only the headline issues. See the full list of [Key Limitations](/docs/integrate/ens-subgraph/key-limitations).
<LinkCard
title="Key Limitations 🚨"
href="/docs/integrate/ens-subgraph/key-limitations"
description="See the full list of Key Subgraph Limitations and how the Omnigraph addresses them."
/>
:::

:::tip[Start here instead: the ENS Omnigraph API]
Expand Down
Loading
Loading