New record kind alongside h / s3 / ip / u: `p` reverse-proxies the
request to a full upstream URL while keeping the BNS host in the
address bar. Unlike `ip` (which pins the upstream to a raw IP + on-chain
TLS fingerprint), `p` uses the upstream's own DNS + public CA cert and
sends `Host:` of the upstream so vhost-based origins answer correctly.
Argus (record-picker.js):
- Placed AFTER `ip` in the apex chain: a name carrying both keeps its
existing pinned-IP behavior; names with only `p` get honored instead
of falling through to `u` and 302-ing away.
- Not applied to subdomain inheritance — `p` is single-URL by intent,
and inheriting through a subdomain would silently mangle the target.
Theseus (main.js serveBns):
- Fetches the upstream (path prefix from the `p` URL is preserved) and
returns the response body/status/content-type verbatim. Provenance
label "mirror" appears in the source badge.
Tests: record-picker.test.mjs covers `p`-only, `p`+ip precedence, and
the subdomain-suppression rule.
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).
Root cause of the "Firefox 'Server Not Found' (github)" and Node
`getaddrinfo EAI_FAIL` reports against the shipped daemon: reply() in
bnsd.js built responses from scratch and never copied the query's EDNS0
OPT record from the additional section. RFC 6891 §6.1.1 requires the
response to echo OPT when the query carried one; strict clients (glibc
getaddrinfo, Firefox with TRR off) treat the missing OPT as FORMERR and
surface EAI_FAIL / "Server Not Found". Lenient clients (nslookup, Chrome
async-dns) tolerate the loss, which is why the bug looked flaky.
The prior commit (ef19db1) extracted src/lib/dns-server.js as a testable
surface but left bnsd.js still calling the old inline helpers. This
finishes the migration:
- src/lib/dns-server.js:
- buildReply() now walks the additional section, finds the OPT RR by
name=root/type=41, and appends it to the response. When the query
had no OPT, none is fabricated (RFC 6891 §7). Preserves RD and
opcode from the query rather than hardcoding 0x8580.
- parseQuestion() rejects QDCOUNT != 1 and truncated labels early,
and skipName() tolerates DNS compression pointers per RFC 1035
§4.1.4 so the OPT walker doesn't trip on a compressed name.
- forwardQuery() accepts "host" (default port 53) or "host:port" so
it can be tested off port 53.
- src/daemon/bnsd.js: replaces the inline helpers with imports; the
icann-first branch keeps its rcode-inspecting callback via a small
forwardInspect() wrapper around the Promise-based forwardQuery.
- test/dns-server.test.mjs (new): 14 tests. Includes parseQuestion
cases (plain / EDNS / bad QDCOUNT / truncated), buildReply invariants
(OPT echoed / OPT never fabricated / RD preserved / NODATA still
echoes OPT), full dns.Resolver round-trips against an in-process
server (A / AAAA-NODATA / forward-to-mock-upstream), and two pinned
regression tests that copy the OLD reply() verbatim and assert its
OPT-dropping behavior so a future regression is caught immediately.
- AriadneResolver/ariadne-resolver/{src/daemon/bnsd.js, src/lib/dns-server.js}:
synced from Argus so the packaged installer picks up the fix.
Pre-existing failures in test/portfolio-index.test.mjs (require is not
defined at src/lib/chain.js:54) are unrelated and predate this work.
Theseus Navigator:
- Firefox-style toolbar: SVG back/fwd/reload/home buttons
- security padlock badge in the address bar opens a floating site-info
overlay VIEW (on top of the page, never pushes content down)
- Edge-style favorites bar (shown only on the new-tab/home page)
- search-engine picker (DuckDuckGo/Google/Bing/Brave/Startpage)
- Theseus logo moved right, opens Settings; native menu removed
- address bar doubles as search; bottom resolver status line
Argus:
- BNS-only indexer: an electrum endpoint over a bare BCHN node
(watches just the beacon, caches txs so no txindex needed) + test
- registry lifecycle / portfolio / name-index modules
Site restructure (nav/apps/store/hermes/choose) + runbook notes.