ADR-002: ENSIP-1 namehash compatibility
- Status: Accepted
- Date: 2026-04-22
- Deciders: Core team
Context
Every name in Oniym is keyed by a 32-byte node identifier. The algorithm for deriving this identifier from a human-readable name must be chosen up front — changing it later breaks every integration.
Two approaches were considered:
- ENSIP-1 namehash — the algorithm used by ENS (recursive right-to-left keccak256).
- Custom algorithm — e.g. flat keccak256 of the full name, or a Merkle-based scheme.
Decision
Adopt ENSIP-1 namehash unchanged.Rationale
-
Zero learning curve for developers — anyone who has worked with ENS can integrate Oniym immediately. The resolver interface, node derivation, and subdomain semantics are all identical.
-
Tooling compatibility — existing libraries (viem, ethers, web3.py) already ship namehash implementations. We inherit test vectors, edge-case handling, and battle-testing.
-
Hierarchical subdomains are trivially supported —
wallet.kyy.idis a natural extension, and subdomain ownership can be delegated without custom logic. -
Future L1 interop — if we ever expose Oniym names as
.ethvia CCIP-Read, the node format must match ENS. -
Cryptographic soundness is already established — keccak256 collision resistance plus recursive structure = well-understood security properties.
Consequences
Positive
- Interoperable with any ENS-compatible wallet, library, or dApp
- Reuses standard normalization (UTS-46) — we don't reinvent it
- Shared mental model reduces documentation burden
Negative
- We inherit ENS's choices, including some minor inefficiencies (e.g. recursive hashing is not the tightest possible encoding)
- If ENS updates the spec, we may need to track changes
Mitigations
- Implementation is in a small, pure library (
Namehash.sol) — easy to audit - Test vectors are pinned to ENS canonical values; any drift is caught in CI
Reference implementation
See contracts/src/lib/Namehash.sol and sdk/src/namehash.ts. A parity test ensures Solidity and TypeScript produce identical output.

