Skip to content

v1.11.0

Choose a tag to compare

@github-actions github-actions released this 05 May 20:29
· 154 commits to main since this release
ca39fbe

@ensnode/datasources@1.11.0

Minor Changes

  • #2036 43d8a9b Thanks @shrugs! - Update sepolia-v2 namespace to point to the most recent Sepolia V2 deployment on the virtual Sepolia chain.

Patch Changes

  • #2049 5729ac1 Thanks @shrugs! - Removed LegacyEthRegistrarController, WrappedEthRegistrarController, and UniversalRegistrarRenewalWithReferrer placeholder entries from the sepolia-v2 namespace, and UniversalRegistrarRenewalWithReferrer from ens-test-env. AnyRegistrarControllerABI now also includes the UniversalRegistrarRenewalWithReferrer ABI.

@namehash/ens-referrals@1.11.0

Minor Changes

  • #1986 aa26180 Thanks @Goader! - Add BaseReferralProgramEditionConfig as the shared parent of ReferralProgramEditionConfig and BaseReferralProgramEditionSummary.

  • #1986 aa26180 Thanks @Goader! - Expose the per-award-model (pie-split, rev-share-cap) Zod schemas via @namehash/ens-referrals/internal.

  • #1986 aa26180 Thanks @Goader! - Reject overlapping referral program editions: for a given subregistryId, no two editions may share any point in time.

Patch Changes

@ensnode/ensdb-sdk@1.11.0

Minor Changes

  • #2016 7e77c5c Thanks @shrugs! - migrated_nodes renamed to migrated_nodes_by_parent and re-keyed by composite (parentNode, labelHash) to match the payload of ENSv1Registry(Old)#NewOwner events. New sibling migrated_nodes_by_node keyed solely by node for the three ENSv1RegistryOld handlers (Transfer / NewTTL / NewResolver) that emit only node. Both rows are written together by the migration helper so each read site addresses whichever key matches its event payload. Schema definitions live in a new migrated-nodes.schema.ts.

  • #2056 0e7c601 Thanks @shrugs! - Introduced IndexingMetadataContext as a single record type in the ENSNode Metadata table, replacing three separate record types (ensdb_version, ensindexer_public_config, ensindexer_indexing_status).

    • EnsDbReader: added getIndexingMetadataContext(), isHealthy(), isReady().
    • EnsDbWriter: added upsertIndexingMetadataContext().
    • Old per-record read/write methods removed.
    • EnsNodeMetadataKeys reduced to a single IndexingMetadataContext key.
  • #1983 6173160 Thanks @shrugs! - Unify v1Domain + v2Domain into a single polymorphic domain table discriminated by a type enum ("ENSv1Domain" | "ENSv2Domain"), and make Registry polymorphic across concrete ENSv1 (mainnet Registry, Basenames Registry, Lineanames Registry), ENSv1 Virtual (per-parent-domain virtual Registry managed by each ENSv1 domain that has children), and ENSv2 Registries.

    Breaking schema + id format changes

    • ENSv1DomainId is now a dash-delimited tuple: ${ENSv1RegistryId}-${node} (was Node). Every ENSv1 Domain is addressable through a concrete Registry, so bare node values no longer identify a Domain by themselves.
    • RegistryId is a union of ENSv1RegistryId, ENSv1VirtualRegistryId, and ENSv2RegistryId. New id constructors: makeENSv1RegistryId, makeENSv2RegistryId, makeENSv1VirtualRegistryId, and makeConcreteRegistryId (returns ENSv1RegistryId | ENSv2RegistryId for callsites that only need to address a concrete Registry contract). makeENSv1DomainId now takes (AccountId, Node).
    • domains table: replaces v1_domains + v2_domains. Adds type, nullable tokenId (non-null iff ENSv2), nullable node (non-null iff ENSv1), nullable rootRegistryOwnerId (v1 only). parentId removed; parent relationships flow through registryCanonicalDomain for both v1 and v2.
    • registries table: adds type enum column and nullable node (non-null iff ENSv1VirtualRegistry). Unique (chainId, address) index becomes a plain index so virtual Registries can share their concrete parent's (chainId, address).
    • registryCanonicalDomain.domainId is typed as the unified DomainId.

    GraphQL

    • Registry becomes a GraphQL interface with ENSv1Registry, ENSv1VirtualRegistry, and ENSv2Registry implementations. ENSv1VirtualRegistry exposes node: Node!.
    • Domain interface gains parent: Domain (resolved via the canonical-path dataloader); ENSv1Domain exposes node: Node! and rootRegistryOwner; ENSv2Domain exposes tokenId, registry, subregistry, permissions.
    • Query.registry(by: { contract }) now DB-looks up the concrete Registry by (chainId, address, type IN (ENSv1Registry, ENSv2Registry)). Virtual Registries are not addressable via AccountId alone.

