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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/dirty-snakes-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ensapi": minor
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

This changeset describes a breaking API surface change (removing ENSv2Domain.canonicalId) but bumps ensapi as minor. If consumers rely on the GraphQL schema and ensapi is semver-stable (1.x), consider using a major bump (or clarify why this is intentionally a minor bump).

Suggested change
"ensapi": minor
"ensapi": major

Copilot uses AI. Check for mistakes.
---

Omnigraph API (BREAKING): Removed `ENSv2Domain.canonicalId` in favor of accessing `ENSv2Domain.tokenId` directly.
Comment thread
shrugs marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useValidatedSelectedConnection } from "@/hooks/active/use-selected-conn
export default function Actions() {
const selectedConnection = useValidatedSelectedConnection();
const url = useMemo(
() => new URL(`/api/graphql`, selectedConnection).toString(),
() => new URL(`/api/omnigraph`, selectedConnection).toString(),
[selectedConnection],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function GraphQLPage() {
const namespace = useActiveNamespace();
const selectedConnection = useValidatedSelectedConnection();
const url = useMemo(
() => new URL(`/api/graphql`, selectedConnection).toString(),
() => new URL(`/api/omnigraph`, selectedConnection).toString(),
[selectedConnection],
);

Expand All @@ -44,7 +44,7 @@ function GraphQLPage() {

export default function Page() {
return (
<RequireENSAdminFeature title="ENSNode GraphQL API" feature="graphql">
<RequireENSAdminFeature title="ENSNode Omnigraph API" feature="omnigraph">
<GraphQLPage />
</RequireENSAdminFeature>
);
Expand Down
4 changes: 2 additions & 2 deletions apps/ensadmin/src/components/app-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ const navItems = [
url: "/api/subgraph",
},
{
title: "GraphQL (ENS v1 + v2)",
url: "/api/graphql",
title: "Omnigraph (ENS v1 + v2)",
url: "/api/omnigraph",
},
],
},
Expand Down
12 changes: 6 additions & 6 deletions apps/ensadmin/src/hooks/active/use-ensadmin-features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useMemo } from "react";

import { useENSNodeConfig } from "@ensnode/ensnode-react";
import {
hasGraphqlApiConfigSupport,
hasOmnigraphApiConfigSupport,
hasRegistrarActionsConfigSupport,
hasRegistrarActionsIndexingStatusSupport,
hasSubgraphApiConfigSupport,
Expand Down Expand Up @@ -33,9 +33,9 @@ export interface ENSAdminFeatures {
subgraph: FeatureStatus;

/**
* Whether ENSAdmin's ENSNode GraphQL API tooling is supported by the connected ENSNode.
* Whether ENSAdmin's ENSNode Omnigraph API tooling is supported by the connected ENSNode.
*/
graphql: FeatureStatus;
omnigraph: FeatureStatus;
}

const prerequisiteResultToFeatureStatus = (result: PrerequisiteResult): FeatureStatus => {
Expand Down Expand Up @@ -96,13 +96,13 @@ export function useENSAdminFeatures(): ENSAdminFeatures {
return prerequisiteResultToFeatureStatus(hasSubgraphApiConfigSupport(ensIndexerPublicConfig));
}, [configQuery]);

const graphql: FeatureStatus = useMemo(() => {
const omnigraph: FeatureStatus = useMemo(() => {
if (configQuery.status === "error") return CONFIG_ERROR_STATUS;
if (configQuery.status === "pending") return CONNECTING_STATUS;

const { ensIndexerPublicConfig } = configQuery.data;
return prerequisiteResultToFeatureStatus(hasGraphqlApiConfigSupport(ensIndexerPublicConfig));
return prerequisiteResultToFeatureStatus(hasOmnigraphApiConfigSupport(ensIndexerPublicConfig));
}, [configQuery]);

return { registrarActions, subgraph, graphql };
return { registrarActions, subgraph, omnigraph };
}
2 changes: 1 addition & 1 deletion apps/ensapi/biome.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"overrides": [
// allow unused function parameters in pothos schema files due to resolve() pattern
{
"includes": ["./src/graphql-api/**/*.ts"],
"includes": ["./src/omnigraph-api/**/*.ts"],
"linter": {
"rules": {
"correctness": {
Expand Down
3 changes: 2 additions & 1 deletion apps/ensapi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"lint": "biome check --write .",
"lint:ci": "biome ci",
"typecheck": "tsgo --noEmit",
"generate:gqlschema": "tsx src/graphql-api/lib/write-graphql-schema.ts"
"generate:gqlschema": "tsx src/omnigraph-api/lib/write-graphql-schema.ts"
},
"dependencies": {
"@ensdomains/ensjs": "^4.0.2",
Expand Down Expand Up @@ -50,6 +50,7 @@
"dataloader": "^2.2.3",
"date-fns": "catalog:",
"drizzle-orm": "catalog:",
"enssdk": "workspace:*",
"graphql": "^16.11.0",
"graphql-yoga": "^5.16.0",
"hono": "catalog:",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import config from "@/config";

import { hasGraphqlApiConfigSupport } from "@ensnode/ensnode-sdk";
import { hasOmnigraphApiConfigSupport } from "@ensnode/ensnode-sdk";

import { createApp } from "@/lib/hono-factory";

const app = createApp();

// 503 if prerequisites not met
app.use(async (c, next) => {
const prerequisite = hasGraphqlApiConfigSupport(config.ensIndexerPublicConfig);
const prerequisite = hasOmnigraphApiConfigSupport(config.ensIndexerPublicConfig);
if (!prerequisite.supported) {
return c.text(`Service Unavailable: ${prerequisite.reason}`, 503);
}
Comment thread
shrugs marked this conversation as resolved.
Expand All @@ -20,7 +20,7 @@ app.use(async (c) => {
// defer the loading of the GraphQL Server until runtime, which allows these modules to require
// the Namechain datasource
// TODO(ensv2): this can be removed if/when all ENSNamespaces define the Namechain Datasource
const { yoga } = await import("@/graphql-api/yoga");
const { yoga } = await import("@/omnigraph-api/yoga");
return yoga.fetch(c.req.raw, c.var);
});

Expand Down
4 changes: 2 additions & 2 deletions apps/ensapi/src/handlers/api/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { createApp } from "@/lib/hono-factory";

import nameTokensApi from "./explore/name-tokens-api";
import registrarActionsApi from "./explore/registrar-actions-api";
import ensnodeGraphQLApi from "./graphql/ensnode-graphql-api";
import realtimeApi from "./meta/realtime-api";
import statusApi from "./meta/status-api";
import omnigraphApi from "./omnigraph/omnigraph-api";
import resolutionApi from "./resolution/resolution-api";

const app = createApp();
Expand All @@ -14,6 +14,6 @@ app.route("/realtime", realtimeApi);
app.route("/resolve", resolutionApi);
app.route("/name-tokens", nameTokensApi);
app.route("/registrar-actions", registrarActionsApi);
app.route("/graphql", ensnodeGraphQLApi);
app.route("/omnigraph", omnigraphApi);

export default app;
2 changes: 1 addition & 1 deletion apps/ensapi/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { getReferralLeaderboardEditionsCaches } from "@/cache/referral-leaderboa
import { referralProgramEditionConfigSetCache } from "@/cache/referral-program-edition-set.cache";
import { referrerLeaderboardCache } from "@/cache/referrer-leaderboard.cache";
import { redactEnsApiConfig } from "@/config/redact";
import { writeGraphQLSchema } from "@/graphql-api/lib/write-graphql-schema";
import { sdk } from "@/lib/instrumentation";
import logger from "@/lib/logger";
import { writeGraphQLSchema } from "@/omnigraph-api/lib/write-graphql-schema";

import app from "./app";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import SchemaBuilder, { type MaybePromise } from "@pothos/core";
import DataloaderPlugin from "@pothos/plugin-dataloader";
import RelayPlugin from "@pothos/plugin-relay";
import type { Address, Hex } from "viem";

import type {
ChainId,
CoinType,
Expand All @@ -17,9 +15,10 @@ import type {
RenewalId,
ResolverId,
ResolverRecordsId,
} from "@ensnode/ensnode-sdk";
} from "enssdk";
import type { Address, Hex } from "viem";

import type { context } from "@/graphql-api/context";
import type { context } from "@/omnigraph-api/context";

export const builder = new SchemaBuilder<{
Context: ReturnType<typeof context>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { and, asc, desc, gt, lt } from "drizzle-orm";
import z from "zod/v4";

import { cursors } from "@/graphql-api/lib/cursors";
import { cursors } from "@/omnigraph-api/lib/cursors";

type Column = Parameters<typeof lt>[0];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { DomainId } from "@ensnode/ensnode-sdk";

import { cursors } from "@/graphql-api/lib/cursors";
import type { DomainOrderValue } from "@/graphql-api/lib/find-domains/types";
import type { DomainsOrderBy } from "@/graphql-api/schema/domain";
import type { OrderDirection } from "@/graphql-api/schema/order-direction";
import { cursors } from "@/omnigraph-api/lib/cursors";
import type { DomainOrderValue } from "@/omnigraph-api/lib/find-domains/types";
import type { DomainsOrderBy } from "@/omnigraph-api/schema/domain";
import type { OrderDirection } from "@/omnigraph-api/schema/order-direction";

/**
* Composite Domain cursor for keyset pagination.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect, it, vi } from "vitest";

vi.mock("@/config", () => ({ default: { namespace: "mainnet" } }));
vi.mock("@/graphql-api/lib/find-domains/find-domains-by-labelhash-path", () => ({}));
vi.mock("@/omnigraph-api/lib/find-domains/find-domains-by-labelhash-path", () => ({}));
Comment thread
shrugs marked this conversation as resolved.
Outdated

import { isEffectiveDesc } from "./find-domains-resolver-helpers";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { asc, desc, type SQL, sql } from "drizzle-orm";

import type { DomainCursor } from "@/graphql-api/lib/find-domains/domain-cursor";
import type { DomainsWithOrderingMetadata } from "@/graphql-api/lib/find-domains/layers/with-ordering-metadata";
import type { DomainsOrderBy } from "@/graphql-api/schema/domain";
import type { OrderDirection } from "@/graphql-api/schema/order-direction";
import type { DomainCursor } from "@/omnigraph-api/lib/find-domains/domain-cursor";
import type { DomainsWithOrderingMetadata } from "@/omnigraph-api/lib/find-domains/layers/with-ordering-metadata";
import type { DomainsOrderBy } from "@/omnigraph-api/schema/domain";
import type { OrderDirection } from "@/omnigraph-api/schema/order-direction";

/**
* Get the order column for a given DomainsOrderBy value.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@pothos/plugin-relay";
import { and, count } from "drizzle-orm";

import type { context as createContext } from "@/graphql-api/context";
import { ensDb } from "@/lib/ensdb/singleton";
import { makeLogger } from "@/lib/logger";
import type { context as createContext } from "@/omnigraph-api/context";
import type {
DomainsWithOrderingMetadata,
DomainsWithOrderingMetadataResult,
} from "@/graphql-api/lib/find-domains/layers/with-ordering-metadata";
import { lazyConnection } from "@/graphql-api/lib/lazy-connection";
import { rejectAnyErrors } from "@/graphql-api/lib/reject-any-errors";
} from "@/omnigraph-api/lib/find-domains/layers/with-ordering-metadata";
import { lazyConnection } from "@/omnigraph-api/lib/lazy-connection";
import { rejectAnyErrors } from "@/omnigraph-api/lib/reject-any-errors";
import {
PAGINATION_DEFAULT_MAX_SIZE,
PAGINATION_DEFAULT_PAGE_SIZE,
} from "@/graphql-api/schema/constants";
} from "@/omnigraph-api/schema/constants";
import {
DOMAINS_DEFAULT_ORDER_BY,
DOMAINS_DEFAULT_ORDER_DIR,
type Domain,
DomainInterfaceRef,
type DomainsOrderBy,
} from "@/graphql-api/schema/domain";
import type { OrderDirection } from "@/graphql-api/schema/order-direction";
import { ensDb } from "@/lib/ensdb/singleton";
import { makeLogger } from "@/lib/logger";
} from "@/omnigraph-api/schema/domain";
import type { OrderDirection } from "@/omnigraph-api/schema/order-direction";

import { DomainCursors } from "./domain-cursor";
import { cursorFilter, orderFindDomains } from "./find-domains-resolver-helpers";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@poth
import { and, count, eq, getTableColumns, gte, inArray, lte, type SQL, sql } from "drizzle-orm";
import type { Address, Hex } from "viem";

import { orderPaginationBy, paginateBy } from "@/graphql-api/lib/connection-helpers";
import { lazyConnection } from "@/graphql-api/lib/lazy-connection";
import { ID_PAGINATED_CONNECTION_ARGS } from "@/graphql-api/schema/constants";
import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton";
import { orderPaginationBy, paginateBy } from "@/omnigraph-api/lib/connection-helpers";
import { lazyConnection } from "@/omnigraph-api/lib/lazy-connection";
import { ID_PAGINATED_CONNECTION_ARGS } from "@/omnigraph-api/schema/constants";

/**
* A join table that relates some entity to events via an `eventId` column.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const ENSSDK_ROOT = resolve(MONOREPO_ROOT, "packages/enssdk/");
const OUTPUT_PATH = resolve(ENSSDK_ROOT, "src/omnigraph/generated/schema.graphql");

async function _writeGraphQLSchema() {
const { schema } = await import("@/graphql-api/schema");
const { schema } = await import("@/omnigraph-api/schema");
const schemaAsString = printSchema(lexicographicSortSchema(schema));

await writeFile(OUTPUT_PATH, schemaAsString);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { builder } from "@/graphql-api/builder";
import { builder } from "@/omnigraph-api/builder";

import "./schema/account-id";
import "./schema/connection";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { AccountId } from "@ensnode/ensnode-sdk";

import { builder } from "@/graphql-api/builder";
import { builder } from "@/omnigraph-api/builder";

export const AccountIdRef = builder.objectRef<AccountId>("AccountId");
AccountIdRef.implement({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { beforeAll, describe, expect, it } from "vitest";

import type { Name } from "@ensnode/ensnode-sdk";

import { gql } from "@/test/integration/ensnode-graphql-api-client";
import {
AccountDomainsPaginated,
type PaginatedDomainResult,
Expand All @@ -21,6 +20,7 @@ import {
type PaginatedGraphQLConnection,
request,
} from "@/test/integration/graphql-utils";
import { gql } from "@/test/integration/omnigraph-api-client";

// via devnet
const DEVNET_DEPLOYER: Address = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@ import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@poth
import { and, count, eq, getTableColumns } from "drizzle-orm";
import type { Address } from "viem";

import { builder } from "@/graphql-api/builder";
import { orderPaginationBy, paginateBy } from "@/graphql-api/lib/connection-helpers";
import { resolveFindDomains } from "@/graphql-api/lib/find-domains/find-domains-resolver";
import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton";
import { builder } from "@/omnigraph-api/builder";
import { orderPaginationBy, paginateBy } from "@/omnigraph-api/lib/connection-helpers";
import { resolveFindDomains } from "@/omnigraph-api/lib/find-domains/find-domains-resolver";
import {
domainsBase,
filterByCanonical,
filterByName,
filterByOwner,
withOrderingMetadata,
} from "@/graphql-api/lib/find-domains/layers";
import { resolveFindEvents } from "@/graphql-api/lib/find-events/find-events-resolver";
import { getModelId } from "@/graphql-api/lib/get-model-id";
import { lazyConnection } from "@/graphql-api/lib/lazy-connection";
import { AccountIdInput } from "@/graphql-api/schema/account-id";
import { ID_PAGINATED_CONNECTION_ARGS } from "@/graphql-api/schema/constants";
} from "@/omnigraph-api/lib/find-domains/layers";
import { resolveFindEvents } from "@/omnigraph-api/lib/find-events/find-events-resolver";
import { getModelId } from "@/omnigraph-api/lib/get-model-id";
import { lazyConnection } from "@/omnigraph-api/lib/lazy-connection";
import { AccountIdInput } from "@/omnigraph-api/schema/account-id";
import { ID_PAGINATED_CONNECTION_ARGS } from "@/omnigraph-api/schema/constants";
import {
AccountDomainsWhereInput,
DomainInterfaceRef,
DomainsOrderInput,
} from "@/graphql-api/schema/domain";
import { AccountEventsWhereInput, EventRef } from "@/graphql-api/schema/event";
import { PermissionsUserRef } from "@/graphql-api/schema/permissions";
import { RegistryPermissionsUserRef } from "@/graphql-api/schema/registry-permissions-user";
import { ResolverPermissionsUserRef } from "@/graphql-api/schema/resolver-permissions-user";
import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton";
} from "@/omnigraph-api/schema/domain";
import { AccountEventsWhereInput, EventRef } from "@/omnigraph-api/schema/event";
import { PermissionsUserRef } from "@/omnigraph-api/schema/permissions";
import { RegistryPermissionsUserRef } from "@/omnigraph-api/schema/registry-permissions-user";
import { ResolverPermissionsUserRef } from "@/omnigraph-api/schema/resolver-permissions-user";

export const AccountRef = builder.loadableObjectRef("Account", {
load: (ids: Address[]) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { builder } from "@/graphql-api/builder";
import { builder } from "@/omnigraph-api/builder";

builder.globalConnectionField("totalCount", (t) =>
t.field({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { cursors } from "@/graphql-api/lib/cursors";
import { getModelId } from "@/graphql-api/lib/get-model-id";
import { cursors } from "@/omnigraph-api/lib/cursors";
import { getModelId } from "@/omnigraph-api/lib/get-model-id";

export const PAGINATION_DEFAULT_PAGE_SIZE = 100;
export const PAGINATION_DEFAULT_MAX_SIZE = 1000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { beforeAll, describe, expect, it } from "vitest";
import type { InterpretedLabel, Name } from "@ensnode/ensnode-sdk";

import { DEVNET_ETH_LABELS } from "@/test/integration/devnet-names";
import { gql } from "@/test/integration/ensnode-graphql-api-client";
import {
DomainSubdomainsPaginated,
type PaginatedDomainResult,
Expand All @@ -21,6 +20,7 @@ import {
type PaginatedGraphQLConnection,
request,
} from "@/test/integration/graphql-utils";
import { gql } from "@/test/integration/omnigraph-api-client";

const NAME_WITH_EVENTS = "newowner.eth";

Expand Down
Loading
Loading