diff --git a/DESIGN-root-tld-cert.md b/DESIGN-root-tld-cert.md index cf661de..96f857d 100644 --- a/DESIGN-root-tld-cert.md +++ b/DESIGN-root-tld-cert.md @@ -59,10 +59,24 @@ await updateName(w, "tlds.bch", { ``` Once the tx confirms and resolver indexes refresh (typically < 60 s), every -client picks up the new TLD without a software update or reinstall. The -certificate is held by the operator wallet on chipnet — for a real deployment -this needs to be a multisig, a covenant, or a governance body (Athenae council, -see `ROADMAP-IDEAS.md §4`) so the root isn't controlled by a single key. +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 diff --git a/src/indexer/ELECTRUM-SOURCE-README.md b/src/indexer/ELECTRUM-SOURCE-README.md new file mode 100644 index 0000000..3dd6129 --- /dev/null +++ b/src/indexer/ELECTRUM-SOURCE-README.md @@ -0,0 +1,133 @@ +# Electrum-sourced BNS indexer + +**Live on the VPS as `bns-indexer.service` (2026-07-30).** + +A companion to the BCHN-sourced [`bns-indexer.js`](README.md). This variant needs +**no BCHN node, no Fulcrum, no disk, no chain sync** — instead it polls public +electrum servers for the two calls BNS resolution uses (beacon `get_history` + +`transaction.get`), caches the beacon set, and serves the same electrum-WS +endpoint the resolver expects. It's a **pinned-IP, DNS-independent caching relay** +that fits any tiny VPS. + +## When to use which + +| Variant | Data source | Sovereignty | Footprint | +|---|---|---|---| +| [`bns-indexer.js`](README.md) (RpcSource) | your own BCHN node | full — you own the chain | ~10 GB + sync | +| **`electrum-source.js`** (this doc) | public electrum servers | relay — trusts upstreams | one Node process | + +Both serve identical electrum-WS output; clients can't tell them apart. + +## Config (env) + +``` +BNS_ELECTRUM_SERVERS comma-separated list, tried in order + (default: chipnet.bch.ninja, chipnet.imaginary.cash, chipnet.c3-soft.com) +BNS_WS_BIND default 127.0.0.1 +BNS_WS_PORT default 50010 +BNS_POLL_MS default 30000 (re-sync interval) +BNS_BEACON_SCRIPTHASH overridable; defaults to the canonical BNS beacon +``` + +## Run + +```sh +cd /opt/bns-indexer +node electrum-source.js +``` + +The service on the VPS (already deployed): +``` +/etc/systemd/system/bns-indexer.service -> starts electrum-source.js + at boot, restart=always +``` +Status: `systemctl status bns-indexer` · logs: `journalctl -u bns-indexer -f`. + +## Deploy to a fresh VPS (~5 minutes) + +Assumes Node 18+ and a working `ws` module reachable in `node_modules/`. + +```sh +mkdir -p /opt/bns-indexer && cd /opt/bns-indexer +# copy bns-indexer.js AND electrum-source.js from Argus/src/indexer/ +# (electrum-source.js imports BeaconIndex + startElectrumWS from bns-indexer.js) +printf '{"type":"module"}\n' > package.json +# link ws from any existing Node app on the box, or `npm i ws` +ln -sfn /opt/bns-gateway/node_modules ./node_modules # example + +cat > /etc/systemd/system/bns-indexer.service < VPS IP`. + +Then publish it in the on-chain `el` record (see the sibling README §4) so +Theseus discovers it without a build update: +``` +el = "wss://chain.silentmode.st:50011| wss://chipnet.bch.ninja:50004|135.148.236.244" +``` + +## Trade-off (honest) + +This variant **trusts the public electrum servers you point it at.** They can +return incorrect data (e.g., omit a registration). Mitigations: +- Point at multiple servers (they're tried in order; you get the first one that + responds — not a quorum, but resilience against downtime). +- Pair it with `bns-indexer.js` (BCHN-sourced) elsewhere for a sovereign source, + and cross-check. + +Not a replacement for your own node — a relay in front of one, or a lightweight +option when a node is impractical (small VPS). + +## Verify + +Any BNS resolver, pointed at the indexer, should resolve every registered name: + +```js +import WebSocket from "ws"; +import { resolveName } from "./resolver-web.js"; +const r = await resolveName("hello.bch", { + WebSocket, electrum: [{ url: "ws://127.0.0.1:50010" }], +}); +console.log(r?.records); // e.g. { s3: "bns/…" } +```