Patch Changes

@ensnode/ensnode-sdk@1.11.0

Minor Changes

  • #2036 43d8a9b Thanks @shrugs! - Replaces the flat DEVNET_DEPLOYER / DEVNET_OWNER / DEVNET_USER / DEVNET_USER2 constants exported from @ensnode/ensnode-sdk/internal with a single DevnetAccounts object that groups each account's address and resolver. Consumers must migrate to DevnetAccounts.{deployer,owner,user,user2}.{address,resolver}.

  • #2017 824d819 Thanks @Goader! - Add $ENS Tokens as a supported currency in @ensnode/ensnode-sdk: CurrencyIds.ENSTokens, PriceEnsTokens/SerializedPriceEnsTokens types, and the priceEnsTokens, parseEnsTokens, serializePriceEnsTokens, deserializePriceEnsTokens helpers.

  • #1983 6173160 Thanks @shrugs! - Centralized Managed Name and Root Registry helpers.

    • Removed: getEthnamesSubregistryId, getEthnamesSubregistryManagedName, getBasenamesSubregistryId, getBasenamesSubregistryManagedName, getLineanamesSubregistryId, getLineanamesSubregistryManagedName.
    • Added: getManagedName(namespace, contract) — given any contract in the ENSv1 ecosystem, returns its Managed Name, namehash, and concrete ENSv1 Registry. Replaces the per-plugin helpers above. Also exposes isNameWrapper(namespace, contract).
    • Added: getRootRegistryId(namespace) returns the namespace's primary Root Registry (prefers ENSv2 when defined). getRootRegistryIds(namespace) returns every top-level Root Registry — concrete ENSv1 Root, Basenames/Lineanames base.eth/linea.eth ENSv1VirtualRegistries, and the ENSv2 Root when defined — for consumers that walk the full canonical-set tree.
    • Added: getENSv1RootRegistryId(namespace).
  • #1988 0d8a4b4 Thanks @tk-o! - Introduced a set of "stack info" data models: EnsIndexerStackInfo, EnsNodeStackInfo.

  • #2056 0e7c601 Thanks @shrugs! - Added EnsIndexerStackInfo as a base type; refactored EnsNodeStackInfo to extend it.

  • #2056 0e7c601 Thanks @shrugs! - Breaking: EnsIndexerPublicConfig: renamed labelSetclientLabelSet.

  • #2056 0e7c601 Thanks @shrugs! - Added replaceBigInts (sourced from @ponder/utils) and toJson helpers to @ensnode/ensnode-sdk. toJson takes an options object ({ pretty?: boolean }) with pretty defaulting to false — pass { pretty: true } for indented output.

  • #1983 6173160 Thanks @shrugs! - Unify v1Domain + v2Domain into a single polymorphic domain table discriminated by a type enum ("ENSv1Domain" | "ENSv2Domain"), and make Registry polymorphic across concrete ENSv1 (mainnet Registry, Basenames Registry, Lineanames Registry), ENSv1 Virtual (per-parent-domain virtual Registry managed by each ENSv1 domain that has children), and ENSv2 Registries.

    Breaking schema + id format changes

    • ENSv1DomainId is now a dash-delimited tuple: ${ENSv1RegistryId}-${node} (was Node). Every ENSv1 Domain is addressable through a concrete Registry, so bare node values no longer identify a Domain by themselves.
    • RegistryId is a union of ENSv1RegistryId, ENSv1VirtualRegistryId, and ENSv2RegistryId. New id constructors: makeENSv1RegistryId, makeENSv2RegistryId, makeENSv1VirtualRegistryId, and makeConcreteRegistryId (returns ENSv1RegistryId | ENSv2RegistryId for callsites that only need to address a concrete Registry contract). makeENSv1DomainId now takes (AccountId, Node).
    • domains table: replaces v1_domains + v2_domains. Adds type, nullable tokenId (non-null iff ENSv2), nullable node (non-null iff ENSv1), nullable rootRegistryOwnerId (v1 only). parentId removed; parent relationships flow through registryCanonicalDomain for both v1 and v2.
    • registries table: adds type enum column and nullable node (non-null iff ENSv1VirtualRegistry). Unique (chainId, address) index becomes a plain index so virtual Registries can share their concrete parent's (chainId, address).
    • registryCanonicalDomain.domainId is typed as the unified DomainId.

    GraphQL

    • Registry becomes a GraphQL interface with ENSv1Registry, ENSv1VirtualRegistry, and ENSv2Registry implementations. ENSv1VirtualRegistry exposes node: Node!.
    • Domain interface gains parent: Domain (resolved via the canonical-path dataloader); ENSv1Domain exposes node: Node! and rootRegistryOwner; ENSv2Domain exposes tokenId, registry, subregistry, permissions.
    • Query.registry(by: { contract }) now DB-looks up the concrete Registry by (chainId, address, type IN (ENSv1Registry, ENSv2Registry)). Virtual Registries are not addressable via AccountId alone.

