diff --git a/.changeset/datasources-identify-contracts.md b/.changeset/datasources-identify-contracts.md new file mode 100644 index 0000000000..386f744815 --- /dev/null +++ b/.changeset/datasources-identify-contracts.md @@ -0,0 +1,5 @@ +--- +"@ensnode/datasources": patch +--- + +Add contract identification by address. `@ensnode/datasources` exports `identifyDatasourceContracts(namespaceId, query)`, which finds every well-known contract in a namespace's datasources whose address matches a given address, optionally scoped to a chain. diff --git a/.changeset/enscli-datasources-identify.md b/.changeset/enscli-datasources-identify.md new file mode 100644 index 0000000000..57d2e58324 --- /dev/null +++ b/.changeset/enscli-datasources-identify.md @@ -0,0 +1,5 @@ +--- +"enscli": patch +--- + +`enscli` gains `datasources identify
`: an offline command that reports which well-known ENS contract an address corresponds to. It accepts a bare address, a chain-scoped `chainId:address`, or full CAIP-10 `eip155:chainId:address`, and `--namespace` (default `mainnet`) selects which namespace to search. A miss returns `{ matches: [] }` with exit code `0`. diff --git a/.changeset/enscli-initial.md b/.changeset/enscli-initial.md new file mode 100644 index 0000000000..e41026a279 --- /dev/null +++ b/.changeset/enscli-initial.md @@ -0,0 +1,5 @@ +--- +"enscli": patch +--- + +Introduce `enscli`, a new agent- and human-friendly CLI for ENS that wraps `enssdk` and the ENS Omnigraph. It supports raw Omnigraph queries (`enscli ensnode omnigraph "" --variables …`), offline schema exploration (`enscli ensnode omnigraph schema [Type[.field]]`), indexing status, ENSRainbow healing, and `namehash`/`labelhash`. It defaults to NameHash-hosted instances per `--namespace` (mainnet, sepolia, sepolia-v2), resolves config from flags/env/`.env`, outputs JSON when piped and a pretty form in a TTY, and hardens inputs against agent hallucinations. diff --git a/.changeset/ensnode-sdk-sepolia-v2-default.md b/.changeset/ensnode-sdk-sepolia-v2-default.md new file mode 100644 index 0000000000..81540ccba8 --- /dev/null +++ b/.changeset/ensnode-sdk-sepolia-v2-default.md @@ -0,0 +1,5 @@ +--- +"@ensnode/ensnode-sdk": patch +--- + +`getDefaultEnsNodeUrl` now returns the hosted default for the `sepolia-v2` namespace (`https://api.v2-sepolia.ensnode.io`). diff --git a/.changeset/ensskills-datasources-identify.md b/.changeset/ensskills-datasources-identify.md new file mode 100644 index 0000000000..5685e04672 --- /dev/null +++ b/.changeset/ensskills-datasources-identify.md @@ -0,0 +1,5 @@ +--- +"ensskills": patch +--- + +The `enscli` agent skill documents the new `datasources identify` command. diff --git a/.changeset/ensskills-initial.md b/.changeset/ensskills-initial.md new file mode 100644 index 0000000000..8491f0934d --- /dev/null +++ b/.changeset/ensskills-initial.md @@ -0,0 +1,5 @@ +--- +"ensskills": patch +--- + +Introduce `ensskills`, a versioned, `skills-npm`-installable package of ENS agent skills. It ships the `ens-protocol` skill (a concise, stable, vendor-neutral conceptual model of the ENS protocol β€” nametree, normalization, hashing, registry/resolver/registrar, resolution, records, multichain β€” with pull-as-needed reference pages), the `omnigraph` skill (autogenerated schema reference + vetted example queries, plus prose on the unified ENSv1+ENSv2 datamodel and resolution), and the `enscli` skill (running Omnigraph queries and the other CLI commands, with the output contract, namespace/URL resolution, and input hardening), with stub skills reserved for `enssdk`, `enskit`, `migrate-to-omnigraph`, and `unigraph-sql`. diff --git a/.changeset/ensskills-llms-txt-link.md b/.changeset/ensskills-llms-txt-link.md new file mode 100644 index 0000000000..418dafba9f --- /dev/null +++ b/.changeset/ensskills-llms-txt-link.md @@ -0,0 +1,5 @@ +--- +"ensskills": patch +--- + +Point the base skill at the published `llms.txt` / `llms-full.txt` docs endpoints so agents can load the full ENSNode documentation when a question reaches beyond the skills. diff --git a/LICENSE b/LICENSE index 24d66814d7..08d139577c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 NameHash +Copyright (c) 2026 NameHash Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/apps/ensadmin/LICENSE b/apps/ensadmin/LICENSE index 24d66814d7..08d139577c 100644 --- a/apps/ensadmin/LICENSE +++ b/apps/ensadmin/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 NameHash +Copyright (c) 2026 NameHash Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/apps/ensapi/LICENSE b/apps/ensapi/LICENSE index 24d66814d7..08d139577c 100644 --- a/apps/ensapi/LICENSE +++ b/apps/ensapi/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 NameHash +Copyright (c) 2026 NameHash Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/apps/ensapi/src/omnigraph-api/schema/domain.ts b/apps/ensapi/src/omnigraph-api/schema/domain.ts index 25cd91262c..8c56dec249 100644 --- a/apps/ensapi/src/omnigraph-api/schema/domain.ts +++ b/apps/ensapi/src/omnigraph-api/schema/domain.ts @@ -145,7 +145,7 @@ DomainInterfaceRef.implement({ owner: t.field({ type: AccountRef, description: - "If this is an ENSv1Domain, this is the effective owner of the Domain. If this is an ENSv2Domain, this is the on-chain owner address (the HCA account address if used).", + "If this is an ENSv1Domain, this is the effective owner of the Domain (derived from the Registry, the Registrar, or the NameWrapper, in that order). If this is an ENSv2Domain, this is the on-chain owner address (the HCA account address if used).", nullable: true, resolve: (parent) => parent.ownerId, }), @@ -279,7 +279,7 @@ DomainInterfaceRef.implement({ // Domain.subdomains ///////////////////// subdomains: t.connection({ - description: "All Domains that are direct descendents of this Domain in the namegraph.", + description: "All Domains that are direct descendants of this Domain in the namegraph.", type: DomainInterfaceRef, args: { where: t.arg({ type: SubdomainsWhereInput }), diff --git a/apps/ensindexer/LICENSE b/apps/ensindexer/LICENSE index 24d66814d7..08d139577c 100644 --- a/apps/ensindexer/LICENSE +++ b/apps/ensindexer/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 NameHash +Copyright (c) 2026 NameHash Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/apps/ensrainbow/LICENSE b/apps/ensrainbow/LICENSE index 24d66814d7..08d139577c 100644 --- a/apps/ensrainbow/LICENSE +++ b/apps/ensrainbow/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 NameHash +Copyright (c) 2026 NameHash Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/apps/fallback-ensapi/LICENSE b/apps/fallback-ensapi/LICENSE index 24d66814d7..08d139577c 100644 --- a/apps/fallback-ensapi/LICENSE +++ b/apps/fallback-ensapi/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 NameHash +Copyright (c) 2026 NameHash Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/docs/ensnode.io/LICENSE b/docs/ensnode.io/LICENSE index 24d66814d7..08d139577c 100644 --- a/docs/ensnode.io/LICENSE +++ b/docs/ensnode.io/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 NameHash +Copyright (c) 2026 NameHash Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal 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 7e20f42bbe..3ddf735176 100644 --- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts +++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts @@ -26,6 +26,10 @@ export const integrateSidebarTopic = { }, ], }, + { + label: "AI/LLM Tooling πŸ€–", + link: "/docs/integrate/ai-llm", + }, { label: "ENS Subgraph", collapsed: false, @@ -236,9 +240,5 @@ export const integrateSidebarTopic = { }, ], }, - { - label: "AI / LLM Tooling", - link: "/docs/integrate/ai-llm", - }, ], }; diff --git a/docs/ensnode.io/src/components/molecules/HostedInstanceSdkVersionWarning.astro b/docs/ensnode.io/src/components/molecules/HostedInstanceSdkVersionWarning.astro deleted file mode 100644 index e76f944d03..0000000000 --- a/docs/ensnode.io/src/components/molecules/HostedInstanceSdkVersionWarning.astro +++ /dev/null @@ -1,23 +0,0 @@ ---- -import { Aside } from "@astrojs/starlight/components"; - -import snapshot from "@data/omnigraph-examples/snapshot.json"; - -// The SDK version is locked to the production-deployed Omnigraph version (see the vendored -// `@data/omnigraph-examples/snapshot.json`). The SDK bundles the Omnigraph schema, so pinning the -// matching version keeps gql.tada's generated types aligned with the deployed API. -const VERSION = snapshot.sdkVersion; ---- - - diff --git a/docs/ensnode.io/src/components/molecules/HostedInstanceVersionWarning.astro b/docs/ensnode.io/src/components/molecules/HostedInstanceVersionWarning.astro new file mode 100644 index 0000000000..ee46dfbabf --- /dev/null +++ b/docs/ensnode.io/src/components/molecules/HostedInstanceVersionWarning.astro @@ -0,0 +1,53 @@ +--- +import { Aside } from "@astrojs/starlight/components"; + +import snapshot from "@data/omnigraph-examples/snapshot.json"; +// TEMP prerelease: enscli/ensskills aren't published at `snapshot.sdkVersion` yet β€” remove at the +// first official release (see @data/enscli-ensskills-prerelease). +import { ENSCLI_ENSSKILLS_NPM_SPEC } from "@data/enscli-ensskills-prerelease"; + +// The ENSNode suite is version-locked to the production-deployed Omnigraph (see the vendored +// `@data/omnigraph-examples/snapshot.json`). The SDK bundles the Omnigraph schema (consumed by the +// `gql.tada` TypeScript plugin) and `ensskills` bundles the schema plus example queries, so pinning +// the matching version keeps generated types / agent knowledge aligned with the deployed API. +interface Props { + // "sdk" warns about pinning enssdk/enskit for gql.tada types; "skills" warns about pinning + // ensskills/enscli for agent knowledge. + variant: "sdk" | "skills"; +} + +const { variant } = Astro.props; +const VERSION = snapshot.sdkVersion; +--- + + diff --git a/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro b/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro index 5e98e4c61b..e7b7b1a619 100644 --- a/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro +++ b/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro @@ -1,11 +1,11 @@ --- import { Aside, LinkCard } from "@astrojs/starlight/components"; -import HostedInstanceSdkVersionWarning from "./HostedInstanceSdkVersionWarning.astro"; +import HostedInstanceVersionWarning from "./HostedInstanceVersionWarning.astro"; --- - + diff --git a/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx b/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx index 1efd4cdef2..5f1a5ee0c8 100644 --- a/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx +++ b/docs/ensnode.io/src/content/docs/docs/hosted-instances.mdx @@ -7,7 +7,7 @@ sidebar: import { LinkCard } from "@astrojs/starlight/components"; import HostedEnsNodeInstance from "@components/molecules/HostedEnsNodeInstance.astro"; -import HostedInstanceSdkVersionWarning from "@components/molecules/HostedInstanceSdkVersionWarning.astro"; +import HostedInstanceVersionWarning from "@components/molecules/HostedInstanceVersionWarning.astro"; import EnsSubgraphCorrectnessPostEnsV2Launch from "@components/molecules/EnsSubgraphCorrectnessPostEnsV2Launch.astro"; export const subgraphCompatibilityApiLevel = `API-level Subgraph Compatibility. This ENSNode instance has a fully backwards compatible ENS Subgraph GraphQL API. However, additional plugins have been activated which index a superset of data into the subgraph data model in ENSDb. This superset of indexed data means that the data returned for some ENS Subgraph API queries may be different.`; @@ -24,7 +24,7 @@ NameHash Labs provides hosted instances of ENSNode for developers building on EN These instances are currently provided free of charge with no API key required, have no rate limiting, and are maintained and monitored by the NameHash Labs team. - + ### ENS Namespaces diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx index 499b95d541..45d9e343d9 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx @@ -3,11 +3,57 @@ title: AI / LLM Tooling description: AI and LLM tooling for building on ENSv2. --- -import { LinkCard } from "@astrojs/starlight/components"; +import { Code, LinkCard } from "@astrojs/starlight/components"; +// TEMP prerelease: enscli/ensskills install pins β€” remove at first official release (see enscli-ensskills-prerelease.ts) +import { ENSCLI_ENSSKILLS_NPM_SPEC, ENSCLI_ENSSKILLS_GIT_REF } from "@data/enscli-ensskills-prerelease"; +import HostedInstanceVersionWarning from "@components/molecules/HostedInstanceVersionWarning.astro"; -AI and LLM tooling is a key priority for ENSNode, and we're building the infrastructure to make ENS a first-class citizen in the world of AI coding assistants and chat-based interfaces. +We're building the infrastructure to make ENS a first-class citizen for AI agents. -Next on the roadmap for this space are [`enscli`](/docs/integrate/integration-options/enscli) and [`ensskills`](/docs/integrate/integration-options/ensskills) β€” the foundation for how developers and their AI agents will reach for ENS. +The foundation for how developers and their AI agents reach for ENS is [`ensskills`](/docs/integrate/integration-options/ensskills), that teach your AI assistant about ENS, ENSNode, the ENS Omnigraph, and how to drive [`enscli`](/docs/integrate/integration-options/enscli) β€” an agent- and human-friendly CLI β€” on your behalf. + + + +## Quickstart (`npm`/`pnpm`/`yarn`/`bun`) + +Add `ensskills` and [`skills-npm`](https://github.com/antfu/skills-npm) to your project and wire a `prepare` script so the pinned skills re-sync into your agent directories (`.claude/skills`, `.cursor/skills`, …) on every install: + + + +```bash +npm install # symlinks the skills for your detected agents +``` + +## Quickstart (`npx skills`) + +Not in a Node project? [`skills`](https://github.com/vercel-labs/skills) installs every ENS skill straight from the repo. It normally pins to the matching `v…` release tag; during the current prerelease window it tracks `main` until `enscli`/`ensskills` ship in their first official release: + + + +## Next Steps + +That's it β€” your AI agent now has all of [`ensskills`](/docs/integrate/integration-options/ensskills) at its disposal. + +```md title=prompt.md +Which address currently owns vitalik.eth +and how many other domains do they own? +``` -Check back soon for more detail on our AI / LLM tooling roadmap. +## Documentation as `llms.txt` + +If you aren't using `ensskills`, the entire documentation site is also published in the [`llms.txt`](https://llmstxt.org/) format so any agent or LLM can load it directly as context: + +- [`/llms.txt`](https://ensnode.io/llms.txt) β€” a structured index of the documentation with links to every page. +- [`/llms-full.txt`](https://ensnode.io/llms-full.txt) β€” the entire documentation concatenated into a single file, ready to drop into a model's context window. + +Paste this at the top of a prompt to point your agent at the full documentation before asking your question: + +```md title="prompt.md" +Load the ENSNode documentation from https://ensnode.io/llms-full.txt to answer the following question: +``` diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/ens-subgraph/key-limitations.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/ens-subgraph/key-limitations.mdx index 3fd9c3307f..2984a195a6 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/ens-subgraph/key-limitations.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/ens-subgraph/key-limitations.mdx @@ -128,7 +128,7 @@ The Subgraph schema spreads ownership across multiple fields β€” `owner`, `regis ::: :::tip[One effective owner field] -In the [Omnigraph API](/docs/integrate/omnigraph) `Domain.owner` is _always_ the effective owner's addressβ€”no weird edge-cases! For ENSv2 Domains, `Domain.owner` is Smart-Account-aware and represents the true owner of the Domain at a given time. +In the [Omnigraph API](/docs/integrate/omnigraph) `Domain.owner` is _always_ the effective owner's address β€” no weird edge-cases! For ENSv2 Domains, `Domain.owner` is Smart-Account-aware and represents the true owner of the Domain at a given time. ::: ## Missing all offchain ENS names diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enscli.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enscli.mdx index 1a0781f833..11265d0711 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enscli.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enscli.mdx @@ -1,33 +1,131 @@ --- title: enscli (CLI) -description: Coming soon β€” an agent- and human-friendly CLI for the ENS Omnigraph API, wrapping enssdk. +description: An agent- and human-friendly CLI for ENS β€” query the ENS Omnigraph, explore the schema, resolve hashes, heal labels, and check indexing status from the terminal. --- import { Aside, LinkCard } from "@astrojs/starlight/components"; +import HostedInstanceVersionWarning from "@components/molecules/HostedInstanceVersionWarning.astro"; -