nova) and a name under it (alice.nova). That’s the whole grammar — no sub-subdomains, no arbitrary depth. It matches how the names are used: a business owns the namespace, its users hold names under it.
The three layers
Labels
A label (the part before or after the dot) has exactly one on-chain representation:- 1–63 bytes
- lowercase ASCII
a-z, digits0-9, and- - no leading or trailing hyphen
Namehash
On chain, names are keyed by a 32-byte recursive hash, not by strings:soran.namehash(ns) for a namespace, soran.node(name) for a full name — so anything you compute locally matches what the contracts compute.
The two clocks
Every name record involves two completely different clocks, and Soran never conflates them:
Stellar archives ledger entries whose rent lapses. If availability were derived from “is the entry present,” a lapsed entry would look unowned — and someone else could register a name that’s still yours. That’s the name-theft bug, and Soran’s contracts are built so it can’t happen: availability and resolution are decided only by
expires_at, never by whether the entry is currently live in storage.
Live and cold names
- ● Live — the ledger entry is paid up and resolves normally.
- ◇ Cold — the entry’s storage TTL lapsed and it was archived. The name is still owned; ownership didn’t change, only its storage state.
expires_at. Two permissionless keeper calls let anyone pay to keep entries warm — touch(label) bumps one name’s storage TTL without touching ownership, and keep_alive() bumps the Registrar itself (if the Registrar’s own entry goes cold, every name under it stops resolving until restored, so anyone may fund it).
When a name genuinely expires — its
expires_at passes under a timed policy — that’s the ownership clock, not the storage clock. See ownership guarantees for what each policy allows.What this means for integrators
- Resolve by name; the SDK hashes for you. Compare nodes, not strings, if you cache.
- Never infer availability or expiry from an RPC “entry not found” — a cold entry is not an unowned name. The SDK’s
isAvailable()andresolve()already handle this correctly. - If you operate a namespace, budget for storage rent or run a keeper that calls
touch— or let names go cold and wake on use, which is safe by construction.
Next
Ownership guarantees
Permanent, reclaimable, timed — and how permanence is proven.
Claiming a namespace
The public window: announce, objections, execution.