Patch Changes

@ensnode/ensrainbow-sdk@1.11.0

Minor Changes

  • #2056 0e7c601 Thanks @shrugs! - Breaking: Updated core data models.

    • EnsRainbowApiClientOptions: renamed labelSetclientLabelSet.
    • EnsRainbowPublicConfig:
      • Replaced version: string with versionInfo: EnsRainbowVersionInfo.
      • Renamed labelSetserverLabelSet.
      • Removed recordsCount.
  • #2056 0e7c601 Thanks @shrugs! - Added EnsRainbowApiClient.ready(), plus EnsRainbow.ReadyResponse / EnsRainbow.ServiceUnavailableError types and ErrorCode.ServiceUnavailable. The client now throws a typed EnsRainbowHttpError (with structured status / statusText properties) from ready(), health(), and config() whenever the service responds with a non-2xx HTTP status, so callers can branch their retry/abort logic on the status without parsing message strings.

Patch Changes

enssdk@1.11.0

Minor Changes

  • #2050 92ca54f Thanks @shrugs! - Add beautifyInterpretedName(name: InterpretedName): BeautifiedName for converting an InterpretedName into a UI-presentable Name, plus a new BeautifiedName nominally-typed alias. Each label is either preserved verbatim (Encoded LabelHashes) or passed through ens_beautify (normalized labels), so e.g. "♾♾♾♾.eth" renders as "♾️♾️♾️♾️.eth". The branded BeautifiedName return type prevents the result from being passed to APIs that expect an InterpretedName — continue to use the source InterpretedName for navigation targets and lookups.

  • #2016 7e77c5c Thanks @shrugs! - Switch composite ids to dash-delimited tuples so Ponder's profile-pattern matcher can decompose them and prefetch hot tables.

    Every id constructor (makeENSv1RegistryId, makeENSv2RegistryId, makeENSv1VirtualRegistryId, makeConcreteRegistryId, makeResolverId, makeENSv1DomainId, makeENSv2DomainId, makePermissionsId, makePermissionsResourceId, makePermissionsUserId, makeResolverRecordsId, makeRegistrationId, makeRenewalId) now joins its components with - instead of CAIP-style mixed : / / delimiters. makeENSv2DomainId no longer wraps the registry contract in CAIP-19 ERC1155 form since the registry already namespaces it. Ponder's matcher only does single-level string-delimiter splits, so the unified - tuple is the shape it can decompose to derive prefetch lookup keys from event args.

  • #1983 6173160 Thanks @shrugs! - Unify v1Domain + v2Domain into a single polymorphic domain table discriminated by a type enum ("ENSv1Domain" | "ENSv2Domain"), and make Registry polymorphic across concrete ENSv1 (mainnet Registry, Basenames Registry, Lineanames Registry), ENSv1 Virtual (per-parent-domain virtual Registry managed by each ENSv1 domain that has children), and ENSv2 Registries.

    Breaking schema + id format changes

    • ENSv1DomainId is now a dash-delimited tuple: ${ENSv1RegistryId}-${node} (was Node). Every ENSv1 Domain is addressable through a concrete Registry, so bare node values no longer identify a Domain by themselves.
    • RegistryId is a union of ENSv1RegistryId, ENSv1VirtualRegistryId, and ENSv2RegistryId. New id constructors: makeENSv1RegistryId, makeENSv2RegistryId, makeENSv1VirtualRegistryId, and makeConcreteRegistryId (returns ENSv1RegistryId | ENSv2RegistryId for callsites that only need to address a concrete Registry contract). makeENSv1DomainId now takes (AccountId, Node).
    • domains table: replaces v1_domains + v2_domains. Adds type, nullable tokenId (non-null iff ENSv2), nullable node (non-null iff ENSv1), nullable rootRegistryOwnerId (v1 only). parentId removed; parent relationships flow through registryCanonicalDomain for both v1 and v2.
    • registries table: adds type enum column and nullable node (non-null iff ENSv1VirtualRegistry). Unique (chainId, address) index becomes a plain index so virtual Registries can share their concrete parent's (chainId, address).
    • registryCanonicalDomain.domainId is typed as the unified DomainId.

    GraphQL

    • Registry becomes a GraphQL interface with ENSv1Registry, ENSv1VirtualRegistry, and ENSv2Registry implementations. ENSv1VirtualRegistry exposes node: Node!.
    • Domain interface gains parent: Domain (resolved via the canonical-path dataloader); ENSv1Domain exposes node: Node! and rootRegistryOwner; ENSv2Domain exposes tokenId, registry, subregistry, permissions.
    • Query.registry(by: { contract }) now DB-looks up the concrete Registry by (chainId, address, type IN (ENSv1Registry, ENSv2Registry)). Virtual Registries are not addressable via AccountId alone.

