This is a Ponder project for the ENS. It is a simple inder that stores the ENS registry, subregistries, and resolvers.
-
Domain → Registry:
domain.registry
referencesregistry.id
- Each domain belongs to one registry
-
Registry → Subregistry:
registry.subregistryId
referencesregistry.id
- Registries can have subregistries (hierarchical structure)
-
Registry → Resolver:
registry.resolver
referencesresolver.id
- Each registry entry can have an associated resolver
V1:
- Only has 1 registry
- Shared resolver (eg: DefaultResolver)
V2:
- Has multiple registries (eg: EthRegistry, RootRegistry, etc.)
- Registries are hierarchical via subregistryId
- Each user deploys own resolver (eg: OwnedResolver) using verifiable factory
erDiagram
domain {
string id PK
string label
string[] name
string labelHash
string owner
string registry FK
boolean isTld
bigint createdAt
bigint updatedAt
}
registry {
string id PK
string labelHash
string label
string subregistryId FK
string resolver FK
bigint flags
bigint createdAt
bigint updatedAt
}
subregistryUpdateEvent {
string id PK
string registryId FK
string labelHash
string subregistryId
bigint flags
bigint createdAt
bigint updatedAt
}
resolverUpdateEvent {
string id PK
string registryId FK
string labelHash
string resolverId
bigint flags
bigint createdAt
bigint updatedAt
}
newSubnameEvent {
string id PK
string registryId FK
string label
string labelHash
string source
bigint createdAt
bigint updatedAt
}
resolver {
string id PK
string address
string node
bigint createdAt
bigint updatedAt
}
transferSingleEvent {
string id PK
string registryId FK
string tokenId
string from
string to
bigint value
string source
bigint createdAt
bigint updatedAt
}
domain ||--|{ registry : "registry"
registry ||--|{ registry : "subregistry"
registry ||--|{ resolver : "resolver"
subregistryUpdateEvent }|--|| registry : "registry"
resolverUpdateEvent }|--|| registry : "registry"
newSubnameEvent }|--|| registry : "registry"
transferSingleEvent }|--|| registry : "registry"
-
RegistryDatastore:SubregistryUpdate
- Creates/updates registry relationships
- Updates subregistry mappings
-
RegistryDatastore:ResolverUpdate
- Links resolvers to registry entries
- Creates resolver records if they don't exist
-
EthRegistry:TransferSingle
- Creates new domain records
- Records ownership transfers
-
EthRegistry:NewSubname
- Updates domain labels
- Links domains to registry entries
-
RootRegistry:TransferSingle
- Similar to EthRegistry but for root domains
- Creates new root domain records
-
RootRegistry:NewSubname
- Updates root domain labels
- Links root domains to registry entries
OwnedResolver:AddressChanged
- Updates resolver address records
- Links ENS nodes to resolved addresses
-
When a new domain is created:
TransferSingle
event creates the initial domain recordNewSubname
event updates the domain with its label
-
When a registry relationship is established:
SubregistryUpdate
creates the registry relationship- Links parent registry to child registry
-
When a resolver is set:
ResolverUpdate
links the resolver to the registryAddressChanged
updates the resolver's address information
Domain IDs are generated as composite keys:
- Format:
${registryAddress}-${labelHash}
Event IDs are generated as composite keys:
- Format:
${event.block.number}-${event.logIndex}
- Currently only indexing test deployments on Sepolia
- All address fields are stored as strings
- Timestamps are stored as BigInts
- Relations are maintained through Ponder's relation system
- Events are processed in order to maintain data consistency
git clone https://github.com/ensdomains/ens-ponder.git
cd ens-ponder
pnpm install
pnpm dev
- Make sure it works when multiple tlds are used
- Make sure it works when a registry is the subregistry of another registry
- Add Support for different resolver record (currently only supports ETH address)
- Add Support for UserRegistries (contract not ready yet)
- Support for name migration from L1 to L2 (contract not ready yet)
- Support for name bridging from L2 to L1 (contract not ready yet)