[Temp Check] ENS Offchain Subname Publication Standard

Overview

This proposal suggests establishing a standard for offchain subname gateways to publish subname events to OrbisDB (a decentralized database on the Ceramic Network). By standardizing how these events are published, offchain subnames can become first-class citizens in the ENS ecosystem with capabilities previously limited to onchain names, while enabling reliable and efficient indexing.

Motivation

Offchain subnames provide scalability and cost benefits but currently exist in isolated silos, with each gateway storing data in separate databases that can only be accessed through gateway-specific APIs, making ecosystem-wide discoverability and integration challenging. By standardizing the publication of offchain subname events to a decentralized database like OrbisDB, we can:

  1. Enable offchain subnames to become full “first-class citizens” in ENS with capabilities similar to that of onchain names
  2. Allow for reliable and efficient indexing of offchain subnames
  3. Create consistency across different gateway implementations
  4. Enhance discoverability and usability of offchain subnames

Specification

This standard proposes that all offchain subname gateways publish events to OrbisDB on the Ceramic Network in a standardized format that captures the three key states of a subname:

Event Types

Events can be broken down into three types:

  • SUBDOMAIN_CREATED: When a subname is initially created
  • SUBDOMAIN_UPDATED: When a subname’s records or other properties are modified
  • SUBDOMAIN_DELETED: When a subname is deleted

Data Structure

Events would be published with the following standard structure:

{
  "controller": "[controller address in did:pkh format]",
  "payload": {
    "ensName": "[parent domain]",
    "subdomainName": "[subname]",
    "chainId": 1,
    "metadata": {
      "contentHash": "",
      "addresses": [{
        "address": "[ethereum address]",
        "coinType": 60
      }],
      "textRecords": [
        {
          "key": "[record key]",
          "value": "[record value]"
        }
      ]
    }
  },
  "createdAt": "[timestamp]",
  "eventType": "[SUBDOMAIN_CREATED|SUBDOMAIN_UPDATED|SUBDOMAIN_DELETED]",
  "indexed_at": "[indexing timestamp]"
}

For SUBDOMAIN_DELETED events, only the ensName, subdomainName, and chainId fields are required in the payload.

Why OrbisDB

OrbisDB was selected as the recommended database solution for this standard for several compelling reasons:

  1. Decentralization: As a database built on the Ceramic Network, OrbisDB aligns with ENS’s ethos of reducing central points of failure. This ensures that offchain subname data remains resilient and censorship-resistant.
  2. Permissionless Access: Any service can read from OrbisDB without special permissions or API keys, ensuring that subname data remains openly accessible to all ecosystem participants.
  3. Verifiable Publication: OrbisDB leverages DIDs (Decentralized Identifiers) for authentication, allowing gateway operators to sign their published events. This creates a verifiable trail of subname operations that can be cryptographically validated.
  4. Scalability: OrbisDB is designed to handle high throughput of events, which is crucial for supporting the potentially large volume of offchain subname operations across the ENS ecosystem.
  5. SQL Capabilities: OrbisDB provides SQL query capabilities, making it easier for developers to efficiently query and filter subname data.

Implementation Example

We have already implemented this standard at JustaName, demonstrating its feasibility. A complete implementation showing all three event types (creation, updates, and deletion) is available and can be viewed at status.justaname.id. This public dashboard provides a live view of our offchain subname events as they’re published to OrbisDB, maintaining the consistent data structure described in this specification.

Benefits

For ENS Users

  1. Greater consistency in how offchain subnames function across various services
  2. Improved discoverability of offchain subnames
  3. More reliable resolution of offchain subnames

For Developers

  1. Easier integration with offchain subnames through standardized indexing (ENSNode)
  2. Ability to build applications that can interact with both onchain and offchain subnames consistently
  3. Reduced development overhead when working with multiple offchain subname providers

For the ENS Ecosystem

  1. Enhanced capabilities for offchain subnames to match those of onchain subnames
  2. Improved scalability of the ENS ecosystem through efficient offchain solutions
  3. Establishment of best practices for offchain data publication

Next Steps

If this temp check receives favorable feedback, the next step would be to:

  1. Draft the specification as an ENS Improvement Proposal (ENSIP)
  2. Create documentation and tools to help gateways implement the standard
  3. Assist indexers, mainly ENSNode, in implementing support for indexing these standardized events

Questions for the Community

  1. Are there additional fields or event types that should be included in the standard?
  2. Should we consider other decentralized databases beyond OrbisDB/Ceramic?
  3. What tooling would be helpful to facilitate adoption of this standard?
  4. What’s the best approach for sharing and discovering gateway-specific OrbisDB identifiers to ensure consistent access to each gateway’s events? Should we create a central registry, use ENS records to store this information, or implement another discovery mechanism?
2 Likes

ENSIP-16 already created a consistent API for pulling metadata from offchain gateways. Picking a specific chain to publish that metadata to would of course have efficiency benefits for indexing, but it is not at all chain-agnostic, and as such doesn’t seem to be suitable as a standard for the ENS ecosystem.

Beyond that, it’d probably make more sense to critique ENSIP-16 for any functionality that you think is missing.

The main purpose behind the proposal is to create a standardized way for gateways to publish events to a common location, which would facilitate indexing previously siloed names. I believe that falls out of the scope of ENSIP-16, making it unfeasible to critique it for this reason. ENSIP-16 can however potentially be used/expanded for the discovery part that this proposal is missing


While OrbisDB was chosen for the aforementioned reasons, it is not set in stone. We are open to substituting it with any alternative that would satisfy the community. Furthermore, Ceramic protocol (where OrbisDB is hosted) is not a chain, from their docs:

“Ceramic is a decentralized data storage network made up of different components, and can replace or augment existing storage solutions. To make it easier to grasp, you can think about implementing Ceramic just like you might think about implementing a traditional SQL or PostgreSQL database.”

