Collision modes (BCNR/ICANN) + root TLD cert + VPS electrum-source indexer

Theseus soft-mode UX: 'Open with...' modal on collision, per-name/per-TLD
overrides, live per-tab switcher in the site-info popover, and a Naming section
in Settings for policy + reset. Backed by an on-chain root TLD certificate
(tlds.bch) that resolver-web.js discovers via fetchBcnrTlds()/isBcnrNativeTld().

Companion pieces:
- Argus/src/indexer/ELECTRUM-SOURCE-README.md — the featherweight VPS variant
  (no BCHN node, no Fulcrum) now live as bns-indexer.service.
- Argus/DESIGN-root-tld-cert.md — clarified: NOT a governance workflow, just
  ordinary key management (single wallet MVP -> 2-of-3 multisig). List gates
  registration / surgical NRPT / soft-mode classifier — never resolution.
- ROADMAP-IDEAS.md — recorded SiaGit/GitHub.sia + user-friendly Sia UI ideas.

Full spec: Argus/DESIGN-collision-modes.md (already tracked).
This commit is contained in:
Local Dev 2026-08-02 11:39:00 +02:00
parent 83a8fff021
commit 2c307249a1
2 changed files with 151 additions and 4 deletions

View file

@ -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

View file

@ -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 <<EOF
[Unit]
Description=BNS electrum-sourced indexer (public-server relay)
After=network.target
[Service]
WorkingDirectory=/opt/bns-indexer
Environment=BNS_WS_BIND=127.0.0.1
Environment=BNS_WS_PORT=50010
Environment=BNS_ELECTRUM_SERVERS=wss://chipnet.bch.ninja:50004,wss://chipnet.imaginary.cash:50004,wss://chipnet.c3-soft.com:64004
ExecStart=/usr/bin/node electrum-source.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now bns-indexer
```
## Expose as public `wss://` (optional)
By default it listens on `127.0.0.1:50010` — clients on the same box use it
directly (that's how the gateway works today). To expose it as a public
DNS-independent bootstrap for Theseus / mobile / the extension, terminate TLS at
nginx using a Let's Encrypt cert:
```nginx
server {
listen 50011 ssl;
server_name chain.silentmode.st; # or your host
ssl_certificate /etc/letsencrypt/live/chain.silentmode.st/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/chain.silentmode.st/privkey.pem;
location / {
proxy_pass http://127.0.0.1:50010;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
}
```
`ufw allow 50011/tcp` → reload nginx. Add DNS `A chain.silentmode.st -> 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|<vps-ip> 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/…" }
```