enskit@1.11.0

Patch Changes

@ensnode/ensnode-react@1.11.0

Patch Changes

@namehash/namehash-ui@1.11.0

Patch Changes

ensskills@1.11.0

@ensnode/ponder-sdk@1.11.0

@ensnode/ponder-subgraph@1.11.0

ensadmin@1.11.0

Minor Changes

  • #1988 0d8a4b4 Thanks @tk-o! - Removed Records Count info from the ENSRainbow card UI on the Connection page.

  • #1988 0d8a4b4 Thanks @tk-o! - Renamed ENSNodeConfig* components to follow the EnsNodeStackInfo* pattern.

Patch Changes

  • #2001 7c1c048 Thanks @notrab! - Fix ENSAdmin GraphiQL docs sidebar failing to stay open on the omnigraph page. The editor now memoizes its fetcher, storage, and plugins so 1Hz parent re-renders (driven by the realtime indexing-status projection) no longer trigger schema re-introspection.

  • #1951 c56e32c Thanks @notrab! - Introduced interactive REST API Reference playground (/api/rest) powered by Scalar, enabling discovery and testing of all REST APIs published by a connected ENSApi instance. Added @ensnode/scalar-react wrapper package.

  • Updated dependencies [43d8a9b, 824d819, 5729ac1, 6173160, 92ca54f, 7e77c5c, 0d8a4b4, 0e7c601, 0e7c601, 0e7c601, 43d8a9b, 6173160]:

    • @ensnode/ensnode-sdk@1.11.0
    • @ensnode/datasources@1.11.0
    • enssdk@1.11.0
    • @ensnode/ensnode-react@1.11.0
    • @namehash/namehash-ui@1.11.0
    • @ensnode/scalar-react@0.0.0

