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 bcfd7d91a..5ad76b7ab 100644 --- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts +++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts @@ -92,6 +92,10 @@ export const integrateSidebarTopic = { label: "Core Concepts", link: "/docs/integrate/omnigraph/concepts", }, + { + label: "ENS Resolution", + link: "/docs/integrate/omnigraph/ens-resolution", + }, { label: "Protocol Acceleration", link: "/docs/integrate/omnigraph/protocol-acceleration", diff --git a/docs/ensnode.io/src/components/organisms/OmnigraphStaticExampleSet.astro b/docs/ensnode.io/src/components/organisms/OmnigraphStaticExampleSet.astro index 4a4311969..885e2a6b3 100644 --- a/docs/ensnode.io/src/components/organisms/OmnigraphStaticExampleSet.astro +++ b/docs/ensnode.io/src/components/organisms/OmnigraphStaticExampleSet.astro @@ -37,7 +37,13 @@ const { description } = getOmnigraphExampleById(id); const data = resolveOmnigraphStaticExample(id); --- -{!hideDescription &&

{description}

} +{ + !hideDescription && ( +
+

+

+ ) +}
+ +What you get in `resolve.profile`: + +- **Addresses** — keyed by chain (`ethereum`, `solana`, `base`, …) in chain-native encodings. +- **Social accounts** — `{ handle, httpUrl }` pairs, ready to link. +- **Avatar and header images** — `httpUrl` values you can use directly in ``, including derivation from NFT references per [ENSIP-12](https://docs.ens.domains/ensip/12). +- **Missing or invalid records** — `null`, so you can render without extra guards. + +The same predictable shape works well for AI agents — structured fields and `null` for anything missing or invalid, without decoding resolver data in the prompt. + + + +## Forward resolution — raw `records` + +`resolve.records` returns protocol-accurate resolver data: numeric coin types, arbitrary text keys, and unparsed bytes. This is the shape you would work with if you decoded resolver storage yourself — or if you need records that `profile` does not model. + + + +## Reverse resolution — `primaryName` + +**Reverse resolution** answers a simple question: _what name does this address want to be known by?_ On a given chain, that is its **primary name** ([ENSIP-19](https://docs.ens.domains/ensip/19)). If the address has not set one, the result is `null` — safe to render like any other missing field. + +Primary names are per-chain. Use friendly chain names like `ETHEREUM` or `BASE` rather than raw coin types. `beautified` is ready for UI rendering; `interpreted` is the stable form for lookups and links. See [Beautified Name](/docs/reference/terminology#beautified-name). + + + +If you need the display data that goes with that name — not just the name itself — see **Identity resolution** below. + +## Identity resolution — full address resolve + +**Identity resolution** is the pattern most wallets and explorers actually use: start from an address, get the primary name, and load its full display data — all in one request. It is reverse resolution followed immediately by forward resolution, with no extra round trip. + + + +Breaking down the example above: + +- **Start from an address** — pass any wallet address; the query looks up that account's ENS identity. +- **Pick a chain** — primary names are per-chain (e.g. Ethereum mainnet). Use friendly chain names like `ETHEREUM` or `BASE` instead of raw coin types. +- **Display the name** — `beautified` is ready for UI rendering; `interpreted` is the stable form for lookups and links. +- **Load the display data in the same request** — avatar, bio, and social links are forward-resolved from the primary name. The response shape is the same `resolve.profile` structure covered in the forward resolution section above. diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-events.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-events.mdx index 2408b1b56..30961a7f6 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-events.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-events.mdx @@ -1,8 +1,6 @@ --- title: Account Events description: Indexed events involving an address across ENS contracts. -sidebar: - order: 11 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-migrated-names.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-migrated-names.mdx index db3d65c24..65419a8c1 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-migrated-names.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-migrated-names.mdx @@ -1,8 +1,6 @@ --- title: Account Migration Counts description: Count an account's ENSv1 vs ENSv2 domains to gauge migration progress. -sidebar: - order: 18 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-primary-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-primary-name-records.mdx similarity index 63% rename from docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-primary-name.mdx rename to docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-primary-name-records.mdx index 2c4e6340b..22f071fcb 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-primary-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-primary-name-records.mdx @@ -1,9 +1,7 @@ --- title: Account Primary Name -sidebar: - order: 10 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; - + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-resolver-permissions.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-resolver-permissions.mdx index e1f4c70d8..6c4c6d404 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-resolver-permissions.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/account-resolver-permissions.mdx @@ -1,8 +1,6 @@ --- title: Account Resolver Permissions description: Resolver contracts where an account holds resolver-scoped permissions. -sidebar: - order: 15 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-by-name.mdx index bc809b1ce..5e4a77ce6 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-by-name.mdx @@ -1,8 +1,6 @@ --- title: Domain By Name description: Omnigraph query for a single domain with v1/v2 fields. -sidebar: - order: 2 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-events.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-events.mdx index d6e90795a..ec1bb7025 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-events.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-events.mdx @@ -1,8 +1,6 @@ --- title: Domain Events description: Contract events linked to a domain’s on-chain records. -sidebar: - order: 8 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-profile.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-profile.mdx index f440a1ffa..752b899f7 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-profile.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-profile.mdx @@ -1,7 +1,5 @@ --- title: Domain Profile -sidebar: - order: 3 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-records.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-records.mdx index d4529eb64..2d90e274d 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-records.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-records.mdx @@ -1,7 +1,5 @@ --- title: Domain Raw Records -sidebar: - order: 4 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-resolver.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-resolver.mdx index f806dc526..f6b53bd38 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-resolver.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-resolver.mdx @@ -1,8 +1,6 @@ --- title: Domain Resolver description: Assigned resolver, records, permissions, and resolver events for a name. -sidebar: - order: 16 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-subdomains-recently-registered.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-subdomains-recently-registered.mdx index 3ab770a4e..1dadcb3d9 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-subdomains-recently-registered.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-subdomains-recently-registered.mdx @@ -1,7 +1,5 @@ --- title: Recently Registered Subdomains -sidebar: - order: 7 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-subdomains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-subdomains.mdx index a0903cc96..13cfd2d10 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-subdomains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domain-subdomains.mdx @@ -1,8 +1,6 @@ --- title: Domain Subdomains description: Paginate child names under a parent domain. -sidebar: - order: 6 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domains-by-address.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domains-by-address.mdx index 63760de67..5b7e30179 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domains-by-address.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/domains-by-address.mdx @@ -1,8 +1,6 @@ --- title: Account Domains description: Omnigraph query listing domains for an address. -sidebar: - order: 9 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/eth-by-version.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/eth-by-version.mdx index 3c74cd1fc..cdee81195 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/eth-by-version.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/eth-by-version.mdx @@ -1,8 +1,6 @@ --- title: ETH TLD By Version description: Load the .eth TLD across ENSv1 and ENSv2, discriminated by __typename. -sidebar: - order: 19 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/find-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/find-domains.mdx index c1baf9ea4..e44cd2ae7 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/find-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/find-domains.mdx @@ -1,8 +1,6 @@ --- title: Find Domains description: List domains by name filter with ordering and registration fields. -sidebar: - order: 5 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/index.mdx index cc5b3861b..4aabac033 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/index.mdx @@ -1,8 +1,6 @@ --- title: ENS Omnigraph Example Queries description: Ready-to-run Omnigraph examples with `GraphQL`, `enssdk`, and `enskit` snippets, plus links to ENSAdmin and `curl` samples. -sidebar: - order: 1 --- import { LinkCard, CardGrid } from "@astrojs/starlight/components"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/namegraph.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/namegraph.mdx index 31b623e97..0186c9b52 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/namegraph.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/namegraph.mdx @@ -1,8 +1,6 @@ --- title: Namegraph description: Explore the root tree with nested subdomain connections. -sidebar: - order: 17 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/permissions-by-contract.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/permissions-by-contract.mdx index 53565695c..ba3894cc8 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/permissions-by-contract.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/permissions-by-contract.mdx @@ -1,8 +1,6 @@ --- title: Permissions By Contract description: Role assignments on resources for a registrar or registry contract. -sidebar: - order: 13 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/permissions-by-user.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/permissions-by-user.mdx index 063815b89..b1dfa0ada 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/permissions-by-user.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/permissions-by-user.mdx @@ -1,8 +1,6 @@ --- title: Permissions By User description: Resources and roles granted to an address in the permissions graph. -sidebar: - order: 14 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/registry-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/registry-domains.mdx index ad5ced4a7..4ef6b049a 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/registry-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/omnigraph/examples/registry-domains.mdx @@ -1,8 +1,6 @@ --- title: Registry Domains description: Domains registered under a v2 ETH registry contract. -sidebar: - order: 12 --- import OmnigraphStaticExampleSet from "@components/organisms/OmnigraphStaticExampleSet.astro"; diff --git a/docs/ensnode.io/src/data/omnigraph-examples/config.ts b/docs/ensnode.io/src/data/omnigraph-examples/config.ts index 11fea63f7..ea73c4139 100644 --- a/docs/ensnode.io/src/data/omnigraph-examples/config.ts +++ b/docs/ensnode.io/src/data/omnigraph-examples/config.ts @@ -16,7 +16,7 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ id: "hello-world", title: "Hello World", description: - "From a wallet address: Ethereum primary name and interpreted profile, plus ENSv1 and ENSv2 ownership counts.", + "This query below loads, from a wallet address, the Ethereum primary name and interpreted profile, plus ENSv1 and ENSv2 ownership counts.", category: "Introduction", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: false, @@ -24,7 +24,8 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "domain-profile", title: "Domain Profile", - description: "Load a domain's high-level profile (avatar, socials, addresses, and more).", + description: + "This query below loads a domain's high-level profile (avatar, socials, addresses, and more).", category: "Resolution", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, @@ -32,15 +33,26 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "domain-records", title: "Domain Records", - description: "For given name resolve raw records like `addresses`, `texts`, `contenthash` etc.", + description: + "This query below resolves raw records for a given name, such as addresses, texts, and contenthash.", category: "Resolution", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, }, + { + id: "domain-profile-and-records", + title: "Profile And Records", + description: + "This query below resolves interpreted profile and raw records in one query to compare shapes side by side.", + category: "Resolution", + namespace: ENSNamespaceIds.Mainnet, + hostSeparatePage: false, + }, { id: "domain-by-name", title: "Domain By Name", - description: "Load a domain by interpreted name, including profile information.", + description: + "This query below loads a domain by interpreted name, including profile information.", category: "Resolution", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, @@ -48,7 +60,8 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "find-domains", title: "Find Domains", - description: "List domains matching a name prefix with ordering and registration metadata.", + description: + "This query below lists domains matching a name prefix with ordering and registration metadata.", category: "Search", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, @@ -56,7 +69,7 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "domain-subdomains", title: "Domain Subdomains", - description: "Paginate direct child names under a parent domain.", + description: "This query below paginates direct child names under a parent domain.", category: "Resolution", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, @@ -64,7 +77,8 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "domain-subdomains-recently-registered", title: "Recently Registered Subdomains", - description: "List a parent domain's subdomains ordered by most recent registration first.", + description: + "This query below lists a parent domain's subdomains ordered by most recent registration first.", category: "Resolution", namespace: ENSNamespaceIds.SepoliaV2, hostSeparatePage: true, @@ -72,7 +86,8 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "domain-events", title: "Domain Events", - description: "Raw contract events associated with a domain's registry records.", + description: + "This query below loads raw contract events associated with a domain's registry records.", category: "History", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, @@ -80,15 +95,25 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "domains-by-address", title: "Account Domains", - description: "Load domains owned by an address via the Omnigraph `account` root field.", + description: + "This query below loads domains owned by an address via the Omnigraph `account` root field.", + category: "Accounts", + namespace: ENSNamespaceIds.Mainnet, + hostSeparatePage: true, + }, + { + id: "account-primary-names", + title: "Account Primary Names", + description: "This query loads the primary names for an account on Ethereum and Base.", category: "Accounts", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, }, { - id: "account-primary-name", - title: "Account Primary Name", - description: "Load a primary name for an account on Ethereum, including profile information.", + id: "account-primary-name-records", + title: "Account Primary Name Records", + description: + "This query loads the primary name for an account on Ethereum and forward-resolves its profile in the same request.", category: "Accounts", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, @@ -96,7 +121,7 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "account-events", title: "Account Events", - description: "Events touching an account across indexed ENS contracts.", + description: "This query below loads events touching an account across indexed ENS contracts.", category: "History", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, @@ -104,7 +129,7 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "registry-domains", title: "Registry Domains", - description: "Enumerate domains under a specific v2 ETH registry contract.", + description: "This query below enumerates domains under a specific v2 ETH registry contract.", category: "Registry", namespace: ENSNamespaceIds.SepoliaV2, hostSeparatePage: true, @@ -112,7 +137,8 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "permissions-by-contract", title: "Permissions By Contract", - description: "Roles and users granted on resources for a registrar or registry contract.", + description: + "This query below loads roles and users granted on resources for a registrar or registry contract.", category: "Permissions", namespace: ENSNamespaceIds.SepoliaV2, hostSeparatePage: true, @@ -120,7 +146,8 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "permissions-by-user", title: "Permissions By User", - description: "Resources and roles for an address in the permissions graph.", + description: + "This query below loads resources and roles for an address in the permissions graph.", category: "Permissions", namespace: ENSNamespaceIds.SepoliaV2, hostSeparatePage: true, @@ -128,7 +155,8 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "account-resolver-permissions", title: "Account Resolver Permissions", - description: "Resolver contracts where an account has been granted resolver ACLs.", + description: + "This query below loads resolver contracts where an account has been granted resolver ACLs.", category: "Permissions", namespace: ENSNamespaceIds.SepoliaV2, hostSeparatePage: true, @@ -136,7 +164,8 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "domain-resolver", title: "Domain Resolver", - description: "Assigned resolver contract address and recent resolver events.", + description: + "This query below loads the assigned resolver contract address and recent resolver events.", category: "Resolution", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, @@ -145,7 +174,7 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ id: "namegraph", title: "Namegraph", description: - "Walk a domain's registry, parent, subregistry, and direct subdomains (as in Core Concepts).", + "This query below walks a domain's registry, parent, subregistry, and direct subdomains (as in Core Concepts).", category: "Exploration", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: true, @@ -153,7 +182,8 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ { id: "account-migrated-names", title: "Account Migration Counts", - description: "Count an account's ENSv1 vs ENSv2 domains to gauge its migration progress.", + description: + "This query below counts an account's ENSv1 vs ENSv2 domains to gauge its migration progress.", category: "Migration", namespace: ENSNamespaceIds.SepoliaV2, hostSeparatePage: true, @@ -162,7 +192,7 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ id: "eth-by-version", title: "ETH TLD By Version", description: - "Load the .eth TLD across protocol versions: one Domain per version, discriminated by `__typename` (ENSv1Domain / ENSv2Domain).", + "This query below loads the .eth TLD across protocol versions: one Domain per version, discriminated by `__typename` (ENSv1Domain / ENSv2Domain).", category: "Migration", namespace: ENSNamespaceIds.SepoliaV2, hostSeparatePage: true, @@ -171,7 +201,7 @@ export const OMNIGRAPH_EXAMPLES_CONFIG: OmnigraphExampleConfig[] = [ id: "accelerate-resolve", title: "Resolve primary name and records, and track protocol acceleration", description: - "Resolve primary name and records, and track protocol acceleration with `trace` and `accelerate` arguments.", + "This query below resolves primary name and records, and tracks protocol acceleration with `trace` and `accelerate` arguments.", category: "Resolution", namespace: ENSNamespaceIds.Mainnet, hostSeparatePage: false, diff --git a/docs/ensnode.io/src/data/omnigraph-examples/examples.json b/docs/ensnode.io/src/data/omnigraph-examples/examples.json index 8ad55e0ac..a92e4ba5e 100644 --- a/docs/ensnode.io/src/data/omnigraph-examples/examples.json +++ b/docs/ensnode.io/src/data/omnigraph-examples/examples.json @@ -20,6 +20,13 @@ "name": "gregskril.eth" } }, + { + "id": "domain-profile-and-records", + "query": "query DomainProfileAndRecords($name: InterpretedName!) {\n domain(by: { name: $name }) {\n resolve {\n profile {\n avatar {\n httpUrl\n }\n addresses {\n ethereum\n solana\n }\n socials {\n github {\n handle\n httpUrl\n }\n twitter {\n handle\n httpUrl\n }\n }\n website {\n httpUrl\n }\n }\n records {\n addresses(coinTypes: [60, 501]) {\n coinType\n address\n }\n texts(keys: [\"avatar\", \"com.twitter\", \"com.github\", \"url\"]) {\n key\n value\n }\n }\n }\n }\n}", + "variables": { + "name": "gregskril.eth" + } + }, { "id": "domain-by-name", "query": "query DomainByName($name: InterpretedName!) {\n domain(by: { name: $name }) {\n canonical { name { beautified } }\n owner { address }\n resolve {\n profile {\n description\n addresses {\n ethereum\n }\n }\n }\n }\n}", @@ -69,8 +76,15 @@ } }, { - "id": "account-primary-name", - "query": "query AccountPrimaryName($address: Address!) {\n account(by: { address: $address }) {\n address\n resolve {\n primaryName(by: { chainName: ETHEREUM }) {\n name { interpreted beautified }\n resolve {\n profile {\n description\n socials {\n twitter {\n httpUrl\n }\n }\n }\n }\n }\n }\n }\n}", + "id": "account-primary-names", + "query": "query AccountPrimaryName($address: Address!) {\n account(by: { address: $address }) {\n address\n resolve {\n primaryNames(where: { chainNames: [ETHEREUM, BASE] }) {\n chainName\n name { interpreted beautified }\n }\n }\n }\n}", + "variables": { + "address": "0x179a862703a4adfb29896552df9e307980d19285" + } + }, + { + "id": "account-primary-name-records", + "query": "query AccountPrimaryNameRecords($address: Address!) {\n account(by: { address: $address }) {\n address\n resolve {\n primaryName(by: { chainName: ETHEREUM }) {\n name { interpreted beautified }\n resolve {\n profile {\n description\n socials {\n twitter {\n httpUrl\n }\n }\n }\n }\n }\n }\n }\n}", "variables": { "address": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045" } diff --git a/docs/ensnode.io/src/data/omnigraph-examples/responses.json b/docs/ensnode.io/src/data/omnigraph-examples/responses.json index 0b1116017..de85f76c9 100644 --- a/docs/ensnode.io/src/data/omnigraph-examples/responses.json +++ b/docs/ensnode.io/src/data/omnigraph-examples/responses.json @@ -7,11 +7,11 @@ "trace": [ { "scope": "protocol-tracing", - "id": "span-28795-1780677847832", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121815-1780936916618", + "traceId": "trace-1780936916618-7e1w03a07", "name": "reverse-resolution:reverse-resolution", - "timestamp": 1780677847832000, - "duration": 248000, + "timestamp": 1780936916618000, + "duration": 48000, "attributes": { "ens.protocol": "reverse-resolution", "ens.protocol.step": "reverse-resolution", @@ -30,7 +30,7 @@ "ens.protocol.step": "name-record-exists-check", "ens.protocol.step.result": true }, - "time": 1780677848074000 + "time": 1780936916659000 }, { "name": "reverse-resolution:verify-resolved-address-matches-address (true)", @@ -39,21 +39,21 @@ "ens.protocol.step": "verify-resolved-address-matches-address", "ens.protocol.step.result": true }, - "time": 1780677848080000 + "time": 1780936916666000 } ], "children": [ { "scope": "protocol-tracing", - "id": "span-28796-1780677847832", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121816-1780936916618", + "traceId": "trace-1780936916618-7e1w03a07", "parentSpanContext": { - "traceId": "trace-1780677847832-ia7yzkaya", - "spanId": "span-28795-1780677847832" + "traceId": "trace-1780936916618-7e1w03a07", + "spanId": "span-121815-1780936916618" }, "name": "reverse-resolution:resolve-reverse-name", - "timestamp": 1780677847832000, - "duration": 242000, + "timestamp": 1780936916618000, + "duration": 41000, "attributes": { "ens.protocol": "reverse-resolution", "ens.protocol.step": "resolve-reverse-name", @@ -66,15 +66,15 @@ "children": [ { "scope": "protocol-tracing", - "id": "span-28797-1780677847832", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121817-1780936916618", + "traceId": "trace-1780936916618-7e1w03a07", "parentSpanContext": { - "traceId": "trace-1780677847832-ia7yzkaya", - "spanId": "span-28796-1780677847832" + "traceId": "trace-1780936916618-7e1w03a07", + "spanId": "span-121816-1780936916618" }, "name": "forward-resolution:forward-resolution", - "timestamp": 1780677847832000, - "duration": 242000, + "timestamp": 1780936916618000, + "duration": 41000, "attributes": { "ens.protocol": "forward-resolution", "ens.protocol.step": "forward-resolution", @@ -94,7 +94,7 @@ "ens.protocol.step": "active-resolver-exists", "ens.protocol.step.result": true }, - "time": 1780677847835000 + "time": 1780936916621000 }, { "name": "forward-resolution:accelerate-known-offchain-lookup-resolver (false)", @@ -103,7 +103,7 @@ "ens.protocol.step": "accelerate-known-offchain-lookup-resolver", "ens.protocol.step.result": false }, - "time": 1780677847835000 + "time": 1780936916621000 }, { "name": "forward-resolution:accelerate-known-onchain-static-resolver (false)", @@ -112,20 +112,20 @@ "ens.protocol.step": "accelerate-known-onchain-static-resolver", "ens.protocol.step.result": false }, - "time": 1780677847836000 + "time": 1780936916621000 } ], "children": [ { "scope": "protocol-tracing", - "id": "span-28798-1780677847832", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121818-1780936916618", + "traceId": "trace-1780936916618-7e1w03a07", "parentSpanContext": { - "traceId": "trace-1780677847832-ia7yzkaya", - "spanId": "span-28797-1780677847832" + "traceId": "trace-1780936916618-7e1w03a07", + "spanId": "span-121817-1780936916618" }, "name": "forward-resolution:find-resolver", - "timestamp": 1780677847832000, + "timestamp": 1780936916618000, "duration": 3000, "attributes": { "ens.protocol": "forward-resolution", @@ -141,15 +141,15 @@ }, { "scope": "protocol-tracing", - "id": "span-28799-1780677847836", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121819-1780936916621", + "traceId": "trace-1780936916618-7e1w03a07", "parentSpanContext": { - "traceId": "trace-1780677847832-ia7yzkaya", - "spanId": "span-28797-1780677847832" + "traceId": "trace-1780936916618-7e1w03a07", + "spanId": "span-121817-1780936916618" }, "name": "forward-resolution:require-resolver", - "timestamp": 1780677847836000, - "duration": 228000, + "timestamp": 1780936916621000, + "duration": 29000, "attributes": { "ens.protocol": "forward-resolution", "ens.protocol.step": "require-resolver", @@ -166,15 +166,15 @@ }, { "scope": "protocol-tracing", - "id": "span-28800-1780677848064", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121820-1780936916650", + "traceId": "trace-1780936916618-7e1w03a07", "parentSpanContext": { - "traceId": "trace-1780677847832-ia7yzkaya", - "spanId": "span-28797-1780677847832" + "traceId": "trace-1780936916618-7e1w03a07", + "spanId": "span-121817-1780936916618" }, "name": "forward-resolution:execute-resolve-calls", - "timestamp": 1780677848064000, - "duration": 10000, + "timestamp": 1780936916650000, + "duration": 9000, "attributes": { "ens.protocol": "forward-resolution", "ens.protocol.step": "execute-resolve-calls" @@ -191,15 +191,15 @@ }, { "scope": "protocol-tracing", - "id": "span-28801-1780677848074", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121821-1780936916659", + "traceId": "trace-1780936916618-7e1w03a07", "parentSpanContext": { - "traceId": "trace-1780677847832-ia7yzkaya", - "spanId": "span-28795-1780677847832" + "traceId": "trace-1780936916618-7e1w03a07", + "spanId": "span-121815-1780936916618" }, "name": "reverse-resolution:forward-resolve-address-record", - "timestamp": 1780677848074000, - "duration": 6000, + "timestamp": 1780936916659000, + "duration": 7000, "attributes": { "ens.protocol": "reverse-resolution", "ens.protocol.step": "forward-resolve-address-record", @@ -212,15 +212,15 @@ "children": [ { "scope": "protocol-tracing", - "id": "span-28802-1780677848074", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121822-1780936916659", + "traceId": "trace-1780936916618-7e1w03a07", "parentSpanContext": { - "traceId": "trace-1780677847832-ia7yzkaya", - "spanId": "span-28801-1780677848074" + "traceId": "trace-1780936916618-7e1w03a07", + "spanId": "span-121821-1780936916659" }, "name": "forward-resolution:forward-resolution", - "timestamp": 1780677848074000, - "duration": 6000, + "timestamp": 1780936916659000, + "duration": 7000, "attributes": { "ens.protocol": "forward-resolution", "ens.protocol.step": "forward-resolution", @@ -240,7 +240,7 @@ "ens.protocol.step": "active-resolver-exists", "ens.protocol.step.result": true }, - "time": 1780677848076000 + "time": 1780936916662000 }, { "name": "forward-resolution:accelerate-known-offchain-lookup-resolver (false)", @@ -249,20 +249,20 @@ "ens.protocol.step": "accelerate-known-offchain-lookup-resolver", "ens.protocol.step.result": false }, - "time": 1780677848076000 + "time": 1780936916662000 } ], "children": [ { "scope": "protocol-tracing", - "id": "span-28803-1780677848074", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121823-1780936916660", + "traceId": "trace-1780936916618-7e1w03a07", "parentSpanContext": { - "traceId": "trace-1780677847832-ia7yzkaya", - "spanId": "span-28802-1780677848074" + "traceId": "trace-1780936916618-7e1w03a07", + "spanId": "span-121822-1780936916659" }, "name": "forward-resolution:find-resolver", - "timestamp": 1780677848074000, + "timestamp": 1780936916660000, "duration": 2000, "attributes": { "ens.protocol": "forward-resolution", @@ -278,14 +278,14 @@ }, { "scope": "protocol-tracing", - "id": "span-28804-1780677848076", - "traceId": "trace-1780677847832-ia7yzkaya", + "id": "span-121824-1780936916662", + "traceId": "trace-1780936916618-7e1w03a07", "parentSpanContext": { - "traceId": "trace-1780677847832-ia7yzkaya", - "spanId": "span-28802-1780677848074" + "traceId": "trace-1780936916618-7e1w03a07", + "spanId": "span-121822-1780936916659" }, "name": "forward-resolution:accelerate-known-onchain-static-resolver", - "timestamp": 1780677848076000, + "timestamp": 1780936916662000, "duration": 4000, "attributes": { "ens.protocol": "forward-resolution", @@ -317,11 +317,11 @@ "trace": [ { "scope": "protocol-tracing", - "id": "span-28805-1780677848081", - "traceId": "trace-1780677848081-yhbkxoiix", + "id": "span-121825-1780936916667", + "traceId": "trace-1780936916667-f1rkjo2s5", "name": "forward-resolution:forward-resolution", - "timestamp": 1780677848081000, - "duration": 4000, + "timestamp": 1780936916667000, + "duration": 6000, "attributes": { "ens.protocol": "forward-resolution", "ens.protocol.step": "forward-resolution", @@ -341,7 +341,7 @@ "ens.protocol.step": "active-resolver-exists", "ens.protocol.step.result": true }, - "time": 1780677848083000 + "time": 1780936916669000 }, { "name": "forward-resolution:accelerate-known-offchain-lookup-resolver (false)", @@ -350,20 +350,20 @@ "ens.protocol.step": "accelerate-known-offchain-lookup-resolver", "ens.protocol.step.result": false }, - "time": 1780677848083000 + "time": 1780936916669000 } ], "children": [ { "scope": "protocol-tracing", - "id": "span-28806-1780677848081", - "traceId": "trace-1780677848081-yhbkxoiix", + "id": "span-121826-1780936916667", + "traceId": "trace-1780936916667-f1rkjo2s5", "parentSpanContext": { - "traceId": "trace-1780677848081-yhbkxoiix", - "spanId": "span-28805-1780677848081" + "traceId": "trace-1780936916667-f1rkjo2s5", + "spanId": "span-121825-1780936916667" }, "name": "forward-resolution:find-resolver", - "timestamp": 1780677848081000, + "timestamp": 1780936916667000, "duration": 2000, "attributes": { "ens.protocol": "forward-resolution", @@ -379,15 +379,15 @@ }, { "scope": "protocol-tracing", - "id": "span-28807-1780677848083", - "traceId": "trace-1780677848081-yhbkxoiix", + "id": "span-121827-1780936916669", + "traceId": "trace-1780936916667-f1rkjo2s5", "parentSpanContext": { - "traceId": "trace-1780677848081-yhbkxoiix", - "spanId": "span-28805-1780677848081" + "traceId": "trace-1780936916667-f1rkjo2s5", + "spanId": "span-121825-1780936916667" }, "name": "forward-resolution:accelerate-known-onchain-static-resolver", - "timestamp": 1780677848083000, - "duration": 2000, + "timestamp": 1780936916669000, + "duration": 4000, "attributes": { "ens.protocol": "forward-resolution", "ens.protocol.step": "accelerate-known-onchain-static-resolver" @@ -1455,7 +1455,7 @@ } } }, - "account-primary-name": { + "account-primary-name-records": { "data": { "account": { "address": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", @@ -1480,6 +1480,31 @@ } } }, + "account-primary-names": { + "data": { + "account": { + "address": "0x179a862703a4adfb29896552df9e307980d19285", + "resolve": { + "primaryNames": [ + { + "chainName": "ETHEREUM", + "name": { + "interpreted": "gregskril.eth", + "beautified": "gregskril.eth" + } + }, + { + "chainName": "BASE", + "name": { + "interpreted": "greg.base.eth", + "beautified": "greg.base.eth" + } + } + ] + } + } + } + }, "account-resolver-permissions": { "data": { "account": { @@ -1662,6 +1687,66 @@ } } }, + "domain-profile-and-records": { + "data": { + "domain": { + "resolve": { + "profile": { + "avatar": { + "httpUrl": "https://gregskril.com/img/profile.jpg" + }, + "addresses": { + "ethereum": "0x179a862703a4adfb29896552df9e307980d19285", + "solana": "2JQANQn1kccapb7GT8XScf9qBy59uMo9vh9WwVQhwStJ" + }, + "socials": { + "github": { + "handle": "gskril", + "httpUrl": "https://github.com/gskril" + }, + "twitter": { + "handle": "gregskril", + "httpUrl": "https://x.com/gregskril" + } + }, + "website": { + "httpUrl": "https://gregskril.com/" + } + }, + "records": { + "addresses": [ + { + "coinType": 60, + "address": "0x179a862703a4adfb29896552df9e307980d19285" + }, + { + "coinType": 501, + "address": "0x1350bfe02357c8bc583d7514f44ba2c31821d8739160e7b79a0a94bc113a4f73" + } + ], + "texts": [ + { + "key": "avatar", + "value": "https://gregskril.com/img/profile.jpg" + }, + { + "key": "com.twitter", + "value": "gregskril" + }, + { + "key": "com.github", + "value": "gskril" + }, + { + "key": "url", + "value": "https://gregskril.com/" + } + ] + } + } + } + } + }, "domain-records": { "data": { "domain": { @@ -3744,12 +3829,12 @@ "hello-world": { "data": { "account": { - "v2DomainsCount": { - "totalCount": 0 - }, "v1DomainsCount": { "totalCount": 514 }, + "v2DomainsCount": { + "totalCount": 0 + }, "resolve": { "primaryName": { "name": { @@ -3786,7 +3871,6 @@ "namegraph": { "data": { "domain": { - "parent": null, "registry": { "id": "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e", "contract": { @@ -3794,6 +3878,7 @@ "address": "0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e" } }, + "parent": null, "subdomains": { "edges": [ { @@ -6070,7 +6155,7 @@ { "node": { "resource": "0", - "roles": "7719472615821079694904732333912527190217998977709370935963838933860875309073" + "roles": "7719472615821079694904732333912527190217998977709370935963838933860875309329" } }, { diff --git a/docs/ensnode.io/src/data/omnigraph-examples/schema.graphql b/docs/ensnode.io/src/data/omnigraph-examples/schema.graphql index 907bcd71f..9fbe48746 100644 --- a/docs/ensnode.io/src/data/omnigraph-examples/schema.graphql +++ b/docs/ensnode.io/src/data/omnigraph-examples/schema.graphql @@ -420,7 +420,7 @@ interface Domain { owner: Account """ - The Domain that this Domain's parent Registry declares as its Canonical Domain, if any. Follows a single unidirectional pointer (`Registry.canonicalDomainId`) and does NOT enforce bidirectional canonical-edge agreement: a non-canonical Domain may have a non-null `parent`, and a canonical Domain's `parent` may itself be non-canonical. Null when the parent Registry does not declare a Canonical Domain. + The Domain that this Domain's parent Registry declares as its Canonical Domain, if any. Follows a single unidirectional pointer (`Registry.canonicalDomainId`) and does NOT enforce bidirectional canonical-edge agreement: a non-canonical Domain may have a non-null `parent`, and a canonical Domain's `parent` may itself be non-canonical. Null when the parent Registry does not declare a Canonical Domain. For an UnindexedDomain (which has no Registry of its own), this reflects the wildcard-bearing ancestor's Registry — see `Domain.registry`. """ parent: Domain @@ -435,7 +435,7 @@ interface Domain { registrations(after: String, before: String, first: Int, last: Int): DomainRegistrationsConnection """ - The Registry under which this Domain exists. + The Registry under which this Domain exists. For an UnindexedDomain — a resolvable-but-unindexed Domain that has no Registry of its own — this is instead the Registry that manages the ancestor Domain bearing the wildcard Resolver (the same Registry encoded in its `id`). """ registry: Registry! @@ -606,6 +606,11 @@ type DomainResolver { The Resolver that this Domain has assigned, if any. NOTE that this is the Domain's _assigned_ Resolver, _not_ its _effective_ Resolver, which can only be determined by following ENS Forward Resolution and ENSIP-10. Do NOT use this Domain-Resolver relationship in isolation to resolve records, that operation is NOT ENS Forward Resolution. """ assigned: Resolver + + """ + The Resolver that ENS Forward Resolution (ENSIP-10) lands on for this Domain — i.e. its _effective_ Resolver. Null when no active Resolver exists or the Domain is not in the Canonical Nametree. + """ + effective: Resolver } type DomainSubdomainsConnection { @@ -736,7 +741,7 @@ type ENSv1Domain implements Domain { owner: Account """ - The Domain that this Domain's parent Registry declares as its Canonical Domain, if any. Follows a single unidirectional pointer (`Registry.canonicalDomainId`) and does NOT enforce bidirectional canonical-edge agreement: a non-canonical Domain may have a non-null `parent`, and a canonical Domain's `parent` may itself be non-canonical. Null when the parent Registry does not declare a Canonical Domain. + The Domain that this Domain's parent Registry declares as its Canonical Domain, if any. Follows a single unidirectional pointer (`Registry.canonicalDomainId`) and does NOT enforce bidirectional canonical-edge agreement: a non-canonical Domain may have a non-null `parent`, and a canonical Domain's `parent` may itself be non-canonical. Null when the parent Registry does not declare a Canonical Domain. For an UnindexedDomain (which has no Registry of its own), this reflects the wildcard-bearing ancestor's Registry — see `Domain.registry`. """ parent: Domain @@ -751,7 +756,7 @@ type ENSv1Domain implements Domain { registrations(after: String, before: String, first: Int, last: Int): DomainRegistrationsConnection """ - The Registry under which this Domain exists. + The Registry under which this Domain exists. For an UnindexedDomain — a resolvable-but-unindexed Domain that has no Registry of its own — this is instead the Registry that manages the ancestor Domain bearing the wildcard Resolver (the same Registry encoded in its `id`). """ registry: Registry! @@ -919,7 +924,7 @@ type ENSv2Domain implements Domain { owner: Account """ - The Domain that this Domain's parent Registry declares as its Canonical Domain, if any. Follows a single unidirectional pointer (`Registry.canonicalDomainId`) and does NOT enforce bidirectional canonical-edge agreement: a non-canonical Domain may have a non-null `parent`, and a canonical Domain's `parent` may itself be non-canonical. Null when the parent Registry does not declare a Canonical Domain. + The Domain that this Domain's parent Registry declares as its Canonical Domain, if any. Follows a single unidirectional pointer (`Registry.canonicalDomainId`) and does NOT enforce bidirectional canonical-edge agreement: a non-canonical Domain may have a non-null `parent`, and a canonical Domain's `parent` may itself be non-canonical. Null when the parent Registry does not declare a Canonical Domain. For an UnindexedDomain (which has no Registry of its own), this reflects the wildcard-bearing ancestor's Registry — see `Domain.registry`. """ parent: Domain @@ -945,7 +950,7 @@ type ENSv2Domain implements Domain { registrations(after: String, before: String, first: Int, last: Int): DomainRegistrationsConnection """ - The Registry under which this Domain exists. + The Registry under which this Domain exists. For an UnindexedDomain — a resolvable-but-unindexed Domain that has no Registry of its own — this is instead the Registry that manages the ancestor Domain bearing the wildcard Resolver (the same Registry encoded in its `id`). """ registry: Registry! @@ -2310,6 +2315,11 @@ type Resolver { where: EventsWhereInput ): ResolverEventsConnection + """ + Whether this Resolver implements ENSIP-10 wildcard resolution (`IExtendedResolver`, interfaceId `0x9061b923`), determined via a single cached `supportsInterface` RPC the first time the Resolver is observed. + """ + extended: Boolean! + """ A unique reference to this Resolver. """ @@ -2548,6 +2558,95 @@ type ThreeDNSRegistration implements Registration { unregistrant: Account } +""" +A resolvable-but-unindexed Domain: not present in the index, but resolvable because an ancestor in its namegraph path has an ENSIP-10 wildcard Resolver (e.g. off-chain / CCIP-Read names, unindexed 3DNS names, wildcard subnames). +""" +type UnindexedDomain implements Domain { + """ + Metadata (name, path, and node) related to the Domain's canonicality, if known. Null when the Domain is not in the canonical nametree. + """ + canonical: DomainCanonical + + """ + All Events associated with this Domain. + """ + events( + after: String + before: String + first: Int + last: Int + where: EventsWhereInput + ): DomainEventsConnection + + """ + A unique and stable reference to this Domain. + """ + id: DomainId! + + """ + The Label associated with this Domain in the ENS Namegraph. + """ + label: Label! + + """ + 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). + """ + owner: Account + + """ + The Domain that this Domain's parent Registry declares as its Canonical Domain, if any. Follows a single unidirectional pointer (`Registry.canonicalDomainId`) and does NOT enforce bidirectional canonical-edge agreement: a non-canonical Domain may have a non-null `parent`, and a canonical Domain's `parent` may itself be non-canonical. Null when the parent Registry does not declare a Canonical Domain. For an UnindexedDomain (which has no Registry of its own), this reflects the wildcard-bearing ancestor's Registry — see `Domain.registry`. + """ + parent: Domain + + """ + The latest Registration for this Domain, if exists. + """ + registration: Registration + + """ + All Registrations for a Domain, including the latest Registration. + """ + registrations(after: String, before: String, first: Int, last: Int): DomainRegistrationsConnection + + """ + The Registry under which this Domain exists. For an UnindexedDomain — a resolvable-but-unindexed Domain that has no Registry of its own — this is instead the Registry that manages the ancestor Domain bearing the wildcard Resolver (the same Registry encoded in its `id`). + """ + registry: Registry! + + """ + Resolve protocol-level data for this Domain. + """ + resolve( + """ + When true (default), Protocol Acceleration will be conditionally used by the server to perform resolution when it is relevant. If false, Protocol Acceleration will be disabled. + @see https://ensnode.io/docs/integrate/omnigraph/protocol-acceleration + """ + accelerate: Boolean = true + ): ForwardResolve! + + """ + Resolver relationship metadata for this Domain. + """ + resolver: DomainResolver! + + """ + All Domains that are direct descendants of this Domain in the namegraph. Ordered by the `order` argument (default: NAME, ASC). When ordering by REGISTRATION_TIMESTAMP or REGISTRATION_EXPIRY, Domains lacking that value — no Registration for REGISTRATION_TIMESTAMP; no Registration or a never-expiring one (treated as +∞) for REGISTRATION_EXPIRY — sort last when `dir: ASC` and first when `dir: DESC`. + """ + subdomains( + after: String + before: String + first: Int + last: Int + order: DomainsOrderInput + where: SubdomainsWhereInput + ): DomainSubdomainsConnection + + """ + The Registry this Domain declares as its Subregistry, if exists. + """ + subregistry: Registry +} + """ Additional metadata for BaseRegistrar Registrations wrapped by the NameWrapper (i.e. in the case of a wrapped .eth name) """ diff --git a/docs/ensnode.io/src/data/omnigraph-examples/snapshot.json b/docs/ensnode.io/src/data/omnigraph-examples/snapshot.json index 31c4e7fa8..24ee96f66 100644 --- a/docs/ensnode.io/src/data/omnigraph-examples/snapshot.json +++ b/docs/ensnode.io/src/data/omnigraph-examples/snapshot.json @@ -1,7 +1,7 @@ { "version": "v1.15.1", - "commit": "01fbd263", + "commit": "1e24a146", "sdkVersion": "1.15.1", "schemaTag": "v1.15.1", - "snapshottedAt": "2026-06-05" + "snapshottedAt": "2026-06-08" } diff --git a/packages/ensnode-sdk/src/omnigraph-api/example-queries.ts b/packages/ensnode-sdk/src/omnigraph-api/example-queries.ts index 072c3e20a..0fe516e75 100644 --- a/packages/ensnode-sdk/src/omnigraph-api/example-queries.ts +++ b/packages/ensnode-sdk/src/omnigraph-api/example-queries.ts @@ -44,6 +44,8 @@ const VITALIK_NAME = asInterpretedName("vitalik.eth"); const GREG_NAME = asInterpretedName("gregskril.eth"); +const GREG_ADDRESS = toNormalizedAddress("0x179a862703a4adfb29896552df9e307980d19285"); + const MAINNET_PUBLIC_RESOLVER = getDatasourceContract( ENSNamespaceIds.Mainnet, DatasourceNames.ReverseResolverRoot, @@ -332,6 +334,50 @@ query DomainProfile($name: InterpretedName!) { variables: { default: { name: GREG_NAME } }, }, + { + id: "domain-profile-and-records", + query: ` +query DomainProfileAndRecords($name: InterpretedName!) { + domain(by: { name: $name }) { + resolve { + profile { + avatar { + httpUrl + } + addresses { + ethereum + solana + } + socials { + github { + handle + httpUrl + } + twitter { + handle + httpUrl + } + } + website { + httpUrl + } + } + records { + addresses(coinTypes: [60, 501]) { + coinType + address + } + texts(keys: ["avatar", "com.twitter", "com.github", "url"]) { + key + value + } + } + } + } +}`, + variables: { default: { name: GREG_NAME } }, + }, + ////////////////////// // Domain Subdomains ////////////////////// @@ -467,9 +513,29 @@ query AccountDomains( // Account Primary Names ///////////////////////// { - id: "account-primary-name", + id: "account-primary-names", query: ` query AccountPrimaryName($address: Address!) { + account(by: { address: $address }) { + address + resolve { + primaryNames(where: { chainNames: [ETHEREUM, BASE] }) { + chainName + name { interpreted beautified } + } + } + } +}`, + variables: { + default: { address: GREG_ADDRESS }, + [ENSNamespaceIds.EnsTestEnv]: { address: accounts.owner.address }, + [ENSNamespaceIds.SepoliaV2]: { address: SEPOLIA_V2_ACCOUNT }, + }, + }, + { + id: "account-primary-name-records", + query: ` +query AccountPrimaryNameRecords($address: Address!) { account(by: { address: $address }) { address resolve { diff --git a/packages/ensskills/skills/omnigraph/SKILL.md b/packages/ensskills/skills/omnigraph/SKILL.md index 881a92689..b31b25852 100644 --- a/packages/ensskills/skills/omnigraph/SKILL.md +++ b/packages/ensskills/skills/omnigraph/SKILL.md @@ -493,6 +493,57 @@ Variables: } ``` +### domain-profile-and-records + +```graphql +query DomainProfileAndRecords($name: InterpretedName!) { + domain(by: { name: $name }) { + resolve { + profile { + avatar { + httpUrl + } + addresses { + ethereum + solana + } + socials { + github { + handle + httpUrl + } + twitter { + handle + httpUrl + } + } + website { + httpUrl + } + } + records { + addresses(coinTypes: [60, 501]) { + coinType + address + } + texts(keys: ["avatar", "com.twitter", "com.github", "url"]) { + key + value + } + } + } + } +} +``` + +Variables: + +```json +{ + "name": "gregskril.eth" +} +``` + ### domain-subdomains ```graphql @@ -667,10 +718,37 @@ Variables: } ``` -### account-primary-name +### account-primary-names ```graphql query AccountPrimaryName($address: Address!) { + account(by: { address: $address }) { + address + resolve { + primaryNames(where: { chainNames: [ETHEREUM, BASE] }) { + chainName + name { + interpreted + beautified + } + } + } + } +} +``` + +Variables: + +```json +{ + "address": "0x179a862703a4adfb29896552df9e307980d19285" +} +``` + +### account-primary-name-records + +```graphql +query AccountPrimaryNameRecords($address: Address!) { account(by: { address: $address }) { address resolve {