sirius/docs/index.html

613 lines
40 KiB
HTML
Raw Normal View History

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
feat(sirius-x): Sirius.X brand rebrand, banner star-divider, WC on portal Three things from one review pass: 1. Rebrand text 'sirius.x' -> 'Sirius.X' as the brand style across all sirius.x pages (titles, meta, nav wordmark, headings, prose, footer). Also flipped the pantheon headings to Title.X form: Silentmode.X, Sirius.X, Theseus.X, Hephaestus.X, Prometheus.X, Helios.X, Hermes.X. Domain literals, URLs, and code samples stay lowercase (sirius.x is the actual on-chain name; only prose changes). Logo/avatar SVG wordmarks and aria-labels updated to match. 2. Banner (brand/banner.svg) redesigned around a centered layout: 'Sirius.X' wordmark above, the star's horizontal arm extended edge-to-edge as a divider line, tagline lines below. Left tip at (0,315), right tip at (1200,315) so the arm crosses the full 1200px banner width; vertical body compact around center. Old layout had the star crammed into the right half and the wordmark on the left. 3. WizardConnect wired up on portal.html: - The 'Connect wallet' button now opens a real WC session via wizardconnect.js, shows the WIZ:// URI (copyable) and waits for the wallet to approve. - Successful connection builds a wallet-shaped wrapper with source: 'wc' and a WC session for signing; siriusProfile now carries the source so the nav dropdown can differentiate. - Record editor dispatches to setRecordsWithExternalWallet when source === 'wc' (bundle already ships the adapter), else stays on setRecordsWithBuiltInWallet. - TLD Register submit is gated off for WC users with a tooltip — no external-wallet variant of registerTld is exported yet, so TLD mint still needs a built-in wallet. - Sign-out disconnects the WC session before dropping the wallet. - toTokenAddress used to derive the tokenAddress for WC users so the 'Signed in' card shows both forms.
2026-09-07 01:35:35 +02:00
<title>Docs — Sirius.X</title>
<meta name="description" content="How BCNR works: the TLD registry, name registration, records, resolver, and how to verify anything against the Bitcoin Cash chain.">
sirius.x portal: /api/holdings endpoint + favicon paths + roadmap link gateway/public-gateway.mjs: * GET /api/holdings/<scripthash> and POST /api/holdings {scripthashes:[…]} — server-side wallet-holdings lookup for the portal. Bns-indexer is beacon-only so it can't answer listunspent for arbitrary addresses; the gateway does the electrum roundtrip and cross-joins with the cached BCNR index. Client posts scripthashes (no libauth needed on the server) and gets back the names owned. * elConnect now falls through to whole-buffer JSON.parse when a Fulcrum response lacks a trailing newline — chipnet.bch.ninja does this and otherwise every elCall to it times out. Same tolerance pattern as bns-indexer.test.mjs's tiny electrum client. * verifyElectrum picks a full electrum with a 3s server.version probe so a hung server fails over to the next in seconds instead of stalling 20. * Skips silentmode.st/electrum and coinspectrum.duckdns.org:50011 for /api/holdings — both are bns-indexer routes that don't do listunspent. web/register-entry.js: export addressToScripthash so the portal can derive the scripthash for each of its wallet's watched addresses before POSTing. Browser bundle rebuilt. site-sirius-x pages: * favicon + logo hrefs made relative (./assets/… on index/portal, ../assets/… on docs/theseus). Absolute /sirius-x/… broke on the sirius.x BCNR route where the site is served from root instead of under /sirius-x/. * Roadmap nav link added back to portal, docs, theseus — the landing has an anchor to a section on itself, so subpages now link to it explicitly. * portal.html: loadNames rewritten to POST scripthashes to /api/holdings instead of doing client-side electrum. Works on browsers whose networks block chipnet electrum ports; same-origin HTTPS on 443. * portal.html: bundle import ?v= bumped so Chrome's in-memory ES module map picks up the new bundle instead of a stale cached copy.
2026-08-31 05:40:47 +02:00
<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml">
<link rel="mask-icon" href="../assets/favicon.svg" color="#d6ff3d">
<meta property="og:type" content="website">
feat(sirius-x): Sirius.X brand rebrand, banner star-divider, WC on portal Three things from one review pass: 1. Rebrand text 'sirius.x' -> 'Sirius.X' as the brand style across all sirius.x pages (titles, meta, nav wordmark, headings, prose, footer). Also flipped the pantheon headings to Title.X form: Silentmode.X, Sirius.X, Theseus.X, Hephaestus.X, Prometheus.X, Helios.X, Hermes.X. Domain literals, URLs, and code samples stay lowercase (sirius.x is the actual on-chain name; only prose changes). Logo/avatar SVG wordmarks and aria-labels updated to match. 2. Banner (brand/banner.svg) redesigned around a centered layout: 'Sirius.X' wordmark above, the star's horizontal arm extended edge-to-edge as a divider line, tagline lines below. Left tip at (0,315), right tip at (1200,315) so the arm crosses the full 1200px banner width; vertical body compact around center. Old layout had the star crammed into the right half and the wordmark on the left. 3. WizardConnect wired up on portal.html: - The 'Connect wallet' button now opens a real WC session via wizardconnect.js, shows the WIZ:// URI (copyable) and waits for the wallet to approve. - Successful connection builds a wallet-shaped wrapper with source: 'wc' and a WC session for signing; siriusProfile now carries the source so the nav dropdown can differentiate. - Record editor dispatches to setRecordsWithExternalWallet when source === 'wc' (bundle already ships the adapter), else stays on setRecordsWithBuiltInWallet. - TLD Register submit is gated off for WC users with a tooltip — no external-wallet variant of registerTld is exported yet, so TLD mint still needs a built-in wallet. - Sign-out disconnects the WC session before dropping the wallet. - toTokenAddress used to derive the tokenAddress for WC users so the 'Signed in' card shows both forms.
2026-09-07 01:35:35 +02:00
<meta property="og:site_name" content="Sirius.X">
<meta property="og:title" content="Sirius.X docs — how BCNR works">
<meta property="og:description" content="The TLD registry, name registration, records, resolver, mainnet pricing, and how to verify anything against the chain.">
<meta property="og:url" content="https://silentmode.st/sirius-x/docs/">
<meta property="og:image" content="https://silentmode.st/sirius-x/brand/banner.svg">
<meta name="twitter:card" content="summary">
feat(sirius-x): Deviant sky palette + Fraunces/Ubuntu reader toggle Design translated from the /design canvas review. Sirius.X now shares Deviant's "signal" theme background (layered sky-rim/mid gradients over #050810) and the Silent Mode family typography stack. Typography: Fraunces (opsz variable serif) headings h1/h2/h3 DM Sans body / UI JetBrains Mono code, hashes, mono cells Ubuntu opt-in Bitcoin Cash brand font, swaps everything at :root when <html data-font-cmp="ubuntu"> All via Google Fonts, one <link> per page. Font picker (js/theme.js): Small pill in the topnav (Fraunces default / Ubuntu alt) — persisted to localStorage.sirius-font. Sets the data-font-cmp attribute; the swap CSS lives in each page's <style> block so !important overrides page-local font-family declarations at the necessary specificity. Mono elements stay JetBrains Mono under both fonts. Palette (cool sky vs old flat dark navy): --bg #0b0e14 → #050810 --panel2 #18202c → #0a0f1c (matches Deviant --sky-mid) --line rgba(255,255,255,.09) → .06 --ink #e7eaf1 → #f1f4fa --mut #8b98a9 → #b8c2d4 --dim #5e6678 → #6a7488 new: --sky-rim #131a2a, --chain-native #0AC18E (BCH brand green, reserved for chain-native badges/proofs like the Bitcoin.Cash body copy) Copy — "no renewals" softened everywhere it appeared. Renewals will be a per-TLD policy set by each TLD owner; the flat claim was wrong across the board. Landing card, tld.html hero and body, plus the og:description all updated. Applied to: index.html, portal.html, tld.html, theseus/index.html, brand/index.html, docs/index.html, admin/index.html.
2026-09-10 00:25:18 +02:00
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300;9..144,400;9..144,500;9..144,600;9..144,700&family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Ubuntu:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root{
feat(sirius-x): Deviant sky palette + Fraunces/Ubuntu reader toggle Design translated from the /design canvas review. Sirius.X now shares Deviant's "signal" theme background (layered sky-rim/mid gradients over #050810) and the Silent Mode family typography stack. Typography: Fraunces (opsz variable serif) headings h1/h2/h3 DM Sans body / UI JetBrains Mono code, hashes, mono cells Ubuntu opt-in Bitcoin Cash brand font, swaps everything at :root when <html data-font-cmp="ubuntu"> All via Google Fonts, one <link> per page. Font picker (js/theme.js): Small pill in the topnav (Fraunces default / Ubuntu alt) — persisted to localStorage.sirius-font. Sets the data-font-cmp attribute; the swap CSS lives in each page's <style> block so !important overrides page-local font-family declarations at the necessary specificity. Mono elements stay JetBrains Mono under both fonts. Palette (cool sky vs old flat dark navy): --bg #0b0e14 → #050810 --panel2 #18202c → #0a0f1c (matches Deviant --sky-mid) --line rgba(255,255,255,.09) → .06 --ink #e7eaf1 → #f1f4fa --mut #8b98a9 → #b8c2d4 --dim #5e6678 → #6a7488 new: --sky-rim #131a2a, --chain-native #0AC18E (BCH brand green, reserved for chain-native badges/proofs like the Bitcoin.Cash body copy) Copy — "no renewals" softened everywhere it appeared. Renewals will be a per-TLD policy set by each TLD owner; the flat claim was wrong across the board. Landing card, tld.html hero and body, plus the og:description all updated. Applied to: index.html, portal.html, tld.html, theseus/index.html, brand/index.html, docs/index.html, admin/index.html.
2026-09-10 00:25:18 +02:00
--bg:#050810; --panel:#141a24; --panel2:#0a0f1c; --line:rgba(255,255,255,.06);
--ink:#f1f4fa; --mut:#b8c2d4; --dim:#6a7488; --acid:#d6ff3d;
--ok:#4fd1a5; --warn:#ffc75f;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
feat(sirius-x): Deviant sky palette + Fraunces/Ubuntu reader toggle Design translated from the /design canvas review. Sirius.X now shares Deviant's "signal" theme background (layered sky-rim/mid gradients over #050810) and the Silent Mode family typography stack. Typography: Fraunces (opsz variable serif) headings h1/h2/h3 DM Sans body / UI JetBrains Mono code, hashes, mono cells Ubuntu opt-in Bitcoin Cash brand font, swaps everything at :root when <html data-font-cmp="ubuntu"> All via Google Fonts, one <link> per page. Font picker (js/theme.js): Small pill in the topnav (Fraunces default / Ubuntu alt) — persisted to localStorage.sirius-font. Sets the data-font-cmp attribute; the swap CSS lives in each page's <style> block so !important overrides page-local font-family declarations at the necessary specificity. Mono elements stay JetBrains Mono under both fonts. Palette (cool sky vs old flat dark navy): --bg #0b0e14 → #050810 --panel2 #18202c → #0a0f1c (matches Deviant --sky-mid) --line rgba(255,255,255,.09) → .06 --ink #e7eaf1 → #f1f4fa --mut #8b98a9 → #b8c2d4 --dim #5e6678 → #6a7488 new: --sky-rim #131a2a, --chain-native #0AC18E (BCH brand green, reserved for chain-native badges/proofs like the Bitcoin.Cash body copy) Copy — "no renewals" softened everywhere it appeared. Renewals will be a per-TLD policy set by each TLD owner; the flat claim was wrong across the board. Landing card, tld.html hero and body, plus the og:description all updated. Applied to: index.html, portal.html, tld.html, theseus/index.html, brand/index.html, docs/index.html, admin/index.html.
2026-09-10 00:25:18 +02:00
body{margin:0;background:radial-gradient(ellipse 1200px 600px at 50% -5%,#131a2a 0%,transparent 60%),radial-gradient(ellipse 900px 500px at 100% 100%,#0a0f1c 0%,transparent 55%),radial-gradient(ellipse 900px 500px at 0% 100%,#0c1424 0%,transparent 55%),var(--bg);
color:var(--ink);font:16px/1.65 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;min-height:100vh}
a{color:var(--acid)}
.wrap{max-width:900px;margin:0 auto;padding:0 1.2rem}
.topnav{position:sticky;top:0;z-index:20;display:flex;gap:2px;align-items:center;flex-wrap:wrap;
padding:10px 1.2rem;background:rgba(11,14,20,.82);backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
.topnav .brand{font-weight:600;color:var(--ink);text-decoration:none;margin-right:14px;font-size:15px;letter-spacing:.2px}
.topnav .brand .g{color:var(--acid)}
.topnav a{color:var(--mut);text-decoration:none;padding:6px 12px;border-radius:8px;font-size:14px}
.topnav a:hover{color:var(--ink);background:var(--panel)}
.topnav a.here{color:var(--acid);background:rgba(214,255,61,.08)}
.topnav a.portal{margin-left:auto;background:rgba(214,255,61,.10);color:var(--acid);font-weight:500}
.topnav a.portal:hover{background:rgba(214,255,61,.18)}
header.hero{text-align:center;padding:4rem 1.2rem 1rem}
.mark{font-size:52px;line-height:1}
h1{font-size:clamp(1.8rem,4.8vw,2.5rem);margin:.4rem 0 .3rem}
h1 .g{color:var(--acid)}
.tag{color:var(--mut);font-size:1.05rem;max-width:660px;margin:0 auto}
/* Layout: TOC on the left on wide screens, content on the right. */
.doc-grid{display:grid;grid-template-columns:220px 1fr;gap:32px;margin-top:1.5rem}
@media (max-width:820px){ .doc-grid{grid-template-columns:1fr} }
.toc{position:sticky;top:60px;align-self:start;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px 16px;font-size:14px}
.toc h4{margin:0 0 8px;color:var(--mut);font-size:12px;text-transform:uppercase;letter-spacing:.6px;font-weight:600}
.toc a{display:block;padding:5px 8px;border-radius:6px;color:var(--mut);text-decoration:none;font-size:13.5px}
.toc a:hover{background:var(--panel2);color:var(--ink)}
section{padding:1.6rem 0 2.4rem;border-top:1px solid var(--line);margin-top:1rem}
section:first-of-type{border-top:none;margin-top:0}
h2{font-size:1.35rem;margin:0 0 .5rem}
h3{font-size:1.05rem;margin:1.4rem 0 .35rem}
.lede{color:var(--mut);margin:0 0 1rem;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.2rem}
.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;word-break:break-all}
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);margin:1rem 0}
table.pricing{width:100%;border-collapse:collapse;margin-top:1rem;font-size:14px}
table.pricing th,table.pricing td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--line)}
table.pricing th{color:var(--mut);font-weight:500;font-size:12.5px;text-transform:uppercase;letter-spacing:.4px}
table.pricing td.price{font-family:ui-monospace,monospace;color:var(--acid);font-weight:600}
.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)}
footer{border-top:1px solid var(--line);padding:2rem 0 3rem;color:var(--dim);font-size:13px;text-align:center;margin-top:2.5rem}
feat(sirius-x): Deviant sky palette + Fraunces/Ubuntu reader toggle Design translated from the /design canvas review. Sirius.X now shares Deviant's "signal" theme background (layered sky-rim/mid gradients over #050810) and the Silent Mode family typography stack. Typography: Fraunces (opsz variable serif) headings h1/h2/h3 DM Sans body / UI JetBrains Mono code, hashes, mono cells Ubuntu opt-in Bitcoin Cash brand font, swaps everything at :root when <html data-font-cmp="ubuntu"> All via Google Fonts, one <link> per page. Font picker (js/theme.js): Small pill in the topnav (Fraunces default / Ubuntu alt) — persisted to localStorage.sirius-font. Sets the data-font-cmp attribute; the swap CSS lives in each page's <style> block so !important overrides page-local font-family declarations at the necessary specificity. Mono elements stay JetBrains Mono under both fonts. Palette (cool sky vs old flat dark navy): --bg #0b0e14 → #050810 --panel2 #18202c → #0a0f1c (matches Deviant --sky-mid) --line rgba(255,255,255,.09) → .06 --ink #e7eaf1 → #f1f4fa --mut #8b98a9 → #b8c2d4 --dim #5e6678 → #6a7488 new: --sky-rim #131a2a, --chain-native #0AC18E (BCH brand green, reserved for chain-native badges/proofs like the Bitcoin.Cash body copy) Copy — "no renewals" softened everywhere it appeared. Renewals will be a per-TLD policy set by each TLD owner; the flat claim was wrong across the board. Landing card, tld.html hero and body, plus the og:description all updated. Applied to: index.html, portal.html, tld.html, theseus/index.html, brand/index.html, docs/index.html, admin/index.html.
2026-09-10 00:25:18 +02:00
/* Deviant-family fonts + Fraunces/Ubuntu reader toggle. */
h1,h2,h3{font-family:'Fraunces',Georgia,serif;font-feature-settings:"ss01","ss02"}
code,.mono{font-family:'JetBrains Mono',ui-monospace,monospace}
body{font-family:'DM Sans','Inter',system-ui,sans-serif !important;font-feature-settings:"ss01","ss02"}
html[data-font-cmp="ubuntu"] body,html[data-font-cmp="ubuntu"] h1,html[data-font-cmp="ubuntu"] h2,html[data-font-cmp="ubuntu"] h3,html[data-font-cmp="ubuntu"] p,html[data-font-cmp="ubuntu"] a,html[data-font-cmp="ubuntu"] button,html[data-font-cmp="ubuntu"] span,html[data-font-cmp="ubuntu"] div,html[data-font-cmp="ubuntu"] label,html[data-font-cmp="ubuntu"] input,html[data-font-cmp="ubuntu"] li{font-family:'Ubuntu',system-ui,sans-serif !important}
html[data-font-cmp="ubuntu"] code,html[data-font-cmp="ubuntu"] .mono{font-family:'JetBrains Mono',ui-monospace,monospace !important}
.font-picker{display:inline-flex;align-items:center;gap:2px;padding:2px;margin:0 10px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);border-radius:999px;font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.12em;text-transform:uppercase}
.font-picker button{background:transparent;border:none;color:var(--dim);padding:4px 10px;border-radius:999px;cursor:pointer;font-family:inherit;font-size:inherit;letter-spacing:inherit;text-transform:inherit}
.font-picker button:hover{color:var(--ink)}
.font-picker button.active{background:var(--acid);color:var(--bg);font-weight:600}
</style>
feat(sirius-x): inline wallet dropdown — no navigation, no portal detour Wallet dropdown items (New / Import / WizardConnect) were navigating to portal.html?mode=X and asking the user to click again on arrival. That is 'the sign in landing page which is not functioning' from the user's perspective — a whole redirect for one form. Now every dropdown item opens the mint modal (register-flow.js) inline at the matching step, on whatever page the user is on: New -> stepCreate ('Create your wallet' — password + generate) Import -> stepImport ('Import a recovery phrase' — textarea) WizardConnect -> stepExternal ('Open your wallet' — QR/URI) register-flow.js grew a signInOnly mode: state.name is null, the step Back buttons close instead of going to a wallet-choice step there is no context for, and on wallet-loaded the flow writes siriusProfile and shows a 'Signed in' confirmation instead of Fund -> Confirm -> Mint. WC signInOnly keeps the session alive (state.session) so a later record edit can reuse it without a fresh QR handshake. profile-menu.js: menu items became <a data-action='new|import|wc'> and the click handler lazy-loads register-flow.js on demand — the docs/brand/theseus pages don't ship it in their initial payload, so their nav pill loads it the first time a wallet button is clicked and caches it for subsequent opens. Falls back to portal.html?mode=X if the module can't load. Cache-buster bumped so cached copies pick up the new behavior. Importmap for @bitauth/libauth added to docs/, brand/, theseus/ so the bundle's bare specifier resolves when register-flow.js is lazy-loaded from those pages. Verified end-to-end on the live docs page: all three dropdown items open the modal inline at the correct step, no console errors, no navigation.
2026-09-07 23:52:12 +02:00
<script type="importmap">
{ "imports": { "@bitauth/libauth": "https://silentmode.st/js/libauth.js" } }
</script>
<script src="../js/i18n.js?v=20260920b"></script>
</head>
<body>
<nav class="topnav">
feat(sirius-x): Sirius.X brand rebrand, banner star-divider, WC on portal Three things from one review pass: 1. Rebrand text 'sirius.x' -> 'Sirius.X' as the brand style across all sirius.x pages (titles, meta, nav wordmark, headings, prose, footer). Also flipped the pantheon headings to Title.X form: Silentmode.X, Sirius.X, Theseus.X, Hephaestus.X, Prometheus.X, Helios.X, Hermes.X. Domain literals, URLs, and code samples stay lowercase (sirius.x is the actual on-chain name; only prose changes). Logo/avatar SVG wordmarks and aria-labels updated to match. 2. Banner (brand/banner.svg) redesigned around a centered layout: 'Sirius.X' wordmark above, the star's horizontal arm extended edge-to-edge as a divider line, tagline lines below. Left tip at (0,315), right tip at (1200,315) so the arm crosses the full 1200px banner width; vertical body compact around center. Old layout had the star crammed into the right half and the wordmark on the left. 3. WizardConnect wired up on portal.html: - The 'Connect wallet' button now opens a real WC session via wizardconnect.js, shows the WIZ:// URI (copyable) and waits for the wallet to approve. - Successful connection builds a wallet-shaped wrapper with source: 'wc' and a WC session for signing; siriusProfile now carries the source so the nav dropdown can differentiate. - Record editor dispatches to setRecordsWithExternalWallet when source === 'wc' (bundle already ships the adapter), else stays on setRecordsWithBuiltInWallet. - TLD Register submit is gated off for WC users with a tooltip — no external-wallet variant of registerTld is exported yet, so TLD mint still needs a built-in wallet. - Sign-out disconnects the WC session before dropping the wallet. - toTokenAddress used to derive the tokenAddress for WC users so the 'Signed in' card shows both forms.
2026-09-07 01:35:35 +02:00
<a class="brand" href="../"><span class="g">Sirius.X</span></a>
<a href="../#try">Try it</a>
feat(sirius-x): pencil Register icon + TLD mint via shared modal Two UX polishes: 1. Register-tab icon flipped from 🪪 (identification-card emoji, renders as a hollow box in system-ui fonts without extended emoji) to ✏️ (pencil), which reads as 'edit/create' and ships in every emoji font worth targeting. Changed across the nav on all 8 pages plus the footer injector's Product column. Kept the Register nav item — six items total in the nav, and from any subpage it's one click to the search on landing. 2. tld.html no longer duplicates the wallet-choice + mint flow inline. The Register button on a search result now hands the label off to the shared register-flow.js modal — same modal that name registration uses — via a new window.siriusRegisterTld(label, {serviceFeeSats}) entry point. register-flow.js grew: - startTldFlow / window.siriusRegisterTld: sets state.tld and walks the modal through wallet-choice → Fund → stepConfirmTld → stepRegisterTld → stepDoneTld - stepConfirmTld: shows label + fee + owner, no per-name quote - stepRegisterTld: dispatches to registerTldWithBuiltInWallet or registerTldWithExternalWallet based on state.wallet/state.session - stepDoneTld: 'X is yours' with txid + certificate id + operator address, no record editor (a TLD certificate has no records to set immediately) - stepWallet / stepExternalConfirm branch on state.tld so the modal heading and the WC-confirm path route correctly tld.html trimmed: removed the entire signin-section + mint-section plus their inline handlers (~250 lines gone). Now just search + registered-TLDs list + a delegator to the shared modal. If a user is already signed in via the wallet dropdown, the modal recognises the saved wallet ('Unlock my browser wallet' button appears) instead of asking them to sign in again on this page.
2026-09-08 00:10:11 +02:00
<a href="../#search-input">✏️ Register</a>
<a href="../tld.html">🌐 TLD</a>
feat(bns): name marketplace and TLD-owner co-sign rule Two gaps the owner panel left open. First, a hidden TLD was only a UI gate: anyone could still broadcast a REG under it and every indexer admitted it. Second, there was no way to sell a name without trusting the other side. Co-sign rule (consensus, applied in lockstep by bns.js and resolver-web.js): a REG under a TLD whose records at that height say policy "cosign" or hidden 1 is indexed only if the transaction carries the TLD's own certificate. The certificate can only be spent by the owner's key and is re-issued to them in the same transaction, so it is a co-signature nobody can forge and nothing is consumed. The TLD map now keeps the TUPD timeline so policy is evaluated at the REG height. Owners register under their private TLDs with the certificate added from their own wallet; third parties under a "cosign" TLD build the full transaction, sign their inputs and queue it at /api/cosign, where the owner approves it from the dashboard (signCosignRequest refuses to sign unless the certificate returns to the same locking script). Marketplace: a listing is the seller's certificate input plus a price output signed SIGHASH_SINGLE|ANYONECANPAY, stored by the gateway as a bulletin board (/api/market, verified against the on-chain owner and pruned when the certificate moves). The buyer completes it in one transaction, so the seller is paid exactly when the name moves. Cancelling also spends the certificate once so the offer is void. Site: market.html, Sell sub-tab and Pending approvals in the portal, Market link in nav and footer, six dictionaries extended, cache tags bumped. Verified on chipnet: cosigned.sc registered by a throwaway wallet through the queue with the .sc certificate back at the owner; aloevera.test listed and delisted through the API. Ariadne's resolver-web.js copy and the mobile Bns.java port still need the co-sign rule; until then they admit REGs this index rejects.
2026-09-17 04:04:22 +02:00
<a href="../market.html">🛒 Market</a>
<a href="../theseus/"><svg width="14" height="14" viewBox="0 0 64 64" style="vertical-align:-2px;margin-right:4px" aria-hidden="true"><rect width="64" height="64" rx="12" fill="#0b0e14"/><path d="M32 6 L38 32 L26 32 Z" fill="#e04e4e"/><path d="M38 32 L32 58 L26 32 Z" fill="#d6ff3d"/><path d="M6 32 L32 27 L58 32 L32 37 Z" fill="#d6ff3d" opacity=".55"/><circle cx="32" cy="32" r="3" fill="#0b0e14"/></svg>Theseus</a>
<a href="../portal.html" class="portal">🔑 Sign in</a>
</nav>
<header class="hero">
<div class="mark">📚</div>
feat(sirius-x): Sirius.X brand rebrand, banner star-divider, WC on portal Three things from one review pass: 1. Rebrand text 'sirius.x' -> 'Sirius.X' as the brand style across all sirius.x pages (titles, meta, nav wordmark, headings, prose, footer). Also flipped the pantheon headings to Title.X form: Silentmode.X, Sirius.X, Theseus.X, Hephaestus.X, Prometheus.X, Helios.X, Hermes.X. Domain literals, URLs, and code samples stay lowercase (sirius.x is the actual on-chain name; only prose changes). Logo/avatar SVG wordmarks and aria-labels updated to match. 2. Banner (brand/banner.svg) redesigned around a centered layout: 'Sirius.X' wordmark above, the star's horizontal arm extended edge-to-edge as a divider line, tagline lines below. Left tip at (0,315), right tip at (1200,315) so the arm crosses the full 1200px banner width; vertical body compact around center. Old layout had the star crammed into the right half and the wordmark on the left. 3. WizardConnect wired up on portal.html: - The 'Connect wallet' button now opens a real WC session via wizardconnect.js, shows the WIZ:// URI (copyable) and waits for the wallet to approve. - Successful connection builds a wallet-shaped wrapper with source: 'wc' and a WC session for signing; siriusProfile now carries the source so the nav dropdown can differentiate. - Record editor dispatches to setRecordsWithExternalWallet when source === 'wc' (bundle already ships the adapter), else stays on setRecordsWithBuiltInWallet. - TLD Register submit is gated off for WC users with a tooltip — no external-wallet variant of registerTld is exported yet, so TLD mint still needs a built-in wallet. - Sign-out disconnects the WC session before dropping the wallet. - toTokenAddress used to derive the tokenAddress for WC users so the 'Signed in' card shows both forms.
2026-09-07 01:35:35 +02:00
<h1>Sirius.X <span class="g">docs</span></h1>
<p class="tag">How the pieces fit together: the TLD registry, name registration, records that
tell the resolver where a site lives, the resolver itself, and how anyone can verify anything
against the chain.</p>
</header>
<div class="wrap">
<div class="doc-grid">
<aside class="toc">
<h4>Contents</h4>
<a href="#tld-registry">TLD registry</a>
<a href="#register-name">Register a name</a>
<a href="#private-tlds">Private &amp; co-sign TLDs</a>
<a href="#market">Buying &amp; selling names</a>
<a href="#records">Records &amp; hosting</a>
<a href="#signed-records">Signed off-chain records</a>
<a href="#host">Host your name</a>
<a href="#resolver">Resolver / gateway</a>
<a href="#pricing">Pricing (mainnet)</a>
<a href="#tracker">Tracker &amp; mirrors</a>
<a href="#verify">Verify anything</a>
<a href="#runbook">Operator runbook</a>
</aside>
<div>
<section id="tld-registry">
<h2>The TLD registry</h2>
<p class="lede">Every BCNR name lives under a <b>top-level domain</b> whose certificate is
itself a first-class token on the Bitcoin Cash chain — an NFT with the TLD label as its
commitment, paying dust to a dedicated TLD-registry beacon. That certificate is the
on-chain proof the TLD exists, and once enforcement ships, it is what makes any
second-level name under it valid to conforming resolvers.</p>
<p class="lede">Fourteen public TLDs on chipnet today (2026-08-29):
<code>bch p2p bit nav test x asm neo gt sc sia dex cex nt</code>. The current list and
per-TLD categories are at
<a href="https://silentmode.st/tlds/">silentmode.st/tlds/</a>.</p>
<div class="note"><b>Why per-TLD certs, not a single list.</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. Per-TLD certificates make the TLD set itself
something the chain records, so every resolver sees the same list — and TLDs become
ownable assets that can carry policy, fees, and governance of their own.</div>
</section>
<section id="register-name">
<h2>Register a name — end to end</h2>
<p class="lede">The buyer's certificate mints straight to a wallet they control, in one
transaction that also publishes the initial records and pays the beacon. Nobody
including the operator can take the name back — the covenant work in progress adds an
expiry / reclaim clock but does not change who controls the key.</p>
<ol class="steps">
<li><b>Search a label across every TLD.</b>
<span>The registrar fans out to every TLD in the registry in parallel and shows
available / taken per row. Available names appear first.</span></li>
<li><b>Create or connect a wallet.</b>
<span>Built-in browser wallet (PBKDF2 → AES-GCM in localStorage) or WizardConnect to
Cashonize / Paytaca — both mint to the buyer's own key.</span></li>
<li><b>Confirm the price.</b>
<span>Miner fee + beacon dust + certificate dust + service fee. Chipnet placeholder
is 10,000 sat; real pricing is a mainnet decision.</span></li>
<li><b>The certificate lands in your wallet.</b>
<span>The name resolves the moment the transaction confirms. Records can be set or
changed later — only your key can sign a UPD.</span></li>
</ol>
</section>
<section id="private-tlds">
<h2>Private &amp; co-sign TLDs</h2>
<p class="lede">A TLD owner decides who may register names under it, and the decision is
enforced by every resolver, not just by the shop. Three switches live in the TLD's
on-chain records (a <code>TUPD</code> signed by the owner's key):</p>
<table class="pricing">
<tr><th>Record</th><th>Who can register</th><th>How it is enforced</th></tr>
<tr><td><code>hidden: 1</code> (switched off)</td>
<td>Only the owner, from the dashboard. Off the public list.</td>
<td>Co-sign rule (below).</td></tr>
<tr><td><code>policy: "cosign"</code></td>
<td>Anyone, but every registration needs the owner's approval.</td>
<td>Co-sign rule (below).</td></tr>
<tr><td><code>policy: "frozen"</code></td>
<td>Nobody, owner included.</td>
<td>Resolvers drop every new registration.</td></tr>
</table>
<h3 style="margin-top:1.4rem">The co-sign rule</h3>
<p>A registration under a <code>cosign</code> or <code>hidden</code> TLD is only recognised
when the same transaction also <b>carries the TLD's own certificate</b> — the TLD NFT
goes in as an input and comes back out to its owner. Only the owner's key can spend that
NFT, so its presence is a signature nobody can forge, and nothing is consumed: the
certificate returns in the same transaction. Every conforming client (gateway, Theseus,
Ariadne desktop and mobile) applies the rule when it builds its index, judging each
registration against the TLD policy <b>in force at that block</b>, so switching a TLD
off later never invalidates names registered while it was open.</p>
<ol class="steps">
<li><b>Owner registering under a private TLD.</b>
<span>Open the TLD in the dashboard, type a label, register. The certificate is added
from your own wallet; you pay only the platform share of the name price.</span></li>
<li><b>Anyone registering under a co-sign TLD.</b>
<span>The normal register flow builds the full transaction with the owner's certificate
as its last input, you sign your part, and the request waits in the gateway's approval
queue (<code>POST /api/cosign</code>). Nothing leaves your wallet until the owner
acts; requests expire after 7 days.</span></li>
<li><b>Owner approving.</b>
<span>Dashboard → the TLD → <b>Pending approvals</b>. Approve signs the certificate
input and broadcasts; Decline removes the request. The wallet refuses to sign any
request that would not return the certificate to you.</span></li>
</ol>
<div class="note"><b>Why not a covenant?</b> A covenant-gated mint is the mainnet plan for
fee enforcement; the co-sign rule needs no new script, works today with plain P2PKH
certificates, and gives the owner a human veto rather than a formula.</div>
</section>
<section id="market">
<h2>Buying &amp; selling names</h2>
<p class="lede">Any name can be sold to anyone, in <b>one transaction, with no escrow</b>.
The seller is paid exactly when the certificate moves — or not at all.</p>
<ol class="steps">
<li><b>Seller lists.</b>
<span>Dashboard → the name → <b>Sell</b>, set a price. Your wallet signs a partial
transaction — your certificate as input 0, the price to you as output 0 — with
<code>SIGHASH_SINGLE | ANYONECANPAY</code>. That signature says "whoever completes this
pays me this much"; it constrains nothing else. The gateway stores it and shows it on
the <a href="../market.html">market</a> after checking the signature, the on-chain
owner and that the certificate is still unspent.</span></li>
<li><b>Buyer completes.</b>
<span>Verify the offer locally, add your coins, add the certificate output to your own
token address plus a registry update so every resolver learns the new owner, sign your
inputs, broadcast. The seller's signature is already in place.</span></li>
<li><b>Seller cancels.</b>
<span>Cancelling removes the offer from the market and moves the certificate once (a
no-op update, a few cents), so the signed offer can never be completed afterwards.</span></li>
</ol>
<div class="note"><b>Trust model.</b> The gateway is a bulletin board. A forged or stale
listing fails the buyer's local check or the broadcast; a buyer can never pay without
receiving the certificate in the same transaction, and a seller can never lose the
certificate without being paid. Endpoints: <code>GET /api/market</code>,
<code>GET /api/market/&lt;name&gt;</code>, <code>POST /api/market</code> (a signed listing),
<code>DELETE /api/market/&lt;name&gt;</code> (owner-signed
<code>BNS-MARKET1
&lt;name&gt;
&lt;ts&gt;</code>).</div>
</section>
<section id="records">
<h2>Records &amp; hosting</h2>
<p class="lede">A registered name carries a small JSON records object. Every record is
optional and multiple can coexist. Priority order the gateway uses:
<code>h</code> (inline HTML) → <code>s3</code> (Sia bucket key) → <code>ip</code>
(host header served by an IP) → <code>u</code> (redirect).</p>
<table class="pricing">
<thead><tr><th>Record</th><th>Meaning</th><th>Typical use</th></tr></thead>
<tbody>
<tr><td><code>h</code></td><td>Inline HTML in the OP_RETURN payload itself</td><td>Tiny sites, a profile, a link hub</td></tr>
<tr><td><code>s3</code></td><td>A Sia bucket key (with auto-index for directory-style)</td><td>Multi-file sites, permanent hosting</td></tr>
<tr><td><code>ip</code></td><td>An IPv4 address + optional <code>tls</code> fingerprint</td><td>Your own server, apps behind an IP</td></tr>
<tr><td><code>u</code></td><td>Redirect URL</td><td>Short-form redirects to any web host</td></tr>
<tr><td><code>tls</code></td><td>SHA-256 fingerprint of the leaf cert served at <code>ip</code></td><td>Chain-pinned TLS trust, no OS root store needed</td></tr>
<tr><td><code>np</code>, <code>nr</code></td><td>Nostr pubkey + relay list</td><td>Hermes / NIP-17 messaging bound to the name</td></tr>
<tr><td><code>el</code></td><td>Space-separated electrum server list</td><td>On-chain-updatable resolver bootstrap</td></tr>
</tbody>
</table>
<p class="lede" style="margin-top:1rem">Subdomains inherit from their parent with a slight
priority tweak: for a subdomain query, <code>ip</code> beats <code>s3</code>
(Host-header semantics). Full rule is in <code>Argus/src/lib/record-picker.js</code>.</p>
</section>
<section id="signed-records">
<h2>Free edits — signed off-chain records</h2>
<p class="lede">The on-chain records above (<code>h</code>, <code>s3</code>, <code>ip</code>, <code>u</code>,
<code>tls</code>, <code>np</code>, <code>el</code>) cost a chain transaction to change and are capped
at 200 bytes of OP_RETURN. For DNS-style records (A / AAAA / MX / TXT / CNAME / NS) and any records
you edit often, Sirius.X uses a companion mechanism: a <b>signed off-chain manifest</b> that costs
nothing per change and has no size cap.</p>
<p class="lede" style="margin-top:1rem"><b>The chain says who owns the name. A signed blob says what
the records are. Resolvers verify both.</b> No third party is trusted for records: the manifest is
signed by the same key that holds the on-chain NFT certificate, so an operator (or Sia farmer, or
anyone else in the middle) can't rewrite records without breaking the signature.</p>
<table class="pricing" style="margin-top:1.2rem">
<thead><tr><th>Concern</th><th>Where it lives</th><th>Cost per change</th></tr></thead>
<tbody>
<tr><td>Who owns the name</td><td>Bitcoin Cash chain (NFT certificate)</td><td>1 tx to transfer</td></tr>
<tr><td>Where the site lives</td><td>Chain record: <code>s3</code>, <code>ip</code>, <code>u</code>, <code>h</code></td><td>1 tx per change</td></tr>
<tr><td>DNS records, meta, TXT churn, etc.</td><td>Sia at <code>&lt;s3-bucket&gt;/_records.json</code></td><td><b style="color:var(--acid)">free</b></td></tr>
</tbody>
</table>
<h3 style="margin-top:1.4rem">How the manifest is verified</h3>
<ol class="steps" style="counter-reset:s">
<li><b>Resolver reads</b> the name's chain record, follows <code>records.s3</code> to the Sia bucket,
fetches <code>_records.json</code>.</li>
<li><b>Signature check</b> — recovers the signing pubkey from the manifest's <code>sig</code> field,
derives the CashAddress, compares to the current NFT-holder address from the chain. Mismatch = reject.</li>
<li><b>Replay check</b> — the manifest carries a monotonic <code>seq</code> number. Resolvers cache the
highest seen and reject anything less-or-equal. An old signed blob can't be re-served.</li>
<li><b>Fall-back</b> — if the manifest is missing, invalid, or its signature doesn't match, the resolver
silently falls back to the on-chain records. Signed records never override a name; they extend it.</li>
</ol>
<h3 style="margin-top:1.4rem">The manifest shape</h3>
<pre style="background:#0e131b;border:1px solid var(--line);border-radius:10px;padding:14px 16px;overflow-x:auto;font-family:ui-monospace,monospace;font-size:12.5px;line-height:1.6;color:var(--ink);white-space:pre;margin-top:.6rem">{
"v": 1,
"name": "bitcoin.cash",
"seq": 42,
"updated_at": "2026-09-15T00:00:00Z",
"dns": {
"A": ["1.2.3.4"],
"AAAA": ["2001:db8::1"],
"MX": [{"pref": 10, "host": "mail.example.com"}],
"TXT": ["v=spf1 include:_spf.silentmode.st -all"],
"CNAME": null,
"NS": []
},
"sig": "&lt;BCH message signature over sha256(canonical bytes)&gt;"
}</pre>
<p class="lede" style="margin-top:.8rem">Canonicalisation: sorted keys, no whitespace, <code>null</code>
fields omitted. The signable bytes are the manifest with the <code>sig</code> field removed. Full
spec: <a href="./DESIGN-signed-records-manifest.md"><code>DESIGN-signed-records-manifest.md</code></a>
— signable byte order, seq-monotonicity rules, threat model, v2 roadmap.</p>
<h3 style="margin-top:1.4rem">Endpoints</h3>
<table class="pricing">
<thead><tr><th>Method</th><th>Path</th><th>Effect</th></tr></thead>
<tbody>
<tr><td><b>GET</b></td><td><code>/api/records/&lt;name&gt;</code></td><td>Fetches the raw signed manifest from the name's Sia bucket. Public, cacheable.</td></tr>
<tr><td><b>POST</b></td><td><code>/api/records/&lt;name&gt;</code></td><td>Accepts a signed manifest, verifies against the on-chain owner + seq monotonicity, uploads to Sia.</td></tr>
<tr><td><b>GET</b></td><td><code>/api/dns/&lt;name&gt;</code></td><td><b>Resolver read.</b> Fetches the manifest, verifies the signature against the on-chain owner and rejects rollback of the seq, then returns <em>only</em> the verified <code>dns</code> block. Callers can trust the response without doing their own signature or chain lookups. 30-second cache hint.</td></tr>
</tbody>
</table>
<p class="lede" style="margin-top:.8rem">The distinction between <code>/api/records/&lt;name&gt;</code>
and <code>/api/dns/&lt;name&gt;</code> is deliberate: the former is transparent (raw manifest as
uploaded, including the signature so clients can re-verify), the latter is opinionated (only the
verified DNS records, with the gateway having done the sig + seq work). Bridges and shims should
use <code>/api/dns/</code>; wallets and tools that want to see the full signed blob should use
<code>/api/records/</code>.</p>
<p class="lede" style="margin-top:.8rem">A name needs <code>records.s3</code> set on chain first —
without a storage pointer, the manifest has nowhere to live. Portal and CLI both refuse to
publish a manifest until <code>s3</code> is present.</p>
<div class="note" style="margin-top:1.2rem">
<b>Threat model at a glance.</b> Operator tampers → sig check fails, resolver falls back to chain
records. Replay of an old blob → seq check fails. Owner's key compromised → same as chain-side
compromise; move the name to a new key. Sia object deleted → name still resolves via chain
records, DNS records disappear until republished. Hostile gateway can refuse writes but cannot
forge them; users can PUT directly to Sia with their own credentials to bypass.
</div>
</section>
<section id="host">
<h2>Host your name</h2>
<p class="lede">The end-to-end recipe for putting a static site under a BCNR name. Chipnet
today, mainnet later — the shape is the same. Three ways to host, most people combine
two of them (Sia + VPS mirror) so the site keeps serving if either mirror goes down.</p>
<h3>Pattern A — Sia only</h3>
<p class="lede">Simplest. Site lives on the Sia storage network, name's <code>s3</code> record
points at the bucket key, gateways (navigate.st, silentmode.st, any BCNR-aware browser)
fetch it on demand. Same pattern <code>silentmode.bch</code> uses.</p>
<pre># From a checkout with sia-s3.json credentials:
node Argus/src/lib/sia-upload.js ./my-site bns/myname/
# Set the chain record (once). Note the trailing slash — enables auto-index
# so /myname/ serves myname/index.html and /myname/about/ serves .../about/index.html.
node Argus/src/update.js myname.x '{"s3":"bns/myname/"}'</pre>
<p class="lede">Bucket-path convention: <code>bns/&lt;label&gt;/</code> (no TLD; the label is
unique enough within our Sia namespace and keeps game.x + game.bch from colliding). Files
update by re-running sia-upload; the chain record only changes when the bucket path does.</p>
<h3>Pattern B — Your own server (VPS + <code>ip</code>)</h3>
<p class="lede">Point the name at an IP; every request goes directly to your box. Add a
<code>tls</code> record with the SHA-256 of the leaf certificate so browsers verify the
connection against the chain instead of the OS trust store.</p>
<pre># On your VPS: nginx serves your site over TLS. Then, on chain:
node Argus/src/update.js myname.x '{"ip":"1.2.3.4","tls":"&lt;sha256-of-leaf-cert&gt;"}'</pre>
<h3>Pattern C — Dual host (Sia primary, VPS mirror)</h3>
feat(sirius-x): Sirius.X brand rebrand, banner star-divider, WC on portal Three things from one review pass: 1. Rebrand text 'sirius.x' -> 'Sirius.X' as the brand style across all sirius.x pages (titles, meta, nav wordmark, headings, prose, footer). Also flipped the pantheon headings to Title.X form: Silentmode.X, Sirius.X, Theseus.X, Hephaestus.X, Prometheus.X, Helios.X, Hermes.X. Domain literals, URLs, and code samples stay lowercase (sirius.x is the actual on-chain name; only prose changes). Logo/avatar SVG wordmarks and aria-labels updated to match. 2. Banner (brand/banner.svg) redesigned around a centered layout: 'Sirius.X' wordmark above, the star's horizontal arm extended edge-to-edge as a divider line, tagline lines below. Left tip at (0,315), right tip at (1200,315) so the arm crosses the full 1200px banner width; vertical body compact around center. Old layout had the star crammed into the right half and the wordmark on the left. 3. WizardConnect wired up on portal.html: - The 'Connect wallet' button now opens a real WC session via wizardconnect.js, shows the WIZ:// URI (copyable) and waits for the wallet to approve. - Successful connection builds a wallet-shaped wrapper with source: 'wc' and a WC session for signing; siriusProfile now carries the source so the nav dropdown can differentiate. - Record editor dispatches to setRecordsWithExternalWallet when source === 'wc' (bundle already ships the adapter), else stays on setRecordsWithBuiltInWallet. - TLD Register submit is gated off for WC users with a tooltip — no external-wallet variant of registerTld is exported yet, so TLD mint still needs a built-in wallet. - Sign-out disconnects the WC session before dropping the wallet. - toTokenAddress used to derive the tokenAddress for WC users so the 'Signed in' card shows both forms.
2026-09-07 01:35:35 +02:00
<p class="lede">What Sirius.X itself uses. Sia is the chain-authoritative source (survives
if the VPS is down); the VPS serves the same content on <code>silentmode.st/&lt;path&gt;</code>
for users without a BCNR resolver installed. On the VPS side, extend the nginx vhost
serving <code>silentmode.st</code> with a new <code>location</code> block that aliases
straight from disk:</p>
<pre>location /myname-x/ {
alias /opt/silent-mode/site-myname-x/;
index index.html;
try_files $uri $uri/ =404;
}</pre>
<p class="lede">Then rsync / scp your site tree to <code>silentmode:/opt/silent-mode/site-myname-x/</code>
and reload nginx. This gives you two URLs for the same content:
<code>https://silentmode.st/myname-x/</code> (VPS-direct) and the chain-authoritative
<code>https://myname.x/</code> via any BCNR resolver.</p>
<h3>The dual-host recipe, end to end</h3>
feat(sirius-x): Sirius.X brand rebrand, banner star-divider, WC on portal Three things from one review pass: 1. Rebrand text 'sirius.x' -> 'Sirius.X' as the brand style across all sirius.x pages (titles, meta, nav wordmark, headings, prose, footer). Also flipped the pantheon headings to Title.X form: Silentmode.X, Sirius.X, Theseus.X, Hephaestus.X, Prometheus.X, Helios.X, Hermes.X. Domain literals, URLs, and code samples stay lowercase (sirius.x is the actual on-chain name; only prose changes). Logo/avatar SVG wordmarks and aria-labels updated to match. 2. Banner (brand/banner.svg) redesigned around a centered layout: 'Sirius.X' wordmark above, the star's horizontal arm extended edge-to-edge as a divider line, tagline lines below. Left tip at (0,315), right tip at (1200,315) so the arm crosses the full 1200px banner width; vertical body compact around center. Old layout had the star crammed into the right half and the wordmark on the left. 3. WizardConnect wired up on portal.html: - The 'Connect wallet' button now opens a real WC session via wizardconnect.js, shows the WIZ:// URI (copyable) and waits for the wallet to approve. - Successful connection builds a wallet-shaped wrapper with source: 'wc' and a WC session for signing; siriusProfile now carries the source so the nav dropdown can differentiate. - Record editor dispatches to setRecordsWithExternalWallet when source === 'wc' (bundle already ships the adapter), else stays on setRecordsWithBuiltInWallet. - TLD Register submit is gated off for WC users with a tooltip — no external-wallet variant of registerTld is exported yet, so TLD mint still needs a built-in wallet. - Sign-out disconnects the WC session before dropping the wallet. - toTokenAddress used to derive the tokenAddress for WC users so the 'Signed in' card shows both forms.
2026-09-07 01:35:35 +02:00
<p class="lede">This is the exact sequence Sirius.X itself uses on every publish. The
chain record stays constant; only file contents change, so no per-publish UPD is
needed.</p>
<ol class="steps">
<li><b>Edit locally.</b>
<span>Site source lives at <code>site-myname-x/</code> in your working repo. Any
static generator works (or plain HTML) — the deploy is content-agnostic.</span></li>
<li><b>Push VPS mirror (fast path).</b>
<span>Serves at <code>silentmode.st/myname-x/</code> within seconds. Users without a
BCNR resolver hit this route.
<pre>scp -r site-myname-x/* silentmode:/opt/silent-mode/site-myname-x/</pre></span></li>
<li><b>Push Sia mirror (durable copy).</b>
<span>Serves at <code>sirius.x/</code> via any BCNR gateway. Survives VPS outage.
<pre>node Argus/src/lib/sia-upload.js site-myname-x/ bns/myname/</pre></span></li>
<li><b>Verify both.</b>
<span><code>curl -so /dev/null -w "%{http_code}\n" https://silentmode.st/myname-x/</code>
and <code>curl -so /dev/null -w "%{http_code}\n" https://silentmode.st/bns/myname.x/</code>
— both should return 200.</span></li>
</ol>
<h3>Auto-backup: one command, both mirrors</h3>
<p class="lede">Wrap the two commands into a script so every publish reaches both mirrors
without extra thought. This is exactly what a two-liner deploy hook looks like:</p>
<pre># scripts/deploy-myname-x.sh
#!/usr/bin/env bash
set -eu
SRC="$(dirname "$0")/../site-myname-x"
VPS_DEST="silentmode:/opt/silent-mode/site-myname-x/"
SIA_BUCKET="bns/myname/"
echo "→ VPS mirror"
scp -qr "$SRC"/. "$VPS_DEST"
echo "→ Sia mirror"
node "$(dirname "$0")/../Argus/src/lib/sia-upload.js" "$SRC" "$SIA_BUCKET"
echo "✓ deployed; verifying"
for url in "https://silentmode.st/myname-x/" "https://silentmode.st/bns/myname.x/"; do
code=$(curl -so /dev/null -w '%{http_code}' "$url")
printf ' %s → %s\n' "$url" "$code"
done</pre>
<p class="lede">Wire it into git: <code>chmod +x scripts/deploy-myname-x.sh</code>, add a
<code>.git/hooks/post-commit</code> that runs it if the site subtree changed, or invoke
manually. Sia uploads that fail (network hiccup, quota) leave the VPS mirror ahead until
the next run — same failure mode as any staged deploy.</p>
<h3>Automate the reverse — VPS → Sia periodic backup</h3>
<p class="lede">If your primary publish path is straight-to-VPS (nginx-direct, no Sia
step per publish), a cron job can pull the VPS state and push to Sia on a schedule:</p>
<pre># /etc/cron.d/sirius-x-sia-backup (on the operator's VPS)
17 * * * * root cd /opt/silent-mode && node Argus/src/lib/sia-upload.js \
/opt/silent-mode/site-myname-x/ bns/myname/ &gt;/var/log/sia-backup.log 2&gt;&amp;1</pre>
<p class="lede">Runs hourly at :17 (offset from the top of the hour so it doesn't collide
with everyone else's cron traffic). The tradeoff: up to an hour of drift between VPS
and Sia after a publish — usually fine, since the chain record still resolves
correctly either way and BCNR gateways cache Sia content.</p>
<div class="note"><b>Which mirror is authoritative?</b> The one your chain record points
at. If <code>s3</code> is set, gateways fetch from Sia; the VPS mirror is just a
convenience URL. If only <code>ip</code> is set, gateways fetch from the VPS; Sia is
just backup. If BOTH are set, gateways pick per the priority in the "Records" section
(subdomain-aware; see <code>record-picker.js</code>). Set both for durability, but be
deliberate about which is primary.</div>
<h3>Verify records changed correctly</h3>
<pre>node --input-type=module -e "
import { loadWallet } from './Argus/src/lib/wallet.js';
import { resolveName } from './Argus/src/lib/bns.js';
const w = await loadWallet('main');
console.log(await resolveName(w.provider, 'myname.x'));
process.exit(0);"</pre>
<div class="note"><b>Credentials.</b> Sia upload needs <code>Argus/sia-s3.json</code>. VPS
deploy needs SSH to the operator's box. Neither is in the repo — a session that isn't
run by the operator will need those handed over out-of-band. Full command reference is in
<a href="INSTRUCTIONS.md">INSTRUCTIONS.md</a>, especially §5 (Sia storage) and §6
(deploy).</div>
</section>
<section id="resolver">
<h2>Resolver / gateway</h2>
<p class="lede">Three paths, same chain data. Anyone can pick.</p>
<ol class="steps">
<li><b>Local — Ariadne Resolver.</b>
<span>A system-wide resolver that intercepts BCNR TLDs and answers them from the
chain. Any browser you already use starts opening <code>.bch</code> URLs directly.
Installs a local root CA for TLS.
<a href="../theseus/">Download →</a></span></li>
<li><b>In-browser — Theseus Navigator.</b>
<span>A Chromium build with the resolver baked in, plus an on-chain TLS trust anchor.
No OS trust-store install; nothing modified globally.
<a href="../theseus/">Download →</a></span></li>
<li><b>Public gateway — navigate.st.</b>
<span>For anyone without the resolver installed:
<code>https://navigate.st/bns/&lt;name&gt;/</code> proxies through a hosted resolver.
Same content, fewer guarantees — trust the gateway to fetch honestly, or run one of
the first two.</span></li>
</ol>
</section>
<section id="pricing">
<h2>Pricing (mainnet)</h2>
<p class="lede">On mainnet the covenant enforces USD-denominated floors, tiered by TLD
label length. This is what keeps someone from land-grabbing every ICANN TLD in one
afternoon. TLD registration is <b>one-time</b> — a TLD is closer to a domain purchase
than a lease.</p>
<table class="pricing">
<thead><tr><th>Label length</th><th>Floor (USD)</th><th>Notes</th></tr></thead>
<tbody>
<tr><td>1 char</td><td class="price">100,000</td><td>Effectively unique; ENS-like scarcity</td></tr>
<tr><td>2 char</td><td class="price">50,000</td><td>The <code>.ai</code> / <code>.io</code> tier</td></tr>
<tr><td>3 char</td><td class="price">15,000</td><td>Order of magnitude below ICANN's $185k application floor</td></tr>
<tr><td>4 char</td><td class="price">5,000</td><td>Floor for short but reasonable TLDs</td></tr>
<tr><td>58 char</td><td class="price">1,000</td><td>Bulk-registerable but not spam</td></tr>
<tr><td>9+ char</td><td class="price">250</td><td>Descriptive TLDs, low economic gravity</td></tr>
</tbody>
</table>
<p class="lede" style="margin-top:1rem">On <b>name registration under a TLD</b>, the TLD's
owner collects a share (<code>fee_bps</code>, default 5%, cap 50%). Chain-enforced when
the TLD's policy is <code>covenant</code>; honour-system otherwise. Name registration is
yearly and priced separately.</p>
<p class="lede" style="margin-top:1rem">The TLD owner also sets what names under it <b>sell for</b> and whether the TLD is <b>on or off</b>, straight from the portal: a <code>price</code> record (flat USD per name, replaces the length tiers for every buyer) and a <code>hidden</code> record (<code>1</code> makes it a <b>private TLD</b>: off the public list, nobody but the owner can register names under it — the owner still can from the portal, paying only the platform share — until it is switched back on). Both ride the same signed <code>TUPD</code>, so every client reads them from the chain; the owner keeps 90% of each sale.</p>
</section>
<section id="tracker">
<h2>Tracker &amp; mirrors</h2>
<p class="lede">A tracker publishes signed snapshots of the TLD registry to Sia and Nostr so
downstream clients don't have to walk the chain themselves. The chain is authoritative;
the tracker is speed. Every snapshot carries a <b>root</b> hash anyone can recompute
locally — a lying mirror is caught by any recipient who bothers to check.</p>
<p class="lede">A conforming client falls through: (1) fetch snapshot from a mirror,
(2) verify <code>root</code>, (3) if suspicious, walk the beacon and rebuild. All three
yield the same list for any given block height.</p>
</section>
<section id="verify">
<h2>Verify anything</h2>
<p class="lede">You do not have to trust that sirius.x, silentmode.st, or navigate.st are
serving honest content. Every name's certificate is on chain; every record is a signed
on-chain payload; every host is checkable independently.</p>
<h3>Confirm a specific name on chain</h3>
<pre>node --input-type=module -e "
import { loadWallet } from './Argus/src/lib/wallet.js';
import { resolveName } from './Argus/src/lib/bns.js';
const w = await loadWallet('main');
console.log(await resolveName(w.provider, 'sirius.x'));
process.exit(0);"</pre>
<h3>Fetch the operator-signed TLD snapshot from Nostr</h3>
<dl class="verify">
<dt>Kind / d-tag</dt>
<dd>30078 / bns-tld-list</dd>
<dt>Pubkey (x-only, hex)</dt>
<dd>f2c925194c531c7c398017e35b2396df64a61a613aa5fadebdf1f4990f2267f4</dd>
<dt>Relays</dt>
<dd>wss://nos.lol · wss://relay.damus.io</dd>
</dl>
<h3>Reach any site via more than one route</h3>
<p class="lede">Same content should be served from at least two independent paths:</p>
<ul style="color:var(--mut);font-size:14px;margin:.6rem 0 0;padding-left:1.2rem">
<li>Direct BCNR: <code>https://&lt;name&gt;/</code> (requires local resolver + CA)</li>
<li>Public gateway: <code>https://navigate.st/bns/&lt;name&gt;/</code></li>
<li>silentmode.st mirror: <code>https://silentmode.st/bns/&lt;name&gt;/</code></li>
<li>Direct from Sia (content-addressed) via the name's <code>s3</code> record</li>
</ul>
</section>
<section id="runbook">
<h2>Operator runbook</h2>
<p class="lede">These docs describe <i>what</i>. The <i>how</i> — exact bash commands to
register TLDs, mint names, update records, and deploy — is
<code>INSTRUCTIONS.md</code>. Three ways to read it, in order of "how much do I already
have installed":</p>
<ol class="steps">
<li><b>Just read it in the browser</b>
<span>Served straight from the docs directory:
<a href="INSTRUCTIONS.md">/sirius-x/docs/INSTRUCTIONS.md</a>. Plain text; every
browser renders it.</span></li>
<li><b>Clone the git remote</b>
<span><code>git clone https://silentmode.st/sirius-x/repo/silent-mode.git</code> — dumb-HTTP,
no auth. Get the whole tree, browse offline, run the scripts.</span></li>
<li><b>Browse the Forgejo mirror</b>
<span>Repo lives at
<a href="https://code.silentmode.st/silentmode/sirius">code.silentmode.st/silentmode/sirius</a>
on the Silent Mode Hephaestus forge. Rendered runbook:
<a href="https://code.silentmode.st/silentmode/sirius/src/branch/master/docs/INSTRUCTIONS.md">docs/INSTRUCTIONS.md</a>.
Clone: <code>git clone https://code.silentmode.st/silentmode/sirius.git</code> — public,
no auth.</span></li>
</ol>
<p class="lede">The runbook covers CLI name registration, TLD-registry seeding, record
updates, Sia upload, VPS deploy, tests, and the historically-costly gotchas.</p>
</section>
</div>
</div>
</div>
feat(sirius-x): footer everywhere, redesigned wallet button, dropdown auto-acts Three UX fixes: 1. Beautiful footer on every page. Extracted the 4-column landing footer into js/site-footer.js — reads the nav brand link to derive per-page base ('./' at root, '../' in subdirs) so links resolve from any depth without duplicating the HTML across 8 pages. Every page now ships an empty <footer id="site-footer"></footer> and includes the injector; inline footer + its CSS block removed from landing too so the source stays in one place. 2. Wallet button redesign. Pill now shows a state dot (dim when not signed in, green with subtle glow when signed in), a monospace short address label when signed in ('qra6rs…7yl2') OR 'Wallet' when not, a WC/seed badge on signed-in state, and a subtle caret. Full border and hover states, proper aria-expanded/aria-label wiring. Dropdown menu itself upgraded: grid layout per item (icon column + title + hint), heavier backdrop blur, larger min-width, clearer typography. 3. Dropdown options actually do something. Removed the redundant 'Open sign-in page →' item — the other three all land on portal too, so listing 'open the page' as a fourth option was noise. On portal arrival, the ?mode= handler now AUTO-TRIGGERS the primary action for each mode: new -> click Generate a phrase (12 words appear immediately) import -> focus the seed textarea (cursor ready to paste) wc -> click Connect wallet (WC session starts, URI shown) No extra clicks between dropdown choice and the flow it names. Cache-buster on the profile-menu.js include bumped to ?v=20260907wallet so cached copies pick up the new design; footer injector at ?v=20260907rel.
2026-09-07 22:00:21 +02:00
<footer id="site-footer"></footer>
<script src="../js/session.js?v=20260917dash"></script>
feat(sirius-x/signin): PIN escrow — encrypted-at-rest quick unlock, 3-strike password fallback Removes the sessionStorage plaintext-mnemonic cache (fixed under the same commit) and replaces it with a PIN-encrypted blob in localStorage. No plaintext secret ever touches disk or memory outside the live BuiltInWallet object. New js/pin-escrow.js — WebCrypto PBKDF2(50k) + AES-GCM(256). Public API on window.siriusPin: savePinBlob(mnemonic, pin), tryUnlock(pin), hasPin(), attemptsUsed(), attemptsRemaining(), clear(), MAX_ATTEMPTS. Iteration count is lighter than BuiltInWallet's 250k because a 4-6 digit PIN's key space is small anyway; the point is 'not plaintext at rest,' not brute-force resistance — the durable secret is the full password. register-flow.js: - After a fresh password unlock (Import / Create / Unlock), stepSetPin offers a 4-6 digit PIN with confirm — skippable with 'Not now'. Never overwrites an existing PIN blob. - stepUnlock now shows a numeric PIN pad when a PIN blob is present; the password field only appears when the user opts to 'Use password instead' or after the blob was wiped. - Wrong PIN → increment counter, surface 'N attempts left'. Third wrong PIN → wipe blob and route to a 'PIN reset' screen that hands off to the password form. - Correct PIN → decrypt the mnemonic in-browser, rebuild the BuiltInWallet, finishSignIn(). Attempt counter resets to 0. profile-menu.js: - Sign-out clears the PIN blob (via siriusPin.clear()) alongside the siriusProfile so the device isn't quick-unlockable with a stale PIN. All pages that host the sign-in flow now include pin-escrow.js. Same tabbed layout in stepUnlock — the PIN pad and the password field both live under 🔓 Unlock, transparent tab-switch works exactly as before. Verified live: - Fresh Import → 'Set a PIN' step → 4242 confirmed → blob written - Reload → PIN pad, 3 attempts remaining - Correct PIN 4242 → signed in, counter resets to 0 - 3 wrong PIN attempts → 'Wrong PIN — N attempts left' per attempt, then 'PIN locked — enter your full password to continue', blob wiped, next reload shows the password form - localStorage contains only ciphertext + salt + iv + counter; no plaintext mnemonic anywhere on disk or in sessionStorage.
2026-09-09 01:31:18 +02:00
<script src="../js/pin-escrow.js?v=20260909pin"></script>
feat(bns): name marketplace and TLD-owner co-sign rule Two gaps the owner panel left open. First, a hidden TLD was only a UI gate: anyone could still broadcast a REG under it and every indexer admitted it. Second, there was no way to sell a name without trusting the other side. Co-sign rule (consensus, applied in lockstep by bns.js and resolver-web.js): a REG under a TLD whose records at that height say policy "cosign" or hidden 1 is indexed only if the transaction carries the TLD's own certificate. The certificate can only be spent by the owner's key and is re-issued to them in the same transaction, so it is a co-signature nobody can forge and nothing is consumed. The TLD map now keeps the TUPD timeline so policy is evaluated at the REG height. Owners register under their private TLDs with the certificate added from their own wallet; third parties under a "cosign" TLD build the full transaction, sign their inputs and queue it at /api/cosign, where the owner approves it from the dashboard (signCosignRequest refuses to sign unless the certificate returns to the same locking script). Marketplace: a listing is the seller's certificate input plus a price output signed SIGHASH_SINGLE|ANYONECANPAY, stored by the gateway as a bulletin board (/api/market, verified against the on-chain owner and pruned when the certificate moves). The buyer completes it in one transaction, so the seller is paid exactly when the name moves. Cancelling also spends the certificate once so the offer is void. Site: market.html, Sell sub-tab and Pending approvals in the portal, Market link in nav and footer, six dictionaries extended, cache tags bumped. Verified on chipnet: cosigned.sc registered by a throwaway wallet through the queue with the .sc certificate back at the owner; aloevera.test listed and delisted through the API. Ariadne's resolver-web.js copy and the mobile Bns.java port still need the co-sign rule; until then they admit REGs this index rejects.
2026-09-17 04:04:22 +02:00
<script src="../js/pricing.js?v=20260917market"></script>
<script defer src="../js/site-footer.js?v=20260917market"></script>
feat(sirius-x): Deviant sky palette + Fraunces/Ubuntu reader toggle Design translated from the /design canvas review. Sirius.X now shares Deviant's "signal" theme background (layered sky-rim/mid gradients over #050810) and the Silent Mode family typography stack. Typography: Fraunces (opsz variable serif) headings h1/h2/h3 DM Sans body / UI JetBrains Mono code, hashes, mono cells Ubuntu opt-in Bitcoin Cash brand font, swaps everything at :root when <html data-font-cmp="ubuntu"> All via Google Fonts, one <link> per page. Font picker (js/theme.js): Small pill in the topnav (Fraunces default / Ubuntu alt) — persisted to localStorage.sirius-font. Sets the data-font-cmp attribute; the swap CSS lives in each page's <style> block so !important overrides page-local font-family declarations at the necessary specificity. Mono elements stay JetBrains Mono under both fonts. Palette (cool sky vs old flat dark navy): --bg #0b0e14 → #050810 --panel2 #18202c → #0a0f1c (matches Deviant --sky-mid) --line rgba(255,255,255,.09) → .06 --ink #e7eaf1 → #f1f4fa --mut #8b98a9 → #b8c2d4 --dim #5e6678 → #6a7488 new: --sky-rim #131a2a, --chain-native #0AC18E (BCH brand green, reserved for chain-native badges/proofs like the Bitcoin.Cash body copy) Copy — "no renewals" softened everywhere it appeared. Renewals will be a per-TLD policy set by each TLD owner; the flat claim was wrong across the board. Landing card, tld.html hero and body, plus the og:description all updated. Applied to: index.html, portal.html, tld.html, theseus/index.html, brand/index.html, docs/index.html, admin/index.html.
2026-09-10 00:25:18 +02:00
<script defer src="../js/theme.js?v=20260910font"></script>
<script defer src="../js/profile-menu.js?v=20260920m"></script>
</body>
</html>