ensapi@1.11.0

Minor Changes

  • #2014 6bd4154 Thanks @shrugs! - Adds HCA-aware Event.sender to the Omnigraph API alongside the existing Event.from. For ENSv2 events that emit an explicit sender/owner/account/ERC1155 operator argument, Event.sender is set from that argument (the HCA Smart Account address, if used) and falls back to tx.from otherwise. Adds a sender filter to EventsWhereInput. Account.events now filters by sender (HCA-aware) instead of tx.from. Documents HCA-aware semantics on Domain.owner, Registration.registrant/unregistrant, and *.PermissionsUser.user.

  • #2056 0e7c601 Thanks @shrugs! - indexing-status.cache and stack-info.cache updated to consume the new IndexingMetadataContext record. Config schema updated to fetch EnsIndexerPublicConfig from EnsNodeStackInfo.

  • #2007 e40ce8f Thanks @shrugs! - Adds PermissionsUser.events to the Omnigraph API, exposing the per-role-assignment event history (grants, revokes, role-bitmap mutations) for a specific (contract, resource, user) tuple.

  • #1983 6173160 Thanks @shrugs! - Query.root is now non-null and returns the namespace's Root Registry — preferring the ENSv2 Root Registry when defined, falling back to the ENSv1 Root Registry.

  • #2021 6824f35 Thanks @tk-o! - Integrated ENSDb health check and readiness check into ENSApi /health and /ready endpoints.

  • #1983 6173160 Thanks @shrugs! - Unify v1Domain + v2Domain into a single polymorphic domain table discriminated by a type enum ("ENSv1Domain" | "ENSv2Domain"), and make Registry polymorphic across concrete ENSv1 (mainnet Registry, Basenames Registry, Lineanames Registry), ENSv1 Virtual (per-parent-domain virtual Registry managed by each ENSv1 domain that has children), and ENSv2 Registries.

    Breaking schema + id format changes

    • ENSv1DomainId is now a dash-delimited tuple: ${ENSv1RegistryId}-${node} (was Node). Every ENSv1 Domain is addressable through a concrete Registry, so bare node values no longer identify a Domain by themselves.
    • RegistryId is a union of ENSv1RegistryId, ENSv1VirtualRegistryId, and ENSv2RegistryId. New id constructors: makeENSv1RegistryId, makeENSv2RegistryId, makeENSv1VirtualRegistryId, and makeConcreteRegistryId (returns ENSv1RegistryId | ENSv2RegistryId for callsites that only need to address a concrete Registry contract). makeENSv1DomainId now takes (AccountId, Node).
    • domains table: replaces v1_domains + v2_domains. Adds type, nullable tokenId (non-null iff ENSv2), nullable node (non-null iff ENSv1), nullable rootRegistryOwnerId (v1 only). parentId removed; parent relationships flow through registryCanonicalDomain for both v1 and v2.
    • registries table: adds type enum column and nullable node (non-null iff ENSv1VirtualRegistry). Unique (chainId, address) index becomes a plain index so virtual Registries can share their concrete parent's (chainId, address).
    • registryCanonicalDomain.domainId is typed as the unified DomainId.

    GraphQL

    • Registry becomes a GraphQL interface with ENSv1Registry, ENSv1VirtualRegistry, and ENSv2Registry implementations. ENSv1VirtualRegistry exposes node: Node!.
    • Domain interface gains parent: Domain (resolved via the canonical-path dataloader); ENSv1Domain exposes node: Node! and rootRegistryOwner; ENSv2Domain exposes tokenId, registry, subregistry, permissions.
    • Query.registry(by: { contract }) now DB-looks up the concrete Registry by (chainId, address, type IN (ENSv1Registry, ENSv2Registry)). Virtual Registries are not addressable via AccountId alone.

Patch Changes

ensindexer@1.11.0

