HNS.ONE

Docs · The main road

Delegate your TLD once. Change everything after that for free.

Handshake is a root zone. It stores delegation, not content — so a name you own cannot carry a website, a mailbox or a social handle until some nameserver answers for it. Point yours at ours with one on-chain update and every record afterwards is an ordinary DNS edit: instant, unlimited, and costing nothing.

Why it can't be done the old way

The chain stores exactly seven record types — NS, DS, GLUE4, GLUE6, SYNTH4, SYNTH6 and TXT. There is no A, no MX, no CNAME. That is not a gap in the design; a root zone's job is to delegate.

It is also why you do not want to keep your records on-chain even where you could. Every change is a transaction with a fee, and it does not reach other people's resolvers until the name tree commits — up to about six hours later. Delegation moves that cost to exactly one transaction, once.

The one on-chain step

You publish a resource on your name containing two NS records and nothing else:

{"records": [
  {"type": "NS", "ns": "ns1.hns.one."},
  {"type": "NS", "ns": "ns2.hns.one."}
]}

Trailing dots as shown. No GLUE4 or GLUE6ns1.hns.one is an ordinary ICANN hostname, so it is out of bailiwick and resolvers look its address up the normal way. You never need our IP address to delegate.

Publish the records

In whichever wallet holds the name — Bob Wallet, an hsd wallet, or your registrar's record editor. It is an UPDATE covenant.

Wait for the tree

One block (~10 minutes) to confirm, then up to ~6 hours — 36 blocks — before the wider network sees it. An external resolver still showing the old delegation during that window has not failed.

Claim it at the panel

https://app.hns.one/names/. Only the name's holder can set NS on-chain, so the delegation itself is the proof of ownership — there is nothing else for us to check, and we never ask for a key.

If you drive hsd directly

The wallet HTTP API, which is what our own tooling calls:

curl -X POST http://127.0.0.1:12039/wallet/<id>/update \
  -H 'content-type: application/json' \
  -d '{"name":"yourname",
       "data":{"records":[{"type":"NS","ns":"ns1.hns.one."},
                          {"type":"NS","ns":"ns2.hns.one."}]},
       "broadcast":true}'

The equivalent RPC is sendupdate [NAME, RESOURCE]. Either one spends coin and needs your wallet unlocked.

An UPDATE replaces the whole resource

It is not a merge. If your name already carries a TXT pointer or a DS record and you send only the two NS records, those are gone — which for a DS means every validating resolver starts failing closed on your name. Read the current resource first, keep what you need, and send the union.

Our own bulk tooling does this by construction and refuses to touch a name carrying a DS anchor it cannot sign for.

What it costs

ItemCostHow we know
The one UPDATE transaction ~0.03 HNS ~308 vbytes at hsd's default 100,000 doo/kB. Measured on a real mainnet update: 30,900 doos
Every DNS change afterwardsFree Ordinary zone edits; nothing touches the chain
Publishing and re-publishing a siteFree Control-key publishes are not billed
Time to confirm~10 minutesOne block
Time to be visible everywhereup to ~6 hours 36-block tree interval

Exactly what we can and cannot do once you delegate

  • We answer every query at and under your nameThat is what delegation means. yourname, www.yourname, alice.yourname — all of it arrives at our nameservers, and your name resolves if and only if we are up.
  • We can repoint your nameWe hold the zone. Nothing in the protocol stops an operator from changing where a name points. That is the trust you are extending, and it is the honest reason to keep a second operator in your NS set.
  • We cannot tamper with your published contentA published site is named by its own hash. We can change which hash your name points at — visibly, in a record you can read — but we cannot alter the bytes behind a hash without the hash changing.
  • We cannot touch your name on-chainWe never hold your key. Transfers, renewals and the delegation itself all need it, and the panel has no route that could ask for it.
  • We cannot change your apex NS or DSThose live on-chain. The DNS editor refuses them for everyone, including us, with the message that they are changed in your wallet.

What you can edit, and where

The editor is at https://app.hns.one/dns/, with a JSON API at /api/dns/records, /api/dns/mutate and /api/dns/pointer. The user-settable types are exactly the set our nameserver can serve and our signer can sign:

A AAAA CNAME TXT MX SRV TLSA CAA NS, and DS only alongside NS.

Limits: 20 records per owner name, 100 per label subtree, owner names ≤ 200 characters, values ≤ 1000 bytes. Addresses must be public unicast — private, CGNAT, loopback and documentation ranges are refused, because "point it at an IP" means one the internet can reach.

