# Root TLD certificate (BCNR's IANA-root) **Status: ✅ deployed on chipnet (2026-07-30).** The authoritative list of BCNR-native TLDs — the "IANA root" for BCNR — lives in a single on-chain certificate. Clients read it to know which TLDs BCNR considers its own, which is what makes multi-TLD support and collision detection work without hardcoded lists. ## The name **`tlds.bch`** — registered on chipnet (see the wallet's index). One record: - **`tlds`** (string) — space-separated list of TLD suffixes, lowercase, `[a-z0-9-]{1,16}` each. Bootstrap set (2026-07-30): `"bch p2p deviant nav sia dgb nt sm lm"`. Chosen shape: - **Space-separated string, not JSON.** Fits the 200-byte OP_RETURN payload comfortably, mirrors the existing `el` electrum-server-list record (`electrum.silentmode.bch`), avoids escaping in on-chain payloads. - **One well-known name at the well-known TLD (`.bch`).** No chicken-and-egg — a client that only knows `.bch` can still resolve `tlds.bch` and learn the rest. This is the sole hardcoded name; the rest are on-chain. ## Client API (`resolver-web.js`) ```js import { ROOT_TLD_NAME, BOOTSTRAP_TLDS, fetchBcnrTlds, getBcnrTlds, parseTldsRecord, isBcnrNativeTld } from "./resolver-web.js"; // One-shot: connect, read the on-chain list, return it const tlds = await fetchBcnrTlds({ WebSocket, electrum: [...] }); // Or reuse an already-built index (no extra round-trip) const tlds = getBcnrTlds(index); // Classify a TLD isBcnrNativeTld(tlds, "p2p") // -> true isBcnrNativeTld(tlds, "de") // -> false ``` Fallbacks: unpublished / unreachable / empty → `BOOTSTRAP_TLDS = ["bch"]`. Callers should treat the list as **live but cacheable** (short TTL, e.g. one hour) — every consumer already has a name-index cache, so add the TLD read to the same warm path. ## How to update the list Adding a TLD is one on-chain UPDATE (proves ownership by moving the certificate): ```js import { loadWallet } from "./src/lib/wallet.js"; import { updateName } from "./src/lib/bns.js"; const w = await loadWallet(); await updateName(w, "tlds.bch", { tlds: "bch p2p deviant nav sia dgb nt sm lm bit test x silentmode", }); ``` Once the tx confirms and resolver indexes refresh (typically < 60 s), every client picks up the new TLD without a software update or reinstall. **Key management, not governance.** The TLD list is a **rarely-changed activation list** (the "constitution"), not a workflow with continuous decisions. After launch, a new TLD gets added occasionally — quarterly, maybe. So the cert needs ordinary key hygiene, not a standing governance body: - **MVP / chipnet:** single operator wallet is fine. - **Real deployment:** **2-of-3 multisig** (operator + backup keys) for bus-factor and key-loss protection. Not "decentralized governance" — just multiple keyholders to protect one occasionally-updated list. Note the strict scope: the TLD cert has **no editorial power** — it doesn't decide what names may exist within a TLD (that's permissionless), doesn't take names away from existing owners, and doesn't moderate content. **Moderation is a different concern**, about *sites* not TLDs, continuous rather than occasional — that's where Athenae Politeia + paid members earn their keep (see `ROADMAP-IDEAS.md §4`). Keep the two systems separate. ## What this unlocks — and what it does NOT **The root cert does NOT gate resolution.** The resolver stays TLD-agnostic — any registered name under any TLD resolves. The activated list has three real consumers: 1. **Registrar** (`register.html`) — the TLD dropdown for buyers is limited to activated TLDs. Storefront quality bar; keeps stray experimental TLDs out of the buying UI. Names *already* registered under unlisted TLDs still resolve. 2. **Surgical-mode routing** (`install.ps1 -Mode nrpt`) — the installer reads the root cert and writes one NRPT rule per activated TLD. Adding a TLD on-chain + re-running the installer picks it up (no code change). Users who want any-TLD system-wide routing pick **Full mode** instead. 3. **Collision-mode classifier** (soft "Open with…" prompt) — clients use it as a hint: "is this TLD BCNR-native → probably not a collision, don't prompt." A TLD not on the list falls through to normal collision handling; the list is a *preemption* aid, not a filter. The resolver never consults the list. Registration and resolution are separate concerns; permissionless resolution + curated activation is deliberate. ## Not in scope here - **Per-TLD registry designation** (which chain / operator backs each TLD, à la the `.bit` on BCH vs Namecoin question). The current record is flat; if we need per-TLD metadata, upgrade the record to `tlds` = space-separated tokens of shape `||…`, mirroring `el`'s `url|ip` shape. Or move to a Sia-hosted manifest referenced by hash in the record (unlocks arbitrary metadata without OP_RETURN size worries). - **Root cert key ownership.** For real use the key holding `tlds.bch` must be more than one operator's hot wallet — see the governance discussion in `ROADMAP-IDEAS.md §4`. ## Test / verify Any BNS resolver (local Fulcrum, VPS BNS indexer, public electrum) reads it: ```js import WebSocket from "ws"; import { fetchBcnrTlds } from "./src/lib/resolver-web.js"; console.log(await fetchBcnrTlds({ WebSocket, electrum: [{ url: "ws://127.0.0.1:50003" }], })); // -> ["bch","p2p","deviant","nav","sia","dgb","nt","sm","lm"] ``` Registration tx (2026-07-30): `f5a34ec7b995541f2f9b10f85d30b29cc76ebf75960e794a9001a68b16f6b3e9`.