Minor Changes

  • #2036 43d8a9b Thanks @shrugs! - Updates ens-test-env devnet commit to 580c60a.

  • #2056 0e7c601 Thanks @shrugs! - Consolidated startup init into initIndexingOnchainEvents() for reliable execution on every ENSIndexer startup. Added IndexingMetadataContextBuilder and StackInfoBuilder. EnsDbWriterWorker simplified to a single recurring task. The HTTP /config and /indexing-status endpoints now read from in-memory builders instead of ENSDb. initializeIndexingSetup / initializeIndexingActivation replaced by initIndexingOnchainEvents.

  • #1983 6173160 Thanks @shrugs! - Unify v1Domain + v2Domain into a single polymorphic domain table discriminated by a type enum ("ENSv1Domain" | "ENSv2Domain"), and make Registry polymorphic across concrete ENSv1 (mainnet Registry, Basenames Registry, Lineanames Registry), ENSv1 Virtual (per-parent-domain virtual Registry managed by each ENSv1 domain that has children), and ENSv2 Registries.

    Breaking schema + id format changes

    • ENSv1DomainId is now a dash-delimited tuple: ${ENSv1RegistryId}-${node} (was Node). Every ENSv1 Domain is addressable through a concrete Registry, so bare node values no longer identify a Domain by themselves.
    • RegistryId is a union of ENSv1RegistryId, ENSv1VirtualRegistryId, and ENSv2RegistryId. New id constructors: makeENSv1RegistryId, makeENSv2RegistryId, makeENSv1VirtualRegistryId, and makeConcreteRegistryId (returns ENSv1RegistryId | ENSv2RegistryId for callsites that only need to address a concrete Registry contract). makeENSv1DomainId now takes (AccountId, Node).
    • domains table: replaces v1_domains + v2_domains. Adds type, nullable tokenId (non-null iff ENSv2), nullable node (non-null iff ENSv1), nullable rootRegistryOwnerId (v1 only). parentId removed; parent relationships flow through registryCanonicalDomain for both v1 and v2.
    • registries table: adds type enum column and nullable node (non-null iff ENSv1VirtualRegistry). Unique (chainId, address) index becomes a plain index so virtual Registries can share their concrete parent's (chainId, address).
    • registryCanonicalDomain.domainId is typed as the unified DomainId.

    GraphQL

    • Registry becomes a GraphQL interface with ENSv1Registry, ENSv1VirtualRegistry, and ENSv2Registry implementations. ENSv1VirtualRegistry exposes node: Node!.
    • Domain interface gains parent: Domain (resolved via the canonical-path dataloader); ENSv1Domain exposes node: Node! and rootRegistryOwner; ENSv2Domain exposes tokenId, registry, subregistry, permissions.
    • Query.registry(by: { contract }) now DB-looks up the concrete Registry by (chainId, address, type IN (ENSv1Registry, ENSv2Registry)). Virtual Registries are not addressable via AccountId alone.

Patch Changes

  • #2049 5729ac1 Thanks @shrugs! - Fixed a bug in ensv2 plugin where only UnwrappedEthRegistrarController was indexed; LegacyEthRegistrarController and WrappedEthRegistrarController were silently dropped. Fixes #2048.

  • #2056 0e7c601 Thanks @shrugs! - waitForEnsRainbowToBeReady now polls /ready (via ensRainbowClient.ready()) instead of /health, so it correctly waits for the database to finish bootstrapping. It also aborts retries immediately on non-503 HTTP responses (e.g. 404 from a misconfigured ENSRAINBOW_URL, 500 from a broken instance) instead of blocking startup for ~1h, while still retrying on 503 Service Unavailable and on transient network errors.

  • #2056 0e7c601 Thanks @shrugs! - Migrated to @ensnode/ensnode-sdk's replaceBigInts / toJson helpers. Dropped the direct @ponder/utils dependency from ensapi.

  • #1989 16ecad1 Thanks @shrugs! - ENSIndexer's ensv2 plugin now avoids attempting to heal addr.reverse subnames if they've already been healed.

  • Updated dependencies [43d8a9b, 824d819, 5729ac1, 7e77c5c, 6173160, 92ca54f, 7e77c5c, 0d8a4b4, 0e7c601, 0e7c601, 0e7c601, 0e7c601, 0e7c601, 0e7c601, 43d8a9b, c186ad8, 6173160]:

    • @ensnode/ensnode-sdk@1.11.0
    • @ensnode/datasources@1.11.0
    • @ensnode/ensdb-sdk@1.11.0
    • enssdk@1.11.0
    • @ensnode/ensrainbow-sdk@1.11.0
    • @ensnode/ponder-sdk@1.11.0

