// Keep the CDN's interpreted name index fresh from the gateway's own index. // // Ariadne for Android (and Theseus, via NETWORKS.cdnIndexUrl) pull // https://dl.silentmode.st/bns-name-index.json on cold start: a snapshot of // every registered name with its records, so the first page loads before // the electrum walk finishes. It was produced by publish-name-mirror.mjs, // which needs the operator wallet and ran by hand — the CDN copy went stale // for weeks (seven names behind on 2026-09-28). The gateway already holds // the same index in memory and serves it as /api/registry, so this script // simply reshapes that into the snapshot format and writes the CDN file. // Runs on the VPS from a systemd timer (VPS/SilentMode/cdn-name-index.*). // // node cdn-name-index.mjs [--gateway http://127.0.0.1:8700] [--out /opt/silent-mode/dl/bns-name-index.json] // // Snapshot shape (what Bns.java's loadDisk / pullSiaIndex parse): // [{ name, category, records, txid, height, updatedTxid }, …] import { readFileSync, writeFileSync, renameSync, existsSync } from "node:fs"; const args = process.argv.slice(2); const opt = (k, d) => { const i = args.indexOf(k); return i >= 0 && args[i + 1] ? args[i + 1] : d; }; const GATEWAY = opt("--gateway", "http://127.0.0.1:8700"); const OUT = opt("--out", "/opt/silent-mode/dl/bns-name-index.json"); const MIN_NAMES = 10; // a shorter answer is a gateway still warming up, not the registry const r = await fetch(`${GATEWAY}/api/registry`, { signal: AbortSignal.timeout(20_000) }); if (!r.ok) throw new Error(`gateway ${r.status}`); const reg = await r.json(); const names = Array.isArray(reg.names) ? reg.names : []; if (names.length < MIN_NAMES) throw new Error(`only ${names.length} names — not writing`); const snapshot = names .filter((e) => e && typeof e.name === "string" && e.records && typeof e.records === "object") .map((e) => ({ name: e.name, category: e.category || "", records: e.records, txid: e.txid || "", height: Number(e.height) || 0, updatedTxid: e.updated_txid ?? e.updatedTxid ?? null, })) .sort((a, b) => (a.height || 0) - (b.height || 0) || a.name.localeCompare(b.name)); const next = JSON.stringify(snapshot); const prev = existsSync(OUT) ? readFileSync(OUT, "utf8") : ""; if (prev === next) { console.log(`unchanged (${snapshot.length} names)`); process.exit(0); } writeFileSync(OUT + ".tmp", next); renameSync(OUT + ".tmp", OUT); console.log(`wrote ${OUT}: ${snapshot.length} names, height hint ${reg.height_hint ?? "?"}`);