Some names are managed by a flow rather than by hand and are shown read-only: _hns.* and _atproto.*, OPENPGPKEY and SMIMEA anywhere (those belong to the mail encryption flow and are an operator-run step, not something the account panel can do today), and _443._tcp* TLSA in zones where DANE is enabled — there, the pin is rewritten on every certificate rollover and a manual edit would be silently overwritten.

You can also delegate a label under your own name to someone else's nameservers. Our server answers with a proper referral, and if you supply a DS alongside the NS we sign it, so the handoff stays secure.

DNSSEC: who signs what

Delegation makes your name resolve. A DS record makes the answers provable. The two halves are deliberately split, because only one of them can be done by someone holding your key.

StepWho does itDetail
Generate the zone keyHNS.ONE One ECDSAP256SHA256 key (algorithm 13) per zone, flags 257, kept on the operator machine at mode 0600
Sign the zoneHNS.ONE RRSIG, DNSKEY and NSEC written to a pre-signed zone file; signatures are valid for 30 days and are re-signed
Serve signed answersHNS.ONE Our nameserver answers the DO path from that file
Publish the DS on-chain You We give you the keytag, algorithm, digest type and digest; only the name's holder can commit it

The record you publish looks like this, alongside your NS records in the same resource:

{"type": "DS", "keyTag": 64223, "algorithm": 13,
 "digestType": 2, "digest": "9ebe72e3f4b8...."}

There is one combined signing key per zone, not a KSK/ZSK pair. It is published with the SEP bit set and signs every RRset directly.

Order matters, and getting it wrong fails closed

A DS on-chain for a key nobody can sign with is worse than no DNSSEC at all: a validating resolver can prove the answer should be signed, finds it is not, and returns SERVFAIL. Your name goes dark for exactly the resolvers that check.

So: delegate first, confirm we are answering, then publish the DS we give you. If you are moving away, remove the DS before you move the NS.

Our signer has not been checked by anyone else's validator

The signatures are verified by the same code that produces them. That catches implementation mistakes but not a shared misreading of the spec — both sides would make the same one. Independent validation (ldns-verify-zone, delv) has not been run against these zones. Treat the DNSSEC path as unvalidated until it has.

Signatures also expire on a 30-day cycle and must be regenerated. If that ever lapses, a signed zone fails closed — every name under it stops resolving for validating resolvers.

Verify it landed

Ask our nameserver directly, before and after:

# the delegation, straight from the chain
hsd-cli --api-key="$HSD_NODE_API_KEY" rpc getnameresource '"yourname"'

# what we actually answer for it
dig @ns1.hns.one yourname NS
dig @ns1.hns.one yourname SOA
dig @ns1.hns.one +dnssec yourname DNSKEY

A working delegation answers NOERROR with our two NS records and a SOA whose primary is ns1.hns.one. Expect exactly the two NS records and no glue.

Leaving

There is no lock-in mechanism, because there is nothing to lock: we never held your key, and the delegation you published is the only thing pointing the name at us.

Remove the DS first

Publish an updated resource without the DS record, and wait for the tree to commit. Skipping this leaves an anchor your new operator cannot sign for, and validating resolvers fail closed.

Repoint the NS

One more UPDATE, same cost, naming your own nameservers or another operator's.

Copy your records across

Read them from the DNS editor or GET /api/dns/records and recreate them wherever you are going.

There is no one-click export, and no export format

You can read every record we serve for your name through the editor or the records API, but there is no "download my zone" button and nothing emits a BIND zone file. Moving out today means copying records across by hand or by script. That is a gap, not a policy.

We also do not block or detect-and-stall a departure: when a name stops delegating to us our tooling notices and warns that we are still answering only until resolvers' caches expire.

Honest status

What is manual, and what is not built

Delegation is not self-service and cannot be. The on-chain update needs your key, which we will never hold, so there is no "delegate" button and no API endpoint that could do it for you. The panel's job starts after the update lands.

Both nameservers are one machine. ns1.hns.one and ns2.hns.one both resolve to 198.44.116.200. Add a second operator to your NS set if the name matters.

Every name we serve today is one of our own. The code path for an owner delegating their own TLD to us is implemented and tested, and the detection runs on both planes — but we have no third-party name live on it yet. You would be first.

Zone signing runs on the operator machine, not the edge. A record change made on the public plane serves immediately on the unsigned path and becomes visible to validating resolvers only after the operator drains the signing queue. The queue drainer for tenant publishes is not implemented yet — see Publishing.