diff --git a/.changeset/enssdk-migrate-core-types.md b/.changeset/enssdk-migrate-core-types.md new file mode 100644 index 0000000000..a3e7ce364d --- /dev/null +++ b/.changeset/enssdk-migrate-core-types.md @@ -0,0 +1,15 @@ +--- +"enssdk": minor +"@ensnode/ensnode-sdk": minor +--- + +Migrated core ENS types and utilities from `ensnode-sdk` to `enssdk`: +- `UnixTimestamp` type moved to enssdk +- `normalizeName` function (wraps `@adraffy/ens-normalize`) added; `isNormalizedName`/`isNormalizedLabel` consolidated into `normalization.ts` +- `makeSubdomainNode` moved to enssdk +- `reinterpretLabel`/`reinterpretName` moved to enssdk +- `labelhash` renamed to `labelhashInterpretedLabel` (requires branded `InterpretedLabel` input) +- `namehash` renamed to `namehashInterpretedName` (requires branded `InterpretedName` input) +- Added `asInterpretedLabel`, `asInterpretedName`, `asLiteralLabel` validated cast helpers +- Subregistry managed name functions now return `InterpretedName` +- Removed `@adraffy/ens-normalize` dependency from ensnode-sdk (provided by enssdk) diff --git a/apps/ensadmin/package.json b/apps/ensadmin/package.json index 19035a985e..c07e14bd41 100644 --- a/apps/ensadmin/package.json +++ b/apps/ensadmin/package.json @@ -25,6 +25,7 @@ "@ensnode/datasources": "workspace:*", "@ensnode/ensnode-react": "workspace:*", "@ensnode/ensnode-sdk": "workspace:*", + "enssdk": "workspace:*", "@formkit/auto-animate": "^0.9.0", "@graphiql/plugin-explorer": "5.1.1", "@graphiql/react": "0.37.1", diff --git a/apps/ensadmin/src/app/@actions/name/page.tsx b/apps/ensadmin/src/app/@actions/name/page.tsx index bbdfbf8dab..6fbcf211da 100644 --- a/apps/ensadmin/src/app/@actions/name/page.tsx +++ b/apps/ensadmin/src/app/@actions/name/page.tsx @@ -1,12 +1,11 @@ "use client"; import { getEnsManagerNameDetailsUrl } from "@namehash/namehash-ui"; +import type { Name } from "enssdk"; import { ScanSearch } from "lucide-react"; import Link from "next/link"; import { useSearchParams } from "next/navigation"; -import type { Name } from "@ensnode/ensnode-sdk"; - import { ExternalLinkWithIcon } from "@/components/link"; import { getRecordResolutionRelativePath } from "@/components/name-links"; import { Button } from "@/components/ui/button"; diff --git a/apps/ensadmin/src/app/@breadcrumbs/inspect/records/page.tsx b/apps/ensadmin/src/app/@breadcrumbs/inspect/records/page.tsx index 0dca383e7a..b544b1c46b 100644 --- a/apps/ensadmin/src/app/@breadcrumbs/inspect/records/page.tsx +++ b/apps/ensadmin/src/app/@breadcrumbs/inspect/records/page.tsx @@ -1,11 +1,10 @@ "use client"; import { NameDisplay } from "@namehash/namehash-ui"; +import type { Name } from "enssdk"; import Link from "next/link"; import { useSearchParams } from "next/navigation"; -import type { Name } from "@ensnode/ensnode-sdk"; - import { BreadcrumbItem, BreadcrumbLink, diff --git a/apps/ensadmin/src/app/@breadcrumbs/name/page.tsx b/apps/ensadmin/src/app/@breadcrumbs/name/page.tsx index d838481197..8e2b6093bf 100644 --- a/apps/ensadmin/src/app/@breadcrumbs/name/page.tsx +++ b/apps/ensadmin/src/app/@breadcrumbs/name/page.tsx @@ -1,11 +1,10 @@ "use client"; import { NameDisplay } from "@namehash/namehash-ui"; +import type { Name } from "enssdk"; import Link from "next/link"; import { useSearchParams } from "next/navigation"; -import type { Name } from "@ensnode/ensnode-sdk"; - import BreadcrumbsGroup from "@/components/breadcrumbs/group"; import { BreadcrumbItem, diff --git a/apps/ensadmin/src/app/inspect/_lib/example-addresses.ts b/apps/ensadmin/src/app/inspect/_lib/example-addresses.ts index 3786dc8e28..b8232c9d80 100644 --- a/apps/ensadmin/src/app/inspect/_lib/example-addresses.ts +++ b/apps/ensadmin/src/app/inspect/_lib/example-addresses.ts @@ -1,6 +1,6 @@ -import { Address } from "viem"; +import type { Address, Name } from "enssdk"; -import { ENSNamespaceIds, Name, NamespaceSpecificValue } from "@ensnode/ensnode-sdk"; +import { ENSNamespaceIds, type NamespaceSpecificValue } from "@ensnode/ensnode-sdk"; export const EXAMPLE_ADDRESSES: NamespaceSpecificValue> = { default: [ diff --git a/apps/ensadmin/src/app/inspect/_lib/example-names.ts b/apps/ensadmin/src/app/inspect/_lib/example-names.ts index 3ed0411dd9..76090ee6d3 100644 --- a/apps/ensadmin/src/app/inspect/_lib/example-names.ts +++ b/apps/ensadmin/src/app/inspect/_lib/example-names.ts @@ -1,4 +1,6 @@ -import { ENSNamespaceIds, type Name, type NamespaceSpecificValue } from "@ensnode/ensnode-sdk"; +import type { Name } from "enssdk"; + +import { ENSNamespaceIds, type NamespaceSpecificValue } from "@ensnode/ensnode-sdk"; export const EXAMPLE_NAMES: NamespaceSpecificValue = { default: [ diff --git a/apps/ensadmin/src/app/inspect/primary-name/page.tsx b/apps/ensadmin/src/app/inspect/primary-name/page.tsx index 468da3912c..0705f52d86 100644 --- a/apps/ensadmin/src/app/inspect/primary-name/page.tsx +++ b/apps/ensadmin/src/app/inspect/primary-name/page.tsx @@ -1,18 +1,16 @@ "use client"; import { AddressDisplay, getChainName } from "@namehash/namehash-ui"; +import type { Address, DefaultableChainId } from "enssdk"; +import { DEFAULT_EVM_CHAIN_ID } from "enssdk"; import { useRouter, useSearchParams } from "next/navigation"; import { useEffect, useMemo, useState } from "react"; import { useDebouncedValue } from "rooks"; -import { type Address, isAddress } from "viem"; +import { isAddress } from "viem"; import { getENSRootChainId } from "@ensnode/datasources"; import { usePrimaryName } from "@ensnode/ensnode-react"; -import { - DEFAULT_EVM_CHAIN_ID, - type DefaultableChainId, - getNamespaceSpecificValue, -} from "@ensnode/ensnode-sdk"; +import { getNamespaceSpecificValue } from "@ensnode/ensnode-sdk"; import { makeDefaultableChainIdStringSchema } from "@ensnode/ensnode-sdk/internal"; import { RenderRequestsOutput } from "@/app/inspect/_components/render-requests-output"; diff --git a/apps/ensadmin/src/app/inspect/primary-names/page.tsx b/apps/ensadmin/src/app/inspect/primary-names/page.tsx index 49dffc2df1..b1a3e59369 100644 --- a/apps/ensadmin/src/app/inspect/primary-names/page.tsx +++ b/apps/ensadmin/src/app/inspect/primary-names/page.tsx @@ -1,10 +1,11 @@ "use client"; import { AddressDisplay } from "@namehash/namehash-ui"; +import type { Address } from "enssdk"; import { useRouter, useSearchParams } from "next/navigation"; import { useEffect, useMemo, useState } from "react"; import { useDebouncedValue } from "rooks"; -import { type Address, isAddress } from "viem"; +import { isAddress } from "viem"; import { usePrimaryNames } from "@ensnode/ensnode-react"; import { getNamespaceSpecificValue } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensadmin/src/app/inspect/records/page.tsx b/apps/ensadmin/src/app/inspect/records/page.tsx index 063838a05c..775cfb2ff2 100644 --- a/apps/ensadmin/src/app/inspect/records/page.tsx +++ b/apps/ensadmin/src/app/inspect/records/page.tsx @@ -1,12 +1,13 @@ "use client"; +import type { Name } from "enssdk"; import { User } from "lucide-react"; import Link from "next/link"; import { useRouter, useSearchParams } from "next/navigation"; import { useEffect, useMemo, useState } from "react"; import { useRecords } from "@ensnode/ensnode-react"; -import { getNamespaceSpecificValue, type Name } from "@ensnode/ensnode-sdk"; +import { getNamespaceSpecificValue } from "@ensnode/ensnode-sdk"; import { RenderRequestsOutput } from "@/app/inspect/_components/render-requests-output"; import { ResolveButton } from "@/app/inspect/_components/resolve-button"; diff --git a/apps/ensadmin/src/app/mock/display-identity/page.tsx b/apps/ensadmin/src/app/mock/display-identity/page.tsx index 9d17a9fb7b..5ebe54dda0 100644 --- a/apps/ensadmin/src/app/mock/display-identity/page.tsx +++ b/apps/ensadmin/src/app/mock/display-identity/page.tsx @@ -5,19 +5,16 @@ import { getChainName, getEnsManagerAddressDetailsUrl, } from "@namehash/namehash-ui"; +import type { Address, ChainId, DefaultableChainId, Name } from "enssdk"; +import { asLowerCaseAddress, DEFAULT_EVM_CHAIN_ID } from "enssdk"; import { useState } from "react"; -import { type Address, isAddress } from "viem"; +import { isAddress } from "viem"; import { getENSNamespace, getENSRootChainId } from "@ensnode/datasources"; import { - asLowerCaseAddress, - type ChainId, - DEFAULT_EVM_CHAIN_ID, - type DefaultableChainId, type ENSNamespaceId, ENSNamespaceIds, type Identity, - type Name, type NamedIdentity, type ResolutionStatusId, ResolutionStatusIds, diff --git a/apps/ensadmin/src/app/mock/registrar-actions/mocks.ts b/apps/ensadmin/src/app/mock/registrar-actions/mocks.ts index 476c155473..c7e40fa2cc 100644 --- a/apps/ensadmin/src/app/mock/registrar-actions/mocks.ts +++ b/apps/ensadmin/src/app/mock/registrar-actions/mocks.ts @@ -1,4 +1,6 @@ -import { Duration, InterpretedName, NamedRegistrarAction } from "@ensnode/ensnode-sdk"; +import { asInterpretedName } from "enssdk"; + +import { type Duration, type NamedRegistrarAction } from "@ensnode/ensnode-sdk"; export const registrationWithReferral = { action: { @@ -45,7 +47,7 @@ export const registrationWithReferral = { "176209761600000000111551110000000009545322000000000000006750000000000000071", ], }, - name: "nh35.eth" as InterpretedName, + name: asInterpretedName("nh35.eth"), } satisfies NamedRegistrarAction; export const renewalWithNoReferral = { @@ -78,7 +80,7 @@ export const renewalWithNoReferral = { "176304520800000000111551110000000009621987000000000000011350000000000000259", ], }, - name: "user1-extend.eth" as InterpretedName, + name: asInterpretedName("user1-extend.eth"), } satisfies NamedRegistrarAction; export const registrationWithNoReferralAndEncodedLabelHashes = { @@ -115,7 +117,7 @@ export const registrationWithNoReferralAndEncodedLabelHashes = { eventIds: ["176234701200000000111551110000000009566045000000000000014150000000000000198"], }, - name: "[e4310bf4547cb18b16b5348881d24a66d61fa94a013e5636b730b86ee64a3923].eth" as InterpretedName, + name: asInterpretedName("[e4310bf4547cb18b16b5348881d24a66d61fa94a013e5636b730b86ee64a3923].eth"), } satisfies NamedRegistrarAction; export const registrationWithZeroEncodedReferrer = { @@ -151,7 +153,7 @@ export const registrationWithZeroEncodedReferrer = { "176304488400000000111551110000000009621960000000000000003350000000000000031", ], }, - name: "alix407.eth" as InterpretedName, + name: asInterpretedName("alix407.eth"), } satisfies NamedRegistrarAction; export const registrationWithReferrerNotMatchingENSHolidayAwardsFormat = { @@ -199,7 +201,7 @@ export const registrationWithReferrerNotMatchingENSHolidayAwardsFormat = { "176305292400000000111551110000000009622628000000000000002750000000000000053", ], }, - name: "sonu100.eth" as InterpretedName, + name: asInterpretedName("sonu100.eth"), } satisfies NamedRegistrarAction; function registrarActionWithUpdatedIncrementalDuration( @@ -209,7 +211,7 @@ function registrarActionWithUpdatedIncrementalDuration( return { ...registrarAction, action: { ...registrarAction.action, incrementalDuration }, - name: `incrementalDuration-${incrementalDuration}.${registrarAction.name}` as InterpretedName, + name: asInterpretedName(`incrementalDuration-${incrementalDuration}.${registrarAction.name}`), } satisfies NamedRegistrarAction; } diff --git a/apps/ensadmin/src/app/mock/relative-time/page.tsx b/apps/ensadmin/src/app/mock/relative-time/page.tsx index e3041ddcb5..2bd230f3c8 100644 --- a/apps/ensadmin/src/app/mock/relative-time/page.tsx +++ b/apps/ensadmin/src/app/mock/relative-time/page.tsx @@ -1,11 +1,10 @@ "use client"; import { AbsoluteTime, InfoIcon, RelativeTime } from "@namehash/namehash-ui"; +import type { UnixTimestamp } from "enssdk"; import { CheckIcon, X as XIcon } from "lucide-react"; import { useMemo, useState } from "react"; -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; - import mockDataJson from "@/app/mock/relative-time/data.json"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; diff --git a/apps/ensadmin/src/app/name/_components/NameDetailPageContent.tsx b/apps/ensadmin/src/app/name/_components/NameDetailPageContent.tsx index b0b1340ab4..b46147ae90 100644 --- a/apps/ensadmin/src/app/name/_components/NameDetailPageContent.tsx +++ b/apps/ensadmin/src/app/name/_components/NameDetailPageContent.tsx @@ -1,7 +1,9 @@ "use client"; +import type { Name } from "enssdk"; + import { ASSUME_IMMUTABLE_QUERY, useRecords } from "@ensnode/ensnode-react"; -import { type Name, type ResolverRecordsSelection } from "@ensnode/ensnode-sdk"; +import type { ResolverRecordsSelection } from "@ensnode/ensnode-sdk"; import { Card, CardContent } from "@/components/ui/card"; import { useActiveNamespace } from "@/hooks/active/use-active-namespace"; diff --git a/apps/ensadmin/src/app/name/_components/ProfileHeader.tsx b/apps/ensadmin/src/app/name/_components/ProfileHeader.tsx index 2cfbb24ac1..25c7a5fa94 100644 --- a/apps/ensadmin/src/app/name/_components/ProfileHeader.tsx +++ b/apps/ensadmin/src/app/name/_components/ProfileHeader.tsx @@ -1,8 +1,9 @@ "use client"; import { EnsAvatar, NameDisplay } from "@namehash/namehash-ui"; +import type { Name } from "enssdk"; -import type { ENSNamespaceId, Name } from "@ensnode/ensnode-sdk"; +import type { ENSNamespaceId } from "@ensnode/ensnode-sdk"; import { ExternalLinkWithIcon } from "@/components/link"; import { Card, CardContent } from "@/components/ui/card"; diff --git a/apps/ensadmin/src/app/name/page.tsx b/apps/ensadmin/src/app/name/page.tsx index 56ab72d495..221d18d4c1 100644 --- a/apps/ensadmin/src/app/name/page.tsx +++ b/apps/ensadmin/src/app/name/page.tsx @@ -1,15 +1,12 @@ "use client"; import { NameDisplay } from "@namehash/namehash-ui"; +import type { Name } from "enssdk"; import { useRouter, useSearchParams } from "next/navigation"; import { type ChangeEvent, useMemo, useState } from "react"; import { ENSNamespaceIds } from "@ensnode/datasources"; -import { - getNamespaceSpecificValue, - type Name, - type NamespaceSpecificValue, -} from "@ensnode/ensnode-sdk"; +import { getNamespaceSpecificValue, type NamespaceSpecificValue } from "@ensnode/ensnode-sdk"; import { getNameDetailsRelativePath, NameLink } from "@/components/name-links"; import { Button } from "@/components/ui/button"; diff --git a/apps/ensadmin/src/components/indexing-status/block-refs.tsx b/apps/ensadmin/src/components/indexing-status/block-refs.tsx index e3b02af5cd..dded1ce4bb 100644 --- a/apps/ensadmin/src/components/indexing-status/block-refs.tsx +++ b/apps/ensadmin/src/components/indexing-status/block-refs.tsx @@ -3,9 +3,10 @@ */ import { getBlockExplorerBlockUrl, RelativeTime } from "@namehash/namehash-ui"; +import type { ChainId } from "enssdk"; import { ExternalLink as ExternalLinkIcon } from "lucide-react"; -import type { BlockRef, ChainId } from "@ensnode/ensnode-sdk"; +import type { BlockRef } from "@ensnode/ensnode-sdk"; interface BlockNumberProps { chainId: ChainId; diff --git a/apps/ensadmin/src/components/indexing-status/indexing-timeline-utils.ts b/apps/ensadmin/src/components/indexing-status/indexing-timeline-utils.ts index 81255a1197..7d8a353d77 100644 --- a/apps/ensadmin/src/components/indexing-status/indexing-timeline-utils.ts +++ b/apps/ensadmin/src/components/indexing-status/indexing-timeline-utils.ts @@ -1,6 +1,5 @@ import { getUnixTime } from "date-fns"; - -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; /** * Calculate the position of a date in a timeline. diff --git a/apps/ensadmin/src/components/indexing-status/indexing-timeline.tsx b/apps/ensadmin/src/components/indexing-status/indexing-timeline.tsx index 7bb79a734d..ad267debbd 100644 --- a/apps/ensadmin/src/components/indexing-status/indexing-timeline.tsx +++ b/apps/ensadmin/src/components/indexing-status/indexing-timeline.tsx @@ -3,13 +3,9 @@ */ import { AbsoluteTime, ChainIcon, getChainName } from "@namehash/namehash-ui"; +import type { ChainId, UnixTimestamp } from "enssdk"; -import { - type BlockRef, - type ChainId, - ChainIndexingStatusIds, - type UnixTimestamp, -} from "@ensnode/ensnode-sdk"; +import { type BlockRef, ChainIndexingStatusIds } from "@ensnode/ensnode-sdk"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { formatChainStatus } from "@/lib/indexing-status"; diff --git a/apps/ensadmin/src/components/indexing-status/projection-info.tsx b/apps/ensadmin/src/components/indexing-status/projection-info.tsx index 677e80a073..9c18b1b375 100644 --- a/apps/ensadmin/src/components/indexing-status/projection-info.tsx +++ b/apps/ensadmin/src/components/indexing-status/projection-info.tsx @@ -1,9 +1,10 @@ "use client"; import { formatRelativeTime, RelativeTime, useNow } from "@namehash/namehash-ui"; +import type { UnixTimestamp } from "enssdk"; import { InfoIcon } from "lucide-react"; -import type { Duration, UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { Duration } from "@ensnode/ensnode-sdk"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; diff --git a/apps/ensadmin/src/components/name-links/index.tsx b/apps/ensadmin/src/components/name-links/index.tsx index 04365bae89..4941abf893 100644 --- a/apps/ensadmin/src/components/name-links/index.tsx +++ b/apps/ensadmin/src/components/name-links/index.tsx @@ -1,8 +1,7 @@ +import type { Name } from "enssdk"; import type { PropsWithChildren } from "react"; import * as React from "react"; -import { type Name } from "@ensnode/ensnode-sdk"; - import { InternalLink } from "@/components/link"; import { useRawConnectionUrlParam } from "@/hooks/use-connection-url-param"; diff --git a/apps/ensadmin/src/components/nav-main.tsx b/apps/ensadmin/src/components/nav-main.tsx index 8bbe924c8b..3af1b3443c 100644 --- a/apps/ensadmin/src/components/nav-main.tsx +++ b/apps/ensadmin/src/components/nav-main.tsx @@ -1,11 +1,10 @@ "use client"; +import type { UrlString } from "enssdk"; import { ChevronRight, type LucideIcon } from "lucide-react"; import Link from "next/link"; import { usePathname } from "next/navigation"; -import type { UrlString } from "@ensnode/ensnode-sdk"; - import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; import { SidebarGroup, diff --git a/apps/ensadmin/src/lib/default-records-selection.ts b/apps/ensadmin/src/lib/default-records-selection.ts index 57c2462e1a..ac34a1d0ca 100644 --- a/apps/ensadmin/src/lib/default-records-selection.ts +++ b/apps/ensadmin/src/lib/default-records-selection.ts @@ -1,10 +1,8 @@ +import type { CoinType } from "enssdk"; +import { ETH_COIN_TYPE, evmChainIdToCoinType } from "enssdk"; + import { type ENSNamespaceId, ENSNamespaceIds } from "@ensnode/datasources"; -import { - CoinType, - ETH_COIN_TYPE, - evmChainIdToCoinType, - ResolverRecordsSelection, -} from "@ensnode/ensnode-sdk"; +import type { ResolverRecordsSelection } from "@ensnode/ensnode-sdk"; import { getENSIP19SupportedChainIds } from "@/lib/get-ensip19-supported-chain-ids"; diff --git a/apps/ensadmin/src/lib/get-ensip19-supported-chain-ids.ts b/apps/ensadmin/src/lib/get-ensip19-supported-chain-ids.ts index 4b6842ec29..a6dbe7861e 100644 --- a/apps/ensadmin/src/lib/get-ensip19-supported-chain-ids.ts +++ b/apps/ensadmin/src/lib/get-ensip19-supported-chain-ids.ts @@ -1,5 +1,7 @@ +import type { ChainId } from "enssdk"; + import { DatasourceNames, type ENSNamespaceId, maybeGetDatasource } from "@ensnode/datasources"; -import { type ChainId, uniq } from "@ensnode/ensnode-sdk"; +import { uniq } from "@ensnode/ensnode-sdk"; /** * Returns the unique set of chain IDs that support ENSIP-19 reverse resolution diff --git a/apps/ensapi/src/handlers/api/explore/name-tokens-api.ts b/apps/ensapi/src/handlers/api/explore/name-tokens-api.ts index 3bcec10a77..490c41c5af 100644 --- a/apps/ensapi/src/handlers/api/explore/name-tokens-api.ts +++ b/apps/ensapi/src/handlers/api/explore/name-tokens-api.ts @@ -1,15 +1,18 @@ import config from "@/config"; -import { namehash } from "viem"; - import { + asInterpretedName, ENS_ROOT, getParentNameFQDN, + type Node, + namehashInterpretedName, +} from "enssdk"; + +import { type NameTokensRequest, NameTokensResponseCodes, NameTokensResponseErrorCodes, type NameTokensResponseErrorNameTokensNotIndexed, - type Node, type PluginName, serializeNameTokensResponse, } from "@ensnode/ensnode-sdk"; @@ -66,7 +69,7 @@ app.openapi(getNameTokensRoute, async (c) => { let domainId: Node; if (request.name !== undefined) { - const { name } = request; + const name = asInterpretedName(request.name); // return 404 when the requested name was the ENS Root if (name === ENS_ROOT) { @@ -80,7 +83,7 @@ app.openapi(getNameTokensRoute, async (c) => { ); } - const parentNode = namehash(getParentNameFQDN(name)); + const parentNode = namehashInterpretedName(getParentNameFQDN(name)); const subregistry = indexedSubregistries.find((s) => s.node === parentNode); // Return 404 response with error code for Name Tokens Not Indexed when @@ -97,7 +100,7 @@ app.openapi(getNameTokensRoute, async (c) => { ); } - domainId = namehash(name); + domainId = namehashInterpretedName(name); } else if (request.domainId !== undefined) { domainId = request.domainId; } else { diff --git a/apps/ensapi/src/handlers/api/explore/registrar-actions-api.ts b/apps/ensapi/src/handlers/api/explore/registrar-actions-api.ts index 89a0093a62..ae9eb34619 100644 --- a/apps/ensapi/src/handlers/api/explore/registrar-actions-api.ts +++ b/apps/ensapi/src/handlers/api/explore/registrar-actions-api.ts @@ -1,8 +1,8 @@ import { trace } from "@opentelemetry/api"; +import type { Node } from "enssdk"; import { buildPageContext, - type Node, type RegistrarActionsFilter, RegistrarActionsResponseCodes, type RegistrarActionsResponseError, diff --git a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/closeout.ts b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/closeout.ts index 933e0987da..33226faf8a 100644 --- a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/closeout.ts +++ b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/closeout.ts @@ -1,7 +1,8 @@ import type { ReferralProgramRules } from "@namehash/ens-referrals/v1"; import { minutesToSeconds } from "date-fns"; +import type { UnixTimestamp } from "enssdk"; -import { addDuration, type Duration, type UnixTimestamp } from "@ensnode/ensnode-sdk"; +import { addDuration, type Duration } from "@ensnode/ensnode-sdk"; /** * Duration after which we assume a closed edition is safe from chain reorganizations. diff --git a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/database-v1.ts b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/database-v1.ts index 139f77ddd3..b78e803c5c 100644 --- a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/database-v1.ts +++ b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/database-v1.ts @@ -5,8 +5,8 @@ import { type ReferrerMetrics, } from "@namehash/ens-referrals/v1"; import { and, asc, count, desc, eq, gte, isNotNull, lte, ne, sql, sum } from "drizzle-orm"; -import { stringifyAccountId } from "enssdk"; -import { type Address, zeroAddress } from "viem"; +import { type Address, stringifyAccountId } from "enssdk"; +import { zeroAddress } from "viem"; import { deserializeDuration, priceEth } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/database.ts b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/database.ts index 27d0298099..98f40a20ba 100644 --- a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/database.ts +++ b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/database.ts @@ -4,8 +4,8 @@ import { type ReferrerMetrics, } from "@namehash/ens-referrals"; import { and, count, desc, eq, gte, isNotNull, lte, ne, sql, sum } from "drizzle-orm"; -import { stringifyAccountId } from "enssdk"; -import { type Address, zeroAddress } from "viem"; +import { type Address, stringifyAccountId } from "enssdk"; +import { zeroAddress } from "viem"; import { deserializeDuration } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/get-referrer-leaderboard-v1.ts b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/get-referrer-leaderboard-v1.ts index 2562174a78..32e73d9c8b 100644 --- a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/get-referrer-leaderboard-v1.ts +++ b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/get-referrer-leaderboard-v1.ts @@ -5,8 +5,7 @@ import { type ReferralProgramRules, type ReferrerLeaderboard, } from "@namehash/ens-referrals/v1"; - -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import { getReferralEvents, getReferrerMetrics } from "./database-v1"; diff --git a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/get-referrer-leaderboard.ts b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/get-referrer-leaderboard.ts index bb25d59511..7110df449b 100644 --- a/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/get-referrer-leaderboard.ts +++ b/apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/get-referrer-leaderboard.ts @@ -3,8 +3,7 @@ import { type ReferralProgramRules, type ReferrerLeaderboard, } from "@namehash/ens-referrals"; - -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import { getReferrerMetrics } from "./database"; diff --git a/apps/ensapi/src/lib/handlers/params.schema.test.ts b/apps/ensapi/src/lib/handlers/params.schema.test.ts index 3b9d83421b..496c4e0480 100644 --- a/apps/ensapi/src/lib/handlers/params.schema.test.ts +++ b/apps/ensapi/src/lib/handlers/params.schema.test.ts @@ -1,9 +1,8 @@ -import { labelhash, zeroAddress } from "viem"; +import { asInterpretedLabel, DEFAULT_EVM_CHAIN_ID, labelhashInterpretedLabel } from "enssdk"; +import { zeroAddress } from "viem"; import { describe, expect, it } from "vitest"; import { ZodError } from "zod/v4"; -import { DEFAULT_EVM_CHAIN_ID } from "@ensnode/ensnode-sdk"; - import { params } from "./params.schema"; describe("params.name", () => { @@ -18,7 +17,9 @@ describe("params.name", () => { it("requires normalized name", () => { expect(() => params.name.parse("Vitalik.eth")).toThrow(ZodError); expect(() => params.name.parse("unnormalizable|name.eth")).toThrow(ZodError); - expect(() => params.name.parse(`[${labelhash("vitalik")}].eth`)).toThrow(ZodError); + expect(() => + params.name.parse(`[${labelhashInterpretedLabel(asInterpretedLabel("vitalik"))}].eth`), + ).toThrow(ZodError); }); }); diff --git a/apps/ensapi/src/lib/handlers/params.schema.ts b/apps/ensapi/src/lib/handlers/params.schema.ts index 00d83c22d6..7c1550a565 100644 --- a/apps/ensapi/src/lib/handlers/params.schema.ts +++ b/apps/ensapi/src/lib/handlers/params.schema.ts @@ -1,12 +1,7 @@ import { z } from "@hono/zod-openapi"; +import { DEFAULT_EVM_CHAIN_ID, isNormalizedName, type Name } from "enssdk"; -import { - DEFAULT_EVM_CHAIN_ID, - isNormalizedName, - isSelectionEmpty, - type Name, - type ResolverRecordsSelection, -} from "@ensnode/ensnode-sdk"; +import { isSelectionEmpty, type ResolverRecordsSelection } from "@ensnode/ensnode-sdk"; import { makeCoinTypeStringSchema, makeDefaultableChainIdStringSchema, diff --git a/apps/ensapi/src/lib/name-tokens/find-name-tokens-for-domain.ts b/apps/ensapi/src/lib/name-tokens/find-name-tokens-for-domain.ts index cca14cec1b..d602790202 100644 --- a/apps/ensapi/src/lib/name-tokens/find-name-tokens-for-domain.ts +++ b/apps/ensapi/src/lib/name-tokens/find-name-tokens-for-domain.ts @@ -1,16 +1,14 @@ import config from "@/config"; import { eq } from "drizzle-orm/sql"; +import { type AccountId, asInterpretedName, type Node } from "enssdk"; import { - type AccountId, bigIntToNumber, getNameTokenOwnership, - type InterpretedName, type NameToken, type NameTokenOwnership, type NFTMintStatus, - type Node, parseAssetId, type RegisteredNameTokens, type UnixTimestamp, @@ -104,7 +102,8 @@ function _recordsToRegisteredNameTokens( chainId: record.nameTokens.chainId, address: record.nameTokens.owner, } satisfies AccountId; - const name = record.domains.name as InterpretedName; + // biome-ignore lint/style/noNonNullAssertion: domain.name guaranteed to exist + const name = asInterpretedName(record.domains.name!); const ownership = getNameTokenOwnership(config.namespace, name, owner); const token = _recordToNameToken(record, ownership); const expiresAt = bigIntToNumber(record.registrationLifecycles.expiresAt); diff --git a/apps/ensapi/src/lib/name-tokens/get-indexed-subregistries.ts b/apps/ensapi/src/lib/name-tokens/get-indexed-subregistries.ts index 16946bdc38..d8e7e7d65b 100644 --- a/apps/ensapi/src/lib/name-tokens/get-indexed-subregistries.ts +++ b/apps/ensapi/src/lib/name-tokens/get-indexed-subregistries.ts @@ -1,4 +1,4 @@ -import { namehash } from "viem"; +import { namehashInterpretedName } from "enssdk"; import type { ENSNamespaceId } from "@ensnode/datasources"; import { @@ -24,20 +24,21 @@ export function getIndexedSubregistries( if (activePlugins.includes(PluginName.Subgraph)) { indexedSubregistries.push({ subregistryId: getEthnamesSubregistryId(namespaceId), - node: namehash(getEthnamesSubregistryManagedName(namespaceId)), + node: namehashInterpretedName(getEthnamesSubregistryManagedName(namespaceId)), }); } + if (activePlugins.includes(PluginName.Basenames)) { indexedSubregistries.push({ subregistryId: getBasenamesSubregistryId(namespaceId), - node: namehash(getBasenamesSubregistryManagedName(namespaceId)), + node: namehashInterpretedName(getBasenamesSubregistryManagedName(namespaceId)), }); } if (activePlugins.includes(PluginName.Lineanames)) { indexedSubregistries.push({ subregistryId: getLineanamesSubregistryId(namespaceId), - node: namehash(getLineanamesSubregistryManagedName(namespaceId)), + node: namehashInterpretedName(getLineanamesSubregistryManagedName(namespaceId)), }); } diff --git a/apps/ensapi/src/lib/protocol-acceleration/find-resolver.ts b/apps/ensapi/src/lib/protocol-acceleration/find-resolver.ts index 5aa88be231..10a03464e0 100644 --- a/apps/ensapi/src/lib/protocol-acceleration/find-resolver.ts +++ b/apps/ensapi/src/lib/protocol-acceleration/find-resolver.ts @@ -2,28 +2,22 @@ import config from "@/config"; import { bytesToPacket } from "@ensdomains/ensjs/utils"; import { SpanStatusCode, trace } from "@opentelemetry/api"; -import { - type Address, - isAddressEqual, - namehash, - type PublicClient, - toHex, - zeroAddress, -} from "viem"; -import { packetToBytes } from "viem/ens"; - -import { DatasourceNames, getDatasource } from "@ensnode/datasources"; import { type AccountId, - accountIdEqual, + type Address, + asInterpretedName, type DomainId, - getDatasourceContract, getNameHierarchy, - isENSv1Registry, type Name, type Node, type NormalizedName, -} from "@ensnode/ensnode-sdk"; + namehashInterpretedName, +} from "enssdk"; +import { isAddressEqual, type PublicClient, toHex, zeroAddress } from "viem"; +import { packetToBytes } from "viem/ens"; + +import { DatasourceNames, getDatasource } from "@ensnode/datasources"; +import { accountIdEqual, getDatasourceContract, isENSv1Registry } from "@ensnode/ensnode-sdk"; import { ensDb } from "@/lib/ensdb/singleton"; import { withActiveSpanAsync, withSpanAsync } from "@/lib/instrumentation/auto-span"; @@ -200,7 +194,7 @@ async function findResolverWithIndex( // 2. compute domainId of each node // NOTE: this is currently ENSv1-specific - const nodes = names.map((name) => namehash(name) as Node); + const nodes = names.map((name) => namehashInterpretedName(asInterpretedName(name)) as Node); const domainIds = nodes as DomainId[]; // 3. for each domain, find its associated resolver in the selected registry diff --git a/apps/ensapi/src/lib/protocol-acceleration/get-primary-name-from-index.ts b/apps/ensapi/src/lib/protocol-acceleration/get-primary-name-from-index.ts index 55d3f5b786..98abb92506 100644 --- a/apps/ensapi/src/lib/protocol-acceleration/get-primary-name-from-index.ts +++ b/apps/ensapi/src/lib/protocol-acceleration/get-primary-name-from-index.ts @@ -1,12 +1,11 @@ import { trace } from "@opentelemetry/api"; -import type { Address } from "viem"; - import { + type Address, type CoinType, coinTypeReverseLabel, DEFAULT_EVM_COIN_TYPE, type Name, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; import { ensDb } from "@/lib/ensdb/singleton"; import { withSpanAsync } from "@/lib/instrumentation/auto-span"; diff --git a/apps/ensapi/src/lib/protocol-acceleration/get-records-from-index.ts b/apps/ensapi/src/lib/protocol-acceleration/get-records-from-index.ts index 4b1efbbdf7..d09e930b84 100644 --- a/apps/ensapi/src/lib/protocol-acceleration/get-records-from-index.ts +++ b/apps/ensapi/src/lib/protocol-acceleration/get-records-from-index.ts @@ -1,11 +1,8 @@ import config from "@/config"; -import { - type AccountId, - DEFAULT_EVM_COIN_TYPE, - type Node, - type ResolverRecordsSelection, -} from "@ensnode/ensnode-sdk"; +import { type AccountId, DEFAULT_EVM_COIN_TYPE, type Node } from "enssdk"; + +import type { ResolverRecordsSelection } from "@ensnode/ensnode-sdk"; import { staticResolverImplementsAddressRecordDefaulting } from "@ensnode/ensnode-sdk/internal"; import { ensDb } from "@/lib/ensdb/singleton"; diff --git a/apps/ensapi/src/lib/protocol-acceleration/resolver-records-indexed-on-chain.ts b/apps/ensapi/src/lib/protocol-acceleration/resolver-records-indexed-on-chain.ts index 6bd6a5e694..31cdfedcc1 100644 --- a/apps/ensapi/src/lib/protocol-acceleration/resolver-records-indexed-on-chain.ts +++ b/apps/ensapi/src/lib/protocol-acceleration/resolver-records-indexed-on-chain.ts @@ -1,4 +1,6 @@ -import type { ChainId, ENSNamespaceId } from "@ensnode/ensnode-sdk"; +import type { ChainId } from "enssdk"; + +import type { ENSNamespaceId } from "@ensnode/ensnode-sdk"; import { getDatasourcesWithResolvers } from "@ensnode/ensnode-sdk/internal"; /** diff --git a/apps/ensapi/src/lib/public-client.ts b/apps/ensapi/src/lib/public-client.ts index b726162e4f..8b51cf4ecf 100644 --- a/apps/ensapi/src/lib/public-client.ts +++ b/apps/ensapi/src/lib/public-client.ts @@ -1,9 +1,8 @@ import config from "@/config"; +import type { ChainId } from "enssdk"; import { createPublicClient, fallback, http, type PublicClient } from "viem"; -import type { ChainId } from "@ensnode/ensnode-sdk"; - const _cache = new Map(); /** diff --git a/apps/ensapi/src/lib/registrar-actions/find-registrar-actions.ts b/apps/ensapi/src/lib/registrar-actions/find-registrar-actions.ts index 9d087ea829..73d8b56890 100644 --- a/apps/ensapi/src/lib/registrar-actions/find-registrar-actions.ts +++ b/apps/ensapi/src/lib/registrar-actions/find-registrar-actions.ts @@ -1,10 +1,10 @@ import { trace } from "@opentelemetry/api"; import { and, count, desc, eq, gte, isNotNull, lte, not, type SQL } from "drizzle-orm/sql"; +import { asInterpretedName } from "enssdk"; import { type BlockRef, bigIntToNumber, - type InterpretedName, type NamedRegistrarAction, parseAccountId, priceEth, @@ -248,7 +248,8 @@ function _mapToNamedRegistrarAction(record: MapToNamedRegistrarActionArgs): Name eventIds: record.registrarActions.eventIds as [string, ...string[]], } satisfies RegistrarAction; - const name = record.domain.name as InterpretedName; + // biome-ignore lint/style/noNonNullAssertion: domain.name guarnateed to exist + const name = asInterpretedName(record.domain.name!); return { action, diff --git a/apps/ensapi/src/lib/resolution/forward-resolution.ts b/apps/ensapi/src/lib/resolution/forward-resolution.ts index e305f597a6..ccd2dec8b1 100644 --- a/apps/ensapi/src/lib/resolution/forward-resolution.ts +++ b/apps/ensapi/src/lib/resolution/forward-resolution.ts @@ -2,20 +2,23 @@ import config from "@/config"; import { trace } from "@opentelemetry/api"; import { replaceBigInts } from "@ponder/utils"; -import { namehash } from "viem"; -import { normalize } from "viem/ens"; - import { type AccountId, + asInterpretedName, + isNormalizedName, + type Node, + namehashInterpretedName, + normalizeName, + parseReverseName, +} from "enssdk"; + +import { type ForwardResolutionArgs, ForwardResolutionProtocolStep, type ForwardResolutionResult, getENSv1Registry, - isNormalizedName, isSelectionEmpty, - type Node, PluginName, - parseReverseName, type ResolverRecordsResponse, type ResolverRecordsSelection, TraceableENSProtocol, @@ -56,7 +59,7 @@ const tracer = trace.getTracer("forward-resolution"); // NOTE: normalize generic name to force the normalization lib to lazy-load itself (otherwise the // first trace generated here would be unusually slow) -normalize("example.eth"); +normalizeName("example.eth"); /** * Implements Forward Resolution of record values for a specified ENS Name. @@ -143,7 +146,7 @@ async function _resolveForward( throw new Error(`Invariant: Name "${name}" must be normalized.`); } - const node: Node = namehash(name); + const node: Node = namehashInterpretedName(asInterpretedName(name)); span.setAttribute("node", node); // if selection is empty, give them what they asked for diff --git a/apps/ensapi/src/lib/resolution/make-records-response.test.ts b/apps/ensapi/src/lib/resolution/make-records-response.test.ts index bd060f2a24..322f13c59e 100644 --- a/apps/ensapi/src/lib/resolution/make-records-response.test.ts +++ b/apps/ensapi/src/lib/resolution/make-records-response.test.ts @@ -1,6 +1,7 @@ +import type { CoinType } from "enssdk"; import { describe, expect, it } from "vitest"; -import type { CoinType, ResolverRecordsSelection } from "@ensnode/ensnode-sdk"; +import type { ResolverRecordsSelection } from "@ensnode/ensnode-sdk"; import { type IndexedResolverRecords, diff --git a/apps/ensapi/src/lib/resolution/make-records-response.ts b/apps/ensapi/src/lib/resolution/make-records-response.ts index ff77bf3871..ba8f98e5b4 100644 --- a/apps/ensapi/src/lib/resolution/make-records-response.ts +++ b/apps/ensapi/src/lib/resolution/make-records-response.ts @@ -1,8 +1,9 @@ -import { - bigintToCoinType, - type ResolverRecordsResponse, - type ResolverRecordsResponseBase, - type ResolverRecordsSelection, +import { bigintToCoinType } from "enssdk"; + +import type { + ResolverRecordsResponse, + ResolverRecordsResponseBase, + ResolverRecordsSelection, } from "@ensnode/ensnode-sdk"; import type { ResolveCallsAndResults } from "./resolve-calls-and-results"; diff --git a/apps/ensapi/src/lib/resolution/multichain-primary-name-resolution.ts b/apps/ensapi/src/lib/resolution/multichain-primary-name-resolution.ts index 05b0af3f45..930b0142e9 100644 --- a/apps/ensapi/src/lib/resolution/multichain-primary-name-resolution.ts +++ b/apps/ensapi/src/lib/resolution/multichain-primary-name-resolution.ts @@ -1,11 +1,11 @@ import config from "@/config"; import { trace } from "@opentelemetry/api"; +import type { ChainId } from "enssdk"; import { mainnet } from "viem/chains"; import { DatasourceNames, maybeGetDatasource } from "@ensnode/datasources"; import { - type ChainId, type MultichainPrimaryNameResolutionArgs, type MultichainPrimaryNameResolutionResult, uniq, diff --git a/apps/ensapi/src/lib/resolution/resolve-calls-and-results.ts b/apps/ensapi/src/lib/resolution/resolve-calls-and-results.ts index 25d7af7dac..f9c57c6a95 100644 --- a/apps/ensapi/src/lib/resolution/resolve-calls-and-results.ts +++ b/apps/ensapi/src/lib/resolution/resolve-calls-and-results.ts @@ -1,6 +1,6 @@ import { trace } from "@opentelemetry/api"; +import type { Address, Name, Node } from "enssdk"; import { - type Address, ContractFunctionExecutionError, decodeAbiParameters, encodeFunctionData, @@ -12,7 +12,7 @@ import { import { packetToBytes } from "viem/ens"; import { ResolverABI } from "@ensnode/datasources"; -import type { Name, Node, ResolverRecordsSelection } from "@ensnode/ensnode-sdk"; +import type { ResolverRecordsSelection } from "@ensnode/ensnode-sdk"; import { interpretAddressRecordValue, interpretNameRecordValue, diff --git a/apps/ensapi/src/lib/resolution/resolve-with-universal-resolver.ts b/apps/ensapi/src/lib/resolution/resolve-with-universal-resolver.ts index 5e041141de..515c6102eb 100644 --- a/apps/ensapi/src/lib/resolution/resolve-with-universal-resolver.ts +++ b/apps/ensapi/src/lib/resolution/resolve-with-universal-resolver.ts @@ -1,5 +1,6 @@ import config from "@/config"; +import type { Name } from "enssdk"; import { bytesToHex, ContractFunctionExecutionError, @@ -15,7 +16,6 @@ import { DatasourceNames, ResolverABI, UniversalResolverABI } from "@ensnode/dat import { getDatasourceContract, maybeGetDatasourceContract, - type Name, type ResolverRecordsSelection, } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensapi/src/lib/resolution/reverse-resolution.ts b/apps/ensapi/src/lib/resolution/reverse-resolution.ts index 9a556daaa8..b9cc05b8a2 100644 --- a/apps/ensapi/src/lib/resolution/reverse-resolution.ts +++ b/apps/ensapi/src/lib/resolution/reverse-resolution.ts @@ -1,14 +1,12 @@ import { SpanStatusCode, trace } from "@opentelemetry/api"; +import { coinTypeReverseLabel, evmChainIdToCoinType, reverseName } from "enssdk"; import { isAddress, isAddressEqual } from "viem"; import { - coinTypeReverseLabel, - evmChainIdToCoinType, type ResolverRecordsSelection, type ReverseResolutionArgs, ReverseResolutionProtocolStep, type ReverseResolutionResult, - reverseName, TraceableENSProtocol, } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensapi/src/omnigraph-api/builder.ts b/apps/ensapi/src/omnigraph-api/builder.ts index 3690b44002..16b1097d1a 100644 --- a/apps/ensapi/src/omnigraph-api/builder.ts +++ b/apps/ensapi/src/omnigraph-api/builder.ts @@ -5,9 +5,11 @@ import RelayPlugin from "@pothos/plugin-relay"; import TracingPlugin, { isRootField } from "@pothos/plugin-tracing"; import { AttributeNames, createOpenTelemetryWrapper } from "@pothos/tracing-opentelemetry"; import type { + Address, ChainId, CoinType, DomainId, + Hex, InterpretedLabel, InterpretedName, Node, @@ -22,7 +24,6 @@ import type { } from "enssdk"; import { getNamedType } from "graphql"; import superjson from "superjson"; -import type { Address, Hex } from "viem"; import type { context } from "@/omnigraph-api/context"; diff --git a/apps/ensapi/src/omnigraph-api/context.ts b/apps/ensapi/src/omnigraph-api/context.ts index c57fd01f61..a1ae5ac114 100644 --- a/apps/ensapi/src/omnigraph-api/context.ts +++ b/apps/ensapi/src/omnigraph-api/context.ts @@ -1,7 +1,6 @@ import DataLoader from "dataloader"; import { getUnixTime } from "date-fns"; - -import type { CanonicalPath, ENSv1DomainId, ENSv2DomainId } from "@ensnode/ensnode-sdk"; +import type { CanonicalPath, ENSv1DomainId, ENSv2DomainId } from "enssdk"; import { getV1CanonicalPath, getV2CanonicalPath } from "./lib/get-canonical-path"; diff --git a/apps/ensapi/src/omnigraph-api/lib/find-domains/domain-cursor.test.ts b/apps/ensapi/src/omnigraph-api/lib/find-domains/domain-cursor.test.ts index 1572f27370..eed8bcf308 100644 --- a/apps/ensapi/src/omnigraph-api/lib/find-domains/domain-cursor.test.ts +++ b/apps/ensapi/src/omnigraph-api/lib/find-domains/domain-cursor.test.ts @@ -1,7 +1,6 @@ +import type { DomainId } from "enssdk"; import { describe, expect, it } from "vitest"; -import type { DomainId } from "@ensnode/ensnode-sdk"; - import { type DomainCursor, DomainCursors } from "./domain-cursor"; describe("DomainCursor", () => { diff --git a/apps/ensapi/src/omnigraph-api/lib/find-domains/domain-cursor.ts b/apps/ensapi/src/omnigraph-api/lib/find-domains/domain-cursor.ts index 4aa463fecb..44fe5a0d05 100644 --- a/apps/ensapi/src/omnigraph-api/lib/find-domains/domain-cursor.ts +++ b/apps/ensapi/src/omnigraph-api/lib/find-domains/domain-cursor.ts @@ -1,4 +1,4 @@ -import type { DomainId } from "@ensnode/ensnode-sdk"; +import type { DomainId } from "enssdk"; import { cursors } from "@/omnigraph-api/lib/cursors"; import type { DomainOrderValue } from "@/omnigraph-api/lib/find-domains/types"; diff --git a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/base-domain-set.ts b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/base-domain-set.ts index adf976cd19..ec3e2fdebd 100644 --- a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/base-domain-set.ts +++ b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/base-domain-set.ts @@ -1,8 +1,6 @@ import { and, eq, sql } from "drizzle-orm"; import { alias, unionAll } from "drizzle-orm/pg-core"; -import type { Address } from "viem"; - -import type { DomainId } from "@ensnode/ensnode-sdk"; +import type { Address, DomainId } from "enssdk"; import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; diff --git a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name.ts b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name.ts index 611a9b2902..30b1d82396 100644 --- a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name.ts +++ b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name.ts @@ -1,12 +1,13 @@ import { eq, like, Param, sql } from "drizzle-orm"; import { alias, unionAll } from "drizzle-orm/pg-core"; - -import type { ENSv1DomainId, ENSv2DomainId, LabelHashPath } from "@ensnode/ensnode-sdk"; import { type DomainId, + type ENSv1DomainId, + type ENSv2DomainId, interpretedLabelsToLabelHashPath, + type LabelHashPath, parsePartialInterpretedName, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; diff --git a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-owner.ts b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-owner.ts index f63ed4e31b..5c040ddfef 100644 --- a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-owner.ts +++ b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-owner.ts @@ -1,5 +1,5 @@ import { eq } from "drizzle-orm"; -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { ensDb } from "@/lib/ensdb/singleton"; diff --git a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-parent.ts b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-parent.ts index ff8e70855d..10c4898895 100644 --- a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-parent.ts +++ b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-parent.ts @@ -1,6 +1,5 @@ import { eq } from "drizzle-orm"; - -import type { DomainId } from "@ensnode/ensnode-sdk"; +import type { DomainId } from "enssdk"; import { ensDb } from "@/lib/ensdb/singleton"; diff --git a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-registry.ts b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-registry.ts index c28104771b..8156f3b9a3 100644 --- a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-registry.ts +++ b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-registry.ts @@ -1,6 +1,5 @@ import { eq } from "drizzle-orm"; - -import type { RegistryId } from "@ensnode/ensnode-sdk"; +import type { RegistryId } from "enssdk"; import { ensDb } from "@/lib/ensdb/singleton"; diff --git a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/with-ordering-metadata.ts b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/with-ordering-metadata.ts index 616209a7c3..a58698554a 100644 --- a/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/with-ordering-metadata.ts +++ b/apps/ensapi/src/omnigraph-api/lib/find-domains/layers/with-ordering-metadata.ts @@ -1,6 +1,5 @@ import { and, eq, sql } from "drizzle-orm"; - -import type { DomainId } from "@ensnode/ensnode-sdk"; +import type { DomainId } from "enssdk"; import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; diff --git a/apps/ensapi/src/omnigraph-api/lib/find-events/find-events-resolver.ts b/apps/ensapi/src/omnigraph-api/lib/find-events/find-events-resolver.ts index 593d013bf9..5031b290f2 100644 --- a/apps/ensapi/src/omnigraph-api/lib/find-events/find-events-resolver.ts +++ b/apps/ensapi/src/omnigraph-api/lib/find-events/find-events-resolver.ts @@ -1,6 +1,6 @@ import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@pothos/plugin-relay"; import { and, count, eq, getTableColumns, gte, inArray, lte, type SQL, sql } from "drizzle-orm"; -import type { Address, Hex } from "viem"; +import type { Address, Hex } from "enssdk"; import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; import { orderPaginationBy, paginateBy } from "@/omnigraph-api/lib/connection-helpers"; diff --git a/apps/ensapi/src/omnigraph-api/lib/get-canonical-path.ts b/apps/ensapi/src/omnigraph-api/lib/get-canonical-path.ts index f9df7c14c2..b3ba0a107e 100644 --- a/apps/ensapi/src/omnigraph-api/lib/get-canonical-path.ts +++ b/apps/ensapi/src/omnigraph-api/lib/get-canonical-path.ts @@ -1,16 +1,16 @@ import config from "@/config"; import { sql } from "drizzle-orm"; - import { type CanonicalPath, type DomainId, type ENSv1DomainId, type ENSv2DomainId, - maybeGetENSv2RootRegistryId, type RegistryId, ROOT_NODE, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; + +import { maybeGetENSv2RootRegistryId } from "@ensnode/ensnode-sdk"; import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; import { lazy } from "@/lib/lazy"; diff --git a/apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts b/apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts index ef2d77f3a5..e1ff67ff88 100644 --- a/apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts +++ b/apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts @@ -2,8 +2,6 @@ import config from "@/config"; import { trace } from "@opentelemetry/api"; import { Param, sql } from "drizzle-orm"; -import { namehash } from "viem"; - import { type DomainId, type ENSv2DomainId, @@ -12,9 +10,11 @@ import { interpretedNameToInterpretedLabels, type LabelHash, makeENSv1DomainId, - maybeGetENSv2RootRegistryId, + namehashInterpretedName, type RegistryId, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; + +import { maybeGetENSv2RootRegistryId } from "@ensnode/ensnode-sdk"; import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; import { withActiveSpanAsync } from "@/lib/instrumentation/auto-span"; @@ -93,13 +93,12 @@ export async function getDomainIdByInterpretedName( * Retrieves the ENSv1DomainId for the provided `name`, if exists. */ async function v1_getDomainIdByInterpretedName(name: InterpretedName): Promise { - const node = namehash(name); - const domainId = makeENSv1DomainId(node); + const domainId = makeENSv1DomainId(namehashInterpretedName(name)); const domain = await ensDb.query.v1Domain.findFirst({ where: (t, { eq }) => eq(t.id, domainId) }); const exists = domain !== undefined; - v1Logger.debug({ node, exists }); + v1Logger.debug({ domainId, exists }); return exists ? domainId : null; } diff --git a/apps/ensapi/src/omnigraph-api/lib/get-domain-resolver.ts b/apps/ensapi/src/omnigraph-api/lib/get-domain-resolver.ts index 1698ada89a..4652b95756 100644 --- a/apps/ensapi/src/omnigraph-api/lib/get-domain-resolver.ts +++ b/apps/ensapi/src/omnigraph-api/lib/get-domain-resolver.ts @@ -1,4 +1,4 @@ -import type { DomainId } from "@ensnode/ensnode-sdk"; +import type { DomainId } from "enssdk"; import { ensDb } from "@/lib/ensdb/singleton"; diff --git a/apps/ensapi/src/omnigraph-api/lib/get-latest-registration.ts b/apps/ensapi/src/omnigraph-api/lib/get-latest-registration.ts index 3aa5da47fc..c5ea387cd5 100644 --- a/apps/ensapi/src/omnigraph-api/lib/get-latest-registration.ts +++ b/apps/ensapi/src/omnigraph-api/lib/get-latest-registration.ts @@ -1,4 +1,4 @@ -import type { DomainId } from "@ensnode/ensnode-sdk"; +import type { DomainId } from "enssdk"; import { ensDb } from "@/lib/ensdb/singleton"; diff --git a/apps/ensapi/src/omnigraph-api/schema/account-id.ts b/apps/ensapi/src/omnigraph-api/schema/account-id.ts index 61661f88e9..2235dd6969 100644 --- a/apps/ensapi/src/omnigraph-api/schema/account-id.ts +++ b/apps/ensapi/src/omnigraph-api/schema/account-id.ts @@ -1,4 +1,4 @@ -import type { AccountId } from "@ensnode/ensnode-sdk"; +import type { AccountId } from "enssdk"; import { builder } from "@/omnigraph-api/builder"; diff --git a/apps/ensapi/src/omnigraph-api/schema/account.integration.test.ts b/apps/ensapi/src/omnigraph-api/schema/account.integration.test.ts index a05b8ab96b..82203b911b 100644 --- a/apps/ensapi/src/omnigraph-api/schema/account.integration.test.ts +++ b/apps/ensapi/src/omnigraph-api/schema/account.integration.test.ts @@ -1,8 +1,6 @@ -import type { Address } from "viem"; +import type { Address, Name } from "enssdk"; import { beforeAll, describe, expect, it } from "vitest"; -import type { Name } from "@ensnode/ensnode-sdk"; - import { AccountDomainsPaginated, type PaginatedDomainResult, diff --git a/apps/ensapi/src/omnigraph-api/schema/account.ts b/apps/ensapi/src/omnigraph-api/schema/account.ts index c6f0017c1a..55a4d07365 100644 --- a/apps/ensapi/src/omnigraph-api/schema/account.ts +++ b/apps/ensapi/src/omnigraph-api/schema/account.ts @@ -1,6 +1,6 @@ import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@pothos/plugin-relay"; import { and, count, eq, getTableColumns } from "drizzle-orm"; -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; import { builder } from "@/omnigraph-api/builder"; diff --git a/apps/ensapi/src/omnigraph-api/schema/domain.integration.test.ts b/apps/ensapi/src/omnigraph-api/schema/domain.integration.test.ts index 9dce92052e..3b937066ca 100644 --- a/apps/ensapi/src/omnigraph-api/schema/domain.integration.test.ts +++ b/apps/ensapi/src/omnigraph-api/schema/domain.integration.test.ts @@ -1,7 +1,6 @@ +import type { InterpretedLabel, Name } from "enssdk"; 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 { DomainSubdomainsPaginated, diff --git a/apps/ensapi/src/omnigraph-api/schema/domain.ts b/apps/ensapi/src/omnigraph-api/schema/domain.ts index 6ed8c662e2..31d98b1c70 100644 --- a/apps/ensapi/src/omnigraph-api/schema/domain.ts +++ b/apps/ensapi/src/omnigraph-api/schema/domain.ts @@ -1,13 +1,12 @@ import { trace } from "@opentelemetry/api"; import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@pothos/plugin-relay"; import { and, count, eq, getTableColumns } from "drizzle-orm"; - import { type DomainId, type ENSv1DomainId, type ENSv2DomainId, interpretedLabelsToInterpretedName, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; import { withSpanAsync } from "@/lib/instrumentation/auto-span"; diff --git a/apps/ensapi/src/omnigraph-api/schema/permissions.integration.test.ts b/apps/ensapi/src/omnigraph-api/schema/permissions.integration.test.ts index a11b665d3a..44b1a1c38f 100644 --- a/apps/ensapi/src/omnigraph-api/schema/permissions.integration.test.ts +++ b/apps/ensapi/src/omnigraph-api/schema/permissions.integration.test.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { toEventSelector } from "viem"; import { beforeAll, describe, expect, it } from "vitest"; diff --git a/apps/ensapi/src/omnigraph-api/schema/permissions.ts b/apps/ensapi/src/omnigraph-api/schema/permissions.ts index f7e9c52bf7..664bad766f 100644 --- a/apps/ensapi/src/omnigraph-api/schema/permissions.ts +++ b/apps/ensapi/src/omnigraph-api/schema/permissions.ts @@ -6,10 +6,9 @@ import { type PermissionsId, type PermissionsResourceId, type PermissionsUserId, + ROOT_RESOURCE, } from "enssdk"; -import { ROOT_RESOURCE } from "@ensnode/ensnode-sdk"; - import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; import { builder } from "@/omnigraph-api/builder"; import { orderPaginationBy, paginateBy } from "@/omnigraph-api/lib/connection-helpers"; diff --git a/apps/ensapi/src/omnigraph-api/schema/query.integration.test.ts b/apps/ensapi/src/omnigraph-api/schema/query.integration.test.ts index 3b761f5d53..267ceec9f0 100644 --- a/apps/ensapi/src/omnigraph-api/schema/query.integration.test.ts +++ b/apps/ensapi/src/omnigraph-api/schema/query.integration.test.ts @@ -1,17 +1,20 @@ -import { type Address, labelhash, namehash } from "viem"; -import { describe, expect, it } from "vitest"; - -import { DatasourceNames } from "@ensnode/datasources"; import { + type Address, + asInterpretedLabel, + asInterpretedName, type DomainId, - getDatasourceContract, - getENSv2RootRegistryId, type InterpretedLabel, + labelhashInterpretedLabel, makeENSv1DomainId, makeENSv2DomainId, makeStorageId, type Name, -} from "@ensnode/ensnode-sdk"; + namehashInterpretedName, +} from "enssdk"; +import { describe, expect, it } from "vitest"; + +import { DatasourceNames } from "@ensnode/datasources"; +import { getDatasourceContract, getENSv2RootRegistryId } from "@ensnode/ensnode-sdk"; import { DEVNET_NAMES } from "@/test/integration/devnet-names"; import { @@ -35,9 +38,8 @@ const V2_ROOT_REGISTRY = getDatasourceContract( "RootRegistry", ); -const V1_ETH_DOMAIN_ID = makeENSv1DomainId(namehash("eth")); - -const V2_ETH_STORAGE_ID = makeStorageId(labelhash("eth")); +const V1_ETH_DOMAIN_ID = makeENSv1DomainId(namehashInterpretedName(asInterpretedName("eth"))); +const V2_ETH_STORAGE_ID = makeStorageId(labelhashInterpretedLabel(asInterpretedLabel("eth"))); const V2_ETH_DOMAIN_ID = makeENSv2DomainId(V2_ROOT_REGISTRY, V2_ETH_STORAGE_ID); describe("Query.root", () => { diff --git a/apps/ensapi/src/omnigraph-api/schema/registration.ts b/apps/ensapi/src/omnigraph-api/schema/registration.ts index 97dca5a0c8..87a69e8fe7 100644 --- a/apps/ensapi/src/omnigraph-api/schema/registration.ts +++ b/apps/ensapi/src/omnigraph-api/schema/registration.ts @@ -1,12 +1,11 @@ import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@pothos/plugin-relay"; import { and, eq } from "drizzle-orm"; +import type { ENSv1DomainId, RegistrationId } from "enssdk"; import { hexToBigInt } from "viem"; import { - type ENSv1DomainId, isRegistrationFullyExpired, isRegistrationInGracePeriod, - type RegistrationId, type RequiredAndNotNull, } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensapi/src/omnigraph-api/schema/registry.integration.test.ts b/apps/ensapi/src/omnigraph-api/schema/registry.integration.test.ts index 574061542e..e63dfb8428 100644 --- a/apps/ensapi/src/omnigraph-api/schema/registry.integration.test.ts +++ b/apps/ensapi/src/omnigraph-api/schema/registry.integration.test.ts @@ -1,7 +1,8 @@ +import type { InterpretedLabel } from "enssdk"; import { describe, expect, it } from "vitest"; import { DatasourceNames } from "@ensnode/datasources"; -import { getDatasourceContract, type InterpretedLabel } from "@ensnode/ensnode-sdk"; +import { getDatasourceContract } from "@ensnode/ensnode-sdk"; import { DEVNET_ETH_LABELS } from "@/test/integration/devnet-names"; import { diff --git a/apps/ensapi/src/omnigraph-api/schema/renewal.ts b/apps/ensapi/src/omnigraph-api/schema/renewal.ts index 1fe79a03f2..eea55888a7 100644 --- a/apps/ensapi/src/omnigraph-api/schema/renewal.ts +++ b/apps/ensapi/src/omnigraph-api/schema/renewal.ts @@ -1,4 +1,4 @@ -import type { RenewalId } from "@ensnode/ensnode-sdk"; +import type { RenewalId } from "enssdk"; import { ensDb } from "@/lib/ensdb/singleton"; import { builder } from "@/omnigraph-api/builder"; diff --git a/apps/ensapi/src/omnigraph-api/schema/resolver-records.ts b/apps/ensapi/src/omnigraph-api/schema/resolver-records.ts index bbc6b674af..bd86b519b3 100644 --- a/apps/ensapi/src/omnigraph-api/schema/resolver-records.ts +++ b/apps/ensapi/src/omnigraph-api/schema/resolver-records.ts @@ -1,4 +1,4 @@ -import { bigintToCoinType, type ResolverRecordsId } from "@ensnode/ensnode-sdk"; +import { bigintToCoinType, type ResolverRecordsId } from "enssdk"; import { ensDb } from "@/lib/ensdb/singleton"; import { builder } from "@/omnigraph-api/builder"; diff --git a/apps/ensapi/src/omnigraph-api/schema/resolver.ts b/apps/ensapi/src/omnigraph-api/schema/resolver.ts index 75e68bfee3..5493a36b51 100644 --- a/apps/ensapi/src/omnigraph-api/schema/resolver.ts +++ b/apps/ensapi/src/omnigraph-api/schema/resolver.ts @@ -2,8 +2,12 @@ import config from "@/config"; import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@pothos/plugin-relay"; import { and, eq } from "drizzle-orm"; -import { makePermissionsId, makeResolverRecordsId, type ResolverId } from "enssdk"; -import { namehash } from "viem"; +import { + makePermissionsId, + makeResolverRecordsId, + namehashInterpretedName, + type ResolverId, +} from "enssdk"; import { isBridgedResolver } from "@ensnode/ensnode-sdk/internal"; @@ -109,7 +113,7 @@ ResolverRef.implement({ args: { for: t.arg({ type: NameOrNodeInput, required: true }) }, nullable: true, resolve: async ({ chainId, address }, args) => { - const node = args.for.node ?? namehash(args.for.name); + const node = args.for.node ?? namehashInterpretedName(args.for.name); return makeResolverRecordsId({ chainId, address }, node); }, }), diff --git a/apps/ensapi/src/omnigraph-api/schema/scalars.ts b/apps/ensapi/src/omnigraph-api/schema/scalars.ts index 957ece2e10..55b8f43370 100644 --- a/apps/ensapi/src/omnigraph-api/schema/scalars.ts +++ b/apps/ensapi/src/omnigraph-api/schema/scalars.ts @@ -1,12 +1,11 @@ -import { type Address, type Hex, isHex, size } from "viem"; -import { z } from "zod/v4"; - import { + type Address, + asInterpretedLabel, + asInterpretedName, type ChainId, type CoinType, type DomainId, - type InterpretedLabel, - type InterpretedName, + type Hex, isInterpetedLabel, isInterpretedName, type Name, @@ -19,7 +18,10 @@ import { type RenewalId, type ResolverId, type ResolverRecordsId, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; +import { isHex, size } from "viem"; +import { z } from "zod/v4"; + import { makeChainIdSchema, makeCoinTypeSchema, @@ -106,7 +108,7 @@ builder.scalarType("InterpretedName", { }); } }) - .transform((val) => val as InterpretedName) + .transform((val) => asInterpretedName(val)) .parse(value), }); @@ -125,7 +127,7 @@ builder.scalarType("InterpretedLabel", { }); } }) - .transform((val) => val as InterpretedLabel) + .transform((val) => asInterpretedLabel(val)) .parse(value), }); diff --git a/apps/ensapi/src/test/integration/find-domains/domain-pagination-queries.ts b/apps/ensapi/src/test/integration/find-domains/domain-pagination-queries.ts index b9e7f90bd2..ea4fcc26af 100644 --- a/apps/ensapi/src/test/integration/find-domains/domain-pagination-queries.ts +++ b/apps/ensapi/src/test/integration/find-domains/domain-pagination-queries.ts @@ -1,4 +1,4 @@ -import type { InterpretedLabel, Name } from "@ensnode/ensnode-sdk"; +import type { InterpretedLabel, Name } from "enssdk"; import { gql } from "@/test/integration/omnigraph-api-client"; diff --git a/apps/ensindexer/src/config/derived-params.ts b/apps/ensindexer/src/config/derived-params.ts index b03a5303b5..421a69d818 100644 --- a/apps/ensindexer/src/config/derived-params.ts +++ b/apps/ensindexer/src/config/derived-params.ts @@ -1,5 +1,6 @@ +import type { ChainId } from "enssdk"; + import { maybeGetDatasource } from "@ensnode/datasources"; -import type { ChainId } from "@ensnode/ensnode-sdk"; import type { EnsIndexerConfig } from "@/config/types"; import { getPlugin } from "@/plugins"; diff --git a/apps/ensindexer/src/config/serialize.ts b/apps/ensindexer/src/config/serialize.ts index 637ecb1d5c..509668379d 100644 --- a/apps/ensindexer/src/config/serialize.ts +++ b/apps/ensindexer/src/config/serialize.ts @@ -1,9 +1,6 @@ -import { - serializeChainId, - serializeIndexedChainIds, - serializeUrl, - type UrlString, -} from "@ensnode/ensnode-sdk"; +import type { UrlString } from "enssdk"; + +import { serializeChainId, serializeIndexedChainIds, serializeUrl } from "@ensnode/ensnode-sdk"; import { redactENSIndexerConfig } from "@/config/redact"; diff --git a/apps/ensindexer/src/config/serialized-types.ts b/apps/ensindexer/src/config/serialized-types.ts index 4fb0a5bf60..1d67489100 100644 --- a/apps/ensindexer/src/config/serialized-types.ts +++ b/apps/ensindexer/src/config/serialized-types.ts @@ -1,4 +1,5 @@ -import type { ChainId, ChainIdString, UrlString } from "@ensnode/ensnode-sdk"; +import type { ChainId, ChainIdString, UrlString } from "enssdk"; + import type { RpcConfig } from "@ensnode/ensnode-sdk/internal"; import type { EnsRainbowClientLabelSet } from "@ensnode/ensrainbow-sdk"; diff --git a/apps/ensindexer/src/config/types.ts b/apps/ensindexer/src/config/types.ts index b998579305..924e062cae 100644 --- a/apps/ensindexer/src/config/types.ts +++ b/apps/ensindexer/src/config/types.ts @@ -1,6 +1,8 @@ +import type { ChainId } from "enssdk"; + import type { ENSNamespaceId } from "@ensnode/datasources"; import type { EnsDbConfig } from "@ensnode/ensdb-sdk"; -import type { BlockNumberRange, ChainId, PluginName } from "@ensnode/ensnode-sdk"; +import type { BlockNumberRange, PluginName } from "@ensnode/ensnode-sdk"; import { RpcConfig, type RpcConfigs } from "@ensnode/ensnode-sdk/internal"; import type { EnsRainbowClientLabelSet } from "@ensnode/ensrainbow-sdk"; diff --git a/apps/ensindexer/src/config/validations.ts b/apps/ensindexer/src/config/validations.ts index 9c983f044b..168c0d9ce3 100644 --- a/apps/ensindexer/src/config/validations.ts +++ b/apps/ensindexer/src/config/validations.ts @@ -1,7 +1,9 @@ -import { type Address, isAddress } from "viem"; +import type { Address } from "enssdk"; +import { asLowerCaseAddress } from "enssdk"; +import { isAddress } from "viem"; import { type DatasourceName, type ENSNamespace, getENSNamespace } from "@ensnode/datasources"; -import { asLowerCaseAddress, PluginName } from "@ensnode/ensnode-sdk"; +import { PluginName } from "@ensnode/ensnode-sdk"; import type { ZodCheckFnInput } from "@ensnode/ensnode-sdk/internal"; import { getPlugin } from "@/plugins"; diff --git a/apps/ensindexer/src/lib/currencies.ts b/apps/ensindexer/src/lib/currencies.ts index 6b6f3c5702..3952d3a012 100644 --- a/apps/ensindexer/src/lib/currencies.ts +++ b/apps/ensindexer/src/lib/currencies.ts @@ -1,7 +1,8 @@ -import { type Address, zeroAddress } from "viem"; +import type { AccountId, Address, ChainId } from "enssdk"; +import { zeroAddress } from "viem"; import { base, baseSepolia, linea, lineaSepolia, mainnet, optimism, sepolia } from "viem/chains"; -import { type AccountId, type ChainId, type CurrencyId, CurrencyIds } from "@ensnode/ensnode-sdk"; +import { type CurrencyId, CurrencyIds } from "@ensnode/ensnode-sdk"; // NOTE: this mapping currently only considers the subset of chains where we have // supported token issuing contracts. diff --git a/apps/ensindexer/src/lib/dns-helpers.test.ts b/apps/ensindexer/src/lib/dns-helpers.test.ts index 3e6a7cd13f..111b9fb73f 100644 --- a/apps/ensindexer/src/lib/dns-helpers.test.ts +++ b/apps/ensindexer/src/lib/dns-helpers.test.ts @@ -5,8 +5,9 @@ import { describe, expect, it } from "vitest"; import "@/lib/__test__/mockLogger"; +import type { DNSEncodedLiteralName } from "enssdk"; + import { getDatasource } from "@ensnode/datasources"; -import type { DNSEncodedLiteralName } from "@ensnode/ensnode-sdk"; import { decodeTXTData, diff --git a/apps/ensindexer/src/lib/dns-helpers.ts b/apps/ensindexer/src/lib/dns-helpers.ts index d2e831e2c6..5fc782309f 100644 --- a/apps/ensindexer/src/lib/dns-helpers.ts +++ b/apps/ensindexer/src/lib/dns-helpers.ts @@ -1,17 +1,17 @@ import dnsPacket, { type Answer } from "dns-packet"; -import type { Hex } from "viem"; - import { type DNSEncodedLiteralName, type DNSEncodedName, decodeDNSEncodedLiteralName, decodeDNSEncodedName, + type Hex, type Label, literalLabelsToLiteralName, type Name, type SubgraphInterpretedLabel, type SubgraphInterpretedName, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; + import { interpretTextRecordKey, interpretTextRecordValue } from "@ensnode/ensnode-sdk/internal"; import { logger } from "@/lib/logger"; diff --git a/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts index fe7def041b..0209813ace 100644 --- a/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { interpretAddress } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts index 1b018a6567..78f3f3401b 100644 --- a/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts @@ -1,6 +1,6 @@ -import type { Address } from "viem"; +import type { Address, ENSv1DomainId } from "enssdk"; -import { type ENSv1DomainId, interpretAddress } from "@ensnode/ensnode-sdk"; +import { interpretAddress } from "@ensnode/ensnode-sdk"; import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts index a6b7edd9f5..9495500b82 100644 --- a/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts @@ -1,12 +1,11 @@ -import { labelhash } from "viem"; - import { + asInterpretedLabel, encodeLabelHash, - type InterpretedLabel, type LabelHash, type LiteralLabel, + labelhashLiteralLabel, literalLabelToInterpretedLabel, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; @@ -15,7 +14,7 @@ import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-eng * Ensures that the LiteralLabel `label` is interpreted and upserted into the Label rainbow table. */ export async function ensureLabel(context: IndexingEngineContext, label: LiteralLabel) { - const labelHash = labelhash(label); + const labelHash = labelhashLiteralLabel(label); const interpreted = literalLabelToInterpretedLabel(label); await context.ensDb @@ -40,7 +39,7 @@ export async function ensureUnknownLabel(context: IndexingEngineContext, labelHa if (healedLabel) return await ensureLabel(context, healedLabel); // otherwise upsert label entity - const interpreted = encodeLabelHash(labelHash) as InterpretedLabel; + const interpreted = asInterpretedLabel(encodeLabelHash(labelHash)); await context.ensDb .insert(ensIndexerSchema.label) .values({ labelHash, interpreted }) diff --git a/apps/ensindexer/src/lib/get-this-account-id.ts b/apps/ensindexer/src/lib/get-this-account-id.ts index b6e88a7328..541339a523 100644 --- a/apps/ensindexer/src/lib/get-this-account-id.ts +++ b/apps/ensindexer/src/lib/get-this-account-id.ts @@ -1,4 +1,4 @@ -import type { AccountId } from "@ensnode/ensnode-sdk"; +import type { AccountId } from "enssdk"; import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { LogEventBase } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/lib/graphnode-helpers.test.ts b/apps/ensindexer/src/lib/graphnode-helpers.test.ts index c80bef6dbc..8d71a23256 100644 --- a/apps/ensindexer/src/lib/graphnode-helpers.test.ts +++ b/apps/ensindexer/src/lib/graphnode-helpers.test.ts @@ -1,7 +1,6 @@ +import type { LabelHash } from "enssdk"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import type { LabelHash } from "@ensnode/ensnode-sdk"; - import { setupConfigMock, setupEnsDbConfigMock } from "@/lib/__test__/mockConfig"; import "@/lib/__test__/mockLogger"; diff --git a/apps/ensindexer/src/lib/graphnode-helpers.ts b/apps/ensindexer/src/lib/graphnode-helpers.ts index 2115d23936..f0433a5a2c 100644 --- a/apps/ensindexer/src/lib/graphnode-helpers.ts +++ b/apps/ensindexer/src/lib/graphnode-helpers.ts @@ -1,6 +1,6 @@ +import { asLiteralLabel, type LabelHash, type LiteralLabel } from "enssdk"; import pRetry from "p-retry"; -import type { LabelHash, LiteralLabel } from "@ensnode/ensnode-sdk"; import { type EnsRainbow, ErrorCode, isHealError } from "@ensnode/ensrainbow-sdk"; import { ensRainbowClient } from "@/lib/ensrainbow/singleton"; @@ -97,5 +97,5 @@ export async function labelByLabelHash(labelHash: LabelHash): Promise { beforeEach(() => { vi.resetAllMocks(); diff --git a/apps/ensindexer/src/lib/managed-names.ts b/apps/ensindexer/src/lib/managed-names.ts index 9470b7983f..1e0fdb87e3 100644 --- a/apps/ensindexer/src/lib/managed-names.ts +++ b/apps/ensindexer/src/lib/managed-names.ts @@ -1,15 +1,19 @@ import config from "@/config"; -import { namehash } from "viem"; +import { + type AccountId, + asInterpretedName, + type InterpretedName, + type Name, + type Node, + namehashInterpretedName, +} from "enssdk"; import { DatasourceNames, type ENSNamespaceId } from "@ensnode/datasources"; import { - type AccountId, accountIdEqual, getDatasourceContract, maybeGetDatasourceContract, - type Name, - type Node, } from "@ensnode/ensnode-sdk"; import { toJson } from "@/lib/json-stringify-with-bigints"; @@ -131,7 +135,7 @@ const cachedNamehash = (name: Name): Node => { const cached = namehashCache.get(name); if (cached !== undefined) return cached; - const node = namehash(name); + const node = namehashInterpretedName(asInterpretedName(name)); namehashCache.set(name, node); return node; }; @@ -141,14 +145,16 @@ const cachedNamehash = (name: Name): Node => { * * @dev Caches the result of namehash(name). */ -export const getManagedName = (contract: AccountId): { name: Name; node: Node } => { +export const getManagedName = (contract: AccountId): { name: InterpretedName; node: Node } => { for (const [managedName, contracts] of Object.entries(CONTRACTS_BY_MANAGED_NAME)) { const isAnyOfTheContracts = contracts.some((_contract) => accountIdEqual(_contract, contract)); if (isAnyOfTheContracts) { const namespaceSpecific = MANAGED_NAME_BY_NAMESPACE[config.namespace]?.[managedName]; // use the namespace-specific Managed Name if specified, otherwise use the default from CONTRACTS_BY_MANAGED_NAME - const name = namespaceSpecific ?? managedName; + // NOTE: we cast to InterpretedName directly to avoid the overhead of asInterpretedName and + // both namespaceSpecific and managedName are guaranteed to be InterpretedName (see above) + const name = (namespaceSpecific ?? managedName) as InterpretedName; const node = cachedNamehash(name); return { name, node }; diff --git a/apps/ensindexer/src/lib/maybe-heal-label-by-addr-reverse-subname.test.ts b/apps/ensindexer/src/lib/maybe-heal-label-by-addr-reverse-subname.test.ts index b8e4c6b8fc..b4a3178203 100644 --- a/apps/ensindexer/src/lib/maybe-heal-label-by-addr-reverse-subname.test.ts +++ b/apps/ensindexer/src/lib/maybe-heal-label-by-addr-reverse-subname.test.ts @@ -1,15 +1,19 @@ -import { type Address, labelhash } from "viem"; +import { + type Address, + addrReverseLabel, + type InterpretedLabel, + labelhashInterpretedLabel, + labelhashLiteralLabel, +} from "enssdk"; import { describe, expect, it } from "vitest"; -import { addrReverseLabel } from "@ensnode/ensnode-sdk"; - import { maybeHealLabelByAddrReverseSubname } from "./maybe-heal-label-by-addr-reverse-subname"; describe("maybeHealLabelByAddrReverseSubname", () => { const address: Address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; const reverseAddressSubname = addrReverseLabel(address); - const labelHash = labelhash(reverseAddressSubname); - const notMatchingLabelHash = labelhash("test.eth"); + const labelHash = labelhashLiteralLabel(reverseAddressSubname); + const notMatchingLabelHash = labelhashInterpretedLabel("test.eth" as InterpretedLabel); it("should return null if the label cannot be healed", () => { expect(maybeHealLabelByAddrReverseSubname(notMatchingLabelHash, address)).toBe(null); diff --git a/apps/ensindexer/src/lib/maybe-heal-label-by-addr-reverse-subname.ts b/apps/ensindexer/src/lib/maybe-heal-label-by-addr-reverse-subname.ts index 2842de47b0..8985383964 100644 --- a/apps/ensindexer/src/lib/maybe-heal-label-by-addr-reverse-subname.ts +++ b/apps/ensindexer/src/lib/maybe-heal-label-by-addr-reverse-subname.ts @@ -1,11 +1,10 @@ -import type { Address } from "viem"; - import { + type Address, addrReverseLabel, type LabelHash, type LiteralLabel, labelhashLiteralLabel, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; /** * Attempt to heal the labelHash of an addr.reverse subname using an address. diff --git a/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts b/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts index 163dcf3e1c..416238e73c 100644 --- a/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts +++ b/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts @@ -1,6 +1,5 @@ -import { type Address, isAddressEqual, zeroAddress } from "viem"; - -import type { AccountId, DomainId } from "@ensnode/ensnode-sdk"; +import type { AccountId, Address, DomainId } from "enssdk"; +import { isAddressEqual, zeroAddress } from "viem"; import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts b/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts index c0713f45d3..7d653124aa 100644 --- a/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts +++ b/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts @@ -1,7 +1,8 @@ import config from "@/config"; +import type { Node } from "enssdk"; + import { getENSRootChainId } from "@ensnode/datasources"; -import type { Node } from "@ensnode/ensnode-sdk"; import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts b/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts index f432d6929a..40164c3958 100644 --- a/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts +++ b/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts @@ -1,11 +1,11 @@ import { type AccountId, + type Address, type CoinType, makeResolverId, makeResolverRecordsId, type Node, } from "enssdk"; -import type { Address } from "viem"; import { interpretAddressRecordValue, diff --git a/apps/ensindexer/src/lib/subgraph/db-helpers.ts b/apps/ensindexer/src/lib/subgraph/db-helpers.ts index badd42f5f1..b7f47d6c43 100644 --- a/apps/ensindexer/src/lib/subgraph/db-helpers.ts +++ b/apps/ensindexer/src/lib/subgraph/db-helpers.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { LogEventBase } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/lib/subgraph/ids.test.ts b/apps/ensindexer/src/lib/subgraph/ids.test.ts index f3765e4f81..4491453298 100644 --- a/apps/ensindexer/src/lib/subgraph/ids.test.ts +++ b/apps/ensindexer/src/lib/subgraph/ids.test.ts @@ -11,7 +11,13 @@ import { setupEnsDbConfigMock(); setupConfigMock(); -import { labelhash, namehash, zeroAddress } from "viem"; +import { + asInterpretedLabel, + asInterpretedName, + labelhashInterpretedLabel, + namehashInterpretedName, +} from "enssdk"; +import { zeroAddress } from "viem"; import { makeEventId, makeRegistrationId, makeResolverId } from "./ids"; @@ -29,7 +35,7 @@ describe("ids", () => { makeResolverId( CHAIN_ID, "0x2aaecbf301b736859333be66942cb6dbd3e9cafe", - namehash("vitalik.eth"), + namehashInterpretedName(asInterpretedName("vitalik.eth")), ), ).toEqual( "1337-0x2aaecbf301b736859333be66942cb6dbd3e9cafe-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", @@ -52,7 +58,13 @@ describe("ids", () => { describe("makeResolverId", () => { it("should not include chain id", () => { - expect(makeResolverId(CHAIN_ID, zeroAddress, namehash("vitalik.eth"))).toEqual( + expect( + makeResolverId( + CHAIN_ID, + zeroAddress, + namehashInterpretedName(asInterpretedName("vitalik.eth")), + ), + ).toEqual( "0x0000000000000000000000000000000000000000-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", ); }); @@ -66,9 +78,12 @@ describe("ids", () => { describe("makeRegistrationId", () => { it("should use the labelHash of the registered name", () => { - expect(makeRegistrationId(labelhash("vitalik"), namehash("vitalik.eth"))).toEqual( - labelhash("vitalik"), - ); + expect( + makeRegistrationId( + labelhashInterpretedLabel(asInterpretedLabel("vitalik")), + namehashInterpretedName(asInterpretedName("vitalik.eth")), + ), + ).toEqual(labelhashInterpretedLabel(asInterpretedLabel("vitalik"))); }); }); }); @@ -76,7 +91,13 @@ describe("ids", () => { describe("not in subgraph compatibility mode", () => { describe("makeResolverId", () => { it("should include chain id", () => { - expect(makeResolverId(CHAIN_ID, zeroAddress, namehash("vitalik.eth"))).toEqual( + expect( + makeResolverId( + CHAIN_ID, + zeroAddress, + namehashInterpretedName(asInterpretedName("vitalik.eth")), + ), + ).toEqual( "1337-0x0000000000000000000000000000000000000000-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", ); }); @@ -90,9 +111,12 @@ describe("ids", () => { describe("makeRegistrationId", () => { it("should use the node of the registered name", () => { - expect(makeRegistrationId(labelhash("vitalik"), namehash("vitalik.linea.eth"))).toEqual( - namehash("vitalik.linea.eth"), - ); + expect( + makeRegistrationId( + labelhashInterpretedLabel(asInterpretedLabel("vitalik")), + namehashInterpretedName(asInterpretedName("vitalik.linea.eth")), + ), + ).toEqual(namehashInterpretedName(asInterpretedName("vitalik.linea.eth"))); }); }); }); diff --git a/apps/ensindexer/src/lib/subgraph/ids.ts b/apps/ensindexer/src/lib/subgraph/ids.ts index 83aaed566c..14363f552b 100644 --- a/apps/ensindexer/src/lib/subgraph/ids.ts +++ b/apps/ensindexer/src/lib/subgraph/ids.ts @@ -1,8 +1,6 @@ import config from "@/config"; -import type { Address } from "viem"; - -import type { LabelHash, Node } from "@ensnode/ensnode-sdk"; +import type { Address, LabelHash, Node } from "enssdk"; /** * Makes a unique, chain-scoped resolver ID. diff --git a/apps/ensindexer/src/lib/subgraph/is-label-subgraph-indexable.test.ts b/apps/ensindexer/src/lib/subgraph/is-label-subgraph-indexable.test.ts index 85bc7d67fb..98ccc2fc7e 100644 --- a/apps/ensindexer/src/lib/subgraph/is-label-subgraph-indexable.test.ts +++ b/apps/ensindexer/src/lib/subgraph/is-label-subgraph-indexable.test.ts @@ -1,15 +1,14 @@ +import { asLiteralLabel, type LiteralLabel } from "enssdk"; import { describe, expect, it } from "vitest"; -import type { LiteralLabel } from "@ensnode/ensnode-sdk"; - import { isLabelSubgraphIndexable } from "./is-label-subgraph-indexable"; describe("isLabelSubgraphIndexable", () => { it("should return false for labels containing subgraph-unindexable characters", () => { - expect(isLabelSubgraphIndexable("test\0" as LiteralLabel)).toBe(false); - expect(isLabelSubgraphIndexable("test." as LiteralLabel)).toBe(false); - expect(isLabelSubgraphIndexable("test[" as LiteralLabel)).toBe(false); - expect(isLabelSubgraphIndexable("test]" as LiteralLabel)).toBe(false); + expect(isLabelSubgraphIndexable(asLiteralLabel("test\0"))).toBe(false); + expect(isLabelSubgraphIndexable(asLiteralLabel("test."))).toBe(false); + expect(isLabelSubgraphIndexable(asLiteralLabel("test["))).toBe(false); + expect(isLabelSubgraphIndexable(asLiteralLabel("test]"))).toBe(false); }); it("should return false for unknown label", () => { @@ -17,13 +16,13 @@ describe("isLabelSubgraphIndexable", () => { }); it("should return true for labels without subgraph-unindexable characters", () => { - expect(isLabelSubgraphIndexable("test" as LiteralLabel)).toBe(true); - expect(isLabelSubgraphIndexable("example" as LiteralLabel)).toBe(true); - expect(isLabelSubgraphIndexable("21🚀bingo" as LiteralLabel)).toBe(true); + expect(isLabelSubgraphIndexable(asLiteralLabel("test"))).toBe(true); + expect(isLabelSubgraphIndexable(asLiteralLabel("example"))).toBe(true); + expect(isLabelSubgraphIndexable(asLiteralLabel("21🚀bingo"))).toBe(true); // unnormalized - expect(isLabelSubgraphIndexable("ABC" as LiteralLabel)).toBe(true); - expect(isLabelSubgraphIndexable("abc|xyz" as LiteralLabel)).toBe(true); + expect(isLabelSubgraphIndexable(asLiteralLabel("ABC"))).toBe(true); + expect(isLabelSubgraphIndexable(asLiteralLabel("abc|xyz"))).toBe(true); }); it("should return true for empty label", () => { diff --git a/apps/ensindexer/src/lib/subgraph/is-label-subgraph-indexable.ts b/apps/ensindexer/src/lib/subgraph/is-label-subgraph-indexable.ts index b379a7775d..16ff43221f 100644 --- a/apps/ensindexer/src/lib/subgraph/is-label-subgraph-indexable.ts +++ b/apps/ensindexer/src/lib/subgraph/is-label-subgraph-indexable.ts @@ -1,4 +1,4 @@ -import type { LiteralLabel } from "@ensnode/ensnode-sdk"; +import type { LiteralLabel } from "enssdk"; /** * The following 4 characters are classified as "unindexable" in emitted labels by the ENS Subgraph. diff --git a/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts b/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts index 7654b8e912..bf6a5308f3 100644 --- a/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts +++ b/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts @@ -1,9 +1,8 @@ import config from "@/config"; +import { type Node, ROOT_NODE } from "enssdk"; import { isAddressEqual, zeroAddress } from "viem"; -import { type Node, ROOT_NODE } from "@ensnode/ensnode-sdk"; - import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { upsertAccount } from "@/lib/subgraph/db-helpers"; diff --git a/apps/ensindexer/src/lib/threedns-helpers.ts b/apps/ensindexer/src/lib/threedns-helpers.ts index cd5ce0d5ca..fc06c6a69e 100644 --- a/apps/ensindexer/src/lib/threedns-helpers.ts +++ b/apps/ensindexer/src/lib/threedns-helpers.ts @@ -1,7 +1,6 @@ +import type { Node, TokenId } from "enssdk"; import { hexToBigInt } from "viem"; -import type { Node, TokenId } from "@ensnode/ensnode-sdk"; - /** * ThreeDNSToken's tokenId is the bigint representation of a Domain's Node */ diff --git a/apps/ensindexer/src/lib/tokenscope/nft-issuers.ts b/apps/ensindexer/src/lib/tokenscope/nft-issuers.ts index 5c3ca8827b..91b2c2e359 100644 --- a/apps/ensindexer/src/lib/tokenscope/nft-issuers.ts +++ b/apps/ensindexer/src/lib/tokenscope/nft-issuers.ts @@ -1,22 +1,28 @@ -import { interpretTokenIdAsLabelHash, interpretTokenIdAsNode } from "enssdk"; - -import { type DatasourceName, DatasourceNames, type ENSNamespaceId } from "@ensnode/datasources"; import { type AccountId, type AssetNamespace, AssetNamespaces, - accountIdEqual, - BASENAMES_NODE, - type DomainAssetId, + asInterpretedName, ETH_NODE, - getDatasourceContract, - LINEANAMES_NODE, + interpretTokenIdAsLabelHash, + interpretTokenIdAsNode, makeSubdomainNode, - maybeGetDatasourceContract, type Node, + namehashInterpretedName, type TokenId, +} from "enssdk"; + +import { type DatasourceName, DatasourceNames, type ENSNamespaceId } from "@ensnode/datasources"; +import { + accountIdEqual, + type DomainAssetId, + getDatasourceContract, + maybeGetDatasourceContract, } from "@ensnode/ensnode-sdk"; +export const BASENAMES_NODE: Node = namehashInterpretedName(asInterpretedName("base.eth")); +export const LINEANAMES_NODE: Node = namehashInterpretedName(asInterpretedName("linea.eth")); + /** * A contract that issues tokenized ENS names in a manner that is supported by * TokenScope. diff --git a/apps/ensindexer/src/lib/tokenscope/sales.ts b/apps/ensindexer/src/lib/tokenscope/sales.ts index ea0f4cbd1d..6723fe3b0e 100644 --- a/apps/ensindexer/src/lib/tokenscope/sales.ts +++ b/apps/ensindexer/src/lib/tokenscope/sales.ts @@ -1,4 +1,4 @@ -import type { Address, Hex } from "viem"; +import type { Address, Hex } from "enssdk"; import type { DomainAssetId, Price } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensindexer/src/lib/tokenscope/seaport-types.ts b/apps/ensindexer/src/lib/tokenscope/seaport-types.ts index d8db6414ff..7bc523104c 100644 --- a/apps/ensindexer/src/lib/tokenscope/seaport-types.ts +++ b/apps/ensindexer/src/lib/tokenscope/seaport-types.ts @@ -1,4 +1,4 @@ -import type { Address, Hex } from "viem"; +import type { Address, Hex } from "enssdk"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/lib/tokenscope/seaport.ts b/apps/ensindexer/src/lib/tokenscope/seaport.ts index 1053a64027..4095343c21 100644 --- a/apps/ensindexer/src/lib/tokenscope/seaport.ts +++ b/apps/ensindexer/src/lib/tokenscope/seaport.ts @@ -1,12 +1,7 @@ +import { type AssetNamespace, AssetNamespaces, type ChainId } from "enssdk"; + import type { ENSNamespaceId } from "@ensnode/datasources"; -import { - type AssetNamespace, - AssetNamespaces, - type ChainId, - CurrencyIds, - type DomainAssetId, - uniq, -} from "@ensnode/ensnode-sdk"; +import { CurrencyIds, type DomainAssetId, uniq } from "@ensnode/ensnode-sdk"; import { getCurrencyIdForContract } from "@/lib/currencies"; import { getSupportedNFTIssuer } from "@/lib/tokenscope/nft-issuers"; diff --git a/apps/ensindexer/src/lib/trace-transaction-helpers.ts b/apps/ensindexer/src/lib/trace-transaction-helpers.ts index 4f3ed19d2a..b847b6a68f 100644 --- a/apps/ensindexer/src/lib/trace-transaction-helpers.ts +++ b/apps/ensindexer/src/lib/trace-transaction-helpers.ts @@ -1,6 +1,5 @@ -import { type Address, type Hash, type Hex, isAddress } from "viem"; - -import { asLowerCaseAddress } from "@ensnode/ensnode-sdk"; +import { type Address, asLowerCaseAddress, type Hex } from "enssdk"; +import { type Hash, isAddress } from "viem"; /** * Options for the `callTracer` tracer. This tracer is used to enlist diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts index 101339dbdc..041706dbd4 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts @@ -1,13 +1,13 @@ import { GRACE_PERIOD_SECONDS } from "@ensdomains/ensjs/utils"; -import { interpretTokenIdAsLabelHash, makeENSv1DomainId } from "enssdk"; -import { type Address, isAddressEqual, zeroAddress } from "viem"; - import { - interpretAddress, - isRegistrationFullyExpired, + type Address, + interpretTokenIdAsLabelHash, + makeENSv1DomainId, makeSubdomainNode, - PluginName, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; +import { isAddressEqual, zeroAddress } from "viem"; + +import { interpretAddress, isRegistrationFullyExpired, PluginName } from "@ensnode/ensnode-sdk"; import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { materializeENSv1DomainEffectiveOwner } from "@/lib/ensv2/domain-db-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts index 09601f847d..64dbf7a6d7 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts @@ -1,16 +1,17 @@ import config from "@/config"; -import { type LabelHash, makeENSv1DomainId, type Node } from "enssdk"; -import { type Address, isAddressEqual, zeroAddress } from "viem"; - import { ADDR_REVERSE_NODE, - getENSRootChainId, - interpretAddress, + type Address, + type LabelHash, + makeENSv1DomainId, makeSubdomainNode, - PluginName, + type Node, ROOT_NODE, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; +import { isAddressEqual, zeroAddress } from "viem"; + +import { getENSRootChainId, interpretAddress, PluginName } from "@ensnode/ensnode-sdk"; import { materializeENSv1DomainEffectiveOwner } from "@/lib/ensv2/domain-db-helpers"; import { ensureDomainEvent } from "@/lib/ensv2/event-db-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts index 05007c4dac..0431da02f8 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts @@ -1,18 +1,23 @@ -import { interpretTokenIdAsNode, makeENSv1DomainId, type Node } from "enssdk"; -import { type Address, isAddressEqual, zeroAddress } from "viem"; - import { + type Address, type DNSEncodedLiteralName, type DNSEncodedName, decodeDNSEncodedLiteralName, + interpretTokenIdAsNode, + type LiteralLabel, + labelhashLiteralLabel, + makeENSv1DomainId, + makeSubdomainNode, + type Node, +} from "enssdk"; +import { isAddressEqual, zeroAddress } from "viem"; + +import { interpretAddress, isPccFuseSet, isRegistrationExpired, isRegistrationFullyExpired, isRegistrationInGracePeriod, - type LiteralLabel, - labelhashLiteralLabel, - makeSubdomainNode, PluginName, } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts index c258fb6076..a94df08e78 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts @@ -1,15 +1,15 @@ /** biome-ignore-all lint/correctness/noUnusedVariables: ignore for now */ -import { type LabelHash, makeENSv1DomainId } from "enssdk"; - import { - type EncodedReferrer, + asLiteralLabel, type Label, - type LiteralLabel, + type LabelHash, labelhashLiteralLabel, + makeENSv1DomainId, makeSubdomainNode, - PluginName, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; + +import { type EncodedReferrer, PluginName } from "@ensnode/ensnode-sdk"; import { ensureDomainEvent } from "@/lib/ensv2/event-db-helpers"; import { ensureLabel, ensureUnknownLabel } from "@/lib/ensv2/label-db-helpers"; @@ -41,8 +41,8 @@ export default function () { referrer?: EncodedReferrer; }>; }) { - const { label: _label, labelHash, baseCost: base, premium, referrer } = event.args; - const label = _label as LiteralLabel | undefined; + const { labelHash, baseCost: base, premium, referrer } = event.args; + const label = event.args.label ? asLiteralLabel(event.args.label) : undefined; // Invariant: If emitted, label must align with labelHash if (label !== undefined && labelHash !== labelhashLiteralLabel(label)) { @@ -94,8 +94,8 @@ export default function () { referrer?: EncodedReferrer; }>; }) { - const { label: _label, labelHash, baseCost: base, premium, referrer } = event.args; - const label = _label as LiteralLabel; + const { labelHash, baseCost: base, premium, referrer } = event.args; + const label = event.args.label ? asLiteralLabel(event.args.label) : undefined; // Invariant: If emitted, label must align with labelHash if (label !== undefined && labelHash !== labelhashLiteralLabel(label)) { diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts index b298e8d852..1b88a4d5aa 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts @@ -1,18 +1,16 @@ import { type AccountId, + type Address, + asLiteralLabel, type LabelHash, + labelhashLiteralLabel, makeENSv2DomainId, makeRegistryId, makeStorageId, } from "enssdk"; -import { type Address, hexToBigInt, labelhash } from "viem"; +import { hexToBigInt } from "viem"; -import { - interpretAddress, - isRegistrationFullyExpired, - type LiteralLabel, - PluginName, -} from "@ensnode/ensnode-sdk"; +import { interpretAddress, isRegistrationFullyExpired, PluginName } from "@ensnode/ensnode-sdk"; import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { ensureDomainEvent, ensureEvent } from "@/lib/ensv2/event-db-helpers"; @@ -53,8 +51,8 @@ export default function () { sender: Address; }>; }) { - const { tokenId, labelHash, label: _label, owner, expiry, sender: registrant } = event.args; - const label = _label as LiteralLabel; + const { tokenId, labelHash, owner, expiry, sender: registrant } = event.args; + const label = asLiteralLabel(event.args.label); const isReservation = owner === undefined; const registry = getThisAccountId(context, event); @@ -63,8 +61,10 @@ export default function () { const domainId = makeENSv2DomainId(registry, storageId); // Sanity Check: LabelHash must match Label - if (labelHash !== labelhash(label)) { - throw new Error(`Sanity Check: labelHash !== labelhash(label)\n${toJson(event.args)}`); + if (labelHash !== labelhashLiteralLabel(label)) { + throw new Error( + `Sanity Check: labelHash !== labelhashLiteralLabel(label)\n${toJson(event.args)}`, + ); } // Sanity Check: StorageId derived from tokenId must match StorageId derived from LabelHash diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts index a4fae11633..038d0d9987 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts @@ -1,12 +1,16 @@ -import { type AccountId, makeENSv2DomainId, makeStorageId } from "enssdk"; -import type { Address } from "viem"; +import { + type AccountId, + type Address, + makeENSv2DomainId, + makeStorageId, + type TokenId, +} from "enssdk"; import { type EncodedReferrer, interpretAddress, isRegistrationFullyExpired, PluginName, - type TokenId, } from "@ensnode/ensnode-sdk"; import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts index da1459e873..2ee4ee0d9e 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts @@ -1,11 +1,12 @@ import { + type Address, type EACResource, type EACRoleBitmap, makePermissionsId, makePermissionsResourceId, makePermissionsUserId, } from "enssdk"; -import { type Address, isAddressEqual, zeroAddress } from "viem"; +import { isAddressEqual, zeroAddress } from "viem"; import { PluginName } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts index efe6898288..a6737a654c 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts @@ -1,10 +1,15 @@ import config from "@/config"; -import { type LabelHash, makeENSv1DomainId, type Node } from "enssdk"; -import type { Address } from "viem"; +import { + type Address, + type LabelHash, + makeENSv1DomainId, + makeSubdomainNode, + type Node, +} from "enssdk"; import { getENSRootChainId } from "@ensnode/datasources"; -import { makeSubdomainNode, PluginName } from "@ensnode/ensnode-sdk"; +import { PluginName } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; import { addOnchainEventListener, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts index f159b4ae20..27570f739b 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts @@ -1,5 +1,4 @@ -import { makeENSv2DomainId, makeStorageId } from "enssdk"; -import type { Address } from "viem"; +import { type Address, makeENSv2DomainId, makeStorageId } from "enssdk"; import { PluginName } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts index cbcc73df8a..d9ccf4667b 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts @@ -1,5 +1,7 @@ +import { bigintToCoinType, type CoinType, ETH_COIN_TYPE } from "enssdk"; + import { ResolverABI } from "@ensnode/datasources"; -import { bigintToCoinType, type CoinType, ETH_COIN_TYPE, PluginName } from "@ensnode/ensnode-sdk"; +import { PluginName } from "@ensnode/ensnode-sdk"; import { parseDnsTxtRecordArgs } from "@/lib/dns-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts index d53bff186b..9ac866ad16 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts @@ -1,7 +1,9 @@ import config from "@/config"; +import { DEFAULT_EVM_COIN_TYPE, evmChainIdToCoinType } from "enssdk"; + import { getENSRootChainId } from "@ensnode/datasources"; -import { DEFAULT_EVM_COIN_TYPE, evmChainIdToCoinType, PluginName } from "@ensnode/ensnode-sdk"; +import { PluginName } from "@ensnode/ensnode-sdk"; import { interpretNameRecordValue } from "@ensnode/ensnode-sdk/internal"; import { addOnchainEventListener, ensIndexerSchema } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts index 2e717d94d3..1dc82f3da0 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts @@ -1,10 +1,16 @@ import config from "@/config"; -import { type LabelHash, makeENSv1DomainId, type Node } from "enssdk"; -import type { Address } from "viem"; +import { + type Address, + type ChainId, + type LabelHash, + makeENSv1DomainId, + makeSubdomainNode, + type Node, +} from "enssdk"; import { DatasourceNames, maybeGetDatasource } from "@ensnode/datasources"; -import { type ChainId, makeSubdomainNode, PluginName } from "@ensnode/ensnode-sdk"; +import { PluginName } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; import { addOnchainEventListener, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts index 3633b2cfde..390c28be3c 100644 --- a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts +++ b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts @@ -1,12 +1,6 @@ -import { interpretTokenIdAsLabelHash } from "enssdk"; +import { interpretTokenIdAsLabelHash, makeSubdomainNode } from "enssdk"; -import { - type BlockRef, - bigIntToNumber, - makeSubdomainNode, - PluginName, - type Subregistry, -} from "@ensnode/ensnode-sdk"; +import { type BlockRef, bigIntToNumber, PluginName, type Subregistry } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts index e269de1d01..273845f7b1 100644 --- a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts +++ b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts @@ -1,5 +1,6 @@ +import { makeSubdomainNode } from "enssdk"; + import { - makeSubdomainNode, PluginName, type RegistrarActionPricingUnknown, type RegistrarActionReferralNotApplicable, diff --git a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts index 49f19c188b..93b36dd1c6 100644 --- a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts +++ b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts @@ -1,12 +1,6 @@ -import { interpretTokenIdAsLabelHash } from "enssdk"; +import { interpretTokenIdAsLabelHash, makeSubdomainNode } from "enssdk"; -import { - type BlockRef, - bigIntToNumber, - makeSubdomainNode, - PluginName, - type Subregistry, -} from "@ensnode/ensnode-sdk"; +import { type BlockRef, bigIntToNumber, PluginName, type Subregistry } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts index fdadaa6cda..b795617940 100644 --- a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts +++ b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts @@ -1,7 +1,8 @@ +import { makeSubdomainNode } from "enssdk"; + import { addPrices, decodeEncodedReferrer, - makeSubdomainNode, PluginName, priceEth, type RegistrarActionPricingAvailable, diff --git a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts index d443cef7f0..5bd158e75b 100644 --- a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts +++ b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts @@ -1,6 +1,7 @@ +import { makeSubdomainNode } from "enssdk"; + import { decodeEncodedReferrer, - makeSubdomainNode, PluginName, type RegistrarActionReferralAvailable, } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts index a8d2d229bb..0125fdb46a 100644 --- a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts +++ b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts @@ -1,12 +1,6 @@ -import { interpretTokenIdAsLabelHash } from "enssdk"; +import { interpretTokenIdAsLabelHash, makeSubdomainNode } from "enssdk"; -import { - type BlockRef, - bigIntToNumber, - makeSubdomainNode, - PluginName, - type Subregistry, -} from "@ensnode/ensnode-sdk"; +import { type BlockRef, bigIntToNumber, PluginName, type Subregistry } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts index 3397c24f22..8d4d98cf94 100644 --- a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts +++ b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts @@ -1,6 +1,7 @@ +import { makeSubdomainNode } from "enssdk"; + import { addPrices, - makeSubdomainNode, PluginName, priceEth, type RegistrarActionPricingAvailable, diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts index 0e0a367945..61913d1e9c 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts @@ -1,10 +1,10 @@ -import type { Address, Hash } from "viem"; +import type { Address, Node } from "enssdk"; +import type { Hash } from "viem"; import { type EncodedReferrer, isRegistrarActionPricingAvailable, isRegistrarActionReferralAvailable, - type Node, type RegistrarActionPricing, type RegistrarActionReferral, } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-events.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-events.ts index 790649541c..72c2777f45 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-events.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-events.ts @@ -2,8 +2,8 @@ * This file contains handlers used in event handlers for a Registrar contract. */ -import { type AccountId, type Node, stringifyAccountId } from "enssdk"; -import type { Address, Hash } from "viem"; +import { type AccountId, type Address, type Node, stringifyAccountId } from "enssdk"; +import type { Hash } from "viem"; import { type BlockRef, diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts index d6a7430fba..e589c293cd 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts @@ -1,7 +1,6 @@ +import type { UnixTimestamp } from "enssdk"; import { type AccountId, type Node, stringifyAccountId } from "enssdk"; -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; - import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts index 1bc0643d65..31c0b319c0 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts @@ -1,9 +1,9 @@ -import type { Address, Hash } from "viem"; +import type { Address, Node } from "enssdk"; +import type { Hash } from "viem"; import { type EncodedReferrer, isRegistrarActionReferralAvailable, - type Node, type RegistrarActionReferral, } from "@ensnode/ensnode-sdk"; diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts index fca6ac45a7..8ea1c5230e 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts @@ -1,4 +1,6 @@ -import { makeSubdomainNode, type Node, PluginName, ROOT_NODE } from "@ensnode/ensnode-sdk"; +import { makeSubdomainNode, type Node, ROOT_NODE } from "enssdk"; + +import { PluginName } from "@ensnode/ensnode-sdk"; import { addOnchainEventListener, diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts index aef9124b3d..812d98ae7f 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts @@ -15,21 +15,20 @@ import config from "@/config"; * Related GitHub issue: https://github.com/ensdomains/ens-subgraph/issues/88 */ import { checkPccBurned as isPccFuseUnset } from "@ensdomains/ensjs/utils"; -import { interpretTokenIdAsNode } from "enssdk"; -import type { Address } from "viem"; - import { + type Address, type DNSEncodedLiteralName, type DNSEncodedName, decodeDNSEncodedLiteralName, type InterpretedLabel, type InterpretedName, + interpretTokenIdAsNode, literalLabelsToInterpretedName, literalLabelToInterpretedLabel, type Node, type SubgraphInterpretedLabel, type SubgraphInterpretedName, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; import { subgraph_decodeDNSEncodedLiteralName } from "@/lib/dns-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts index 3545547455..c70744c9dc 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts @@ -1,8 +1,10 @@ import config from "@/config"; -import type { Address } from "viem"; - import { + type Address, + asInterpretedLabel, + asLiteralLabel, + constructSubInterpretedName, encodeLabelHash, type InterpretedLabel, type InterpretedName, @@ -11,10 +13,11 @@ import { type LiteralLabel, literalLabelToInterpretedLabel, makeSubdomainNode, - type PluginName, type SubgraphInterpretedLabel, type SubgraphInterpretedName, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; + +import type { PluginName } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; @@ -56,7 +59,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } // see https://ensnode.io/docs/reference/terminology#interpreted-label literalLabelToInterpretedLabel(label); - const { node: managedNode, name: managedName } = getManagedName( + const { name: managedName, node: managedNode } = getManagedName( getThisAccountId(context, event), ); const node = makeSubdomainNode(labelHash, managedNode); @@ -174,14 +177,14 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } // Interpret the `healedLabel` Literal Label into an Interpreted Label // see https://ensnode.io/docs/reference/terminology#literal-label // see https://ensnode.io/docs/reference/terminology#interpreted-label - label = ( + label = asInterpretedLabel( healedLabel !== null ? literalLabelToInterpretedLabel(healedLabel) - : encodeLabelHash(labelHash) - ) as InterpretedLabel; + : encodeLabelHash(labelHash), + ); - // a name constructed of Interpreted Labels is Interpreted - name = `${label}.${managedName}` as InterpretedName; + // construct the InterpretedName with InterpretedLabel and parent's InterpretedName + name = constructSubInterpretedName(label, managedName); } // update Domain @@ -225,8 +228,8 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } cost: bigint; }>; }) { - const { label: _label, labelHash, cost } = event.args; - const label = _label as LiteralLabel; // NameRegistered emits Literal Labels + const { labelHash, cost } = event.args; + const label = asLiteralLabel(event.args.label); // NameRegistered emits Literal Labels await setNamePreimage(context, { ...event, args: { label, labelHash, cost } }); }, @@ -242,8 +245,8 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } cost: bigint; }>; }) { - const { label: _label, labelHash, cost } = event.args; - const label = _label as LiteralLabel; // NameRenewed emits Literal Labels + const { labelHash, cost } = event.args; + const label = asLiteralLabel(event.args.label); // NameRenewed emits Literal Labels await setNamePreimage(context, { ...event, args: { label, labelHash, cost } }); }, diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts index ccc5048baf..ac04ed6c1e 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts @@ -1,12 +1,11 @@ import config from "@/config"; -import { type Address, isAddressEqual, zeroAddress } from "viem"; - -import { getENSRootChainId } from "@ensnode/datasources"; import { ADDR_REVERSE_NODE, + type Address, + asInterpretedLabel, + constructSubInterpretedName, encodeLabelHash, - type InterpretedLabel, type InterpretedName, type LabelHash, type LiteralLabel, @@ -15,7 +14,10 @@ import { type Node, type SubgraphInterpretedLabel, type SubgraphInterpretedName, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; +import { isAddressEqual, zeroAddress } from "viem"; + +import { getENSRootChainId } from "@ensnode/datasources"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; import { healAddrReverseSubnameLabel } from "@/lib/heal-addr-reverse-subname-label"; @@ -135,18 +137,19 @@ export const handleNewOwner = // Interpret the `healedLabel` Literal Label into an Interpreted Label // see https://ensnode.io/docs/reference/terminology#literal-label // see https://ensnode.io/docs/reference/terminology#interpreted-label - const interpretedLabel = ( + const interpretedLabel = asInterpretedLabel( healedLabel !== null ? literalLabelToInterpretedLabel(healedLabel) - : encodeLabelHash(labelHash) - ) as InterpretedLabel; + : encodeLabelHash(labelHash), + ); // to construct `Domain.name` use the parent's Name and the Interpreted Label // NOTE: for a TLD, the parent is null, so we just use the Label value as is // a name constructed of Interpreted Labels is Interpreted - const interpretedName = ( - parent?.name ? `${interpretedLabel}.${parent.name}` : interpretedLabel - ) as InterpretedName; + const interpretedName = constructSubInterpretedName( + interpretedLabel, + parent?.name as InterpretedName | undefined, + ); await context.ensDb.update(ensIndexerSchema.subgraph_domain, { id: node }).set({ name: interpretedName, diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts index 7aed738c82..e1f288acbf 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts @@ -1,8 +1,9 @@ import config from "@/config"; -import type { Address, Hash, Hex } from "viem"; +import type { Address, Hex, Node } from "enssdk"; +import type { Hash } from "viem"; -import { hasNullByte, type Node, stripNullBytes, uniq } from "@ensnode/ensnode-sdk"; +import { hasNullByte, stripNullBytes, uniq } from "@ensnode/ensnode-sdk"; import { parseDnsTxtRecordArgs } from "@/lib/dns-helpers"; import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts index c394f33b10..fca6a120f9 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts @@ -1,6 +1,7 @@ -import { type Address, isAddressEqual, zeroAddress, zeroHash } from "viem"; - import { + type Address, + asInterpretedLabel, + constructSubInterpretedName, type DNSEncodedLiteralName, type DNSEncodedName, decodeDNSEncodedLiteralName, @@ -14,7 +15,8 @@ import { literalLabelToInterpretedLabel, makeSubdomainNode, type Node, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; +import { isAddressEqual, zeroAddress, zeroHash } from "viem"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; @@ -78,7 +80,7 @@ function decodeFQDN(fqdn: DNSEncodedLiteralName): { } // due the invariant above, we know that all of the labels are normalized (and therefore Interpreted Labels) - const interpretedLabels = literalLabels as string[] as InterpretedLabel[]; + const interpretedLabels = literalLabels.map(asInterpretedLabel); return { // biome-ignore lint/style/noNonNullAssertion: ok due to length invariant above @@ -176,17 +178,18 @@ export async function handleNewOwner({ // Interpret the `healedLabel` Literal Label into an Interpreted Label // see https://ensnode.io/docs/reference/terminology#literal-label // see https://ensnode.io/docs/reference/terminology#interpreted-label - const interpretedLabel = ( + const interpretedLabel = asInterpretedLabel( healedLabel !== null ? literalLabelToInterpretedLabel(healedLabel) - : encodeLabelHash(labelHash) - ) as InterpretedLabel; + : encodeLabelHash(labelHash), + ); // to construct `Domain.name` use the parent's Name and the Interpreted Label // NOTE: for a TLD, the parent is null, so we just use the Label value as is - const interpretedName = ( - parent?.name ? `${interpretedLabel}.${parent.name}` : interpretedLabel - ) as InterpretedName; + const interpretedName = constructSubInterpretedName( + interpretedLabel, + parent?.name as InterpretedName | undefined, + ); await context.ensDb .update(ensIndexerSchema.subgraph_domain, { id: node }) diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts index 45b7898c58..ea25878bbc 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts @@ -1,9 +1,10 @@ import config from "@/config"; +import type { ChainId } from "enssdk"; import { base, optimism } from "viem/chains"; import { type DatasourceName, DatasourceNames } from "@ensnode/datasources"; -import { type ChainId, type NFTTransferEventMetadata, PluginName } from "@ensnode/ensnode-sdk"; +import { type NFTTransferEventMetadata, PluginName } from "@ensnode/ensnode-sdk"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; diff --git a/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts b/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts index 89a13dd05e..17ec504b5f 100644 --- a/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts +++ b/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts @@ -1,5 +1,5 @@ -import { stringifyAssetId } from "enssdk"; -import { type Address, zeroAddress } from "viem"; +import { type Address, stringifyAssetId } from "enssdk"; +import { zeroAddress } from "viem"; import { type DomainAssetId, diff --git a/apps/ensrainbow/package.json b/apps/ensrainbow/package.json index 0848f795b1..c8167f97cf 100644 --- a/apps/ensrainbow/package.json +++ b/apps/ensrainbow/package.json @@ -33,6 +33,7 @@ "@ensnode/ensrainbow-sdk": "workspace:*", "@ensnode/ensnode-sdk": "workspace:*", "@hono/node-server": "catalog:", + "enssdk": "workspace:*", "classic-level": "^1.4.1", "hono": "catalog:", "pino": "catalog:", diff --git a/apps/ensrainbow/src/commands/convert-csv-command.test.ts b/apps/ensrainbow/src/commands/convert-csv-command.test.ts index 2f8f46ddbf..1ac1f42bbf 100644 --- a/apps/ensrainbow/src/commands/convert-csv-command.test.ts +++ b/apps/ensrainbow/src/commands/convert-csv-command.test.ts @@ -2,7 +2,7 @@ import { mkdtemp, rm, stat, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; -import { labelhash } from "viem"; +import { asLiteralLabel, labelhashLiteralLabel } from "enssdk"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { type LabelSetId, labelHashToBytes } from "@ensnode/ensnode-sdk"; @@ -56,10 +56,18 @@ describe("convert-csv-command", () => { expect(await db.validate()).toBe(true); const recordsCount = await db.getPrecalculatedRainbowRecordCount(); expect(recordsCount).toBe(11); - expect((await db.getVersionedRainbowRecord(labelHashToBytes(labelhash("123"))))?.label).toBe( - "123", - ); - expect(await db.getVersionedRainbowRecord(labelHashToBytes(labelhash("1234")))).toBe(null); + expect( + ( + await db.getVersionedRainbowRecord( + labelHashToBytes(labelhashLiteralLabel(asLiteralLabel("123"))), + ) + )?.label, + ).toBe("123"); + expect( + await db.getVersionedRainbowRecord( + labelHashToBytes(labelhashLiteralLabel(asLiteralLabel("1234"))), + ), + ).toBe(null); await db.close(); }); @@ -94,13 +102,18 @@ describe("convert-csv-command", () => { 'special"quotes"inside', "label with newline\n character", // new line "label-with-null\0byte", // null byte - ]; + ].map(asLiteralLabel); for (const label of labels) { expect( - (await db.getVersionedRainbowRecord(labelHashToBytes(labelhash(label))))?.label, + (await db.getVersionedRainbowRecord(labelHashToBytes(labelhashLiteralLabel(label)))) + ?.label, ).toBe(label); } - expect(await db.getVersionedRainbowRecord(labelHashToBytes(labelhash("1234")))).toBe(null); + expect( + await db.getVersionedRainbowRecord( + labelHashToBytes(labelhashLiteralLabel(asLiteralLabel("1234"))), + ), + ).toBe(null); await db.close(); }); }); @@ -246,16 +259,32 @@ describe("convert-csv-command", () => { // Verify specific labels exist expect( - (await db.getVersionedRainbowRecord(labelHashToBytes(labelhash("label1"))))?.label, + ( + await db.getVersionedRainbowRecord( + labelHashToBytes(labelhashLiteralLabel(asLiteralLabel("label1"))), + ) + )?.label, ).toBe("label1"); expect( - (await db.getVersionedRainbowRecord(labelHashToBytes(labelhash("label2"))))?.label, + ( + await db.getVersionedRainbowRecord( + labelHashToBytes(labelhashLiteralLabel(asLiteralLabel("label2"))), + ) + )?.label, ).toBe("label2"); expect( - (await db.getVersionedRainbowRecord(labelHashToBytes(labelhash("label3"))))?.label, + ( + await db.getVersionedRainbowRecord( + labelHashToBytes(labelhashLiteralLabel(asLiteralLabel("label3"))), + ) + )?.label, ).toBe("label3"); expect( - (await db.getVersionedRainbowRecord(labelHashToBytes(labelhash("label4"))))?.label, + ( + await db.getVersionedRainbowRecord( + labelHashToBytes(labelhashLiteralLabel(asLiteralLabel("label4"))), + ) + )?.label, ).toBe("label4"); await db.close(); @@ -581,12 +610,20 @@ describe("convert-csv-command", () => { // Verify the labels were stored correctly const label1 = "label,with,commas"; const label2 = "another,label"; - expect((await db.getVersionedRainbowRecord(labelHashToBytes(labelhash(label1))))?.label).toBe( - label1, - ); - expect((await db.getVersionedRainbowRecord(labelHashToBytes(labelhash(label2))))?.label).toBe( - label2, - ); + expect( + ( + await db.getVersionedRainbowRecord( + labelHashToBytes(labelhashLiteralLabel(asLiteralLabel(label1))), + ) + )?.label, + ).toBe(label1); + expect( + ( + await db.getVersionedRainbowRecord( + labelHashToBytes(labelhashLiteralLabel(asLiteralLabel(label2))), + ) + )?.label, + ).toBe(label2); await db.close(); }); diff --git a/apps/ensrainbow/src/commands/convert-csv-command.ts b/apps/ensrainbow/src/commands/convert-csv-command.ts index 0950d1c166..fcb6f8b87c 100644 --- a/apps/ensrainbow/src/commands/convert-csv-command.ts +++ b/apps/ensrainbow/src/commands/convert-csv-command.ts @@ -12,8 +12,8 @@ import { finished } from "node:stream/promises"; import { parse } from "@fast-csv/parse"; import { ClassicLevel } from "classic-level"; +import { asLiteralLabel, labelhashLiteralLabel } from "enssdk"; import ProgressBar from "progress"; -import { labelhash } from "viem"; import { type LabelSetId, labelHashToBytes } from "@ensnode/ensnode-sdk"; @@ -333,12 +333,10 @@ type SingleColumnRow = [string]; * Labelhashes are always computed deterministically from labels. */ function createRainbowRecord(row: SingleColumnRow): RainbowRecord { - const label = row[0]; - const labelHashBytes = labelHashToBytes(labelhash(label)); - return { - labelHash: labelHashBytes, - label, - }; + const label = asLiteralLabel(row[0]); + const labelHashBytes = labelHashToBytes(labelhashLiteralLabel(label)); + + return { label, labelHash: labelHashBytes }; } /** diff --git a/apps/ensrainbow/src/commands/server-command.test.ts b/apps/ensrainbow/src/commands/server-command.test.ts index 0acc18175a..9113f37d86 100644 --- a/apps/ensrainbow/src/commands/server-command.test.ts +++ b/apps/ensrainbow/src/commands/server-command.test.ts @@ -1,8 +1,8 @@ import { promises as fs } from "node:fs"; import { serve } from "@hono/node-server"; +import { asLiteralLabel, labelhashLiteralLabel } from "enssdk"; import type { Hono } from "hono"; -import { labelhash } from "viem"; import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { type EnsRainbow, ErrorCode, StatusCode } from "@ensnode/ensrainbow-sdk"; @@ -67,8 +67,8 @@ describe("Server Command Tests", () => { describe("GET /v1/heal/:labelHash", () => { it("should return the label for a valid labelHash", async () => { - const validLabel = "test-label"; - const validLabelHash = labelhash(validLabel); + const validLabel = asLiteralLabel("test-label"); + const validLabelHash = labelhashLiteralLabel(validLabel); // Add test data await db.addRainbowRecord(validLabel, 0); @@ -208,7 +208,7 @@ describe("Server Command Tests", () => { describe("CORS headers for /v1/* routes", () => { it("should return CORS headers for /v1/* routes", async () => { const validLabel = "test-label"; - const validLabelHash = labelhash(validLabel); + const validLabelHash = labelhashLiteralLabel(asLiteralLabel(validLabel)); // Add test data await db.addRainbowRecord(validLabel, 0); diff --git a/apps/ensrainbow/src/lib/database.test.ts b/apps/ensrainbow/src/lib/database.test.ts index 1cd11e550e..66df7d39f8 100644 --- a/apps/ensrainbow/src/lib/database.test.ts +++ b/apps/ensrainbow/src/lib/database.test.ts @@ -2,7 +2,7 @@ import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; -import { labelhash } from "viem"; +import { asLiteralLabel, labelhashLiteralLabel } from "enssdk"; import { afterEach, beforeEach, describe, expect, it, test, vi } from "vitest"; import { labelHashToBytes, parseNonNegativeInteger } from "@ensnode/ensnode-sdk"; @@ -102,7 +102,7 @@ describe("Database", () => { const batch = db.batch(); // Add rainbow record with mismatched labelHash const label = "vitalik"; - const wrongLabelHash = labelhash("ethereum"); + const wrongLabelHash = labelhashLiteralLabel(asLiteralLabel("ethereum")); batch.put(labelHashToBytes(wrongLabelHash), label); await batch.write(); @@ -253,7 +253,7 @@ describe("Database", () => { try { // Add rainbow record with mismatched labelHash (would fail in full validation) const label = "vitalik"; - const wrongLabelHash = labelhash("ethereum"); + const wrongLabelHash = labelhashLiteralLabel(asLiteralLabel("ethereum")); const batch = db.batch(); batch.put(labelHashToBytes(wrongLabelHash), label); await batch.write(); @@ -330,7 +330,7 @@ describe("Database", () => { const db = await ENSRainbowDB.create(tempDir); try { const labelWithNull = "test\0label"; - const labelWithNullLabelHash = labelhash(labelWithNull); + const labelWithNullLabelHash = labelhashLiteralLabel(asLiteralLabel(labelWithNull)); const labelHashBytes = labelHashToBytes(labelWithNullLabelHash); // Add record diff --git a/apps/ensrainbow/src/lib/database.ts b/apps/ensrainbow/src/lib/database.ts index 77c758332e..3452a869fb 100644 --- a/apps/ensrainbow/src/lib/database.ts +++ b/apps/ensrainbow/src/lib/database.ts @@ -1,5 +1,6 @@ import { ClassicLevel } from "classic-level"; -import { type ByteArray, type Hex, labelhash } from "viem"; +import { asLiteralLabel, type Hex, labelhashLiteralLabel } from "enssdk"; +import type { ByteArray } from "viem"; import { buildLabelSetId, @@ -657,7 +658,9 @@ export class ENSRainbowDB { } // Key-Value Validation (Hash Match) - const computedHash = labelHashToBytes(labelhash(versionedRainbowRecord.label)); + const computedHash = labelHashToBytes( + labelhashLiteralLabel(asLiteralLabel(versionedRainbowRecord.label)), + ); if (!byteArraysEqual(computedHash, key)) { logger.error( `Hash mismatch for label "${value}": stored=${keyHex}, computed=0x${Buffer.from( @@ -780,7 +783,7 @@ export class ENSRainbowDB { */ public async addRainbowRecord(label: string, labelSetVersion: LabelSetVersion): Promise { const encodedValue = buildEncodedVersionedRainbowRecord(label, labelSetVersion); - await this.db.put(labelHashToBytes(labelhash(label)), encodedValue); + await this.db.put(labelHashToBytes(labelhashLiteralLabel(asLiteralLabel(label))), encodedValue); } } diff --git a/apps/ensrainbow/src/lib/rainbow-record.ts b/apps/ensrainbow/src/lib/rainbow-record.ts index bf5e04f373..4495456b4e 100644 --- a/apps/ensrainbow/src/lib/rainbow-record.ts +++ b/apps/ensrainbow/src/lib/rainbow-record.ts @@ -1,4 +1,6 @@ -import { buildLabelSetVersion, type Label, type LabelSetVersion } from "@ensnode/ensnode-sdk"; +import type { Label } from "enssdk"; + +import { buildLabelSetVersion, type LabelSetVersion } from "@ensnode/ensnode-sdk"; import { getErrorMessage } from "@/utils/error-utils"; diff --git a/apps/ensrainbow/src/lib/server.ts b/apps/ensrainbow/src/lib/server.ts index 116caecad5..b3da287c5a 100644 --- a/apps/ensrainbow/src/lib/server.ts +++ b/apps/ensrainbow/src/lib/server.ts @@ -1,10 +1,7 @@ +import type { LabelHash } from "enssdk"; import type { ByteArray } from "viem"; -import { - type LabelHash, - labelHashToBytes, - validateSupportedLabelSetAndVersion, -} from "@ensnode/ensnode-sdk"; +import { labelHashToBytes, validateSupportedLabelSetAndVersion } from "@ensnode/ensnode-sdk"; import { type EnsRainbow, type EnsRainbowClientLabelSet, diff --git a/apps/ensrainbow/src/utils/rainbow-record.test.ts b/apps/ensrainbow/src/utils/rainbow-record.test.ts index dea6064986..172aa8e8c0 100644 --- a/apps/ensrainbow/src/utils/rainbow-record.test.ts +++ b/apps/ensrainbow/src/utils/rainbow-record.test.ts @@ -1,7 +1,6 @@ -import { labelhash } from "viem"; +import { asLiteralLabel, type LabelHash, labelhashLiteralLabel } from "enssdk"; import { describe, expect, it } from "vitest"; -import type { LabelHash } from "@ensnode/ensnode-sdk"; import { labelHashToBytes } from "@ensnode/ensnode-sdk"; import { buildRainbowRecord } from "./rainbow-record"; @@ -9,7 +8,7 @@ import { buildRainbowRecord } from "./rainbow-record"; describe("buildRainbowRecord", () => { it("should parse a valid line", () => { const label = "test-label"; - const validLabelHash = labelhash(label); + const validLabelHash = labelhashLiteralLabel(asLiteralLabel(label)); const line = `${validLabelHash}\t${label}`; const record = buildRainbowRecord(line); @@ -19,7 +18,7 @@ describe("buildRainbowRecord", () => { it("should handle labels with special characters", () => { const label = "test🚀label"; - const validLabelHash = labelhash(label); + const validLabelHash = labelhashLiteralLabel(asLiteralLabel(label)); const line = `${validLabelHash}\t${label}`; const record = buildRainbowRecord(line); diff --git a/apps/ensrainbow/src/utils/rainbow-record.ts b/apps/ensrainbow/src/utils/rainbow-record.ts index 8a51ec9155..c13bb877d0 100644 --- a/apps/ensrainbow/src/utils/rainbow-record.ts +++ b/apps/ensrainbow/src/utils/rainbow-record.ts @@ -1,6 +1,6 @@ +import type { LabelHash } from "enssdk"; import type { ByteArray } from "viem"; -import type { LabelHash } from "@ensnode/ensnode-sdk"; import { labelHashToBytes } from "@ensnode/ensnode-sdk"; /** diff --git a/docs/ensnode.io/src/content/docs/docs/reference/terminology.mdx b/docs/ensnode.io/src/content/docs/docs/reference/terminology.mdx index 62508cdf09..ced1d375a7 100644 --- a/docs/ensnode.io/src/content/docs/docs/reference/terminology.mdx +++ b/docs/ensnode.io/src/content/docs/docs/reference/terminology.mdx @@ -94,8 +94,8 @@ In this terminology reference, we say that the **LabelHash** of a **Label** is t That is, `0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc` is the **LabelHash** of `vitalik`, which is the result of calling the **`labelhash` function** like so: ```ts -import { labelhash } from 'viem'; -const labelHash = labelhash("vitalik"); +import { labelhashInterpretedLabel, asInterpretedLabel } from 'enssdk'; +const labelHash = labelhashInterpretedLabel(asInterpretedLabel("vitalik")); ``` :::caution[LabelHash Terminology Outside of this Reference] diff --git a/docs/ensnode.io/src/content/docs/docs/usage/querying-best-practices.mdx b/docs/ensnode.io/src/content/docs/docs/usage/querying-best-practices.mdx index d5800771e0..1365621d2d 100644 --- a/docs/ensnode.io/src/content/docs/docs/usage/querying-best-practices.mdx +++ b/docs/ensnode.io/src/content/docs/docs/usage/querying-best-practices.mdx @@ -41,14 +41,14 @@ Example: First, let's prepare the name for querying by normalizing it and calculating its node: ```typescript -import { namehash, normalize } from "viem/ens"; +import { namehashInterpretedName, normalizeName, asInterpretedName } from "enssdk"; // 1. Normalize the user input according to ENSIP-15 const userInput = "Vitalik.eth"; -const normalizedName = normalize(userInput); +const normalizedName = normalizeName(userInput); // 2. Calculate the node from the normalized name -const node = namehash(normalizedName); +const node = namehashInterpretedName(asInterpretedName(normalizedName)); ``` Now use this node to query the domain id in the ENSNode API: @@ -86,15 +86,15 @@ The query will return the domain information: Here's a complete example showing how to put it all together using a GraphQL client: ```typescript -import { namehash, normalize } from "viem/ens"; +import { namehashInterpretedName, normalizeName, asInterpretedName } from "enssdk"; import { createClient } from "graphql-request"; async function queryENSName(userInput: string) { // 1. Normalize the user input - const normalizedName = normalize(userInput); + const normalizedName = normalizeName(userInput); // 2. Calculate the node - const node = namehash(normalizedName); + const node = namehashInterpretedName(asInterpretedName(normalizedName)); // 3. Set up the GraphQL client const client = createClient({ diff --git a/docs/ensnode.io/src/content/docs/ensrainbow/concepts/unknown-labels.mdx b/docs/ensnode.io/src/content/docs/ensrainbow/concepts/unknown-labels.mdx index f0de5ce662..93abad6cb7 100644 --- a/docs/ensnode.io/src/content/docs/ensrainbow/concepts/unknown-labels.mdx +++ b/docs/ensnode.io/src/content/docs/ensrainbow/concepts/unknown-labels.mdx @@ -84,8 +84,8 @@ The ENS Registry contract is immutable—it cannot be changed or upgraded. The d The [**labelhash**](/ensrainbow/concepts/glossary#labelhash) function computes a 32-byte hash of a label using `keccak256`: ```typescript -import { labelhash } from 'viem'; -const labelHash = labelhash("vitalik"); +import { labelhashInterpretedLabel, asInterpretedLabel } from 'enssdk'; +const labelHash = labelhashInterpretedLabel(asInterpretedLabel("vitalik")); // Returns: 0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc ``` diff --git a/examples/enskit-react-example/src/App.tsx b/examples/enskit-react-example/src/App.tsx index c2c5f8dfdb..0c63931a8a 100644 --- a/examples/enskit-react-example/src/App.tsx +++ b/examples/enskit-react-example/src/App.tsx @@ -42,7 +42,7 @@ export function App() { } /> - } /> + } /> } /> } /> diff --git a/examples/enskit-react-example/src/DomainView.tsx b/examples/enskit-react-example/src/DomainView.tsx index e56e72fb20..2e6c4ed775 100644 --- a/examples/enskit-react-example/src/DomainView.tsx +++ b/examples/enskit-react-example/src/DomainView.tsx @@ -1,5 +1,5 @@ import { type FragmentOf, graphql, readFragment, useOmnigraphQuery } from "enskit/react/omnigraph"; -import type { InterpretedName } from "enssdk"; +import { asInterpretedName } from "enssdk"; import { Link, useParams } from "react-router"; const DomainFragment = graphql(` @@ -40,11 +40,12 @@ function SubdomainLink({ data }: { data: FragmentOf }) { } export function DomainView() { - const { "*": name = "eth" } = useParams(); + const params = useParams(); + const name = asInterpretedName(params.name ?? "eth"); const [result] = useOmnigraphQuery({ query: DomainByNameQuery, - variables: { name: name as InterpretedName }, + variables: { name }, }); const { data, fetching, error } = result; diff --git a/packages/datasources/README.md b/packages/datasources/README.md index f37567a20e..6f86958b31 100644 --- a/packages/datasources/README.md +++ b/packages/datasources/README.md @@ -20,7 +20,7 @@ To use these configurations in your project: ```ts import { getDatasource } from "@ensnode/datasources"; -import { namehash } from "viem"; +import { namehashInterpretedName, asInterpretedName } from "enssdk"; // access the address and abi for the ens root Registry in the canonical mainnet ENS namespace const registryConfig = getDatasource('mainnet', 'ensroot').contracts.Registry; @@ -30,7 +30,7 @@ const vitaliksResolverAddress = await publicClient.readContract({ abi: registryConfig.abi, address: registryConfig.address, functionName: "resolver", - args: [namehash("vitalik.eth")], + args: [namehashInterpretedName(asInterpretedName("vitalik.eth"))], }); ``` diff --git a/packages/ens-referrals/package.json b/packages/ens-referrals/package.json index 7154b4e4a3..f646f2a952 100644 --- a/packages/ens-referrals/package.json +++ b/packages/ens-referrals/package.json @@ -61,6 +61,7 @@ }, "dependencies": { "@ensnode/ensnode-sdk": "workspace:*", + "enssdk": "workspace:*", "zod": "catalog:" }, "devDependencies": { diff --git a/packages/ens-referrals/src/address.ts b/packages/ens-referrals/src/address.ts index 2def2d575e..bcc9b4fc28 100644 --- a/packages/ens-referrals/src/address.ts +++ b/packages/ens-referrals/src/address.ts @@ -1,4 +1,5 @@ -import { type Address, isAddress } from "viem"; +import type { Address } from "enssdk"; +import { isAddress } from "viem"; export const validateLowercaseAddress = (address: Address): void => { if (!isAddress(address, { strict: false })) { diff --git a/packages/ens-referrals/src/api/types.ts b/packages/ens-referrals/src/api/types.ts index 51848e2c2a..76470866cc 100644 --- a/packages/ens-referrals/src/api/types.ts +++ b/packages/ens-referrals/src/api/types.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import type { ReferrerLeaderboardPage, ReferrerLeaderboardPageParams } from "../leaderboard-page"; import type { ReferrerDetail } from "../referrer-detail"; diff --git a/packages/ens-referrals/src/leaderboard-page.test.ts b/packages/ens-referrals/src/leaderboard-page.test.ts index c6cad44d88..149d3e3071 100644 --- a/packages/ens-referrals/src/leaderboard-page.test.ts +++ b/packages/ens-referrals/src/leaderboard-page.test.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { describe, expect, it, vi } from "vitest"; import type { ReferrerLeaderboard } from "./leaderboard"; diff --git a/packages/ens-referrals/src/leaderboard-page.ts b/packages/ens-referrals/src/leaderboard-page.ts index f661e5183e..cd8053e7a6 100644 --- a/packages/ens-referrals/src/leaderboard-page.ts +++ b/packages/ens-referrals/src/leaderboard-page.ts @@ -1,4 +1,4 @@ -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import type { AggregatedReferrerMetrics } from "./aggregations"; import type { ReferrerLeaderboard } from "./leaderboard"; diff --git a/packages/ens-referrals/src/leaderboard.ts b/packages/ens-referrals/src/leaderboard.ts index 14e3106da6..e219916772 100644 --- a/packages/ens-referrals/src/leaderboard.ts +++ b/packages/ens-referrals/src/leaderboard.ts @@ -1,6 +1,4 @@ -import type { Address } from "viem"; - -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { Address, UnixTimestamp } from "enssdk"; import { type AggregatedReferrerMetrics, buildAggregatedReferrerMetrics } from "./aggregations"; import { diff --git a/packages/ens-referrals/src/link.test.ts b/packages/ens-referrals/src/link.test.ts index 5d9064d823..84ad60d179 100644 --- a/packages/ens-referrals/src/link.test.ts +++ b/packages/ens-referrals/src/link.test.ts @@ -1,4 +1,5 @@ -import { type Address, getAddress } from "viem"; +import type { Address } from "enssdk"; +import { getAddress } from "viem"; import { describe, expect, it } from "vitest"; import { buildEnsReferralUrl } from "./link"; diff --git a/packages/ens-referrals/src/link.ts b/packages/ens-referrals/src/link.ts index d6a63e3f2a..e3dc03ea54 100644 --- a/packages/ens-referrals/src/link.ts +++ b/packages/ens-referrals/src/link.ts @@ -1,4 +1,5 @@ -import { type Address, getAddress } from "viem"; +import type { Address } from "enssdk"; +import { getAddress } from "viem"; /** * Build a URL to the official ENS manager app diff --git a/packages/ens-referrals/src/rank.ts b/packages/ens-referrals/src/rank.ts index 093fde9fab..d2d3d95571 100644 --- a/packages/ens-referrals/src/rank.ts +++ b/packages/ens-referrals/src/rank.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import type { Duration } from "@ensnode/ensnode-sdk"; diff --git a/packages/ens-referrals/src/referrer-detail.ts b/packages/ens-referrals/src/referrer-detail.ts index 68ddde88f6..9bd52b8f3e 100644 --- a/packages/ens-referrals/src/referrer-detail.ts +++ b/packages/ens-referrals/src/referrer-detail.ts @@ -1,6 +1,4 @@ -import type { Address } from "viem"; - -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { Address, UnixTimestamp } from "enssdk"; import type { AggregatedReferrerMetrics } from "./aggregations"; import type { ReferrerLeaderboard } from "./leaderboard"; diff --git a/packages/ens-referrals/src/referrer-metrics.ts b/packages/ens-referrals/src/referrer-metrics.ts index b52fc7f94e..837dce6a39 100644 --- a/packages/ens-referrals/src/referrer-metrics.ts +++ b/packages/ens-referrals/src/referrer-metrics.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import type { Duration } from "@ensnode/ensnode-sdk"; diff --git a/packages/ens-referrals/src/rules.ts b/packages/ens-referrals/src/rules.ts index 54dc8c8fa5..d986dc0a4a 100644 --- a/packages/ens-referrals/src/rules.ts +++ b/packages/ens-referrals/src/rules.ts @@ -1,4 +1,4 @@ -import type { AccountId, UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { AccountId, UnixTimestamp } from "enssdk"; import { type USDQuantity, validateUSDQuantity } from "./currency"; import { validateNonNegativeInteger } from "./number"; diff --git a/packages/ens-referrals/src/status.ts b/packages/ens-referrals/src/status.ts index 93ce0e8245..650d5b1475 100644 --- a/packages/ens-referrals/src/status.ts +++ b/packages/ens-referrals/src/status.ts @@ -1,4 +1,4 @@ -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import type { ReferralProgramRules } from "./rules.ts"; diff --git a/packages/ens-referrals/src/time.ts b/packages/ens-referrals/src/time.ts index 46166c28ea..228465341f 100644 --- a/packages/ens-referrals/src/time.ts +++ b/packages/ens-referrals/src/time.ts @@ -1,4 +1,6 @@ -import type { Duration, UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; + +import type { Duration } from "@ensnode/ensnode-sdk"; import { isInteger, isNonNegativeInteger } from "./number"; diff --git a/packages/ens-referrals/src/v1/address.ts b/packages/ens-referrals/src/v1/address.ts index 2def2d575e..bcc9b4fc28 100644 --- a/packages/ens-referrals/src/v1/address.ts +++ b/packages/ens-referrals/src/v1/address.ts @@ -1,4 +1,5 @@ -import { type Address, isAddress } from "viem"; +import type { Address } from "enssdk"; +import { isAddress } from "viem"; export const validateLowercaseAddress = (address: Address): void => { if (!isAddress(address, { strict: false })) { diff --git a/packages/ens-referrals/src/v1/api/types.ts b/packages/ens-referrals/src/v1/api/types.ts index 5e52740974..d23898965d 100644 --- a/packages/ens-referrals/src/v1/api/types.ts +++ b/packages/ens-referrals/src/v1/api/types.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import type { ReferrerLeaderboardPageParams } from "../award-models/shared/leaderboard-page"; import type { ReferralProgramEditionSlug } from "../edition"; diff --git a/packages/ens-referrals/src/v1/award-models/pie-split/edition-metrics.ts b/packages/ens-referrals/src/v1/award-models/pie-split/edition-metrics.ts index d984cf3f7e..e4c3f21047 100644 --- a/packages/ens-referrals/src/v1/award-models/pie-split/edition-metrics.ts +++ b/packages/ens-referrals/src/v1/award-models/pie-split/edition-metrics.ts @@ -1,4 +1,4 @@ -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import type { ReferrerEditionMetricsTypeIds } from "../shared/edition-metrics"; import type { ReferralProgramAwardModels } from "../shared/rules"; diff --git a/packages/ens-referrals/src/v1/award-models/pie-split/leaderboard.ts b/packages/ens-referrals/src/v1/award-models/pie-split/leaderboard.ts index b091765963..236894a58c 100644 --- a/packages/ens-referrals/src/v1/award-models/pie-split/leaderboard.ts +++ b/packages/ens-referrals/src/v1/award-models/pie-split/leaderboard.ts @@ -1,6 +1,4 @@ -import type { Address } from "viem"; - -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { Address, UnixTimestamp } from "enssdk"; import type { ReferrerMetrics } from "../../referrer-metrics"; import { assertLeaderboardInputs } from "../shared/leaderboard-guards"; diff --git a/packages/ens-referrals/src/v1/award-models/pie-split/metrics.ts b/packages/ens-referrals/src/v1/award-models/pie-split/metrics.ts index 6628a34ae0..de02d0d50b 100644 --- a/packages/ens-referrals/src/v1/award-models/pie-split/metrics.ts +++ b/packages/ens-referrals/src/v1/award-models/pie-split/metrics.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { type PriceUsdc, priceEth, priceUsdc, scalePrice } from "@ensnode/ensnode-sdk"; import { makePriceEthSchema, makePriceUsdcSchema } from "@ensnode/ensnode-sdk/internal"; diff --git a/packages/ens-referrals/src/v1/award-models/pie-split/rules.ts b/packages/ens-referrals/src/v1/award-models/pie-split/rules.ts index 797099bd0d..757e056209 100644 --- a/packages/ens-referrals/src/v1/award-models/pie-split/rules.ts +++ b/packages/ens-referrals/src/v1/award-models/pie-split/rules.ts @@ -1,4 +1,6 @@ -import type { AccountId, PriceUsdc, UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { AccountId, UnixTimestamp } from "enssdk"; + +import type { PriceUsdc } from "@ensnode/ensnode-sdk"; import { makePriceUsdcSchema } from "@ensnode/ensnode-sdk/internal"; import { validateNonNegativeInteger } from "../../number"; diff --git a/packages/ens-referrals/src/v1/award-models/pie-split/status.ts b/packages/ens-referrals/src/v1/award-models/pie-split/status.ts index aaadd8f37a..8d49dd33a9 100644 --- a/packages/ens-referrals/src/v1/award-models/pie-split/status.ts +++ b/packages/ens-referrals/src/v1/award-models/pie-split/status.ts @@ -1,4 +1,4 @@ -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import { calcBaseReferralProgramEditionStatus, diff --git a/packages/ens-referrals/src/v1/award-models/rev-share-limit/edition-metrics.ts b/packages/ens-referrals/src/v1/award-models/rev-share-limit/edition-metrics.ts index 0e3d74af7d..9d8c9741ff 100644 --- a/packages/ens-referrals/src/v1/award-models/rev-share-limit/edition-metrics.ts +++ b/packages/ens-referrals/src/v1/award-models/rev-share-limit/edition-metrics.ts @@ -1,4 +1,4 @@ -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import type { ReferrerEditionMetricsTypeIds } from "../shared/edition-metrics"; import type { ReferralProgramAwardModels } from "../shared/rules"; diff --git a/packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts b/packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts index 41c79cd1f1..645357423f 100644 --- a/packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts +++ b/packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { type Duration, diff --git a/packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts b/packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts index b5d0d65719..2a3a1b107c 100644 --- a/packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts +++ b/packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { type PriceUsdc, priceEth, priceUsdc } from "@ensnode/ensnode-sdk"; import { makePriceEthSchema, makePriceUsdcSchema } from "@ensnode/ensnode-sdk/internal"; diff --git a/packages/ens-referrals/src/v1/award-models/rev-share-limit/referral-event.ts b/packages/ens-referrals/src/v1/award-models/rev-share-limit/referral-event.ts index 9c9dfe56a3..5570dcb10a 100644 --- a/packages/ens-referrals/src/v1/award-models/rev-share-limit/referral-event.ts +++ b/packages/ens-referrals/src/v1/award-models/rev-share-limit/referral-event.ts @@ -1,6 +1,6 @@ -import type { Address } from "viem"; +import type { Address, UnixTimestamp } from "enssdk"; -import type { Duration, PriceEth, UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { Duration, PriceEth } from "@ensnode/ensnode-sdk"; /** * Represents a single raw referral event. diff --git a/packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts b/packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts index 9f75014889..1160520bbf 100644 --- a/packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts +++ b/packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts @@ -1,11 +1,6 @@ -import type { Address } from "viem"; +import type { AccountId, Address, UnixTimestamp } from "enssdk"; -import { - type AccountId, - type PriceUsdc, - parseUsdc, - type UnixTimestamp, -} from "@ensnode/ensnode-sdk"; +import { type PriceUsdc, parseUsdc } from "@ensnode/ensnode-sdk"; import { makePriceUsdcSchema } from "@ensnode/ensnode-sdk/internal"; import { normalizeAddress, validateLowercaseAddress } from "../../address"; diff --git a/packages/ens-referrals/src/v1/award-models/rev-share-limit/status.ts b/packages/ens-referrals/src/v1/award-models/rev-share-limit/status.ts index 625582a7f8..a27f41c75c 100644 --- a/packages/ens-referrals/src/v1/award-models/rev-share-limit/status.ts +++ b/packages/ens-referrals/src/v1/award-models/rev-share-limit/status.ts @@ -1,4 +1,4 @@ -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import { calcBaseReferralProgramEditionStatus, diff --git a/packages/ens-referrals/src/v1/award-models/shared/leaderboard-guards.ts b/packages/ens-referrals/src/v1/award-models/shared/leaderboard-guards.ts index 717f44cb19..1676896449 100644 --- a/packages/ens-referrals/src/v1/award-models/shared/leaderboard-guards.ts +++ b/packages/ens-referrals/src/v1/award-models/shared/leaderboard-guards.ts @@ -1,4 +1,4 @@ -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import type { ReferrerMetrics } from "../../referrer-metrics"; import type { BaseReferralProgramRules } from "./rules"; diff --git a/packages/ens-referrals/src/v1/award-models/shared/leaderboard-page.ts b/packages/ens-referrals/src/v1/award-models/shared/leaderboard-page.ts index 1166393d76..da5fb662e7 100644 --- a/packages/ens-referrals/src/v1/award-models/shared/leaderboard-page.ts +++ b/packages/ens-referrals/src/v1/award-models/shared/leaderboard-page.ts @@ -1,6 +1,4 @@ -import type { Address } from "viem"; - -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { Address, UnixTimestamp } from "enssdk"; import type { ReferrerLeaderboard } from "../../leaderboard"; import { isNonNegativeInteger, isPositiveInteger } from "../../number"; diff --git a/packages/ens-referrals/src/v1/award-models/shared/rank.ts b/packages/ens-referrals/src/v1/award-models/shared/rank.ts index e407d27e74..6f25960e53 100644 --- a/packages/ens-referrals/src/v1/award-models/shared/rank.ts +++ b/packages/ens-referrals/src/v1/award-models/shared/rank.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import type { Duration } from "@ensnode/ensnode-sdk"; diff --git a/packages/ens-referrals/src/v1/award-models/shared/rules.ts b/packages/ens-referrals/src/v1/award-models/shared/rules.ts index 72c2e92fe9..23b0ae776c 100644 --- a/packages/ens-referrals/src/v1/award-models/shared/rules.ts +++ b/packages/ens-referrals/src/v1/award-models/shared/rules.ts @@ -1,4 +1,5 @@ -import type { AccountId, UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { AccountId, UnixTimestamp } from "enssdk"; + import { makeAccountIdSchema } from "@ensnode/ensnode-sdk/internal"; import { validateUnixTimestamp } from "../../time"; diff --git a/packages/ens-referrals/src/v1/award-models/shared/status.ts b/packages/ens-referrals/src/v1/award-models/shared/status.ts index 05b1da3406..7d6d4625c0 100644 --- a/packages/ens-referrals/src/v1/award-models/shared/status.ts +++ b/packages/ens-referrals/src/v1/award-models/shared/status.ts @@ -1,4 +1,4 @@ -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; import type { BaseReferralProgramRules } from "./rules"; diff --git a/packages/ens-referrals/src/v1/edition-metrics.ts b/packages/ens-referrals/src/v1/edition-metrics.ts index bba874c074..6efff1189f 100644 --- a/packages/ens-referrals/src/v1/edition-metrics.ts +++ b/packages/ens-referrals/src/v1/edition-metrics.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import type { ReferrerEditionMetricsPieSplit, diff --git a/packages/ens-referrals/src/v1/leaderboard-page.test.ts b/packages/ens-referrals/src/v1/leaderboard-page.test.ts index dbb3a7d61d..a8fe7e8338 100644 --- a/packages/ens-referrals/src/v1/leaderboard-page.test.ts +++ b/packages/ens-referrals/src/v1/leaderboard-page.test.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { describe, expect, it, vi } from "vitest"; import { priceEth, priceUsdc } from "@ensnode/ensnode-sdk"; diff --git a/packages/ens-referrals/src/v1/link.test.ts b/packages/ens-referrals/src/v1/link.test.ts index b6cd960f76..bc6dcb83fa 100644 --- a/packages/ens-referrals/src/v1/link.test.ts +++ b/packages/ens-referrals/src/v1/link.test.ts @@ -1,4 +1,5 @@ -import { type Address, getAddress } from "viem"; +import type { Address } from "enssdk"; +import { getAddress } from "viem"; import { describe, expect, it } from "vitest"; import { buildEnsReferralUrl } from "./link"; diff --git a/packages/ens-referrals/src/v1/link.ts b/packages/ens-referrals/src/v1/link.ts index d6a63e3f2a..e3dc03ea54 100644 --- a/packages/ens-referrals/src/v1/link.ts +++ b/packages/ens-referrals/src/v1/link.ts @@ -1,4 +1,5 @@ -import { type Address, getAddress } from "viem"; +import type { Address } from "enssdk"; +import { getAddress } from "viem"; /** * Build a URL to the official ENS manager app diff --git a/packages/ens-referrals/src/v1/referrer-metrics.ts b/packages/ens-referrals/src/v1/referrer-metrics.ts index 90aa11854d..e447e7b6fe 100644 --- a/packages/ens-referrals/src/v1/referrer-metrics.ts +++ b/packages/ens-referrals/src/v1/referrer-metrics.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import type { Duration, PriceEth } from "@ensnode/ensnode-sdk"; import { makePriceEthSchema } from "@ensnode/ensnode-sdk/internal"; diff --git a/packages/ens-referrals/src/v1/time.ts b/packages/ens-referrals/src/v1/time.ts index 46166c28ea..228465341f 100644 --- a/packages/ens-referrals/src/v1/time.ts +++ b/packages/ens-referrals/src/v1/time.ts @@ -1,4 +1,6 @@ -import type { Duration, UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { UnixTimestamp } from "enssdk"; + +import type { Duration } from "@ensnode/ensnode-sdk"; import { isInteger, isNonNegativeInteger } from "./number"; diff --git a/packages/ensdb-sdk/package.json b/packages/ensdb-sdk/package.json index 3a72d29790..e020bb1ca0 100644 --- a/packages/ensdb-sdk/package.json +++ b/packages/ensdb-sdk/package.json @@ -60,6 +60,7 @@ }, "dependencies": { "@ensnode/ensnode-sdk": "workspace:*", + "enssdk": "workspace:*", "pg-connection-string": "catalog:", "zod": "catalog:" }, diff --git a/packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts b/packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts index 4ea79f2f66..828112322c 100644 --- a/packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts +++ b/packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts @@ -1,12 +1,9 @@ -import { index, onchainEnum, onchainTable, primaryKey, relations, sql, uniqueIndex } from "ponder"; -import type { Address, BlockNumber, Hash } from "viem"; - import type { + Address, ChainId, DomainId, ENSv1DomainId, ENSv2DomainId, - EncodedReferrer, InterpretedLabel, LabelHash, PermissionsId, @@ -16,7 +13,11 @@ import type { RegistryId, RenewalId, ResolverId, -} from "@ensnode/ensnode-sdk"; +} from "enssdk"; +import { index, onchainEnum, onchainTable, primaryKey, relations, sql, uniqueIndex } from "ponder"; +import type { BlockNumber, Hash } from "viem"; + +import type { EncodedReferrer } from "@ensnode/ensnode-sdk"; /** * The ENSv2 Schema diff --git a/packages/ensdb-sdk/src/ensindexer-abstract/protocol-acceleration.schema.ts b/packages/ensdb-sdk/src/ensindexer-abstract/protocol-acceleration.schema.ts index 7c336eb70a..2230813918 100644 --- a/packages/ensdb-sdk/src/ensindexer-abstract/protocol-acceleration.schema.ts +++ b/packages/ensdb-sdk/src/ensindexer-abstract/protocol-acceleration.schema.ts @@ -2,10 +2,8 @@ * Schema Definitions that power Protocol Acceleration in the Resolution API. */ +import type { Address, ChainId, DomainId, Node, ResolverId, ResolverRecordsId } from "enssdk"; import { onchainTable, primaryKey, relations, uniqueIndex } from "ponder"; -import type { Address } from "viem"; - -import type { ChainId, DomainId, Node, ResolverId, ResolverRecordsId } from "@ensnode/ensnode-sdk"; /** * Tracks an Account's ENSIP-19 Reverse Name Records by CoinType. diff --git a/packages/ensdb-sdk/src/ensindexer-abstract/subgraph.schema.ts b/packages/ensdb-sdk/src/ensindexer-abstract/subgraph.schema.ts index 70fb5a6267..e78386a546 100644 --- a/packages/ensdb-sdk/src/ensindexer-abstract/subgraph.schema.ts +++ b/packages/ensdb-sdk/src/ensindexer-abstract/subgraph.schema.ts @@ -1,5 +1,5 @@ +import type { Address } from "enssdk"; import { index, onchainTable, relations } from "ponder"; -import type { Address } from "viem"; import { monkeypatchCollate } from "../lib/collate"; diff --git a/packages/enskit/src/react/omnigraph/lib/cache-exchange.ts b/packages/enskit/src/react/omnigraph/lib/cache-exchange.ts index 77a1f1ebb6..dfcc3ff6bc 100644 --- a/packages/enskit/src/react/omnigraph/lib/cache-exchange.ts +++ b/packages/enskit/src/react/omnigraph/lib/cache-exchange.ts @@ -4,10 +4,9 @@ import { type ResolveInfo, type Variables, } from "@urql/exchange-graphcache"; -import type { AccountId, PermissionsId, RegistryId, ResolverId } from "enssdk"; +import type { AccountId, Address, PermissionsId, RegistryId, ResolverId } from "enssdk"; import { makePermissionsId, makeRegistryId, makeResolverId, stringifyAccountId } from "enssdk"; import { introspection } from "enssdk/omnigraph"; -import type { Address } from "viem"; import { localConnectionResolvers } from "./local-connection-resolvers"; diff --git a/packages/ensnode-react/package.json b/packages/ensnode-react/package.json index 62fa680529..f727239361 100644 --- a/packages/ensnode-react/package.json +++ b/packages/ensnode-react/package.json @@ -56,6 +56,7 @@ "vitest": "catalog:" }, "dependencies": { - "@ensnode/ensnode-sdk": "workspace:*" + "@ensnode/ensnode-sdk": "workspace:*", + "enssdk": "workspace:*" } } diff --git a/packages/ensnode-sdk/package.json b/packages/ensnode-sdk/package.json index f1af3dc109..e36a72b529 100644 --- a/packages/ensnode-sdk/package.json +++ b/packages/ensnode-sdk/package.json @@ -59,7 +59,6 @@ "vitest": "catalog:" }, "dependencies": { - "@adraffy/ens-normalize": "catalog:", "@ensdomains/address-encoder": "^1.1.2", "@ensnode/datasources": "workspace:*", "caip": "catalog:", diff --git a/packages/ensnode-sdk/src/ens/constants.ts b/packages/ensnode-sdk/src/ens/constants.ts deleted file mode 100644 index f89742fc51..0000000000 --- a/packages/ensnode-sdk/src/ens/constants.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { Node } from "enssdk"; -import { namehash, zeroHash } from "viem"; - -export const ROOT_NODE: Node = namehash(""); -export const ETH_NODE: Node = namehash("eth"); -export const BASENAMES_NODE: Node = namehash("base.eth"); -export const LINEANAMES_NODE: Node = namehash("linea.eth"); -export const ADDR_REVERSE_NODE: Node = namehash("addr.reverse"); - -/** - * NODE_ANY is a placeholder Node used in the context of DedicatedResolvers — IResolver events are - * emitted with NODE_ANY as the `node` for which the records are issued, but the DedicatedResolver - * returns those records regardless of the name used for record resolution. - */ -export const NODE_ANY: Node = zeroHash; - -/** - * ROOT_RESOURCE represents the 'root' resource in an EnhancedAccessControl contract. - */ -export const ROOT_RESOURCE = 0n; diff --git a/packages/ensnode-sdk/src/ens/encode-labelhash.ts b/packages/ensnode-sdk/src/ens/encode-labelhash.ts deleted file mode 100644 index d6017c8689..0000000000 --- a/packages/ensnode-sdk/src/ens/encode-labelhash.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { EncodedLabelHash, LabelHash } from "enssdk"; - -import { isLabelHash } from "./labelhash"; - -/** - * Formats a LabelHash as an Encoded LabelHash. - * - * @see https://ensnode.io/docs/reference/terminology#encoded-labelhash - * - * @param labelHash - A 32-byte lowercase hash string starting with '0x' - * @returns The encoded label hash in format `[hash_without_0x_prefix]` - */ -export const encodeLabelHash = (labelHash: LabelHash): EncodedLabelHash => - `[${labelHash.slice(2)}]`; - -/** - * Checks if the input value is an {@link EncodedLabelHash}. - */ -export function isEncodedLabelHash( - maybeEncodedLabelHash: string, -): maybeEncodedLabelHash is EncodedLabelHash { - const expectedFormatting = - maybeEncodedLabelHash.startsWith("[") && maybeEncodedLabelHash.endsWith("]"); - const includesLabelHash = isLabelHash(`0x${maybeEncodedLabelHash.slice(1, -1)}`); - - return expectedFormatting && includesLabelHash; -} diff --git a/packages/ensnode-sdk/src/ens/index.ts b/packages/ensnode-sdk/src/ens/index.ts index 3a9ef37be3..f0935758a7 100644 --- a/packages/ensnode-sdk/src/ens/index.ts +++ b/packages/ensnode-sdk/src/ens/index.ts @@ -1,17 +1,4 @@ -export * from "enssdk"; - export type { ENSNamespaceId } from "@ensnode/datasources"; export { ENSNamespaceIds, getENSRootChainId } from "@ensnode/datasources"; -export * from "./coin-type"; -export * from "./constants"; -export * from "./dns-encoded-name"; -export * from "./encode-labelhash"; export * from "./fuses"; -export * from "./is-normalized"; -export * from "./labelhash"; -export * from "./names"; -export * from "./parse-labelhash"; -export * from "./parse-reverse-name"; -export * from "./reverse-name"; -export * from "./subname-helpers"; diff --git a/packages/ensnode-sdk/src/ens/is-normalized.ts b/packages/ensnode-sdk/src/ens/is-normalized.ts deleted file mode 100644 index 4130419d91..0000000000 --- a/packages/ensnode-sdk/src/ens/is-normalized.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { Label, Name, NormalizedName } from "enssdk"; -import { normalize } from "viem/ens"; - -/** - * Determines whether the Name is normalized. - * - * @param name - The Name to check for normalization - * @returns True if the name is normalized according to ENS normalization rules, false otherwise - */ -export function isNormalizedName(name: Name): name is NormalizedName { - try { - return name === normalize(name); - } catch { - return false; - } -} -/** - * Determines whether the Label is normalized. - * - * @param label - The Label to check for normalization - * @returns True if the label is normalized according to ENS normalization rules, false otherwise - */ -export function isNormalizedLabel(label: Label): boolean { - // empty string is not a normalized label - if (label === "") return false; - - // normalized labels do not contain periods - if (label.includes(".")) return false; - - try { - return label === normalize(label); - } catch { - return false; - } -} diff --git a/packages/ensnode-sdk/src/ens/labelhash.ts b/packages/ensnode-sdk/src/ens/labelhash.ts deleted file mode 100644 index bbb7fdb404..0000000000 --- a/packages/ensnode-sdk/src/ens/labelhash.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { LabelHash } from "enssdk"; -import { isHex } from "viem"; - -/** - * Checks if the input is a {@link LabelHash}. - * - * @see https://ensnode.io/docs/reference/terminology#label-processing-and-classification - */ -export function isLabelHash(maybeLabelHash: string): maybeLabelHash is LabelHash { - const expectedLength = maybeLabelHash.length === 66; - const expectedEncoding = isHex(maybeLabelHash); - const expectedCasing = maybeLabelHash === maybeLabelHash.toLowerCase(); - - return expectedLength && expectedEncoding && expectedCasing; -} diff --git a/packages/ensnode-sdk/src/ens/subname-helpers.test.ts b/packages/ensnode-sdk/src/ens/subname-helpers.test.ts deleted file mode 100644 index ca6a6df4f8..0000000000 --- a/packages/ensnode-sdk/src/ens/subname-helpers.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { labelhash, namehash } from "viem"; -import { describe, expect, it } from "vitest"; - -import { makeSubdomainNode } from "./subname-helpers"; - -describe("makeSubdomainNode", () => { - it("should return the correct namehash for a subnode", () => { - expect(makeSubdomainNode(labelhash("test🚀"), namehash("base.eth"))).toBe( - namehash("test🚀.base.eth"), - ); - }); -}); diff --git a/packages/ensnode-sdk/src/ens/subname-helpers.ts b/packages/ensnode-sdk/src/ens/subname-helpers.ts deleted file mode 100644 index 9c8281f778..0000000000 --- a/packages/ensnode-sdk/src/ens/subname-helpers.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { LabelHash, Node } from "enssdk"; -import { concat, keccak256 } from "viem"; - -/** - * Implements one step of the namehash algorithm, combining `labelHash` with `node` to produce - * the `node` of a given subdomain. Note that the order of the arguments is 'reversed' (as compared to - * the actual concatenation) in order to improve readability (i.e. read as [labelHash].[node]). - */ -export const makeSubdomainNode = (labelHash: LabelHash, node: Node): Node => - keccak256(concat([node, labelHash])); diff --git a/packages/ensnode-sdk/src/ensapi/api/name-tokens/zod-schemas.test.ts b/packages/ensnode-sdk/src/ensapi/api/name-tokens/zod-schemas.test.ts index 7cec63add7..90e6ce9c7d 100644 --- a/packages/ensnode-sdk/src/ensapi/api/name-tokens/zod-schemas.test.ts +++ b/packages/ensnode-sdk/src/ensapi/api/name-tokens/zod-schemas.test.ts @@ -1,4 +1,4 @@ -import { AssetNamespaces, type InterpretedName } from "enssdk"; +import { AssetNamespaces, asInterpretedName } from "enssdk"; import { describe, expect, it } from "vitest"; import { NFTMintStatuses } from "../../../tokenscope/assets"; @@ -11,7 +11,7 @@ const responseOk = { responseCode: NameTokensResponseCodes.Ok, registeredNameTokens: { domainId: "0xe02070fb6710555cd44b79b55959e9a89f47b4029d44bde5a4f7b5fe13fe4688", - name: "texasprivacy.eth" as InterpretedName, + name: asInterpretedName("texasprivacy.eth"), tokens: [ { token: { @@ -65,7 +65,7 @@ describe("Name Tokens: Zod Schemas", () => { accurateAsOf: 1765283111, domainId: "0xe02070fb6710555cd44b79b55959e9a89f47b4029d44bde5a4f7b5fe13fe4688", expiresAt: 1796524355, - name: "texasprivacy.eth" as InterpretedName, + name: asInterpretedName("texasprivacy.eth"), tokens: [ { token: { diff --git a/packages/ensnode-sdk/src/ensapi/api/name-tokens/zod-schemas.ts b/packages/ensnode-sdk/src/ensapi/api/name-tokens/zod-schemas.ts index 1a96f6170f..9fc89551e4 100644 --- a/packages/ensnode-sdk/src/ensapi/api/name-tokens/zod-schemas.ts +++ b/packages/ensnode-sdk/src/ensapi/api/name-tokens/zod-schemas.ts @@ -1,4 +1,4 @@ -import { namehash } from "viem"; +import { namehashInterpretedName } from "enssdk"; import { z } from "zod/v4"; import { @@ -39,7 +39,7 @@ export const makeRegisteredNameTokenSchema = { "176209761600000000111551110000000009545322000000000000006750000000000000071", ], }, - name: "nh35.eth" as InterpretedName, + name: asInterpretedName("nh35.eth"), } satisfies SerializedNamedRegistrarAction; const validNamedRegistrarActionEncodedLabelHash = { @@ -92,7 +92,9 @@ describe("ENSNode API Schema", () => { transactionHash: "0xa71cf08102ae1f634b22349dac8dc158fe96ae74008b5e24cfcda8587e056d53", eventIds: ["176234701200000000111551110000000009566045000000000000014150000000000000198"], }, - name: "[e4310bf4547cb18b16b5348881d24a66d61fa94a013e5636b730b86ee64a3923].eth" as InterpretedName, + name: asInterpretedName( + "[e4310bf4547cb18b16b5348881d24a66d61fa94a013e5636b730b86ee64a3923].eth", + ), } satisfies SerializedNamedRegistrarAction; const validResponseOk = { diff --git a/packages/ensnode-sdk/src/ensapi/api/registrar-actions/zod-schemas.ts b/packages/ensnode-sdk/src/ensapi/api/registrar-actions/zod-schemas.ts index 49ca24011c..9057ddf4d3 100644 --- a/packages/ensnode-sdk/src/ensapi/api/registrar-actions/zod-schemas.ts +++ b/packages/ensnode-sdk/src/ensapi/api/registrar-actions/zod-schemas.ts @@ -1,4 +1,4 @@ -import { namehash } from "viem/ens"; +import { namehashInterpretedName } from "enssdk"; import { z } from "zod/v4"; import type { ParsePayload } from "zod/v4/core"; @@ -11,7 +11,7 @@ import { type NamedRegistrarAction, RegistrarActionsResponseCodes } from "./resp function invariant_registrationLifecycleNodeMatchesName(ctx: ParsePayload) { const { name, action } = ctx.value; const expectedNode = action.registrationLifecycle.node; - const actualNode = namehash(name); + const actualNode = namehashInterpretedName(name); if (actualNode !== expectedNode) { ctx.issues.push({ diff --git a/packages/ensnode-sdk/src/ensapi/client.test.ts b/packages/ensnode-sdk/src/ensapi/client.test.ts index e6d5c910bb..222a4c3464 100644 --- a/packages/ensnode-sdk/src/ensapi/client.test.ts +++ b/packages/ensnode-sdk/src/ensapi/client.test.ts @@ -1,7 +1,7 @@ -import type { Address } from "viem"; +import type { Address, Name } from "enssdk"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { ENSNamespaceIds, type Name } from "../ens"; +import { ENSNamespaceIds } from "../ens"; import { PluginName } from "../ensindexer/config/types"; import { ChainIndexingStatusIds } from "../indexing-status/chain-indexing-status-snapshot"; import { CrossChainIndexingStrategyIds } from "../indexing-status/cross-chain-indexing-status-snapshot"; diff --git a/packages/ensnode-sdk/src/ensapi/client.ts b/packages/ensnode-sdk/src/ensapi/client.ts index 9881159b66..f8822f5193 100644 --- a/packages/ensnode-sdk/src/ensapi/client.ts +++ b/packages/ensnode-sdk/src/ensapi/client.ts @@ -410,7 +410,9 @@ export class EnsApiClient { * registrarActionsFilter, * EnsApiClient, * } from "@ensnode/ensnode-sdk"; - * import { namehash } from "viem/ens"; + * import { ETH_NODE, namehashInterpretedName, asInterpretedName } from "enssdk"; + * + * const BASE_NODE = namehashInterpretedName(asInterpretedName("base.eth")); * * const client: EnsApiClient; * @@ -432,7 +434,7 @@ export class EnsApiClient { * // get latest registrar action records associated with * // subregistry managing `eth` name * await client.registrarActions({ - * filters: [registrarActionsFilter.byParentNode(namehash('eth'))], + * filters: [registrarActionsFilter.byParentNode(ETH_NODE)], * }); * * // get latest registrar action records which include referral info @@ -448,7 +450,7 @@ export class EnsApiClient { * // get latest 10 registrar action records associated with * // subregistry managing `base.eth` name * await client.registrarActions({ - * filters: [registrarActionsFilter.byParentNode(namehash('base.eth'))], + * filters: [registrarActionsFilter.byParentNode(BASE_NODE)], * recordsPerPage: 10 * }); * @@ -622,17 +624,20 @@ export class EnsApiClient { * import { * EnsApiClient, * } from "@ensnode/ensnode-sdk"; - * import { namehash } from "viem/ens"; + * import { namehashInterpretedName, asInterpretedName } from "enssdk"; + * + * const VITALIK_NAME = asInterpretedName("vitalik.eth"); + * const VITALIK_DOMAIN_ID = namehashInterpretedName(VITALIK_NAME); * * const client: EnsApiClient; * * // get latest name token records from the indexed subregistry based on the requested name * const response = await client.nameTokens({ - * name: "vitalik.eth" + * name: VITALIK_NAME, * }); * * const response = await client.nameTokens({ - * domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth') + * domainId: VITALIK_DOMAIN_ID, * }) * ``` */ diff --git a/packages/ensnode-sdk/src/ensindexer/config/label-utils.test.ts b/packages/ensnode-sdk/src/ensindexer/config/label-utils.test.ts index 5364f5404a..1ac84aec0f 100644 --- a/packages/ensnode-sdk/src/ensindexer/config/label-utils.test.ts +++ b/packages/ensnode-sdk/src/ensindexer/config/label-utils.test.ts @@ -1,6 +1,6 @@ +import type { LabelHash } from "enssdk"; import { describe, expect, it } from "vitest"; -import type { LabelHash } from "../../ens"; import { labelHashToBytes } from "./label-utils"; describe("labelHashToBytes", () => { diff --git a/packages/ensnode-sdk/src/identity/identity.ts b/packages/ensnode-sdk/src/identity/identity.ts index b90cd5e1d5..f5d34a398b 100644 --- a/packages/ensnode-sdk/src/identity/identity.ts +++ b/packages/ensnode-sdk/src/identity/identity.ts @@ -1,5 +1,4 @@ -import type { DefaultableChainId } from "enssdk"; -import type { Address } from "viem"; +import type { Address, DefaultableChainId } from "enssdk"; import { type ENSNamespaceId, getENSRootChainId } from "@ensnode/datasources"; diff --git a/packages/ensnode-sdk/src/identity/types.ts b/packages/ensnode-sdk/src/identity/types.ts index 70f163537a..46360c9de8 100644 --- a/packages/ensnode-sdk/src/identity/types.ts +++ b/packages/ensnode-sdk/src/identity/types.ts @@ -1,5 +1,4 @@ -import type { DefaultableChainId, Name } from "enssdk"; -import type { Address } from "viem"; +import type { Address, DefaultableChainId, Name } from "enssdk"; /** * The resolution status for an `Identity`. diff --git a/packages/ensnode-sdk/src/index.ts b/packages/ensnode-sdk/src/index.ts index e3ef28bbea..ea5341ec7e 100644 --- a/packages/ensnode-sdk/src/index.ts +++ b/packages/ensnode-sdk/src/index.ts @@ -13,7 +13,6 @@ export * from "./omnigraph-api/prerequisites"; export * from "./registrars"; export * from "./resolution"; export * from "./shared/account-id"; -export * from "./shared/address"; export * from "./shared/blockrange"; export * from "./shared/cache"; export * from "./shared/collections"; @@ -23,7 +22,6 @@ export * from "./shared/datasource-contract"; export * from "./shared/datetime"; export * from "./shared/deserialize"; export * from "./shared/interpretation"; -export * from "./shared/labelhash"; export * from "./shared/namespace-specific-value"; export * from "./shared/null-bytes"; export * from "./shared/numbers"; diff --git a/packages/ensnode-sdk/src/registrars/basenames-subregistry.ts b/packages/ensnode-sdk/src/registrars/basenames-subregistry.ts index ef79e393b9..d870375f2c 100644 --- a/packages/ensnode-sdk/src/registrars/basenames-subregistry.ts +++ b/packages/ensnode-sdk/src/registrars/basenames-subregistry.ts @@ -1,4 +1,5 @@ -import type { AccountId, Name } from "enssdk"; +import type { AccountId, InterpretedName } from "enssdk"; +import { asInterpretedName } from "enssdk"; import { DatasourceNames, @@ -26,10 +27,7 @@ export function getBasenamesSubregistryId(namespace: ENSNamespaceId): AccountId throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`); } - return { - chainId: datasource.chain.id, - address, - }; + return { chainId: datasource.chain.id, address }; } /** @@ -39,13 +37,13 @@ export function getBasenamesSubregistryId(namespace: ENSNamespaceId): AccountId * @returns registrar managed name * @throws an error when no registrar managed name could be returned */ -export function getBasenamesSubregistryManagedName(namespaceId: ENSNamespaceId): Name { +export function getBasenamesSubregistryManagedName(namespaceId: ENSNamespaceId): InterpretedName { switch (namespaceId) { case ENSNamespaceIds.Mainnet: - return "base.eth"; + return asInterpretedName("base.eth"); case ENSNamespaceIds.Sepolia: case ENSNamespaceIds.SepoliaV2: - return "basetest.eth"; + return asInterpretedName("basetest.eth"); case ENSNamespaceIds.EnsTestEnv: throw new Error( `No registrar managed name is known for the 'basenames' subregistry within the "${namespaceId}" namespace.`, diff --git a/packages/ensnode-sdk/src/registrars/encoded-referrer.test.ts b/packages/ensnode-sdk/src/registrars/encoded-referrer.test.ts index 6c18fd11a0..992107496c 100644 --- a/packages/ensnode-sdk/src/registrars/encoded-referrer.test.ts +++ b/packages/ensnode-sdk/src/registrars/encoded-referrer.test.ts @@ -1,4 +1,5 @@ -import { type Address, concat, getAddress, pad, zeroAddress } from "viem"; +import type { Address } from "enssdk"; +import { concat, getAddress, pad, zeroAddress } from "viem"; import { describe, expect, it } from "vitest"; import { diff --git a/packages/ensnode-sdk/src/registrars/encoded-referrer.ts b/packages/ensnode-sdk/src/registrars/encoded-referrer.ts index 217873be75..399ed86150 100644 --- a/packages/ensnode-sdk/src/registrars/encoded-referrer.ts +++ b/packages/ensnode-sdk/src/registrars/encoded-referrer.ts @@ -1,4 +1,5 @@ -import { type Address, getAddress, type Hex, pad, size, slice, zeroAddress } from "viem"; +import type { Address, Hex } from "enssdk"; +import { getAddress, pad, size, slice, zeroAddress } from "viem"; /** * Encoded Referrer diff --git a/packages/ensnode-sdk/src/registrars/ethnames-subregistry.ts b/packages/ensnode-sdk/src/registrars/ethnames-subregistry.ts index d72d88632d..4e670eb336 100644 --- a/packages/ensnode-sdk/src/registrars/ethnames-subregistry.ts +++ b/packages/ensnode-sdk/src/registrars/ethnames-subregistry.ts @@ -1,4 +1,5 @@ -import type { AccountId, Name } from "enssdk"; +import type { AccountId, InterpretedName } from "enssdk"; +import { asInterpretedName } from "enssdk"; import { DatasourceNames, @@ -26,10 +27,7 @@ export function getEthnamesSubregistryId(namespace: ENSNamespaceId): AccountId { throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`); } - return { - chainId: datasource.chain.id, - address, - }; + return { chainId: datasource.chain.id, address }; } /** @@ -38,12 +36,12 @@ export function getEthnamesSubregistryId(namespace: ENSNamespaceId): AccountId { * @param namespaceId * @returns registrar managed name */ -export function getEthnamesSubregistryManagedName(namespaceId: ENSNamespaceId): Name { +export function getEthnamesSubregistryManagedName(namespaceId: ENSNamespaceId): InterpretedName { switch (namespaceId) { case ENSNamespaceIds.Mainnet: case ENSNamespaceIds.Sepolia: case ENSNamespaceIds.SepoliaV2: case ENSNamespaceIds.EnsTestEnv: - return "eth"; + return asInterpretedName("eth"); } } diff --git a/packages/ensnode-sdk/src/registrars/lineanames-subregistry.ts b/packages/ensnode-sdk/src/registrars/lineanames-subregistry.ts index 52b782d1f7..47af1076b2 100644 --- a/packages/ensnode-sdk/src/registrars/lineanames-subregistry.ts +++ b/packages/ensnode-sdk/src/registrars/lineanames-subregistry.ts @@ -1,4 +1,5 @@ -import type { AccountId, Name } from "enssdk"; +import type { AccountId, InterpretedName } from "enssdk"; +import { asInterpretedName } from "enssdk"; import { DatasourceNames, @@ -26,10 +27,7 @@ export function getLineanamesSubregistryId(namespace: ENSNamespaceId): AccountId throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`); } - return { - chainId: datasource.chain.id, - address, - }; + return { chainId: datasource.chain.id, address }; } /** @@ -39,13 +37,13 @@ export function getLineanamesSubregistryId(namespace: ENSNamespaceId): AccountId * @returns registrar managed name * @throws an error when no registrar managed name could be returned */ -export function getLineanamesSubregistryManagedName(namespaceId: ENSNamespaceId): Name { +export function getLineanamesSubregistryManagedName(namespaceId: ENSNamespaceId): InterpretedName { switch (namespaceId) { case ENSNamespaceIds.Mainnet: - return "linea.eth"; + return asInterpretedName("linea.eth"); case ENSNamespaceIds.Sepolia: case ENSNamespaceIds.SepoliaV2: - return "linea-sepolia.eth"; + return asInterpretedName("linea-sepolia.eth"); case ENSNamespaceIds.EnsTestEnv: throw new Error( `No registrar managed name is known for the 'Lineanames' subregistry within the "${namespaceId}" namespace.`, diff --git a/packages/ensnode-sdk/src/registrars/registrar-action.ts b/packages/ensnode-sdk/src/registrars/registrar-action.ts index 15ec3a0f06..86b2f9a032 100644 --- a/packages/ensnode-sdk/src/registrars/registrar-action.ts +++ b/packages/ensnode-sdk/src/registrars/registrar-action.ts @@ -1,4 +1,5 @@ -import type { Address, Hash } from "viem"; +import type { Address } from "enssdk"; +import type { Hash } from "viem"; import type { EncodedReferrer } from "./encoded-referrer"; diff --git a/packages/ensnode-sdk/src/registrars/zod-schemas.ts b/packages/ensnode-sdk/src/registrars/zod-schemas.ts index 8bef60a73c..f2b12c6eb4 100644 --- a/packages/ensnode-sdk/src/registrars/zod-schemas.ts +++ b/packages/ensnode-sdk/src/registrars/zod-schemas.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { z } from "zod/v4"; import type { ParsePayload } from "zod/v4/core"; diff --git a/packages/ensnode-sdk/src/resolution/ensip19-chainid.ts b/packages/ensnode-sdk/src/resolution/ensip19-chainid.ts index ca49b495ef..136f55bee5 100644 --- a/packages/ensnode-sdk/src/resolution/ensip19-chainid.ts +++ b/packages/ensnode-sdk/src/resolution/ensip19-chainid.ts @@ -1,10 +1,9 @@ import type { ChainId, DefaultableChainId } from "enssdk"; +import { DEFAULT_EVM_CHAIN_ID } from "enssdk"; import { mainnet } from "viem/chains"; import { type ENSNamespaceId, getENSRootChainId } from "@ensnode/datasources"; -import { DEFAULT_EVM_CHAIN_ID } from "../ens"; - /** * Gets the "chainId param" that should be used for a primary name resolution * request. diff --git a/packages/ensnode-sdk/src/resolution/types.ts b/packages/ensnode-sdk/src/resolution/types.ts index 58cdae025e..954000bbc7 100644 --- a/packages/ensnode-sdk/src/resolution/types.ts +++ b/packages/ensnode-sdk/src/resolution/types.ts @@ -1,5 +1,4 @@ -import type { ChainId, Name } from "enssdk"; -import type { Address } from "viem"; +import type { Address, ChainId, Name } from "enssdk"; import type { ResolverRecordsResponse } from "./resolver-records-response"; import type { ResolverRecordsSelection } from "./resolver-records-selection"; diff --git a/packages/ensnode-sdk/src/rpc/eip-165.ts b/packages/ensnode-sdk/src/rpc/eip-165.ts index 1b9142c876..c1698c98bb 100644 --- a/packages/ensnode-sdk/src/rpc/eip-165.ts +++ b/packages/ensnode-sdk/src/rpc/eip-165.ts @@ -1,4 +1,4 @@ -import type { Address, Hex } from "viem"; +import type { Address, Hex } from "enssdk"; /** * EIP-165 ABI diff --git a/packages/ensnode-sdk/src/shared/account-id.test.ts b/packages/ensnode-sdk/src/shared/account-id.test.ts index 29913f87f6..4d87b6e737 100644 --- a/packages/ensnode-sdk/src/shared/account-id.test.ts +++ b/packages/ensnode-sdk/src/shared/account-id.test.ts @@ -1,6 +1,5 @@ -import type { AccountId } from "enssdk"; +import type { AccountId, Address } from "enssdk"; import { stringifyAccountId } from "enssdk"; -import type { Address } from "viem"; import { describe, expect, it } from "vitest"; import { parseAccountId } from "./deserialize"; diff --git a/packages/ensnode-sdk/src/shared/config/build-rpc-urls.ts b/packages/ensnode-sdk/src/shared/config/build-rpc-urls.ts index 0bf9bec708..2af44f0de8 100644 --- a/packages/ensnode-sdk/src/shared/config/build-rpc-urls.ts +++ b/packages/ensnode-sdk/src/shared/config/build-rpc-urls.ts @@ -1,3 +1,4 @@ +import type { ChainId } from "enssdk"; import { arbitrum, arbitrumSepolia, @@ -13,8 +14,6 @@ import { sepolia, } from "viem/chains"; -import type { ChainId } from "@ensnode/ensnode-sdk"; - /** * Builds a Alchemy RPC base URL for the specified chain ID. * diff --git a/packages/ensnode-sdk/src/shared/interpretation/index.ts b/packages/ensnode-sdk/src/shared/interpretation/index.ts index 1741768c13..209a403b36 100644 --- a/packages/ensnode-sdk/src/shared/interpretation/index.ts +++ b/packages/ensnode-sdk/src/shared/interpretation/index.ts @@ -1,3 +1,2 @@ export * from "./interpret-address"; export * from "./interpret-record-values"; -export * from "./interpreted-names-and-labels"; diff --git a/packages/ensnode-sdk/src/shared/interpretation/interpret-address.ts b/packages/ensnode-sdk/src/shared/interpretation/interpret-address.ts index f9d8a17bff..9fd9068a18 100644 --- a/packages/ensnode-sdk/src/shared/interpretation/interpret-address.ts +++ b/packages/ensnode-sdk/src/shared/interpretation/interpret-address.ts @@ -1,4 +1,5 @@ -import { type Address, isAddressEqual, zeroAddress } from "viem"; +import type { Address } from "enssdk"; +import { isAddressEqual, zeroAddress } from "viem"; /** * Interprets a viem#Address. zeroAddress is interpreted as null, otherwise Address. diff --git a/packages/ensnode-sdk/src/shared/interpretation/interpret-record-values.ts b/packages/ensnode-sdk/src/shared/interpretation/interpret-record-values.ts index 8e19305a2c..2efd82ecf6 100644 --- a/packages/ensnode-sdk/src/shared/interpretation/interpret-record-values.ts +++ b/packages/ensnode-sdk/src/shared/interpretation/interpret-record-values.ts @@ -1,8 +1,7 @@ import type { NormalizedName } from "enssdk"; +import { asLowerCaseAddress, isNormalizedName } from "enssdk"; import { isAddress, isAddressEqual, zeroAddress } from "viem"; -import { asLowerCaseAddress, isNormalizedName } from "@ensnode/ensnode-sdk"; - import { hasNullByte } from "../null-bytes"; /** diff --git a/packages/ensnode-sdk/src/shared/labelhash.test.ts b/packages/ensnode-sdk/src/shared/labelhash.test.ts deleted file mode 100644 index d62abc89c6..0000000000 --- a/packages/ensnode-sdk/src/shared/labelhash.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { keccak256, labelhash, stringToBytes } from "viem"; -import { describe, expect, it } from "vitest"; - -import { encodeLabelHash, type LiteralLabel } from "../ens"; -import { labelhashLiteralLabel } from "./labelhash"; - -describe("labelhashLiteralLabel", () => { - it("labelhashes empty string correctly", () => { - expect(labelhashLiteralLabel("" as LiteralLabel)).toEqual(keccak256(stringToBytes(""))); - }); - - it("labelhashes literal label correctly", () => { - expect(labelhashLiteralLabel("example" as LiteralLabel)).toEqual(labelhash("example")); - }); - - it("labelhashes encoded-labelhash-looking-strings as literal labels", () => { - const encodedLabelHashLookingLabel = encodeLabelHash(labelhash("whatever")) as LiteralLabel; - expect(labelhashLiteralLabel(encodedLabelHashLookingLabel)).not.toEqual( - labelhash(encodedLabelHashLookingLabel), - ); - }); -}); diff --git a/packages/ensnode-sdk/src/shared/labelhash.ts b/packages/ensnode-sdk/src/shared/labelhash.ts deleted file mode 100644 index 3dc083137a..0000000000 --- a/packages/ensnode-sdk/src/shared/labelhash.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { LabelHash, LiteralLabel } from "enssdk"; -import { keccak256, stringToBytes } from "viem"; - -/** - * Implements the ENS `labelhash` function for Literal Labels. - * @see https://docs.ens.domains/ensip/1 - * - * @param label the Literal Label to hash - * @returns the hash of the provided label - * @dev This function is viem/ens#labelhash but without the special-case handling of Encoded LabelHashes. - */ -export const labelhashLiteralLabel = (label: LiteralLabel): LabelHash => - keccak256(stringToBytes(label)); diff --git a/packages/ensnode-sdk/src/shared/protocol-acceleration/is-bridged-resolver.ts b/packages/ensnode-sdk/src/shared/protocol-acceleration/is-bridged-resolver.ts index 99377cfe51..9dadb8e568 100644 --- a/packages/ensnode-sdk/src/shared/protocol-acceleration/is-bridged-resolver.ts +++ b/packages/ensnode-sdk/src/shared/protocol-acceleration/is-bridged-resolver.ts @@ -1,6 +1,7 @@ +import type { AccountId } from "enssdk"; + import { DatasourceNames } from "@ensnode/datasources"; import { - type AccountId, type ENSNamespaceId, getDatasourceContract, makeContractMatcher, diff --git a/packages/ensnode-sdk/src/shared/protocol-acceleration/is-ensip-19-reverse-resolver.ts b/packages/ensnode-sdk/src/shared/protocol-acceleration/is-ensip-19-reverse-resolver.ts index 57b2718846..b2f34b529d 100644 --- a/packages/ensnode-sdk/src/shared/protocol-acceleration/is-ensip-19-reverse-resolver.ts +++ b/packages/ensnode-sdk/src/shared/protocol-acceleration/is-ensip-19-reverse-resolver.ts @@ -1,5 +1,7 @@ +import type { AccountId } from "enssdk"; + import { DatasourceNames } from "@ensnode/datasources"; -import { type AccountId, type ENSNamespaceId, makeContractMatcher } from "@ensnode/ensnode-sdk"; +import { type ENSNamespaceId, makeContractMatcher } from "@ensnode/ensnode-sdk"; /** * ENSIP-19 Reverse Resolvers (i.e. DefaultReverseResolver or ChainReverseResolver) simply: diff --git a/packages/ensnode-sdk/src/shared/protocol-acceleration/is-static-resolver.ts b/packages/ensnode-sdk/src/shared/protocol-acceleration/is-static-resolver.ts index ad8d57c578..4a143b86ee 100644 --- a/packages/ensnode-sdk/src/shared/protocol-acceleration/is-static-resolver.ts +++ b/packages/ensnode-sdk/src/shared/protocol-acceleration/is-static-resolver.ts @@ -1,5 +1,7 @@ +import type { AccountId } from "enssdk"; + import { DatasourceNames } from "@ensnode/datasources"; -import { type AccountId, type ENSNamespaceId, makeContractMatcher } from "@ensnode/ensnode-sdk"; +import { type ENSNamespaceId, makeContractMatcher } from "@ensnode/ensnode-sdk"; /** * Returns whether `resolver` is an Static Resolver. diff --git a/packages/ensnode-sdk/src/shared/root-registry.ts b/packages/ensnode-sdk/src/shared/root-registry.ts index ef566c3954..f8d49b931a 100644 --- a/packages/ensnode-sdk/src/shared/root-registry.ts +++ b/packages/ensnode-sdk/src/shared/root-registry.ts @@ -1,10 +1,9 @@ -import type { AccountId } from "enssdk"; +import { type AccountId, makeRegistryId } from "enssdk"; import { DatasourceNames, type ENSNamespaceId } from "@ensnode/datasources"; import { accountIdEqual, getDatasourceContract, - makeRegistryId, maybeGetDatasourceContract, } from "@ensnode/ensnode-sdk"; diff --git a/packages/ensnode-sdk/src/shared/types.ts b/packages/ensnode-sdk/src/shared/types.ts index d2740e5478..ea4e87184b 100644 --- a/packages/ensnode-sdk/src/shared/types.ts +++ b/packages/ensnode-sdk/src/shared/types.ts @@ -10,16 +10,9 @@ export type BlockNumber = number; */ export type Datetime = Date; -/** - * Unix timestamp value - * - * Represents the number of seconds that have elapsed - * since January 1, 1970 (midnight UTC/GMT). - * - * Guaranteed to be an integer. May be zero or negative to represent a time at or - * before Jan 1, 1970. - */ -export type UnixTimestamp = number; +import type { UnixTimestamp } from "enssdk"; + +export type { UnixTimestamp } from "enssdk"; /** * Represents a URL that is used for RPC endpoints. diff --git a/packages/ensnode-sdk/src/shared/zod-schemas.test.ts b/packages/ensnode-sdk/src/shared/zod-schemas.test.ts index 6ce854468d..5d1e5adec8 100644 --- a/packages/ensnode-sdk/src/shared/zod-schemas.test.ts +++ b/packages/ensnode-sdk/src/shared/zod-schemas.test.ts @@ -1,8 +1,7 @@ -import { labelhash } from "viem"; +import { asLiteralLabel, encodeLabelHash, labelhashLiteralLabel } from "enssdk"; import { describe, expect, it } from "vitest"; import { prettifyError, type ZodSafeParseResult } from "zod/v4"; -import { encodeLabelHash } from "../ens"; import { CurrencyIds, priceDai, priceEth, priceUsdc, type SerializedPrice } from "./currencies"; import { makeBooleanStringSchema, @@ -172,7 +171,7 @@ describe("ENSIndexer: Shared", () => { describe("ReinterpretedName", () => { const nameWithNormalizedLabels = "tko.basetest.eth"; const nameWithUnnormalizedLabels = "TKO.basetest.eth"; - const reinterpretedNameFromUnnormalizedLabels = `${encodeLabelHash(labelhash("TKO"))}.basetest.eth`; + const reinterpretedNameFromUnnormalizedLabels = `${encodeLabelHash(labelhashLiteralLabel(asLiteralLabel("TKO")))}.basetest.eth`; it("can reinterpret a name which includes normalized labels", () => { expect(makeReinterpretedNameSchema().parse(nameWithNormalizedLabels)).toBe( diff --git a/packages/ensnode-sdk/src/shared/zod-schemas.ts b/packages/ensnode-sdk/src/shared/zod-schemas.ts index 000227366d..974d549362 100644 --- a/packages/ensnode-sdk/src/shared/zod-schemas.ts +++ b/packages/ensnode-sdk/src/shared/zod-schemas.ts @@ -3,12 +3,15 @@ import { AccountId as CaipAccountId } from "caip"; import type { AccountId, AccountIdString, + Address, ChainId, DefaultableChainId, + Hex, InterpretedName, Node, } from "enssdk"; -import { type Address, type Hex, isAddress, isHex, size } from "viem"; +import { asLowerCaseAddress, reinterpretName } from "enssdk"; +import { isAddress, isHex, size } from "viem"; /** * All zod schemas we define must remain internal implementation details. * We want the freedom to move away from zod in the future without impacting @@ -20,7 +23,6 @@ import { type Address, type Hex, isAddress, isHex, size } from "viem"; import { z } from "zod/v4"; import { ENSNamespaceIds } from "../ens"; -import { asLowerCaseAddress } from "./address"; import { type CurrencyId, CurrencyIds, @@ -28,7 +30,6 @@ import { type PriceEth, type PriceUsdc, } from "./currencies"; -import { reinterpretName } from "./interpretation/reinterpretation"; import type { BlockRef, Datetime, Duration, UnixTimestamp } from "./types"; /** diff --git a/packages/ensnode-sdk/src/tokenscope/assets.ts b/packages/ensnode-sdk/src/tokenscope/assets.ts index de8d7201fc..27f6260142 100644 --- a/packages/ensnode-sdk/src/tokenscope/assets.ts +++ b/packages/ensnode-sdk/src/tokenscope/assets.ts @@ -1,3 +1,4 @@ +import type { Address, Hex } from "enssdk"; import { type AccountId, type AssetId, @@ -8,7 +9,7 @@ import { stringifyAssetId, type TokenId, } from "enssdk"; -import { type Address, type Hex, isAddressEqual, zeroAddress } from "viem"; +import { isAddressEqual, zeroAddress } from "viem"; import { prettifyError } from "zod/v4"; import { makeAssetIdSchema, makeAssetIdStringSchema } from "./zod-schemas"; diff --git a/packages/ensnode-sdk/src/tokenscope/name-token.test.ts b/packages/ensnode-sdk/src/tokenscope/name-token.test.ts index 63f8377616..f2ff556ae5 100644 --- a/packages/ensnode-sdk/src/tokenscope/name-token.test.ts +++ b/packages/ensnode-sdk/src/tokenscope/name-token.test.ts @@ -1,4 +1,4 @@ -import type { AccountId, InterpretedName } from "enssdk"; +import { type AccountId, asInterpretedName } from "enssdk"; import { zeroAddress } from "viem"; import { describe, expect, it } from "vitest"; @@ -39,9 +39,9 @@ describe("Name Token", () => { } as const; const names = { - TestEth: "test.eth" as InterpretedName, - TestBaseEth: "test.base.eth" as InterpretedName, - TestLineaEth: "test.linea.eth" as InterpretedName, + TestEth: asInterpretedName("test.eth"), + TestBaseEth: asInterpretedName("test.base.eth"), + TestLineaEth: asInterpretedName("test.linea.eth"), } as const; it("returns 'NameWrapper' ownership type when NameWrapper account owns the name token", () => { diff --git a/packages/ensnode-sdk/src/tokenscope/name-token.ts b/packages/ensnode-sdk/src/tokenscope/name-token.ts index 3820dae7d4..78de51b5b0 100644 --- a/packages/ensnode-sdk/src/tokenscope/name-token.ts +++ b/packages/ensnode-sdk/src/tokenscope/name-token.ts @@ -1,9 +1,9 @@ import type { AccountId, AssetId, InterpretedName } from "enssdk"; +import { getParentNameFQDN } from "enssdk"; import { isAddressEqual, zeroAddress } from "viem"; import { DatasourceNames, type ENSNamespaceId } from "@ensnode/datasources"; -import { getParentNameFQDN } from "../ens"; import { accountIdEqual } from "../shared/account-id"; import { getDatasourceContract, maybeGetDatasourceContract } from "../shared/datasource-contract"; import { type NFTMintStatus, type SerializedAssetId, serializeAssetId } from "./assets"; diff --git a/packages/ensrainbow-sdk/package.json b/packages/ensrainbow-sdk/package.json index f358be680e..75b779ca54 100644 --- a/packages/ensrainbow-sdk/package.json +++ b/packages/ensrainbow-sdk/package.json @@ -53,6 +53,9 @@ "peerDependencies": { "viem": "catalog:" }, + "dependencies": { + "enssdk": "workspace:*" + }, "devDependencies": { "@ensnode/shared-configs": "workspace:*", "@ensnode/ensnode-sdk": "workspace:*", diff --git a/packages/ensrainbow-sdk/src/client.ts b/packages/ensrainbow-sdk/src/client.ts index 5ef743801d..09bb88ee40 100644 --- a/packages/ensrainbow-sdk/src/client.ts +++ b/packages/ensrainbow-sdk/src/client.ts @@ -1,14 +1,13 @@ +import type { EncodedLabelHash, Label, LabelHash } from "enssdk"; +import { parseLabelHashOrEncodedLabelHash } from "enssdk"; + import { buildEnsRainbowClientLabelSet, type Cache, - type EncodedLabelHash, type EnsRainbowClientLabelSet, type EnsRainbowPublicConfig, type EnsRainbowServerLabelSet, - type Label, - type LabelHash, LruCache, - parseLabelHashOrEncodedLabelHash, } from "@ensnode/ensnode-sdk"; import { DEFAULT_ENSRAINBOW_URL, ErrorCode, StatusCode } from "./consts"; diff --git a/packages/enssdk/package.json b/packages/enssdk/package.json index 50177b32ae..f9171cb3b7 100644 --- a/packages/enssdk/package.json +++ b/packages/enssdk/package.json @@ -53,6 +53,7 @@ "generate:gqlschema": "gql.tada generate-output" }, "dependencies": { + "@adraffy/ens-normalize": "catalog:", "@ensdomains/address-encoder": "^1.1.2", "caip": "catalog:" }, diff --git a/packages/ensnode-sdk/src/shared/address.test.ts b/packages/enssdk/src/lib/address.test.ts similarity index 100% rename from packages/ensnode-sdk/src/shared/address.test.ts rename to packages/enssdk/src/lib/address.test.ts diff --git a/packages/ensnode-sdk/src/shared/address.ts b/packages/enssdk/src/lib/address.ts similarity index 87% rename from packages/ensnode-sdk/src/shared/address.ts rename to packages/enssdk/src/lib/address.ts index 165a854891..2c4e2b5ce8 100644 --- a/packages/ensnode-sdk/src/shared/address.ts +++ b/packages/enssdk/src/lib/address.ts @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "./types"; /** * Converts an EVM address to its lowercase representation. diff --git a/packages/ensnode-sdk/src/ens/coin-type.test.ts b/packages/enssdk/src/lib/coin-type.test.ts similarity index 100% rename from packages/ensnode-sdk/src/ens/coin-type.test.ts rename to packages/enssdk/src/lib/coin-type.test.ts diff --git a/packages/ensnode-sdk/src/ens/coin-type.ts b/packages/enssdk/src/lib/coin-type.ts similarity index 96% rename from packages/ensnode-sdk/src/ens/coin-type.ts rename to packages/enssdk/src/lib/coin-type.ts index deb1cf47a2..433a91063e 100644 --- a/packages/ensnode-sdk/src/ens/coin-type.ts +++ b/packages/enssdk/src/lib/coin-type.ts @@ -2,7 +2,8 @@ import { coinTypeToEvmChainId as _coinTypeToEvmChainId, evmChainIdToCoinType as _evmChainIdToCoinType, } from "@ensdomains/address-encoder/utils"; -import type { ChainId, CoinType, EvmCoinType } from "enssdk"; + +import type { ChainId, CoinType, EvmCoinType } from "./types"; /** * The ETH coinType. diff --git a/packages/enssdk/src/lib/constants.ts b/packages/enssdk/src/lib/constants.ts new file mode 100644 index 0000000000..595fa85255 --- /dev/null +++ b/packages/enssdk/src/lib/constants.ts @@ -0,0 +1,12 @@ +import { asInterpretedName } from "./interpreted-names-and-labels"; +import { namehashInterpretedName } from "./namehash"; +import type { Node } from "./types"; + +export const ROOT_NODE: Node = namehashInterpretedName(asInterpretedName("")); +export const ETH_NODE: Node = namehashInterpretedName(asInterpretedName("eth")); +export const ADDR_REVERSE_NODE: Node = namehashInterpretedName(asInterpretedName("addr.reverse")); + +/** + * ROOT_RESOURCE represents the 'root' resource in an EnhancedAccessControl contract. + */ +export const ROOT_RESOURCE = 0n; diff --git a/packages/ensnode-sdk/src/ens/dns-encoded-name.test.ts b/packages/enssdk/src/lib/dns-encoded-name.test.ts similarity index 86% rename from packages/ensnode-sdk/src/ens/dns-encoded-name.test.ts rename to packages/enssdk/src/lib/dns-encoded-name.test.ts index 5a4811c814..3448f0d61c 100644 --- a/packages/ensnode-sdk/src/ens/dns-encoded-name.test.ts +++ b/packages/enssdk/src/lib/dns-encoded-name.test.ts @@ -1,11 +1,11 @@ -import type { DNSEncodedName, LiteralLabel } from "enssdk"; import { bytesToHex, stringToHex } from "viem"; import { packetToBytes } from "viem/ens"; import { describe, expect, it } from "vitest"; -import { labelhashLiteralLabel } from "../shared/labelhash"; import { decodeDNSEncodedName } from "./dns-encoded-name"; -import { encodeLabelHash } from "./encode-labelhash"; +import { asLiteralLabel } from "./interpreted-names-and-labels"; +import { encodeLabelHash, labelhashLiteralLabel } from "./labelhash"; +import type { DNSEncodedName } from "./types"; const MULTI_BYTE_UNICODE_NAMES = ["👩🏼‍❤‍💋‍👨🏼.eth"]; @@ -51,9 +51,9 @@ describe("decodeDNSEncodedName", () => { }); it("correctly decodes encoded-labelhash-looking-strings", () => { - const literalLabelThatLooksLikeALabelHash = encodeLabelHash( - labelhashLiteralLabel("test" as LiteralLabel), - ) as LiteralLabel; + const literalLabelThatLooksLikeALabelHash = asLiteralLabel( + encodeLabelHash(labelhashLiteralLabel(asLiteralLabel("test"))), + ); expect( decodeDNSEncodedName(stringToHex(`\x42${literalLabelThatLooksLikeALabelHash}\x00`)), diff --git a/packages/ensnode-sdk/src/ens/dns-encoded-name.ts b/packages/enssdk/src/lib/dns-encoded-name.ts similarity index 95% rename from packages/ensnode-sdk/src/ens/dns-encoded-name.ts rename to packages/enssdk/src/lib/dns-encoded-name.ts index 9f93a0d5da..7a17142c20 100644 --- a/packages/ensnode-sdk/src/ens/dns-encoded-name.ts +++ b/packages/enssdk/src/lib/dns-encoded-name.ts @@ -1,6 +1,8 @@ -import type { DNSEncodedLiteralName, DNSEncodedName, LiteralLabel } from "enssdk"; import { bytesToString, hexToBytes } from "viem"; +import { asLiteralLabel } from "./interpreted-names-and-labels"; +import type { DNSEncodedLiteralName, DNSEncodedName, LiteralLabel } from "./types"; + /** * Decodes a DNS-Encoded name consisting of Literal Labels into an ordered list of Literal Labels. * @@ -15,7 +17,7 @@ import { bytesToString, hexToBytes } from "viem"; * @dev This is just `decodeDNSEncodedName` with semantic input/output */ export function decodeDNSEncodedLiteralName(packet: DNSEncodedLiteralName): LiteralLabel[] { - return decodeDNSEncodedName(packet) as LiteralLabel[]; + return decodeDNSEncodedName(packet).map(asLiteralLabel); } /** diff --git a/packages/enssdk/src/lib/index.ts b/packages/enssdk/src/lib/index.ts index bc7f9b56c2..10a039bace 100644 --- a/packages/enssdk/src/lib/index.ts +++ b/packages/enssdk/src/lib/index.ts @@ -1,4 +1,17 @@ +export * from "./address"; export * from "./caip"; +export * from "./coin-type"; +export * from "./constants"; +export * from "./dns-encoded-name"; export * from "./ids"; -export * from "./interpretation"; +export * from "./interpret-token-id"; +export * from "./interpreted-names-and-labels"; +export * from "./labelhash"; +export * from "./namehash"; +export * from "./names"; +export * from "./normalization"; +export * from "./parse-labelhash"; +export * from "./parse-reverse-name"; +export * from "./reinterpretation"; +export * from "./reverse-name"; export * from "./types"; diff --git a/packages/enssdk/src/lib/interpretation/token-id.ts b/packages/enssdk/src/lib/interpret-token-id.ts similarity index 60% rename from packages/enssdk/src/lib/interpretation/token-id.ts rename to packages/enssdk/src/lib/interpret-token-id.ts index 0ec37c066e..65bc8d5cc7 100644 --- a/packages/enssdk/src/lib/interpretation/token-id.ts +++ b/packages/enssdk/src/lib/interpret-token-id.ts @@ -1,15 +1,15 @@ -import { uint256ToHex32 } from "../../_lib/uint256ToHex32"; -import type { LabelHash, Node, TokenId } from "../types"; +import { uint256ToHex32 } from "../_lib/uint256ToHex32"; +import type { LabelHash, Node, TokenId } from "./types"; /** - * Decodes a uint256-encoded-LabelHash (eg. from a tokenId) into a {@link LabelHash}. + * Decodes a uint256-encoded-LabelHash (eg. from a {@link TokenId}) into a {@link LabelHash}. * * @see https://github.com/ensdomains/ens-contracts/blob/db613bc/contracts/ethregistrar/ETHRegistrarController.sol#L215 */ export const interpretTokenIdAsLabelHash = (tokenId: TokenId): LabelHash => uint256ToHex32(tokenId); /** - * Decodes a uint256-encoded-Node (eg. from a tokenId) into a {@link Node}. + * Decodes a uint256-encoded-Node (eg. from a {@link TokenId}) into a {@link Node}. * * @see https://github.com/ensdomains/ens-contracts/blob/db613bc/contracts/wrapper/ERC1155Fuse.sol#L262 */ diff --git a/packages/enssdk/src/lib/interpretation/index.ts b/packages/enssdk/src/lib/interpretation/index.ts deleted file mode 100644 index dafa9a3393..0000000000 --- a/packages/enssdk/src/lib/interpretation/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./token-id"; diff --git a/packages/ensnode-sdk/src/shared/interpretation/interpreted-names-and-labels.test.ts b/packages/enssdk/src/lib/interpreted-names-and-labels.test.ts similarity index 82% rename from packages/ensnode-sdk/src/shared/interpretation/interpreted-names-and-labels.test.ts rename to packages/enssdk/src/lib/interpreted-names-and-labels.test.ts index 24a4233087..31356601b5 100644 --- a/packages/ensnode-sdk/src/shared/interpretation/interpreted-names-and-labels.test.ts +++ b/packages/enssdk/src/lib/interpreted-names-and-labels.test.ts @@ -1,20 +1,16 @@ import { describe, expect, it } from "vitest"; import { - encodeLabelHash, - type InterpretedLabel, - type InterpretedName, - type LiteralLabel, - type Name, -} from "../../ens"; -import { labelhashLiteralLabel } from "../labelhash"; -import { + asInterpretedLabel, + asLiteralLabel, constructSubInterpretedName, interpretedLabelsToInterpretedName, literalLabelsToInterpretedName, literalLabelToInterpretedLabel, parsePartialInterpretedName, } from "./interpreted-names-and-labels"; +import { encodeLabelHash, labelhashLiteralLabel } from "./labelhash"; +import type { InterpretedLabel, InterpretedName, LiteralLabel, Name } from "./types"; const ENCODED_LABELHASH_LABEL = /^\[[\da-f]{64}\]$/; @@ -29,10 +25,9 @@ const NORMALIZED_LABELS = [ "café", "sub", "a".repeat(512), // Long normalized -] as LiteralLabel[]; +].map(asLiteralLabel); const UNNORMALIZED_LABELS = [ - "", // Empty string "Vitalik", // Uppercase "Example", // Uppercase "TEST", // Uppercase @@ -51,14 +46,14 @@ const UNNORMALIZED_LABELS = [ "test\u200B", // Zero-width space "test\u202E", // RTL override "A".repeat(300), // Long non-normalized -] as LiteralLabel[]; +].map(asLiteralLabel); const EXAMPLE_ENCODED_LABEL_HASH = encodeLabelHash( - labelhashLiteralLabel("example" as LiteralLabel), + labelhashLiteralLabel(asLiteralLabel("example")), ); describe("interpretation", () => { - describe("interpretLiteralLabel", () => { + describe("literalLabelToInterpretedLabel", () => { it("should return normalized labels unchanged", () => { NORMALIZED_LABELS.forEach((label) => expect(literalLabelToInterpretedLabel(label)).toBe(label), @@ -72,29 +67,26 @@ describe("interpretation", () => { }); }); - describe("interpretLiteralLabelsIntoInterpretedName", () => { + describe("literalLabelsToInterpretedName", () => { it("correctly interprets labels with period", () => { - expect(literalLabelsToInterpretedName(["a.b", "c"] as LiteralLabel[])).toEqual( - `${encodeLabelHash(labelhashLiteralLabel("a.b" as LiteralLabel))}.c`, + expect(literalLabelsToInterpretedName(["a.b", "c"].map(asLiteralLabel))).toEqual( + `${encodeLabelHash(labelhashLiteralLabel(asLiteralLabel("a.b")))}.c`, ); }); it("correctly interprets labels with NULL", () => { - expect(literalLabelsToInterpretedName(["\0", "c"] as LiteralLabel[])).toEqual( - `${encodeLabelHash(labelhashLiteralLabel("\0" as LiteralLabel))}.c`, + expect(literalLabelsToInterpretedName(["\0", "c"].map(asLiteralLabel))).toEqual( + `${encodeLabelHash(labelhashLiteralLabel(asLiteralLabel("\0")))}.c`, ); }); it("correctly interprets encoded-labelhash-looking-strings", () => { - const literalLabelThatLooksLikeALabelHash = encodeLabelHash( - labelhashLiteralLabel("test" as LiteralLabel), - ) as LiteralLabel; + const literalLabelThatLooksLikeALabelHash = asLiteralLabel( + encodeLabelHash(labelhashLiteralLabel(asLiteralLabel("test"))), + ); expect( - literalLabelsToInterpretedName([ - literalLabelThatLooksLikeALabelHash, - "c", - ] as LiteralLabel[]), + literalLabelsToInterpretedName([literalLabelThatLooksLikeALabelHash, asLiteralLabel("c")]), ).toEqual(`${encodeLabelHash(labelhashLiteralLabel(literalLabelThatLooksLikeALabelHash))}.c`); }); @@ -109,20 +101,17 @@ describe("interpretation", () => { }); it("correctly interprets a single label", () => { - expect(interpretedLabelsToInterpretedName(["a"] as InterpretedLabel[])).toEqual("a"); + expect(interpretedLabelsToInterpretedName(["a"].map(asInterpretedLabel))).toEqual("a"); }); it("correctly interprets a multiple labels, including encoded labelhashes", () => { - const literalLabel = "unnormalized.label" as LiteralLabel; + const literalLabel = asLiteralLabel("unnormalized.label"); const interpretedLabelThatLooksLikeALabelHash = literalLabelToInterpretedLabel(literalLabel); expect( - interpretedLabelsToInterpretedName([ - "a", - "b", - "c", - interpretedLabelThatLooksLikeALabelHash, - ] as InterpretedLabel[]), + interpretedLabelsToInterpretedName( + ["a", "b", "c", interpretedLabelThatLooksLikeALabelHash].map(asInterpretedLabel), + ), ).toEqual(`a.b.c.${interpretedLabelThatLooksLikeALabelHash}`); }); }); diff --git a/packages/ensnode-sdk/src/shared/interpretation/interpreted-names-and-labels.ts b/packages/enssdk/src/lib/interpreted-names-and-labels.ts similarity index 79% rename from packages/ensnode-sdk/src/shared/interpretation/interpreted-names-and-labels.ts rename to packages/enssdk/src/lib/interpreted-names-and-labels.ts index 3a154195b6..7cba074200 100644 --- a/packages/ensnode-sdk/src/shared/interpretation/interpreted-names-and-labels.ts +++ b/packages/enssdk/src/lib/interpreted-names-and-labels.ts @@ -1,3 +1,7 @@ +import { isHex } from "viem"; + +import { encodeLabelHash, labelhashInterpretedLabel, labelhashLiteralLabel } from "./labelhash"; +import { isNormalizedLabel } from "./normalization"; import type { InterpretedLabel, InterpretedName, @@ -7,12 +11,7 @@ import type { LiteralLabel, LiteralName, Name, -} from "enssdk"; -import { isHex } from "viem"; -import { labelhash } from "viem/ens"; - -import { encodeLabelHash, isNormalizedLabel } from "../../ens"; -import { labelhashLiteralLabel } from "../labelhash"; +} from "./types"; /** * Interprets a Literal Label, producing an Interpreted Label. @@ -100,7 +99,15 @@ export function isInterpetedLabel(label: Label): label is InterpretedLabel { return isNormalizedLabel(label); } +/** + * Determines whether `name` is an {@link InterpretedName}. + * The root name ("") is a valid InterpretedName. + * + * @param name + * @returns + */ export function isInterpretedName(name: Name): name is InterpretedName { + if (name === "") return true; return name.split(".").every(isInterpetedLabel); } @@ -121,7 +128,7 @@ export function interpretedLabelsToLabelHashPath(labels: InterpretedLabel[]): La if (maybeLabelHash !== null) return maybeLabelHash; // otherwise, labelhash it - return labelhash(label); + return labelhashInterpretedLabel(label); }) .toReversed(); } @@ -174,3 +181,43 @@ export function parsePartialInterpretedName(partialInterpretedName: Name): { return { concrete, partial }; } + +/** + * Validates and casts a string to an {@link InterpretedLabel}. + * An InterpretedLabel is either a normalized label or an EncodedLabelHash. + * + * @throws if the input is not a valid InterpretedLabel + */ +export function asInterpretedLabel(label: string): InterpretedLabel { + if (!isInterpetedLabel(label as Label)) { + throw new Error(`Not a valid InterpretedLabel: '${label}'`); + } + + return label as InterpretedLabel; +} + +/** + * Validates and casts a string to an {@link InterpretedName}. + * An InterpretedName is composed entirely of InterpretedLabels joined by dots. + * + * @throws if the input is not a valid InterpretedName + */ +export function asInterpretedName(name: string): InterpretedName { + if (!isInterpretedName(name as Name)) { + throw new Error(`Not a valid InterpretedName: '${name}'`); + } + + return name as InterpretedName; +} + +/** + * Validates and casts a string to a {@link LiteralLabel}. + * A LiteralLabel is a label as it literally appears onchain. + * + * @throws if the input is empty + */ +export function asLiteralLabel(label: string): LiteralLabel { + if (label === "") throw new Error("LiteralLabel must not be empty"); + + return label as LiteralLabel; +} diff --git a/packages/ensnode-sdk/src/ens/labelhash.test.ts b/packages/enssdk/src/lib/labelhash.test.ts similarity index 64% rename from packages/ensnode-sdk/src/ens/labelhash.test.ts rename to packages/enssdk/src/lib/labelhash.test.ts index c09aa88a01..9067e49748 100644 --- a/packages/ensnode-sdk/src/ens/labelhash.test.ts +++ b/packages/enssdk/src/lib/labelhash.test.ts @@ -1,6 +1,9 @@ +import { keccak256, labelhash, stringToBytes } from "viem"; import { describe, expect, it } from "vitest"; -import { isLabelHash } from "./labelhash"; +import { asLiteralLabel } from "./interpreted-names-and-labels"; +import { encodeLabelHash, isLabelHash, labelhashLiteralLabel } from "./labelhash"; +import type { LiteralLabel } from "./types"; describe("isLabelHash", () => { // Test case: valid labelHash @@ -41,3 +44,20 @@ describe("isLabelHash", () => { expect(isLabelHash(hash67)).toBe(false); }); }); + +describe("labelhashLiteralLabel", () => { + it("labelhashes empty string correctly", () => { + expect(labelhashLiteralLabel("" as LiteralLabel)).toEqual(keccak256(stringToBytes(""))); + }); + + it("labelhashes literal label correctly", () => { + expect(labelhashLiteralLabel(asLiteralLabel("example"))).toEqual(labelhash("example")); + }); + + it("labelhashes encoded-labelhash-looking-strings as literal labels", () => { + const encodedLabelHashLookingLabel = asLiteralLabel(encodeLabelHash(labelhash("whatever"))); + expect(labelhashLiteralLabel(encodedLabelHashLookingLabel)).not.toEqual( + labelhash(encodedLabelHashLookingLabel), + ); + }); +}); diff --git a/packages/enssdk/src/lib/labelhash.ts b/packages/enssdk/src/lib/labelhash.ts new file mode 100644 index 0000000000..1875f9ead3 --- /dev/null +++ b/packages/enssdk/src/lib/labelhash.ts @@ -0,0 +1,62 @@ +import { isHex, keccak256, stringToBytes } from "viem"; +import { labelhash as viemLabelhash } from "viem/ens"; + +import type { EncodedLabelHash, InterpretedLabel, LabelHash, LiteralLabel } from "./types"; + +/** + * Typed wrapper around viem's `labelhash` that returns a branded {@link LabelHash}, + * requiring an {@link InterpretedLabel} input. + * + * Note: viem's labelhash has special-case handling for Encoded LabelHashes (e.g. `[hash]`). + * Use {@link labelhashLiteralLabel} if you need to hash a label's literal bytes without + * encoded labelhash detection. + * + * @see https://docs.ens.domains/ensip/1 + */ +export const labelhashInterpretedLabel = (label: InterpretedLabel): LabelHash => + viemLabelhash(label); + +/** + * Implements the ENS `labelhash` function for Literal Labels. + * @see https://docs.ens.domains/ensip/1 + * + * @param label the Literal Label to hash + * @returns the hash of the provided label + * @dev This function is viem/ens#labelhash but without the special-case handling of Encoded LabelHashes. + */ +export const labelhashLiteralLabel = (label: LiteralLabel): LabelHash => + keccak256(stringToBytes(label)); + +/** + * Checks if the input is a {@link LabelHash}. + * + * @see https://ensnode.io/docs/reference/terminology#label-processing-and-classification + */ +export function isLabelHash(maybeLabelHash: string): maybeLabelHash is LabelHash { + const expectedLength = maybeLabelHash.length === 66; + const expectedEncoding = isHex(maybeLabelHash); + const expectedCasing = maybeLabelHash === maybeLabelHash.toLowerCase(); + + return expectedLength && expectedEncoding && expectedCasing; +} + +/** + * Formats a LabelHash as an Encoded LabelHash. + * + * @see https://ensnode.io/docs/reference/terminology#encoded-labelhash + * + * @param labelHash - A 32-byte lowercase hash string starting with '0x' + * @returns The encoded label hash in format `[hash_without_0x_prefix]` + */ +export const encodeLabelHash = (labelHash: LabelHash): EncodedLabelHash => + `[${labelHash.slice(2)}]`; + +/** + * Checks if the value is an {@link EncodedLabelHash}. + */ +export function isEncodedLabelHash(value: string): value is EncodedLabelHash { + const expectedFormatting = value.startsWith("[") && value.endsWith("]"); + const includesLabelHash = isLabelHash(`0x${value.slice(1, -1)}`); + + return expectedFormatting && includesLabelHash; +} diff --git a/packages/enssdk/src/lib/namehash.test.ts b/packages/enssdk/src/lib/namehash.test.ts new file mode 100644 index 0000000000..488341bc52 --- /dev/null +++ b/packages/enssdk/src/lib/namehash.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from "vitest"; + +import { asInterpretedLabel, asInterpretedName } from "./interpreted-names-and-labels"; +import { labelhashInterpretedLabel } from "./labelhash"; +import { makeSubdomainNode, namehashInterpretedName } from "./namehash"; + +describe("makeSubdomainNode", () => { + it("should return the correct namehash for a subnode", () => { + expect( + makeSubdomainNode( + labelhashInterpretedLabel(asInterpretedLabel("test🚀")), + namehashInterpretedName(asInterpretedName("base.eth")), + ), + ).toBe(namehashInterpretedName(asInterpretedName("test🚀.base.eth"))); + }); +}); diff --git a/packages/enssdk/src/lib/namehash.ts b/packages/enssdk/src/lib/namehash.ts new file mode 100644 index 0000000000..f6d7df2e24 --- /dev/null +++ b/packages/enssdk/src/lib/namehash.ts @@ -0,0 +1,19 @@ +import { concat, keccak256, namehash as viemNamehash } from "viem"; + +import type { InterpretedName, LabelHash, Node } from "./types"; + +/** + * Typed wrapper around viem's `namehash` that returns a branded {@link Node}, + * requiring an {@link InterpretedName} input and correctly parsing EncodedLabelHashes. + * + * @see https://docs.ens.domains/ensip/1 + */ +export const namehashInterpretedName = (name: InterpretedName): Node => viemNamehash(name); + +/** + * Implements one step of the namehash algorithm, combining `labelHash` with `node` to produce + * the `node` of a given subdomain. Note that the order of the arguments is 'reversed' (as compared to + * the actual concatenation) in order to improve readability (i.e. read as [labelHash].[node]). + */ +export const makeSubdomainNode = (labelHash: LabelHash, node: Node): Node => + keccak256(concat([node, labelHash])); diff --git a/packages/ensnode-sdk/src/ens/names.test.ts b/packages/enssdk/src/lib/names.test.ts similarity index 79% rename from packages/ensnode-sdk/src/ens/names.test.ts rename to packages/enssdk/src/lib/names.test.ts index 7154f47393..d1ae240289 100644 --- a/packages/ensnode-sdk/src/ens/names.test.ts +++ b/packages/enssdk/src/lib/names.test.ts @@ -1,7 +1,8 @@ -import type { Name, NormalizedName } from "enssdk"; import { describe, expect, it } from "vitest"; +import { asInterpretedName } from "./interpreted-names-and-labels"; import { beautifyName, ENS_ROOT, getNameHierarchy, getParentNameFQDN } from "./names"; +import type { Name, NormalizedName } from "./types"; describe("names", () => { describe("getNameHierarchy", () => { @@ -38,15 +39,15 @@ describe("names", () => { }); it("returns ENS Root for top-level name", () => { - expect(getParentNameFQDN("eth")).toStrictEqual(ENS_ROOT); + expect(getParentNameFQDN(asInterpretedName("eth"))).toStrictEqual(ENS_ROOT); }); it("returns FQDN for 2nd-level name", () => { - expect(getParentNameFQDN("base.eth")).toStrictEqual("eth"); + expect(getParentNameFQDN(asInterpretedName("base.eth"))).toStrictEqual("eth"); }); it("returns FQDN for 3rd-level name", () => { - expect(getParentNameFQDN("test.base.eth")).toStrictEqual("base.eth"); + expect(getParentNameFQDN(asInterpretedName("test.base.eth"))).toStrictEqual("base.eth"); }); }); @@ -58,8 +59,8 @@ describe("names", () => { }); it("should beautify normalized labels", () => { - const name = "1⃣2⃣.eth" as NormalizedName; - const expected = "1️⃣2️⃣.eth"; + const name = "1\u20E32\u20E3.eth" as NormalizedName; + const expected = "1\uFE0F\u20E32\uFE0F\u20E3.eth"; expect(beautifyName(name)).toEqual(expected); }); @@ -70,8 +71,8 @@ describe("names", () => { }); it("should selectively beautify labels where possible", () => { - const name = "1⃣2⃣.ABC.eth" as Name; - const expected = "1️⃣2️⃣.ABC.eth"; + const name = "1\u20E32\u20E3.ABC.eth" as Name; + const expected = "1\uFE0F\u20E32\uFE0F\u20E3.ABC.eth"; expect(beautifyName(name)).toEqual(expected); }); diff --git a/packages/ensnode-sdk/src/ens/names.ts b/packages/enssdk/src/lib/names.ts similarity index 71% rename from packages/ensnode-sdk/src/ens/names.ts rename to packages/enssdk/src/lib/names.ts index cc4fac8dba..6abe458650 100644 --- a/packages/ensnode-sdk/src/ens/names.ts +++ b/packages/enssdk/src/lib/names.ts @@ -1,12 +1,17 @@ import { ens_beautify } from "@adraffy/ens-normalize"; -import type { Label, Name, NormalizedName } from "enssdk"; -import { isNormalizedLabel } from "./is-normalized"; +import { + asInterpretedName, + interpretedLabelsToInterpretedName, + interpretedNameToInterpretedLabels, +} from "./interpreted-names-and-labels"; +import { isNormalizedLabel } from "./normalization"; +import type { InterpretedName, Label, Name, NormalizedName } from "./types"; /** * Name for the ENS Root */ -export const ENS_ROOT: Name = ""; +export const ENS_ROOT = asInterpretedName(""); /** * Constructs a name hierarchy from a given NormalizedName. @@ -25,21 +30,17 @@ export const getNameHierarchy = (name: NormalizedName): NormalizedName[] => /** * Get FQDN of parent for a name. */ -export const getParentNameFQDN = (name: Name): Name => { +export const getParentNameFQDN = (name: InterpretedName): InterpretedName => { // Invariant: name is not ENS root. - if (name === ENS_ROOT) { - throw new Error("There is no parent name for ENS Root."); - } + if (name === ENS_ROOT) throw new Error("There is no parent name for ENS Root."); - const labels = name.split("."); + const labels = interpretedNameToInterpretedLabels(name); // For TLDs, return ENS_ROOT - if (labels.length === 1) { - return ENS_ROOT; - } + if (labels.length === 1) return ENS_ROOT; // Strip off the child-most label in the name to get the FQDN of the parent - return labels.slice(1).join("."); + return interpretedLabelsToInterpretedName(labels.slice(1)); }; /** @@ -66,13 +67,14 @@ export const getParentNameFQDN = (name: Name): Name => { * @param name - The name to beautify. * @returns The beautified name. */ -export const beautifyName = (name: Name): Name => { - const beautifiedLabels = name.split(".").map((label: Label) => { - if (isNormalizedLabel(label)) { - return ens_beautify(label); - } else { - return label; - } - }); - return beautifiedLabels.join("."); -}; +export const beautifyName = (name: Name): Name => + name + .split(".") + .map((label: Label) => { + if (isNormalizedLabel(label)) { + return ens_beautify(label); + } else { + return label; + } + }) + .join("."); diff --git a/packages/ensnode-sdk/src/ens/is-normalized.test.ts b/packages/enssdk/src/lib/normalization.test.ts similarity index 95% rename from packages/ensnode-sdk/src/ens/is-normalized.test.ts rename to packages/enssdk/src/lib/normalization.test.ts index 1256420384..7d5b48d76f 100644 --- a/packages/ensnode-sdk/src/ens/is-normalized.test.ts +++ b/packages/enssdk/src/lib/normalization.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import { isNormalizedLabel, isNormalizedName } from "./is-normalized"; +import { isNormalizedLabel, isNormalizedName } from "./normalization"; const NORMALIZED_LABELS = [ "vitalik", @@ -52,7 +52,7 @@ const UNNORMALIZED_NAMES = [ "invalid|name.eth", // unnormalizable ]; -describe("is-normalized", () => { +describe("normalization", () => { describe("isNormalizedLabel", () => { NORMALIZED_LABELS.forEach((label) => { it(`correctly identifies '${label}' as normalized`, () => { diff --git a/packages/enssdk/src/lib/normalization.ts b/packages/enssdk/src/lib/normalization.ts new file mode 100644 index 0000000000..8130b599ac --- /dev/null +++ b/packages/enssdk/src/lib/normalization.ts @@ -0,0 +1,53 @@ +import { ens_normalize } from "@adraffy/ens-normalize"; + +import type { InterpretedLabel, InterpretedName, Label, Name, NormalizedName } from "./types"; + +/** + * Normalizes a Name according to ENS normalization rules (ENSIP-15), returning an InterpretedName. + * + * @throws if the Name is not normalizable + * @see https://docs.ens.domains/ensip/15 + */ +export const normalizeName = (name: Name): InterpretedName => + ens_normalize(name) as InterpretedName; + +/** + * Normalizes a Label according to ENS normalization rules (ENSIP-15), returning an InterpretedLabel. + * + * @throws if the Label is not normalizable + * @see https://docs.ens.domains/ensip/15 + */ +export const normalizeLabel = (label: Label): InterpretedLabel => { + // empty string cannot be a label + if (label === "") throw new Error("Empty string is not a valid Label."); + + // normalized labels do not contain periods + if (label.includes(".")) { + throw new Error(`Label '${label}' includes '.' and cannot be normalized.`); + } + + // NOTE: the ens_normalize function accepts _names_ not labels, and so we must include our own + // invariants above to ensure that the `label` input here can be safely normalized + return ens_normalize(label) as InterpretedLabel; +}; + +/** + * Determines whether the Name is normalized according to ENSIP-15 normalization rules. + */ +export function isNormalizedName(name: Name): name is NormalizedName { + try { + return name === normalizeName(name); + } catch { + return false; + } +} +/** + * Determines whether the Label is normalized according to ENSIP-15 normalization rules. + */ +export function isNormalizedLabel(label: Label): boolean { + try { + return label === normalizeLabel(label); + } catch { + return false; + } +} diff --git a/packages/ensnode-sdk/src/ens/parse-labelhash.test.ts b/packages/enssdk/src/lib/parse-labelhash.test.ts similarity index 100% rename from packages/ensnode-sdk/src/ens/parse-labelhash.test.ts rename to packages/enssdk/src/lib/parse-labelhash.test.ts diff --git a/packages/ensnode-sdk/src/ens/parse-labelhash.ts b/packages/enssdk/src/lib/parse-labelhash.ts similarity index 98% rename from packages/ensnode-sdk/src/ens/parse-labelhash.ts rename to packages/enssdk/src/lib/parse-labelhash.ts index 234cf2236c..98ae231c7b 100644 --- a/packages/ensnode-sdk/src/ens/parse-labelhash.ts +++ b/packages/enssdk/src/lib/parse-labelhash.ts @@ -1,6 +1,7 @@ -import type { LabelHash } from "enssdk"; import { isHex } from "viem"; +import type { LabelHash } from "./types"; + /** * Parses a labelHash string and normalizes it to a canonical `LabelHash`. * diff --git a/packages/ensnode-sdk/src/ens/parse-reverse-name.test.ts b/packages/enssdk/src/lib/parse-reverse-name.test.ts similarity index 100% rename from packages/ensnode-sdk/src/ens/parse-reverse-name.test.ts rename to packages/enssdk/src/lib/parse-reverse-name.test.ts diff --git a/packages/ensnode-sdk/src/ens/parse-reverse-name.ts b/packages/enssdk/src/lib/parse-reverse-name.ts similarity index 91% rename from packages/ensnode-sdk/src/ens/parse-reverse-name.ts rename to packages/enssdk/src/lib/parse-reverse-name.ts index fdca3f675c..b49423e4ac 100644 --- a/packages/ensnode-sdk/src/ens/parse-reverse-name.ts +++ b/packages/enssdk/src/lib/parse-reverse-name.ts @@ -1,8 +1,8 @@ -import type { CoinType, Label, Name } from "enssdk"; -import { type Address, hexToBigInt, isAddress } from "viem"; +import { hexToBigInt, isAddress } from "viem"; -import { asLowerCaseAddress } from "../shared/address"; +import { asLowerCaseAddress } from "./address"; import { bigintToCoinType, DEFAULT_EVM_COIN_TYPE, ETH_COIN_TYPE } from "./coin-type"; +import type { Address, CoinType, Label, Name } from "./types"; /** * Matches an ENSIP-19 Reverse Name diff --git a/packages/ensnode-sdk/src/shared/interpretation/reinterpretation.test.ts b/packages/enssdk/src/lib/reinterpretation.test.ts similarity index 50% rename from packages/ensnode-sdk/src/shared/interpretation/reinterpretation.test.ts rename to packages/enssdk/src/lib/reinterpretation.test.ts index f2964a5771..00b7883e63 100644 --- a/packages/ensnode-sdk/src/shared/interpretation/reinterpretation.test.ts +++ b/packages/enssdk/src/lib/reinterpretation.test.ts @@ -1,25 +1,30 @@ import { describe, expect, it } from "vitest"; -import type { InterpretedLabel } from "../../ens"; +import { asInterpretedLabel } from "./interpreted-names-and-labels"; +import { encodeLabelHash, labelhashLiteralLabel } from "./labelhash"; import { reinterpretLabel } from "./reinterpretation"; +import type { InterpretedLabel, LiteralLabel } from "./types"; + +const UNNORMALIZED_LABEL = "Eth"; +const NORMALIZED_LABEL = asInterpretedLabel("eth"); describe("Reinterpretation", () => { describe("reinterpretLabel()", () => { - const unnormalizedLabel = "Eth"; - const normalizedLabel = "eth" as InterpretedLabel; - const encodedLabelHash = - "[4c10068c4e8f0b2905447ed0a679a3934513092c8a965b7a3d1ea67ea1cd0698]" as InterpretedLabel; + const encodedLabelHash = asInterpretedLabel( + encodeLabelHash(labelhashLiteralLabel(UNNORMALIZED_LABEL as LiteralLabel)), + ); it("can reinterpret EncodedLabelHash", () => { expect(reinterpretLabel(encodedLabelHash)).toBe(encodedLabelHash); }); it("can reinterpret NormalizedLabel", () => { - expect(reinterpretLabel(normalizedLabel)).toBe(normalizedLabel); + expect(reinterpretLabel(NORMALIZED_LABEL)).toBe(NORMALIZED_LABEL); }); it("can reinterpret UnnormalizedLabel", () => { - expect(reinterpretLabel(unnormalizedLabel as InterpretedLabel)).toBe(encodedLabelHash); + // directly cast the unnormalized label to avoid asInterpretedLabel validity checks + expect(reinterpretLabel(UNNORMALIZED_LABEL as InterpretedLabel)).toBe(encodedLabelHash); }); it("refuses to reinterpret an empty Label", () => { diff --git a/packages/ensnode-sdk/src/shared/interpretation/reinterpretation.ts b/packages/enssdk/src/lib/reinterpretation.ts similarity index 73% rename from packages/ensnode-sdk/src/shared/interpretation/reinterpretation.ts rename to packages/enssdk/src/lib/reinterpretation.ts index 979c2b3b85..b64eb30bca 100644 --- a/packages/ensnode-sdk/src/shared/interpretation/reinterpretation.ts +++ b/packages/enssdk/src/lib/reinterpretation.ts @@ -1,7 +1,12 @@ -import type { InterpretedLabel, InterpretedName } from "enssdk"; -import { labelhash as labelToLabelHash } from "viem"; - -import { encodeLabelHash, isEncodedLabelHash, isNormalizedLabel } from "../../ens"; +import { + asInterpretedLabel, + asLiteralLabel, + interpretedLabelsToInterpretedName, + interpretedNameToInterpretedLabels, +} from "./interpreted-names-and-labels"; +import { encodeLabelHash, isEncodedLabelHash, labelhashLiteralLabel } from "./labelhash"; +import { isNormalizedLabel } from "./normalization"; +import type { InterpretedLabel, InterpretedName } from "./types"; /** * Reinterpret Label @@ -33,9 +38,9 @@ export function reinterpretLabel(label: InterpretedLabel): InterpretedLabel { // no change required for NormalizedLabel if (isNormalizedLabel(label)) return label; - // the provided `label` is unnormalized, - // turn into an EncodedLabelHash - return encodeLabelHash(labelToLabelHash(label)) as InterpretedLabel; + // the provided `label` is an unnormalized literal label, encode it + const labelHash = labelhashLiteralLabel(asLiteralLabel(label as string)); + return asInterpretedLabel(encodeLabelHash(labelHash)); } /** @@ -53,9 +58,6 @@ export function reinterpretLabel(label: InterpretedLabel): InterpretedLabel { export function reinterpretName(name: InterpretedName): InterpretedName { if (name === "") return name; - const interpretedLabels = name.split(".") as InterpretedLabel[]; - const reinterpretedLabels = interpretedLabels.map(reinterpretLabel); - const reinterpretedName = reinterpretedLabels.join(".") as InterpretedName; - - return reinterpretedName; + const labels = interpretedNameToInterpretedLabels(name); + return interpretedLabelsToInterpretedName(labels.map(reinterpretLabel)); } diff --git a/packages/ensnode-sdk/src/ens/reverse-name.ts b/packages/enssdk/src/lib/reverse-name.ts similarity index 88% rename from packages/ensnode-sdk/src/ens/reverse-name.ts rename to packages/enssdk/src/lib/reverse-name.ts index 9a6c305a5c..4f849f6090 100644 --- a/packages/ensnode-sdk/src/ens/reverse-name.ts +++ b/packages/enssdk/src/lib/reverse-name.ts @@ -1,7 +1,8 @@ -import type { CoinType, Label, LiteralLabel, Name } from "enssdk"; import type { Address } from "viem"; import { DEFAULT_EVM_COIN_TYPE, ETH_COIN_TYPE } from "./coin-type"; +import { asLiteralLabel } from "./interpreted-names-and-labels"; +import type { CoinType, Label, LiteralLabel, Name } from "./types"; /** * Gets the Label used for the reverse names of subnames as per ENSIP-11 & ENSIP-19. @@ -9,7 +10,7 @@ import { DEFAULT_EVM_COIN_TYPE, ETH_COIN_TYPE } from "./coin-type"; * @see https://docs.ens.domains/ensip/19/#reverse-resolution */ export const addrReverseLabel = (address: Address): LiteralLabel => - address.slice(2) as LiteralLabel; // address is guaranteed to be fully lowercase + asLiteralLabel(address.slice(2)); // address is guaranteed to be fully lowercase /** * Converts `coinType` to prefix-free hex string. diff --git a/packages/enssdk/src/lib/types/evm.ts b/packages/enssdk/src/lib/types/evm.ts index 562635904a..16d2c8805c 100644 --- a/packages/enssdk/src/lib/types/evm.ts +++ b/packages/enssdk/src/lib/types/evm.ts @@ -1,4 +1,8 @@ -import type { Address } from "viem"; +import type { Address as ViemAddress, Hex as ViemHex } from "viem"; + +// re-export viem Address/Hex for consistency +export type Hex = ViemHex; +export type Address = ViemAddress; /** * Chain ID @@ -44,6 +48,17 @@ export const AssetNamespaces = { export type AssetNamespace = (typeof AssetNamespaces)[keyof typeof AssetNamespaces]; +/** + * Unix timestamp value + * + * Represents the number of seconds that have elapsed + * since January 1, 1970 (midnight UTC/GMT). + * + * Guaranteed to be an integer. May be zero or negative to represent a time at or + * before Jan 1, 1970. + */ +export type UnixTimestamp = number; + /** * A uint256 value that identifies a specific NFT within a NFT contract. */ diff --git a/packages/namehash-ui/package.json b/packages/namehash-ui/package.json index 65362169e0..810cc5375e 100644 --- a/packages/namehash-ui/package.json +++ b/packages/namehash-ui/package.json @@ -80,6 +80,7 @@ "dependencies": { "@ensnode/datasources": "workspace:*", "@ensnode/ensnode-sdk": "workspace:*", + "enssdk": "workspace:*", "@radix-ui/react-avatar": "^1.1.10", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tooltip": "^1.2.8", diff --git a/packages/namehash-ui/src/components/chains/ChainIcon.tsx b/packages/namehash-ui/src/components/chains/ChainIcon.tsx index 97e5fb307b..ccbd159408 100644 --- a/packages/namehash-ui/src/components/chains/ChainIcon.tsx +++ b/packages/namehash-ui/src/components/chains/ChainIcon.tsx @@ -1,3 +1,4 @@ +import type { ChainId } from "enssdk"; import { arbitrum, arbitrumSepolia, @@ -14,7 +15,6 @@ import { } from "viem/chains"; import { ensTestEnvChain } from "@ensnode/datasources"; -import type { ChainId } from "@ensnode/ensnode-sdk"; import { ArbitrumIcon } from "./icons/ArbitrumIcon"; import { ArbitrumTestnetIcon } from "./icons/ArbitrumTestnetIcon"; diff --git a/packages/namehash-ui/src/components/chains/ChainName.tsx b/packages/namehash-ui/src/components/chains/ChainName.tsx index 78f3364418..27f060e0bf 100644 --- a/packages/namehash-ui/src/components/chains/ChainName.tsx +++ b/packages/namehash-ui/src/components/chains/ChainName.tsx @@ -1,4 +1,4 @@ -import type { ChainId } from "@ensnode/ensnode-sdk"; +import type { ChainId } from "enssdk"; import { getChainName } from "../../utils/chains"; diff --git a/packages/namehash-ui/src/components/datetime/AbsoluteTime.tsx b/packages/namehash-ui/src/components/datetime/AbsoluteTime.tsx index 4a568ecd2d..bf9b344210 100644 --- a/packages/namehash-ui/src/components/datetime/AbsoluteTime.tsx +++ b/packages/namehash-ui/src/components/datetime/AbsoluteTime.tsx @@ -1,8 +1,7 @@ import { fromUnixTime, intlFormat } from "date-fns"; +import type { UnixTimestamp } from "enssdk"; import { useEffect, useState } from "react"; -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; - /** * Client-only absolute time component */ diff --git a/packages/namehash-ui/src/components/datetime/RelativeTime.tsx b/packages/namehash-ui/src/components/datetime/RelativeTime.tsx index 32d3c32cb8..0f550e726e 100644 --- a/packages/namehash-ui/src/components/datetime/RelativeTime.tsx +++ b/packages/namehash-ui/src/components/datetime/RelativeTime.tsx @@ -1,10 +1,9 @@ import { formatDistance, formatDistanceStrict, fromUnixTime } from "date-fns"; import { millisecondsInSecond } from "date-fns/constants"; +import type { UnixTimestamp } from "enssdk"; import type * as React from "react"; import { useEffect, useState } from "react"; -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; - import { cn } from "../../utils/cn"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; import { AbsoluteTime } from "./AbsoluteTime"; diff --git a/packages/namehash-ui/src/components/identity/Address.tsx b/packages/namehash-ui/src/components/identity/Address.tsx index 47cefc2dce..6a42beb204 100644 --- a/packages/namehash-ui/src/components/identity/Address.tsx +++ b/packages/namehash-ui/src/components/identity/Address.tsx @@ -1,4 +1,4 @@ -import type { Address } from "viem"; +import type { Address } from "enssdk"; import { getAddress } from "viem"; interface AddressDisplayProps { diff --git a/packages/namehash-ui/src/components/identity/EnsAvatar.tsx b/packages/namehash-ui/src/components/identity/EnsAvatar.tsx index a474c9551e..93963228b5 100644 --- a/packages/namehash-ui/src/components/identity/EnsAvatar.tsx +++ b/packages/namehash-ui/src/components/identity/EnsAvatar.tsx @@ -1,8 +1,8 @@ import BoringAvatar from "boring-avatars"; +import type { Name } from "enssdk"; import * as React from "react"; import type { ENSNamespaceId } from "@ensnode/datasources"; -import type { Name } from "@ensnode/ensnode-sdk"; import { cn } from "../../utils/cn"; import { getEnsMetadataServiceAvatarUrl } from "../../utils/ensMetadata"; diff --git a/packages/namehash-ui/src/components/identity/Identity.tsx b/packages/namehash-ui/src/components/identity/Identity.tsx index 1c6afb894e..4ad86b8b92 100644 --- a/packages/namehash-ui/src/components/identity/Identity.tsx +++ b/packages/namehash-ui/src/components/identity/Identity.tsx @@ -1,9 +1,9 @@ +import { DEFAULT_EVM_CHAIN_ID } from "enssdk"; import { CheckIcon, CopyIcon } from "lucide-react"; import type { PropsWithChildren } from "react"; import type { ENSNamespaceId, Identity } from "@ensnode/ensnode-sdk"; import { - DEFAULT_EVM_CHAIN_ID, isResolvedIdentity, ResolutionStatusIds, translateDefaultableChainIdToChainId, diff --git a/packages/namehash-ui/src/components/identity/Name.tsx b/packages/namehash-ui/src/components/identity/Name.tsx index 69e5e55c97..a4bec4f1a0 100644 --- a/packages/namehash-ui/src/components/identity/Name.tsx +++ b/packages/namehash-ui/src/components/identity/Name.tsx @@ -1,5 +1,5 @@ -import type { Name } from "@ensnode/ensnode-sdk"; -import { beautifyName } from "@ensnode/ensnode-sdk"; +import type { Name } from "enssdk"; +import { beautifyName } from "enssdk"; interface NameDisplayProps { name: Name; diff --git a/packages/namehash-ui/src/components/registrar-actions/RegistrarActionCard.tsx b/packages/namehash-ui/src/components/registrar-actions/RegistrarActionCard.tsx index 0e9f2eeb7d..e4b4315f13 100644 --- a/packages/namehash-ui/src/components/registrar-actions/RegistrarActionCard.tsx +++ b/packages/namehash-ui/src/components/registrar-actions/RegistrarActionCard.tsx @@ -1,9 +1,9 @@ +import type { Address, DefaultableChainId } from "enssdk"; import { Info as InfoIcon, CircleQuestionMark as QuestionmarkIcon } from "lucide-react"; import { memo, type PropsWithChildren, type ReactNode } from "react"; -import { type Address, zeroAddress } from "viem"; +import { zeroAddress } from "viem"; import type { - DefaultableChainId, ENSNamespaceId, NamedRegistrarAction, RegistrarActionReferral, diff --git a/packages/namehash-ui/src/hooks/useNow.ts b/packages/namehash-ui/src/hooks/useNow.ts index b3469743e7..832e4d09f7 100644 --- a/packages/namehash-ui/src/hooks/useNow.ts +++ b/packages/namehash-ui/src/hooks/useNow.ts @@ -1,6 +1,7 @@ +import type { UnixTimestamp } from "enssdk"; import { useEffect, useState } from "react"; -import type { Duration, UnixTimestamp } from "@ensnode/ensnode-sdk"; +import type { Duration } from "@ensnode/ensnode-sdk"; import { useSystemClock } from "./useSystemClock"; diff --git a/packages/namehash-ui/src/hooks/useSystemClock.ts b/packages/namehash-ui/src/hooks/useSystemClock.ts index 5594ecdac4..0569bf0b68 100644 --- a/packages/namehash-ui/src/hooks/useSystemClock.ts +++ b/packages/namehash-ui/src/hooks/useSystemClock.ts @@ -1,8 +1,7 @@ import { getUnixTime } from "date-fns"; +import type { UnixTimestamp } from "enssdk"; import { useSyncExternalStore } from "react"; -import type { UnixTimestamp } from "@ensnode/ensnode-sdk"; - import { systemClock } from "../utils/systemClock"; /** diff --git a/packages/namehash-ui/src/utils/blockExplorers.ts b/packages/namehash-ui/src/utils/blockExplorers.ts index 705a91fa7d..a0ec0c0dea 100644 --- a/packages/namehash-ui/src/utils/blockExplorers.ts +++ b/packages/namehash-ui/src/utils/blockExplorers.ts @@ -1,6 +1,5 @@ -import type { Address, Hash } from "viem"; - -import type { ChainId } from "@ensnode/ensnode-sdk"; +import type { Address, ChainId } from "enssdk"; +import type { Hash } from "viem"; import { SUPPORTED_CHAINS } from "./chains"; diff --git a/packages/namehash-ui/src/utils/chains.ts b/packages/namehash-ui/src/utils/chains.ts index 170f2eb91c..fec19abf87 100644 --- a/packages/namehash-ui/src/utils/chains.ts +++ b/packages/namehash-ui/src/utils/chains.ts @@ -1,3 +1,4 @@ +import type { ChainId } from "enssdk"; import { arbitrum, arbitrumSepolia, @@ -14,7 +15,6 @@ import { } from "viem/chains"; import { ensTestEnvChain } from "@ensnode/datasources"; -import type { ChainId } from "@ensnode/ensnode-sdk"; export const SUPPORTED_CHAINS = [ ensTestEnvChain, diff --git a/packages/namehash-ui/src/utils/ensManager.ts b/packages/namehash-ui/src/utils/ensManager.ts index 462965e090..4b488e3328 100644 --- a/packages/namehash-ui/src/utils/ensManager.ts +++ b/packages/namehash-ui/src/utils/ensManager.ts @@ -1,7 +1,7 @@ -import type { Address } from "viem"; +import type { Address, Name } from "enssdk"; import type { ENSNamespaceId } from "@ensnode/datasources"; -import { ENSNamespaceIds, type Name } from "@ensnode/ensnode-sdk"; +import { ENSNamespaceIds } from "@ensnode/ensnode-sdk"; /** * Get the ENS Manager App URL for the provided namespace. diff --git a/packages/namehash-ui/src/utils/ensMetadata.ts b/packages/namehash-ui/src/utils/ensMetadata.ts index 9efbcb1a9a..4f81011798 100644 --- a/packages/namehash-ui/src/utils/ensMetadata.ts +++ b/packages/namehash-ui/src/utils/ensMetadata.ts @@ -1,5 +1,7 @@ +import type { Name } from "enssdk"; + import type { ENSNamespaceId } from "@ensnode/datasources"; -import { ENSNamespaceIds, type Name } from "@ensnode/ensnode-sdk"; +import { ENSNamespaceIds } from "@ensnode/ensnode-sdk"; /** * Build the avatar image URL for a name on the given ENS Namespace that (once fetched) would diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc0e7242bc..f89e28ed7c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -259,6 +259,9 @@ importers: date-fns: specifier: 'catalog:' version: 4.1.0 + enssdk: + specifier: workspace:* + version: link:../../packages/enssdk graphiql: specifier: 5.2.0 version: 5.2.0(@types/node@24.10.9)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(graphql@16.11.0)(immer@9.0.21)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(use-sync-external-store@1.6.0(react@19.2.1)) @@ -580,6 +583,9 @@ importers: classic-level: specifier: ^1.4.1 version: 1.4.1 + enssdk: + specifier: workspace:* + version: link:../../packages/enssdk hono: specifier: 'catalog:' version: 4.12.12 @@ -870,6 +876,9 @@ importers: '@ensnode/ensnode-sdk': specifier: workspace:* version: link:../ensnode-sdk + enssdk: + specifier: workspace:* + version: link:../enssdk zod: specifier: 'catalog:' version: 4.3.6 @@ -900,6 +909,9 @@ importers: '@ensnode/ensnode-sdk': specifier: workspace:* version: link:../ensnode-sdk + enssdk: + specifier: workspace:* + version: link:../enssdk pg-connection-string: specifier: 'catalog:' version: 2.9.1 @@ -980,6 +992,9 @@ importers: '@ensnode/ensnode-sdk': specifier: workspace:* version: link:../ensnode-sdk + enssdk: + specifier: workspace:* + version: link:../enssdk devDependencies: '@ensnode/shared-configs': specifier: workspace:* @@ -1011,9 +1026,6 @@ importers: packages/ensnode-sdk: dependencies: - '@adraffy/ens-normalize': - specifier: 1.11.1 - version: 1.11.1 '@ensdomains/address-encoder': specifier: ^1.1.2 version: 1.1.4 @@ -1054,6 +1066,9 @@ importers: packages/ensrainbow-sdk: dependencies: + enssdk: + specifier: workspace:* + version: link:../enssdk viem: specifier: 'catalog:' version: 2.38.5(typescript@5.9.3)(zod@4.3.6) @@ -1076,6 +1091,9 @@ importers: packages/enssdk: dependencies: + '@adraffy/ens-normalize': + specifier: 1.11.1 + version: 1.11.1 '@ensdomains/address-encoder': specifier: ^1.1.2 version: 1.1.4 @@ -1166,6 +1184,9 @@ importers: date-fns: specifier: 'catalog:' version: 4.1.0 + enssdk: + specifier: workspace:* + version: link:../enssdk lucide-react: specifier: 'catalog:' version: 0.548.0(react@19.2.1)