ensrainbow@1.11.0

Minor Changes

  • #2037 1db1637 Thanks @djstrong! - ENSRainbow's GET /v1/config is now available immediately at startup, removing the cold-start gap that previously forced downstream services (e.g. ENSIndexer) to wait for the entire database download/validation before they could read public config (issue #2020).

    • The entrypoint command now builds the EnsRainbowPublicConfig in-memory from its CLI/env arguments (LABEL_SET_ID, LABEL_SET_VERSION) before the HTTP server starts accepting requests, so /v1/config returns 200 from the first request.
    • After the background bootstrap finishes, ENSRainbow verifies that the on-disk database's stored label set (labelSetId and highestLabelSetVersion) matches the configured one. On mismatch it logs a helpful error naming both the expected and actual label sets, refuses to serve, and terminates with exit code 1.
    • /ready continues to gate on full database readiness (200 only after the database has been attached and the env-vs-DB validation has passed).
    • /v1/heal/{labelhash} and /v1/labels/count continue to return 503 Service Unavailable while the database is still bootstrapping.
    • /health is unchanged and still returns 200 as soon as the HTTP server is listening.
  • #2056 0e7c601 Thanks @shrugs! - ENSRainbow now starts its HTTP server immediately and downloads/validates its database in the background, instead of blocking container startup behind a netcat placeholder.

    • New GET /ready endpoint: returns 200 { status: "ok" } once the database is attached, or 503 Service Unavailable while ENSRainbow is still bootstrapping. /health is now a pure liveness probe that succeeds as soon as the HTTP server is listening.
    • 503 responses for API routes during bootstrap: /v1/heal, /v1/labels/count, and /v1/config return a structured ServiceUnavailableError (errorCode: 503) until the database is ready.
    • New Docker entrypoint: the container now runs pnpm run entrypoint from the apps/ensrainbow working directory (implemented in Node via tsx src/cli.ts entrypoint), which replaces scripts/entrypoint.sh and the netcat workaround.
    • Graceful shutdown during bootstrap: SIGTERM/SIGINT now abort an in-flight bootstrap. Spawned download/tar child processes are terminated (SIGTERM → SIGKILL after a 5s grace period) and any partially-opened LevelDB handle is closed before the HTTP server and DB-backed server shut down, so the container exits promptly without leaking child processes or LevelDB locks.

    Migration: if you previously polled GET /health to gate traffic on database readiness, switch to GET /ready. /health is still available and still returns 200, but it now indicates liveness only.

Patch Changes

@docs/ensnode@1.11.0

Minor Changes

Patch Changes

  • #2056 0e7c601 Thanks @shrugs! - Updated docs and CI test paths to reflect the new docker/ location of docker-compose.yml.

  • Updated dependencies []:

    • @namehash/namehash-ui@1.11.0

@ensnode/ensindexer-perf-testing@1.11.0

Minor Changes

  • #1989 16ecad1 Thanks @shrugs! - Introduces the ENSIndexer Performance Testing package for running a local Prometheus x Grafana stack against an ENSIndexer instance.

@ensnode/integration-test-env@1.11.0

Minor Changes

  • #2056 0e7c601 Thanks @shrugs! - pollIndexingStatus updated to use getIndexingMetadataContext().

Patch Changes

fallback-ensapi@1.11.0

Patch Changes

@docs/ensrainbow@1.11.0

Patch Changes

  • Updated dependencies []:
    • @namehash/namehash-ui@1.11.0

@ensnode/enskit-react-example@0.0.3

Patch Changes

enscli@1.11.0

📦 NPM packages

🐳 Docker images