Per-TLD certificates on a distinct TLD beacon supersede the legacy list-in-one-NFT
model. TLD label is the NFT commitment; TREG/TUPD payloads on the TLD beacon
mirror REG/UPD on the name beacon. Chipnet TLD beacon:
bchtest:qzc4c76vtw9nd49g6x8nmvc0jz62uvk4dc7hmpmerh
scripthash c85db10e106606273422b2733b2a6fb8b35a4d0e7dbfb20cf59bdb0833c008b8
* config.js, resolver-web.{js,d.ts} — TLD_BEACON + TLD_BEACON_SCRIPTHASH
* bns.js — KNOWN_OPS { REG, UPD, TREG, TUPD }, registerTld/updateTld/normalizeTld
* bns.js + resolver-web.js — buildIndex({enforceTld:false}) drops name REGs
whose TLD lacks a live TLD cert at their block height (mempool-friendly).
Lockstep across both files.
* lib/tld-index.js — buildTldSnapshot({history,txs}) → deterministic root over
canonicalised tlds[]. Pure, importable, and stable across insertion order.
* indexer/bns-indexer.js — BeaconIndex is multi-beacon; ws handler dispatches
by scripthash; new HTTP endpoint GET /tld-list.json + /health behind
BNS_HTTP_PORT; state file v1 → v2 migrates in fromJSON.
* publish-tld-mirror.mjs — S3 (floating + immutable content-addressed) plus
NIP-33 kind 30078 d:bns-tld-list to Nostr relays, signed via nostr-tools
(libauth's Schnorr differs from BIP-340 and relays reject it).
* seed-tld-beacon.mjs — idempotent chipnet seed. Current set on the beacon:
bch p2p bit nav test x asm neo gt sc sia com dex cex nt (15). `.com` is
held by the operator: cert on-chain, excluded from public registrar UI.
Design + docs:
* Decentralized.DNS/DESIGN-tld-registry.md — schema, enforcement,
operator-countersig gate, USD-tiered pricing floors, fee splits,
tracker/mirror mechanics, migration/grandfathering.
* INSTRUCTIONS.md §3 rewritten for the 4-step flow (TREG → UI → deploy →
republish snapshot).
* site/tlds/ — public docs page listing current TLDs + verification paths.
* site/sirius/register.html — dropdown removed; parallel search across
every TLD in the TLDS array, sorted available → taken → not-on-registry.
Config:
* ariadne.config.json tlds → [bch, p2p, bit, nav, test, x] (CA constraints;
on-chain registry is now the authoritative source, config is fallback).
* setup/install.ps1 — reads TLD list via fetchTldList (per-TLD registry)
with fallback to fetchBcnrTlds (legacy tls.bch list-NFT) then config.
Tests:
* test/tld-index.test.mjs — 30 self-contained checks (multi-beacon dispatch,
state migration, ws routing, snapshot shape + root recomputability).
* test/tld-enforcement.test.mjs — synthetic + live chipnet integration
(with-gate correctly drops all pre-seed names).
208 lines
13 KiB
HTML
208 lines
13 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>TLDs — the top-level domains on the Bitcoin Cash chain — Silent Mode</title>
|
|
<meta name="description" content="Every BNS name lives under a top-level domain (TLD) whose certificate is itself a first-class token on the Bitcoin Cash chain. Browse the current TLDs, see how new ones are added, and verify the list against the chain.">
|
|
<link rel="stylesheet" href="../shared.css">
|
|
<style>
|
|
/* Page-specific: TLD table + snapshot-verification card */
|
|
.hero{text-align:center;padding:4.5rem 1.2rem 1rem}
|
|
.mark{font-size:52px;line-height:1}
|
|
h1{font-size:clamp(1.9rem,5vw,2.7rem);margin:.4rem 0 .3rem}
|
|
h1 .g{color:var(--acid)}
|
|
.tag{color:var(--mut);font-size:1.05rem;max-width:660px;margin:0 auto}
|
|
.cta{margin-top:1.6rem;display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
|
|
.btn{display:inline-block;text-decoration:none;padding:11px 20px;border-radius:10px;background:#4b7bec;color:#fff;font-size:14px;border:none;cursor:pointer;font-family:inherit}
|
|
.btn.ghost{background:transparent;border:1px solid var(--line);color:var(--ink)}
|
|
.btn.acid{background:var(--acid);color:#0b0e14;font-weight:600}
|
|
section{padding:2.6rem 0;border-top:1px solid var(--line);margin-top:2.5rem}
|
|
section:first-of-type{border-top:none;margin-top:1.5rem}
|
|
h2{font-size:1.4rem;margin:0 0 .4rem}
|
|
h3{font-size:1.05rem;margin:0 0 .3rem}
|
|
.lede{color:var(--mut);margin:0 0 1.5rem;max-width:720px}
|
|
ol.steps{counter-reset:s;list-style:none;padding:0;margin:1.2rem 0 0;display:grid;gap:10px}
|
|
ol.steps li{counter-increment:s;display:grid;grid-template-columns:30px 1fr;gap:14px;align-items:start;
|
|
background:var(--panel2);border:1px solid var(--line);border-radius:12px;padding:13px 16px}
|
|
ol.steps li::before{content:counter(s);grid-column:1;grid-row:1;
|
|
display:grid;place-items:center;width:24px;height:24px;border-radius:50%;
|
|
background:rgba(214,255,61,.14);color:var(--acid);font-size:12.5px;font-weight:700}
|
|
ol.steps li > *{grid-column:2;min-width:0}
|
|
ol.steps b{color:var(--ink)} ol.steps span{color:var(--mut);font-size:14px}
|
|
.note{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--acid);
|
|
border-radius:10px;padding:14px 18px;color:var(--mut);font-size:14px;margin-top:1.4rem}
|
|
.note.warn{border-left-color:var(--warn)}
|
|
.note b{color:var(--ink)}
|
|
code,.mono{background:#0e131b;border:1px solid var(--line);border-radius:6px;padding:1px 6px;font-family:ui-monospace,monospace;font-size:13px}
|
|
pre{background:#0e131b;border:1px solid var(--line);border-radius:10px;padding:12px 14px;overflow-x:auto;
|
|
font-family:ui-monospace,monospace;font-size:13px;color:var(--ink)}
|
|
/* TLD table */
|
|
table.tlds{width:100%;border-collapse:collapse;margin-top:1.2rem;font-size:14px}
|
|
table.tlds th,table.tlds td{padding:9px 12px;text-align:left;border-bottom:1px solid var(--line)}
|
|
table.tlds th{color:var(--mut);font-weight:500;font-size:12.5px;text-transform:uppercase;letter-spacing:.4px}
|
|
table.tlds .tld{font-family:ui-monospace,monospace;color:var(--acid);font-size:15px;font-weight:600}
|
|
table.tlds .cat{font-family:ui-monospace,monospace;color:var(--mut);font-size:12px}
|
|
table.tlds .status{font-size:12px;padding:2px 10px;border-radius:999px;font-weight:600;background:rgba(79,209,165,.15);color:var(--ok)}
|
|
table.tlds .status.held{background:rgba(255,199,95,.14);color:var(--warn)}
|
|
/* verification card */
|
|
.verify{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:16px 18px;margin-top:1.2rem}
|
|
.verify dt{color:var(--mut);font-size:12.5px;text-transform:uppercase;letter-spacing:.3px;margin-top:10px}
|
|
.verify dt:first-of-type{margin-top:0}
|
|
.verify dd{margin:2px 0 0;font-family:ui-monospace,monospace;font-size:12.5px;word-break:break-all;color:var(--ink)}
|
|
.verify dd a{color:var(--acid);text-decoration:none;border-bottom:1px dotted var(--acid)}
|
|
footer{border-top:1px solid var(--line);padding:2.4rem 0 3.5rem;color:var(--dim);font-size:13px;text-align:center;margin-top:2.5rem}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<nav class="topnav">
|
|
<a class="brand" href="../">⛓️ Silent <span class="g">Mode</span></a>
|
|
<a href="../tools/">Tools</a>
|
|
<a href="../prometheus/">Prometheus</a>
|
|
<a href="../sirius/">Sirius</a>
|
|
<a href="./" class="here">TLDs</a>
|
|
<a href="../helios/">Helios</a>
|
|
<a href="../hermes/">Hermes</a>
|
|
</nav>
|
|
|
|
<header class="hero">
|
|
<div class="mark">🌐</div>
|
|
<h1>The <span class="g">TLD registry</span></h1>
|
|
<p class="tag">Every BNS name lives under a <b>top-level domain</b>. Under Silent
|
|
Mode's per-TLD registry, each TLD is itself a certificate on the Bitcoin
|
|
Cash chain — minted once, held in a wallet, and required to exist before
|
|
any name under it can be registered. Browse the list, see how it works,
|
|
verify it against the chain.</p>
|
|
<div class="cta">
|
|
<a class="btn acid" href="../sirius/register.html">Search a name →</a>
|
|
<a class="btn ghost" href="#current">See current TLDs</a>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="wrap">
|
|
|
|
<section>
|
|
<h2>What a TLD is here</h2>
|
|
<p class="lede">A TLD (like <code>.bch</code>, <code>.x</code>, <code>.p2p</code>) is not just a
|
|
convention. Each is a CashTokens NFT with the TLD label as its commitment,
|
|
paying dust to a dedicated TLD-registry beacon on chain. That certificate
|
|
is the on-chain proof the TLD exists — and, once enforcement is on, it is
|
|
what makes any second-level name under it valid.</p>
|
|
<ol class="steps">
|
|
<li><b>Register the TLD first.</b> <span>An operator mints the TLD certificate. Without it, names
|
|
under that TLD are not indexed by conforming resolvers.</span></li>
|
|
<li><b>Then register names under it.</b> <span>Each name is a separate cert, minted through the
|
|
registrar (<a href="../sirius/register.html">sirius/register.html</a>), and paid by the buyer to
|
|
their own wallet.</span></li>
|
|
<li><b>Verify against the chain.</b> <span>Anyone can walk the TLD beacon
|
|
(<code>bchtest:qzc4c76vtw9nd49g6x8nmvc0jz62uvk4dc7hmpmerh</code> on chipnet), rebuild the list,
|
|
and compare its cryptographic root — the tracker is a cache, not authority.</span></li>
|
|
</ol>
|
|
<div class="note"><b>Why this exists.</b> Without a registry, anyone could quietly declare a TLD
|
|
against the same beacon by minting a name under it. That leaves resolvers in
|
|
silent disagreement about what exists. Per-TLD certificates make the TLD set
|
|
itself something the chain records, so every resolver sees the same list.
|
|
Design: <code>Decentralized.DNS/DESIGN-tld-registry.md</code> in the project repo.</div>
|
|
</section>
|
|
|
|
<section id="current">
|
|
<h2>Current TLDs (chipnet)</h2>
|
|
<p class="lede">Fifteen TLDs are minted on the chipnet TLD beacon as of
|
|
2026-08-29. Fourteen are offered for public name registration; one is
|
|
<b>held</b> by the operator (cert on-chain, no second-level names offered).
|
|
Live count on the chain is the authoritative source — this table may lag
|
|
by minutes until the beacon confirms.</p>
|
|
<table class="tlds">
|
|
<thead><tr><th>TLD</th><th>Category (short)</th><th>Status</th></tr></thead>
|
|
<tbody>
|
|
<tr><td class="tld">.bch</td> <td class="cat">56253dcfbdfbeec8…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.p2p</td> <td class="cat">d9b4e56d2293a4f9…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.bit</td> <td class="cat">bc51b2407b13876e…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.nav</td> <td class="cat">d2191a86685fa4c9…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.test</td> <td class="cat">5197632adf1f7fd3…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.x</td> <td class="cat">8dc32d8fd56f863b…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.asm</td> <td class="cat">58d3381435268faf…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.neo</td> <td class="cat">a511e80816976e92…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.gt</td> <td class="cat">249a535df4633767…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.sc</td> <td class="cat">f61fc465404a3eee…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.sia</td> <td class="cat">4b3fccd4076eb48c…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.dex</td> <td class="cat">9b230313b823202c…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.cex</td> <td class="cat">69fd93aedee3d353…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.nt</td> <td class="cat">5d18221bccaab2c0…</td><td><span class="status">public</span></td></tr>
|
|
<tr><td class="tld">.com</td> <td class="cat">211d51c2eef67013…</td><td><span class="status held">held by operator</span></td></tr>
|
|
</tbody>
|
|
</table>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Get a name under one of these</h2>
|
|
<p class="lede">Go to <a href="../sirius/register.html">Sirius / register a name</a>. Type a label — the
|
|
search fans out to every TLD in the registry in parallel and shows which
|
|
are available, which are taken, and which are held off the public
|
|
registry. Available ones mint straight into your own wallet in one
|
|
transaction; no yearly renewal.</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>How new TLDs get added</h2>
|
|
<p class="lede">On chipnet the operator's key can mint any TLD directly. On mainnet, a covenant
|
|
will enforce a countersignature from that same key on every public TLD mint
|
|
— and a USD-denominated price floor tiered by label length. This is what
|
|
keeps someone from land-grabbing every ICANN TLD in one afternoon.</p>
|
|
<ol class="steps">
|
|
<li><b>Operator TREG.</b> <span>The operator's wallet mints the TLD certificate; the label goes
|
|
into the NFT commitment, dust flows to the TLD beacon.</span></li>
|
|
<li><b>UI opt-in.</b> <span>The TLD is added to the registrar's list. A TLD can be minted but
|
|
intentionally omitted from the UI — the "held" pattern that keeps <code>.com</code> off
|
|
the public registry.</span></li>
|
|
<li><b>Snapshot republish.</b> <span>The tracker rebuilds and pushes a signed snapshot to Sia and
|
|
Nostr so downstream clients update without walking the chain themselves.</span></li>
|
|
</ol>
|
|
<div class="note warn"><b>Chipnet is not mainnet.</b> The covenant that turns "operator's key" into
|
|
something enforceable is a mainnet requirement. Until it lands, treat the chipnet TLD list as an
|
|
operator-signed statement, not a decentralized fact.</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Verify the list against the chain</h2>
|
|
<p class="lede">The tracker is a cache. The chain is the authority. Two independent paths, both public:</p>
|
|
|
|
<h3>Fetch the signed snapshot from Nostr</h3>
|
|
<p class="lede">Kind 30078 replaceable event, d-tag <code>bns-tld-list</code>, signed by the
|
|
tracker's Nostr key. Any relay carries it; the event's <code>content</code> field carries the current
|
|
snapshot root and the Sia URL where the full JSON lives.</p>
|
|
<dl class="verify">
|
|
<dt>Pubkey (x-only, hex)</dt>
|
|
<dd>f2c925194c531c7c398017e35b2396df64a61a613aa5fadebdf1f4990f2267f4</dd>
|
|
<dt>Relays</dt>
|
|
<dd>wss://nos.lol · wss://relay.damus.io</dd>
|
|
<dt>Filter (nostr-tools / rust-nostr)</dt>
|
|
<dd>{ authors: [<pubkey>], kinds: [30078], "#d": ["bns-tld-list"] }</dd>
|
|
</dl>
|
|
|
|
<h3>Rebuild locally from the TLD beacon</h3>
|
|
<p class="lede">Any electrum server that indexes the chipnet chain will return the beacon's history. Recompute
|
|
the snapshot's canonical form (sort by TLD, JSON.stringify), sha256 it, compare — if the hash matches
|
|
the tracker's <code>root</code>, the snapshot is a faithful summary of what the chain says.</p>
|
|
<pre>cd Argus && node --input-type=module -e "
|
|
import { loadWallet } from './src/lib/wallet.js';
|
|
import { buildTldSnapshot } from './src/lib/tld-index.js';
|
|
import { TLD_BEACON } from './src/config.js';
|
|
const w = await loadWallet('main');
|
|
const history = await w.provider.getHistory(TLD_BEACON);
|
|
const txs = new Map();
|
|
for (const {tx_hash} of history) try { txs.set(tx_hash, await w.provider.getRawTransactionObject(tx_hash)); } catch {}
|
|
console.log(buildTldSnapshot({ history, txs }));
|
|
process.exit(0);"</pre>
|
|
</section>
|
|
|
|
</div>
|
|
|
|
<footer>
|
|
Silent Mode — a Deviant project · <a href="/">home</a> · <a href="/sirius/">Sirius</a> · <a href="/sirius/register.html">register a name</a><br>
|
|
Alpha on a test network (chipnet). You hold your own keys; verify everything against the chain.
|
|
</footer>
|
|
|
|
</body>
|
|
</html>
|