I understand the point, but events don’t need to be published to a common location to be indexable. They just need a standardised API alongside a discovery mechanism. There is the benefit of efficiency in only needing to index one source, sure, but that seems to be the only benefit here.

Using Ceramic means:

  • relying on a consensus mechanism external to Ethereum
  • resolving data via IPFS which isn’t at all required here (names are stored in a centralised database anyway!)
  • adding an extra stack of services to any general-purpose ENS indexing setup
  • Being subject to potential gas fees. Just because there is nothing at the moment doesn’t mean it will stay that way.
  • Significant write bandwidth limitations. This is completely antithetical to any justification to use OrbisDB for high throughput.

It’s not an EVM blockchain, sure, but it is a stream of verifiable immutable ordered event logs with a consensus mechanism


The proposal can be restructured to remove OrbisDB as a dependency. Initially, OrbisDB was chosen as a “decentralized database” option; however, as you’ve rightly noted, a centralized location is not essential. Therefore, the proposal can explicitly focus instead on establishing a standardized event-based approach for recording subname changes, simplifying the process for indexers to identify and track these changes. Additionally, a standardized endpoint can be added to the specification, and ENSIP-16 can be utilized as a discovery mechanism. Would these changes address your concerns and make the proposal more aligned with what you’d envision?

While ENSIP-16 has its own merits and benefits for fetching offchain data, it still doesn’t cover the issue of indexing these names efficiently. While L1 and L2 names’ states can be tracked easily by listening to their onchain events, offchain names are still practically impossible to index, and having a standardized endpoint for data retrieval is not enough, as it doesn’t provide a consistent way to notify indexers of state changes in real-time. Without an event-based structure, indexers are forced to poll provider endpoints continuously, leading to inefficiencies and delayed updates. Instead of relying on providers to publish events, the proposal has been updated by introducing a standardized API for exposing these events from the provider’s own database, along with a discovery mechanism to locate the relevant endpoints. This allows indexers to query updates in a structured, predictable manner, enabling efficient, reliable tracking of offchain subname changes at scale.

The following edit expands the scope of this temp check to provide flexibility for providers in their backend implementation. Providers may host event data in any database system of their choice, provided they:

  1. Implement the standardized API endpoint for event retrieval
  2. Support the specified discovery mechanism
  3. Store and expose event data according to the standardized JSON format described in this specification

This approach maintains consistency for clients and indexers while giving providers technical freedom in their infrastructure choices, ensuring that all events follow a uniform structure regardless of the underlying storage solution.

Updated Specification

This standard proposes a consistent event format for all offchain subname operations that captures the three key states of a subname:

Event Types

Events can be broken down into three types:

  • SUBDOMAIN_CREATED: When a subname is initially created
  • SUBDOMAIN_UPDATED: When a subname’s records or other properties are modified
  • SUBDOMAIN_DELETED: When a subname is deleted

Data Structure

Events should use the following standard structure regardless of where they are published:

{
  "chainId": 1,
  "payload": {
    "ensName": "[parent domain]",
    "subdomainName": "[subname]",
    "metadata": {
      "contentHash": "",
      "addresses": [{
        "address": "[ethereum address]",
        "coinType": 60
      }],
      "textRecords": [
        {
          "key": "[record key]",
          "value": "[record value]"
        }
      ]
    }
  },
  "createdAt": "[timestamp]",
  "blockNumber": "[eth_blockNumber]",
  "eventType": "[SUBDOMAIN_CREATED|SUBDOMAIN_UPDATED|SUBDOMAIN_DELETED]"
}

The chainId field is used to represent where the 2nd-level domains are hosted. Today, it is only useful to differentiate between mainnet (chainId: 1) and testnet (e.g., Sepolia chainId: 11155111) names.

For SUBDOMAIN_DELETED events, only the ensNameand subdomainName fields are required in the payload.

Standard Events Endpoint

Each gateway implementing this standard should provide a standardized endpoint for accessing these events:

GET /ens/events?from={timestamp}&blockNumber={number}&limit={number}&type={event_type}&chainId={chainId}

Parameters:

  • from: Optional timestamp to start retrieving events from
  • blockNumber: Optional block number to associate events with on-chain context
  • limit: Optional maximum number of events to return
  • type: Optional filter by event type
  • chainId: Optional filter by chain ID

The endpoint should return events in the standardized format, enabling easy consumption by indexers and other services.

Contract Interface

This standard proposes a dedicated interface for discovering the events endpoint:


interface IOffChainResolver {
    function getEventsUrl() external view returns (string memory);
    
    event EventsUrlChanged(
        string previousEventsUrl,
        string newEventsUrl
    );
}

This interface allows resolvers to expose their events endpoint URL while also providing an event that can be emitted when the URL changes. Clients can use the getEventsUrl() method to discover the standardized events endpoint for event-based indexing.

Migration Path for Existing Providers

Existing providers can adopt this standard through a pragmatic migration process:

  1. Data Mapping: Map current database schemas to the standardized event format. This involves:
    • Identifying existing subname records in the provider’s database
    • Creating a translation layer that converts proprietary data structures to the standardized JSON format
  2. Historical Snapshot: For existing subnames, generate SUBDOMAIN_CREATED events that reflect their current state:
    • Create a single SUBDOMAIN_CREATED event for each existing subname
    • Populate these events with the latest known records
    • Set the createdAt timestamp to the actual creation time if available, or use a default timestamp indicating the migration date
  3. Real-time Updates: Implement processes to capture new state changes moving forward:
    • Modify existing state update workflows to generate all three event types (SUBDOMAIN_CREATED, SUBDOMAIN_UPDATED, SUBDOMAIN_DELETED)