sirius/portal.html

714 lines
48 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">
<title>Dashboard — your names on Sirius.X</title>
<meta name="description" content="Manage every BCNR name and TLD your wallet holds: DNS records, content, redirects, transfers, TLD pricing. Your keys never leave the browser.">
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 dashboard — your BCNR names">
<meta property="og:description" content="Manage DNS, content, redirects and TLD policy for every name your wallet holds. Keys never leave the browser.">
<meta property="og:url" content="https://silentmode.st/sirius-x/portal.html">
<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);
--sky-mid:#0a0f1c; --sky-rim:#131a2a;
--ink:#f1f4fa; --mut:#b8c2d4; --dim:#6a7488; --acid:#d6ff3d;
--chain-native:#0AC18E;
--ok:#4fd1a5; --taken:#f6768a; --warn:#ffc75f;
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
--serif:'Fraunces',Georgia,serif;
--sans:'DM Sans','Inter',system-ui,sans-serif;
--mono:'JetBrains Mono',ui-monospace,monospace;
}
*{box-sizing:border-box}
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%,var(--sky-rim) 0%,transparent 60%),
radial-gradient(ellipse 900px 500px at 100% 100%,var(--sky-mid) 0%,transparent 55%),
radial-gradient(ellipse 900px 500px at 0% 100%,#0c1424 0%,transparent 55%),
var(--bg);
background-attachment:fixed;
color:var(--ink);font:15px/1.55 var(--sans);min-height:100vh;font-feature-settings:"ss01","ss02"}
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
h1,h2,h3{font-family:var(--serif);font-feature-settings:"ss01","ss02"}
code,.mono{font-family:var(--mono)}
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:var(--mono) !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:var(--mono);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;transition:color .12s}
.font-picker button:hover{color:var(--ink)}
.font-picker button.active{background:var(--acid);color:var(--bg);font-weight:600}
a{color:var(--acid)}
.wrap{max-width:820px;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)}
.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:3rem 1.2rem 1rem}
.mark{font-size:44px;line-height:1}
h1{font-size:clamp(1.6rem,4.5vw,2.2rem);margin:.3rem 0 .3rem}
h1 .g{color:var(--acid)}
.tag{color:var(--mut);font-size:1rem;max-width:580px;margin:0 auto}
h2{font-size:1.35rem;margin:0 0 .3rem}
h3{font-size:1.05rem;margin:0 0 .3rem}
section{padding:2rem 0;border-top:1px solid var(--line);margin-top:2rem}
section:first-of-type{border-top:none;margin-top:1rem}
.card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:20px 22px;margin-top:1rem}
label{display:block;font-size:13px;color:var(--mut);margin:14px 0 5px}
textarea,input[type=password],input[type=text],input[type=number],select{
width:100%;padding:10px 12px;border-radius:10px;border:1px solid #ffffff22;background:#0e131b;
color:var(--ink);font-size:14px;font-family:inherit;outline:none
}
select{appearance:auto}
textarea{min-height:74px;resize:vertical;font-family:var(--mono);font-size:13px}
textarea:focus,input:focus,select:focus{border-color:#4b7bec}
.btn{display:inline-flex;align-items:center;gap:6px;text-decoration:none;padding:9px 16px;border-radius:10px;background:#4b7bec;color:#fff;font-size:14px;border:none;cursor:pointer;font-family:inherit;line-height:1.2}
.btn.ghost{background:transparent;border:1px solid var(--line);color:var(--ink)}
.btn.acid{background:var(--acid);color:#0b0e14;font-weight:600}
.btn.danger{background:rgba(246,118,138,.14);color:var(--taken);border:1px solid rgba(246,118,138,.35)}
.btn.small{padding:6px 11px;font-size:12.5px}
.btn:hover{filter:brightness(1.12)}
.btn:disabled{opacity:.45;cursor:not-allowed;filter:none}
.row{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px;align-items:center}
.row.end{justify-content:flex-end}
.row.between{justify-content:space-between}
.muted{color:var(--mut);font-size:13px}
.dim{color:var(--dim);font-size:12.5px}
code,.mono{background:#0e131b;border:1px solid var(--line);border-radius:6px;padding:1px 6px;font-family:var(--mono);font-size:12.5px;word-break:break-all}
.badge{display:inline-block;font-size:11px;padding:2px 9px;border-radius:999px;font-weight:600;line-height:1.6}
.b-x{background:rgba(214,255,61,.14);color:var(--acid)}
.b-warn{background:rgba(255,199,95,.14);color:var(--warn)}
.b-ok{background:rgba(79,209,165,.14);color:var(--ok)}
.b-off{background:rgba(246,118,138,.14);color:var(--taken)}
.b-dim{background:rgba(255,255,255,.06);color:var(--mut)}
.err{color:var(--taken);font-size:13.5px;margin-top:10px}
.status{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:10px 14px;font-size:13px;color:var(--mut);margin-top:12px}
.status.ok{border-left:3px solid var(--ok)}
.status.err{border-left:3px solid var(--taken);color:var(--taken)}
.hidden{display:none !important}
/* ---------- dashboard shell ---------- */
.dash{display:grid;grid-template-columns:236px minmax(0,1fr);gap:26px;max-width:1200px;margin:0 auto;padding:1.4rem 1.2rem 3rem}
/* wide screens: let the dashboard use the width — wider sidebar, card
grids for the lists, two-column settings / TLD detail. Text blocks keep
a readable measure via .ph p max-width. */
@media (min-width:1280px){
.dash{max-width:1720px;grid-template-columns:260px minmax(0,1fr);gap:34px;padding:1.6rem 2rem 3rem}
.list.cols{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:10px;margin-top:8px}
.list.cols .drow{margin-top:0;align-content:start}
.list.cols > .empty,.list.cols > .status{grid-column:1/-1}
.grid2{grid-template-columns:repeat(auto-fit,minmax(340px,1fr))}
.pane[data-pane="settings"]:not([hidden]),.pane[data-pane="tld"]:not([hidden]){display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-content:start}
.pane[data-pane="settings"] > .ph,.pane[data-pane="tld"] > .crumbs,.pane[data-pane="tld"] > .dhead,.pane[data-pane="tld"] > .msg,.pane[data-pane="tld"] > .grid2{grid-column:1/-1}
.pane[data-pane="settings"] > .card,.pane[data-pane="tld"] > .card{margin-top:0}
.pane[data-pane="tld"] > .msg:empty{display:none}
.pane[data-pane="domain"] .sub[data-sub="summary"] > .grid2{grid-template-columns:repeat(2,minmax(0,1fr))}
.pane[data-pane="newtld"] .card{max-width:760px !important}
}
@media (min-width:1700px){
.list.cols{grid-template-columns:repeat(auto-fill,minmax(400px,1fr))}
.pane[data-pane="settings"]:not([hidden]){grid-template-columns:repeat(3,minmax(0,1fr))}
}
.side{position:sticky;top:68px;align-self:start;display:flex;flex-direction:column;gap:4px}
.side .who{padding:12px 14px;border-radius:12px;background:var(--panel);border:1px solid var(--line);margin-bottom:8px}
.side .who .lbl{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim)}
.side .who .addr{font-family:var(--mono);font-size:12px;color:var(--ink);word-break:break-all;margin-top:4px}
.side .who .net{font-size:11.5px;color:var(--dim);margin-top:4px}
.side .who .net.pending{color:var(--warn);font-size:11px}
.side .who .refresh{background:none;border:0;color:var(--dim);cursor:pointer;font-size:13px;padding:0 4px;line-height:1;vertical-align:middle}
.side .who .refresh:hover{color:var(--acid)}
.side .who .refresh.spin{animation:spin .8s linear infinite;display:inline-block}
@keyframes spin{to{transform:rotate(360deg)}}
.side .grp{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim);padding:12px 14px 4px}
.side button.item,.side a.item{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:9px 12px;border-radius:10px;
background:transparent;border:1px solid transparent;color:var(--mut);font:inherit;font-size:14px;cursor:pointer;text-decoration:none;transition:all .12s}
.side .item .ic{width:20px;text-align:center;flex:none;opacity:.9}
.side .item .cnt{margin-left:auto;font-family:var(--mono);font-size:11px;padding:1px 7px;border-radius:999px;background:rgba(255,255,255,.08);color:var(--ink)}
.side .item:hover{color:var(--ink);background:rgba(255,255,255,.04)}
.side .item.active{color:var(--acid);background:rgba(214,255,61,.08);border-color:rgba(214,255,61,.18)}
.side .item.active .cnt{background:rgba(214,255,61,.2);color:var(--acid)}
.side .sep{height:1px;background:var(--line);margin:8px 0}
.content{min-width:0}
.pane{animation:paneIn .18s ease-out}
.pane[hidden]{display:none}
@keyframes paneIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.ph{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:.6rem}
.ph p{margin:.2rem 0 0;color:var(--mut);font-size:13.5px;max-width:720px}
.crumbs{font-size:13px;color:var(--dim);margin-bottom:8px}
.crumbs a{color:var(--mut);text-decoration:none}
.crumbs a:hover{color:var(--ink)}
/* stats */
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px;margin-top:1rem}
.stat{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:16px 18px}
.stat .lbl{font-family:var(--mono);font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--dim);margin-bottom:8px;display:flex;align-items:center;gap:6px}
.stat .lbl:before{content:"";width:5px;height:5px;background:var(--acid);border-radius:50%}
.stat .val{font-family:var(--serif);font-size:30px;font-weight:600;color:var(--ink);letter-spacing:-.01em;line-height:1}
.stat .sub{color:var(--mut);font-size:12.5px;margin-top:4px}
/* toolbar + lists */
.toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:10px 0 6px}
.toolbar input[type=text]{max-width:320px}
.toolbar select{width:auto;padding:8px 30px 8px 10px;font-size:13px}
.list{margin-top:6px}
.drow{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px 14px;align-items:center;padding:13px 16px;
background:var(--panel2);border:1px solid var(--line);border-radius:12px;margin-top:8px;cursor:pointer;transition:border-color .12s,background .12s}
.drow:hover{border-color:rgba(214,255,61,.3);background:#0c1220}
.drow .n{font-family:var(--mono);font-size:15px;color:var(--ink);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.drow .n .tld{color:var(--acid)}
.drow .meta{grid-column:1/-1;display:flex;gap:6px;flex-wrap:wrap;align-items:center;color:var(--mut);font-size:12px}
.drow .acts{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
.empty{padding:26px 20px;text-align:center;color:var(--mut);border:1px dashed var(--line);border-radius:12px;margin-top:10px}
/* detail */
.dhead{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.dhead h2{font-family:var(--mono);font-size:1.5rem;margin:0}
.subtabs{display:flex;gap:4px;flex-wrap:wrap;border-bottom:1px solid var(--line);margin:14px 0 16px}
.subtabs button{background:transparent;border:0;border-bottom:2px solid transparent;color:var(--mut);padding:9px 12px;font:inherit;font-size:13.5px;cursor:pointer;margin-bottom:-1px}
.subtabs button:hover{color:var(--ink)}
.subtabs button.active{color:var(--acid);border-bottom-color:var(--acid)}
.kv{display:grid;grid-template-columns:160px minmax(0,1fr);gap:8px 14px;font-size:13.5px;margin-top:10px}
.kv .k{color:var(--dim)}
.kv .v{word-break:break-all}
.kv .v code{font-size:12px}
.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
.card h3{margin-top:0}
.card .hint{color:var(--dim);font-size:12.5px;margin:2px 0 0}
.field-hint{color:var(--dim);font-size:11.5px;margin-left:8px;text-transform:none;letter-spacing:0}
.budget{display:flex;justify-content:space-between;align-items:center;font-size:12px;color:var(--mut);margin-top:14px;padding:8px 12px;background:var(--panel2);border-radius:8px}
.budget.over{background:rgba(246,118,138,.15);color:var(--taken)}
.steps-log{margin-top:12px;font-family:var(--mono);font-size:12px;color:var(--mut);background:#0e131b;border:1px solid var(--line);border-radius:8px;padding:10px 12px;max-height:140px;overflow-y:auto;display:none}
.steps-log.on{display:block}
.steps-log div::before{content:" ";color:var(--acid)}
.msg{font-size:13px;margin-top:12px}
.msg.err{color:var(--taken)} .msg.ok{color:var(--ok)}
/* DNS table */
.tbl{width:100%;border-collapse:separate;border-spacing:0;margin-top:10px;font-size:13px}
.tbl th{font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--dim);text-align:left;padding:8px 10px;border-bottom:1px solid var(--line)}
.tbl td{padding:9px 10px;border-bottom:1px solid var(--line);vertical-align:middle}
.tbl td.t{font-family:var(--mono);color:var(--acid);width:80px}
.tbl td.v{font-family:var(--mono);word-break:break-all}
.tbl td.p{color:var(--mut);white-space:nowrap}
.tbl td.a{text-align:right;white-space:nowrap}
.tbl .x{background:none;border:0;color:var(--dim);cursor:pointer;font-size:16px;padding:2px 6px}
.tbl .x:hover{color:var(--taken)}
.addrow{display:grid;grid-template-columns:110px minmax(0,1fr) 90px 90px 90px auto;gap:8px;align-items:end;margin-top:12px;padding:12px;background:var(--panel2);border:1px solid var(--line);border-radius:10px}
.addrow label{margin:0 0 4px;font-size:11px;text-transform:uppercase;letter-spacing:.08em}
.addrow input,.addrow select{padding:8px 10px;font-size:13px}
.addrow .opt[hidden]{display:none}
.toggle{display:flex;align-items:flex-start;gap:12px;padding:12px 0;border-bottom:1px solid var(--line)}
.toggle:last-child{border-bottom:0}
.toggle .txt b{display:block;font-weight:600;font-size:14px}
.toggle .txt span{color:var(--mut);font-size:12.5px}
.toggle input[type=checkbox]{width:18px;height:18px;margin-top:3px;accent-color:var(--acid);flex:none}
.seg{display:inline-flex;align-items:center;gap:0;flex-wrap:wrap}
.seg button{font:inherit;font-size:13px;font-weight:600;letter-spacing:.02em;padding:7px 16px;cursor:pointer;background:rgba(255,255,255,.04);color:var(--mut);border:1px solid var(--line);margin-left:-1px;transition:background .12s,color .12s}
.seg button:first-child{border-radius:8px 0 0 8px;margin-left:0}
.seg button:last-of-type{border-radius:0 8px 8px 0}
.seg button:hover{color:var(--ink)}
.seg button.active{background:var(--acid);color:#0b0d10;border-color:var(--acid);position:relative;z-index:1}
.seg button:focus-visible{outline:2px solid var(--acid);outline-offset:2px;z-index:2}
.seg .dim{margin-left:12px}
.pill{display:inline-block;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:2px 8px;border-radius:999px;background:rgba(255,255,255,.06);color:var(--dim);margin-left:8px;vertical-align:middle}
/* modals kept for policy editing */
.modal{position:fixed;inset:0;background:rgba(6,9,14,.82);backdrop-filter:blur(3px);
display:none;align-items:flex-start;justify-content:center;padding:3vh 1rem;overflow-y:auto;z-index:50}
.modal.open{display:flex}
.sheet{background:var(--panel);border:1px solid var(--line);border-radius:16px;max-width:620px;width:100%;padding:24px 26px;position:relative}
.sheet h3{margin:0 0 .3rem;font-size:1.15rem;font-family:var(--mono)}
.sheet .sub{color:var(--mut);font-size:13px;margin:0 0 1.2rem}
.sheet .x{position:absolute;top:14px;right:16px;background:none;border:none;color:var(--dim);font-size:22px;cursor:pointer;line-height:1}
.sheet label{display:block;font-size:12px;color:var(--mut);margin:12px 0 4px;text-transform:uppercase;letter-spacing:.4px}
.sheet input[type=text],.sheet textarea,.sheet select{width:100%;padding:9px 12px;border-radius:8px;border:1px solid #ffffff22;background:#0e131b;color:var(--ink);font-size:13px;font-family:var(--mono);outline:none}
.sheet textarea{min-height:60px;resize:vertical}
.sheet .actions{display:flex;gap:10px;justify-content:flex-end;margin-top:16px}
footer{border-top:1px solid var(--line);padding:2rem 0 3rem;color:var(--dim);font-size:13px;text-align:center;margin-top:2.5rem}
@media (max-width:900px){
/* minmax(0,…) + min-width:0: the nowrap address must never widen the page */
.dash{grid-template-columns:minmax(0,1fr);gap:14px}
.side{position:static;flex-direction:row;flex-wrap:wrap;gap:6px;align-items:center;min-width:0}
/* one slim line: short address + live balance + refresh */
.side .who{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;margin:0 0 4px}
.side .who .lbl,.side .who .net.pending{display:none}
.side .who .addr{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0;font-size:11.5px}
.side .who .net{margin:0;white-space:nowrap}
.side .grp,.side .sep{display:none}
/* the menu becomes a row of pills (the wide-screen rule sets width:100% with higher specificity) */
.side button.item,.side a.item{width:auto;padding:7px 11px;font-size:13px;border-color:var(--line)}
.side .item .cnt{margin-left:4px}
.subtabs{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.subtabs::-webkit-scrollbar{display:none}
.subtabs button{white-space:nowrap}
.dhead h2{font-size:1.25rem}
.kv{grid-template-columns:1fr}
.addrow{grid-template-columns:1fr 1fr}
}
</style>
<script src="./js/i18n.js?v=20260921c"></script>
</head>
<body>
<nav class="topnav">
<a class="brand" href="./"><svg width="18" height="18" viewBox="0 0 64 64" style="vertical-align:-4px;margin-right:6px" aria-hidden="true"><rect width="64" height="64" rx="12" fill="#0b0e14"/><path d="M32 4 L36.4 27.6 L60 32 L36.4 36.4 L32 60 L27.6 36.4 L4 32 L27.6 27.6 Z" fill="#d6ff3d"/></svg>Sirius<span class="g">.X</span></a>
<a href="./tld.html">🌐 TLD</a>
<!-- Trailing slash required: market/ is a subdirectory. -->
<a href="./market/">🛒 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<span class="g">.X</span></a>
<a href="./portal.html" class="portal here">🔑 Sign in</a>
</nav>
<!-- ============ signed-out: hero + inline sign-in ============ -->
<div id="signed-out">
<header class="hero">
<div class="mark">🔑</div>
<h1>Your <span class="g">names</span> dashboard</h1>
<p class="tag">Sign in once with your Bitcoin Cash seed phrase or connect an external wallet. This device
stays signed in until you sign out — no passwords on every visit. Your keys never leave this browser.</p>
</header>
<div class="wrap">
<section id="signin">
<h2>Sign in or create a wallet</h2>
<p class="muted">The same wallet that will hold your names does the signing. Pick a tab —
everything happens on this page; keys never leave your browser.</p>
<div id="signin-inline" style="margin-top:1rem"></div>
<div id="signin-err" class="err hidden"></div>
</section>
</div>
</div>
<!-- ============ signed-in: dashboard ============ -->
<div id="me" class="dash hidden">
<aside class="side" aria-label="Dashboard menu">
<div class="who">
<div class="lbl">Signed in</div>
<div class="addr" id="side-addr"></div>
<div class="net">chipnet · <span id="side-balance"></span> <button class="refresh" id="side-refresh" title="Refresh balance" aria-label="Refresh balance"></button></div>
<div class="net pending" id="side-pending" hidden>incl. <span id="side-pending-sats">0</span> unconfirmed · spendable now</div>
</div>
<button class="item" data-go="studio"><span class="ic">🎨</span>Web-Builder</button>
<button class="item active" data-go="domains"><span class="ic">🌐</span>Domain names<span class="cnt" id="cnt-names">0</span></button>
<button class="item" data-go="tlds"><span class="ic">🏷</span>My TLDs<span class="cnt" id="cnt-tlds">0</span></button>
<div class="sep"></div>
<button class="item" data-go="settings"><span class="ic"></span>Settings</button>
<a class="item hidden" id="side-admin" href="./admin"><span class="ic">🛠</span>Admin panel</a>
<button class="item" id="side-signout"><span class="ic">🚪</span>Sign out</button>
</aside>
<main class="content">
<!-- WEB-BUILDER -->
<div class="pane" data-pane="studio" hidden>
<div class="ph"><div><h2>Web-Builder</h2><p>Sirius Studio builds a site for any name you hold: drag blocks, edit text, publish. Pages live in the name's own folder on Sia and the name points at them — no host, no renewal.</p></div>
<div class="row" style="margin:0"><button class="btn ghost small" id="refresh-btn">↻ Refresh</button></div></div>
<div class="status" id="studio-status">Loading names from the chain…</div>
<div id="studio-list" class="list cols"></div>
</div>
<!-- DOMAINS -->
<div class="pane" data-pane="domains">
<div class="ph"><div><h2>Domain names</h2><p>Every BCNR name this wallet holds. Open one to manage DNS, content, redirects or transfer it.</p></div>
<div class="row" style="margin:0"><button class="btn ghost small" id="names-refresh">↻ Refresh</button><a class="btn acid small" href="./#search-input"> Register a name</a></div></div>
<div id="ov-attention" class="list" style="margin-bottom:6px"></div>
<div class="toolbar">
<input type="text" id="dom-search" placeholder="Filter names…" autocomplete="off">
<select id="dom-sort"><option value="name">Sort: name</option><option value="tld">Sort: TLD</option><option value="height">Sort: newest</option></select>
<select id="dom-tld"><option value="">All TLDs</option></select>
<span class="dim" id="dom-count"></span>
</div>
<div class="status" id="names-status">Loading names from the chain…</div>
<div id="names-list" class="list cols"></div>
</div>
<!-- DOMAIN DETAIL -->
<div class="pane" data-pane="domain" hidden>
<div class="crumbs"><a href="#domains" data-go="domains">Domain names</a> <span id="dd-crumb"></span></div>
<div class="dhead">
<h2 id="dd-name"></h2>
<span class="badge b-x">on chain</span>
<span class="badge b-dim" id="dd-dnsbadge">no DNS</span>
<span style="margin-left:auto" class="row" style="margin:0">
<a class="btn ghost small" id="dd-view" href="#" target="_blank" rel="noopener">Open site →</a>
</span>
</div>
<div class="subtabs" role="tablist">
<button data-sub="summary" class="active">Summary</button>
<button data-sub="dns">DNS records</button>
<button data-sub="content">Content &amp; hosting</button>
<button data-sub="redirect">Redirect</button>
<button data-sub="transfer">Transfer</button>
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
<button data-sub="sell">Sell</button>
<button data-sub="export">Export</button>
</div>
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
<div class="sub" data-sub="sell" hidden>
<div class="card" style="margin-top:0">
<h3>Sell this name</h3>
<p class="hint">You sign an offer once: "whoever pays me this price gets the certificate". The offer is stored by the gateway and shown on the <a href="./market/" target="_blank" rel="noopener">market</a>. A buyer completes it in one transaction — you are paid in the same transaction that moves the name, or not at all. No escrow, nothing to trust.</p>
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
<div class="status" id="sell-status">Checking the market…</div>
<div id="sell-form">
<label style="margin-top:0" id="sell-mode-label">Price is fixed in</label>
<div class="seg" id="sell-mode" role="radiogroup" aria-labelledby="sell-mode-label" data-value="usd">
<button type="button" role="radio" aria-checked="true" data-mode="usd" class="active">USD</button>
<button type="button" role="radio" aria-checked="false" data-mode="bch">BCH</button>
<span class="dim" id="sell-mode-hint">The BCH amount follows the market</span>
</div>
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
<div class="row" style="align-items:flex-end">
<div><label style="margin-top:0">Price (USD)</label><input type="text" id="sell-usd" placeholder="25" inputmode="decimal" style="max-width:160px"></div>
<div><label style="margin-top:0">Price (BCH)</label><input type="text" id="sell-bch" placeholder="0.0625" inputmode="decimal" style="max-width:200px"></div>
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
<span class="dim" id="sell-rate"></span>
</div>
<div id="sell-usd-terms">
<div class="row" style="align-items:flex-end">
<div><label style="margin-top:0">Accept between</label><input type="text" id="sell-band" value="25" inputmode="numeric" style="max-width:90px"></div>
<span class="dim" id="sell-band-hint"></span>
</div>
<p class="hint">A dollar price lives in a small contract that holds the certificate while it is for sale. A buyer pays the dollar amount at the Sirius.X price oracle's rate, and the contract keeps the payout inside this band whatever the oracle says, so a wrong or old quote can never take the price outside it. Your name's records are frozen while listed; cancelling returns the certificate.</p>
</div>
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
<div class="row end"><button class="btn acid" id="sell-list">List for sale →</button></div>
</div>
<div id="sell-active" class="hidden">
<div class="kv" id="sell-kv"></div>
<div class="row end">
<button class="btn danger" id="sell-cancel">Cancel listing →</button>
</div>
<p class="hint">Cancelling removes the offer from the market and moves your certificate once (a no-op update, a few cents), so the signed offer can never be completed later.</p>
</div>
<div class="steps-log" id="sell-log"></div>
<div class="msg" id="sell-msg"></div>
</div>
</div>
<div class="sub" data-sub="summary">
<div class="grid2">
<div class="card" style="margin-top:0">
<h3>Certificate</h3>
<div class="kv" id="dd-kv"></div>
</div>
<div class="card" style="margin-top:0">
<h3>Where it points</h3>
<p class="hint">On-chain records decide what a resolver serves. Change them under Content &amp; hosting.</p>
<div class="kv" id="dd-records"></div>
</div>
</div>
<div class="card">
<h3>DNS at a glance</h3>
<p class="hint">Signed off-chain records for mail, verification and classic DNS interop.</p>
<div id="dd-dns-summary" class="muted" style="margin-top:8px"></div>
</div>
</div>
<div class="sub" data-sub="dns" hidden>
<div class="card" style="margin-top:0">
<div class="row between" style="margin:0">
<div><h3 style="margin:0">DNS records</h3>
<p class="hint">Standard records, signed by your key and stored in a manifest on Sia. Free to edit, no chain transaction. Resolvers and the gateway verify the signature against the current NFT holder.</p></div>
<span class="badge b-dim" id="dns-seq">seq —</span>
</div>
<table class="tbl" id="dns-table">
<thead><tr><th>Type</th><th>Value</th><th>Priority / extra</th><th></th></tr></thead>
<tbody></tbody>
</table>
<div class="empty hidden" id="dns-empty">No DNS records yet. Add the first one below.</div>
<div class="addrow">
<div><label>Type</label>
<select id="dns-type">
<option>A</option><option>AAAA</option><option>CNAME</option><option>MX</option>
<option>TXT</option><option>NS</option><option>SRV</option><option>CAA</option>
</select></div>
<div><label id="dns-value-label">Value</label><input type="text" id="dns-value" placeholder="1.2.3.4" autocomplete="off" spellcheck="false"></div>
<div class="opt" data-for="MX SRV"><label>Priority</label><input type="number" id="dns-prio" min="0" placeholder="10"></div>
<div class="opt" data-for="SRV"><label>Weight</label><input type="number" id="dns-weight" min="0" placeholder="0"></div>
<div class="opt" data-for="SRV"><label>Port</label><input type="number" id="dns-port" min="0" placeholder="443"></div>
<div class="opt" data-for="CAA"><label>Tag</label><select id="dns-tag"><option>issue</option><option>issuewild</option><option>iodef</option></select></div>
<div><label>&nbsp;</label><button class="btn small" id="dns-add"> Add</button></div>
</div>
<div class="dim" id="dns-help" style="margin-top:8px"></div>
<div class="steps-log" id="dns-log"></div>
<div class="msg" id="dns-msg"></div>
<div class="row end">
<button class="btn ghost" id="dns-reload">Discard changes</button>
<button class="btn acid" id="dns-publish">Sign &amp; publish →</button>
</div>
</div>
<div class="card">
<h3>Nameservers</h3>
<p class="hint">BCNR names do not need nameservers — resolvers read the chain and this manifest directly. Add NS records above only if you also delegate this name in classic DNS.</p>
</div>
</div>
<div class="sub" data-sub="content" hidden>
<div class="card" style="margin-top:0">
<h3>Content &amp; hosting</h3>
<p class="hint">On-chain records, published as one signed UPD transaction (a few cents of chain dust). Leave a field blank to drop that record. Precedence for resolvers: h, then s3, then p, then ip.</p>
<label>h <span class="field-hint">inline HTML — served as-is at the site root (~150 bytes)</span></label>
<textarea id="ct-h" placeholder="&lt;h1&gt;My site&lt;/h1&gt;"></textarea>
<label>Hosting <span class="field-hint">where the page files live (the s3 record)</span></label>
<select id="ct-s3-mode">
<option value="off">Not hosted on Sia</option>
<option value="sirius">Sirius.X hosting — free, on Sia storage</option>
<option value="custom">Another Sia folder (advanced)</option>
</select>
<p class="hint" id="ct-s3-hint" style="margin:6px 0 0"></p>
<input type="text" id="ct-s3" placeholder="bns/space.x/" style="margin-top:8px" hidden>
<label>p <span class="field-hint">reverse proxy: full upstream URL the gateway mirrors</span></label>
<input type="text" id="ct-p" placeholder="https://origin.example.com">
<label>ip <span class="field-hint">IPv4 that serves this name over Host header</span></label>
<input type="text" id="ct-ip" placeholder="1.2.3.4">
<label>tls <span class="field-hint">SHA-256 of your leaf cert — chain-pinned TLS trust</span></label>
<input type="text" id="ct-tls" placeholder="hex — 64 chars, no separators">
<div class="budget" id="ct-budget">payload: <b><span id="ct-budget-used">0</span></b> / <span id="ct-budget-max">?</span> bytes</div>
<div class="steps-log" id="ct-log"></div>
<div class="msg" id="ct-msg"></div>
<div class="row end">
<button class="btn ghost" id="ct-reset">Reset</button>
<button class="btn acid" id="ct-save">Save records →</button>
</div>
</div>
</div>
<div class="sub" data-sub="redirect" hidden>
<div class="card" style="margin-top:0">
<h3>Redirect</h3>
<p class="hint">Forward this name to any web address. Stored on chain as the <b>u</b> record; resolvers and the gateway issue the redirect. Clear it to stop forwarding.</p>
<label>Destination URL</label>
<input type="text" id="rd-url" placeholder="https://example.com/">
<div class="steps-log" id="rd-log"></div>
<div class="msg" id="rd-msg"></div>
<div class="row end">
<button class="btn ghost" id="rd-clear">Remove redirect</button>
<button class="btn acid" id="rd-save">Save redirect →</button>
</div>
</div>
</div>
<div class="sub" data-sub="transfer" hidden>
<div class="card" style="margin-top:0">
<h3>Transfer ownership</h3>
<p class="hint">Moves the name's certificate to another Bitcoin Cash address in one transaction. Records stay as they are. The new holder controls the name from that moment — this cannot be undone from here.</p>
<label>Recipient address <span class="field-hint">bchtest:… (chipnet)</span></label>
<input type="text" id="tr-addr" placeholder="bchtest:q…" autocomplete="off" spellcheck="false">
<label style="display:flex;align-items:center;gap:8px;margin-top:12px"><input type="checkbox" id="tr-ack" style="width:16px;height:16px;accent-color:var(--acid)"> I understand this hands the name to that address permanently.</label>
<div class="steps-log" id="tr-log"></div>
<div class="msg" id="tr-msg"></div>
<div class="row end"><button class="btn danger" id="tr-send" disabled>Transfer name →</button></div>
</div>
</div>
<div class="sub" data-sub="export" hidden>
<div class="card" style="margin-top:0">
<h3>Export</h3>
<p class="hint">Download this name's DNS as a BIND-style zone file, or its full record set as JSON, for backups or importing elsewhere.</p>
<div class="row">
<button class="btn ghost small" id="ex-zone">⬇ Zone file (.txt)</button>
<button class="btn ghost small" id="ex-json">⬇ Records (.json)</button>
<button class="btn ghost small" id="ex-copy">Copy DNS manifest</button>
</div>
<pre class="mono" id="ex-preview" style="margin-top:12px;padding:12px;white-space:pre-wrap;font-size:12px;max-height:280px;overflow:auto"></pre>
</div>
</div>
</div>
<!-- TLDs -->
<div class="pane" data-pane="tlds" hidden>
<div class="ph"><div><h2>My TLDs</h2><p>Every per-TLD registry NFT this wallet holds. Set the price every name under a TLD sells for, switch it on or off (off = private: only you can register under it), and tune policy. Each change is one signed TUPD on chain; you receive 90% of every sale.</p></div>
<button class="btn acid small" data-go="newtld"> Register a TLD</button></div>
<div class="status" id="tlds-status">Loading TLDs from the chain…</div>
<div id="tlds-list" class="list cols"></div>
</div>
<!-- TLD DETAIL -->
<div class="pane" data-pane="tld" hidden>
<div class="crumbs"><a href="#tlds" data-go="tlds">My TLDs</a> <span id="td-crumb"></span></div>
<div class="dhead">
<h2 id="td-name">.—</h2>
<span class="badge" id="td-state">on</span>
<span class="badge b-x" id="td-price">tier pricing</span>
<span style="margin-left:auto"></span>
<button class="btn ghost small" id="td-toggle">Switch off</button>
<button class="btn acid small" id="td-policy">Price &amp; policy</button>
</div>
<div class="msg" id="td-msg"></div>
<div class="grid2" style="margin-top:14px">
<div class="card" style="margin-top:0">
<h3>Registry</h3>
<div class="kv" id="td-kv"></div>
</div>
<div class="card" style="margin-top:0">
<h3>Register a name under this TLD</h3>
<p class="hint">Works whether the TLD is on or off. As the owner you pay only the platform's 10% share.</p>
<div class="row" style="margin-top:10px">
<input type="text" id="td-label" placeholder="label" maxlength="32" autocomplete="off" spellcheck="false" style="max-width:220px">
<span class="mono" id="td-suffix">.—</span>
<button class="btn small acid" id="td-register">Register →</button>
</div>
</div>
</div>
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
<div class="card" id="td-cosign-card">
<h3>Pending approvals</h3>
<p class="hint">Registrations under this TLD that wait for your co-signature. Approving signs your TLD certificate into the buyer's transaction and broadcasts it; the certificate returns to you in the same transaction. Nothing can be registered under a co-sign or private TLD without this step.</p>
<div id="td-cosign" class="list"></div>
<div class="msg" id="td-cosign-msg"></div>
</div>
<div class="card">
<h3>Names registered under this TLD</h3>
<p class="hint">Everyone's registrations, from the public registry.</p>
<div id="td-names" class="list cols"></div>
</div>
</div>
<!-- NEW TLD -->
<div class="pane" data-pane="newtld" hidden>
<div class="ph"><div><h2>Register a TLD</h2><p>TLDs are per-registry NFTs on the chipnet TLD beacon. Public mints pay a service fee that funds the registry. Chipnet uses a placeholder rate; mainnet prices by label length via a real oracle.</p></div></div>
<div class="card" id="tld-register-card" style="margin-top:0;max-width:640px">
<label>Label <span class="dim" style="margin-left:6px">116 chars, [a-z0-9-]</span></label>
<input type="text" id="tld-label" placeholder="myregistry" autocomplete="off" spellcheck="false" maxlength="16">
<label style="margin-top:12px">Service fee (USD) <span class="dim" style="margin-left:6px">chipnet test rate</span></label>
<input type="text" id="tld-usd" value="5">
<div class="status" id="tld-price">= <b>0 bits</b></div>
<div class="row">
<button class="btn ghost small" id="tld-check" disabled>Check availability</button>
<button class="btn acid small" id="tld-submit" disabled>Register (~0 bits)</button>
</div>
<div id="tld-log" class="status" style="display:none;font-family:var(--mono);font-size:12.5px;margin-top:12px"></div>
<div id="tld-msg" style="margin-top:10px;font-size:13.5px"></div>
</div>
</div>
<!-- SETTINGS -->
<div class="pane" data-pane="settings" hidden>
<div class="ph"><div><h2>Settings</h2><p>Session, security and wallet details for this browser. Nothing here changes what is on chain.</p></div></div>
<div class="card" style="margin-top:0">
<h3>Session</h3>
<div class="toggle"><input type="checkbox" id="set-stay"><div class="txt"><b>Stay signed in on this device</b><span>Your recovery phrase is kept encrypted under a key this browser holds and cannot export. Next visits open the dashboard straight away. Turn off to be asked for your password or PIN every time.</span></div></div>
<div class="toggle"><input type="checkbox" id="set-pinpay"><div class="txt"><b>Ask for PIN before payments</b><span>Adds a PIN prompt when registering a name or TLD. Off by default so signed-in sessions run uninterrupted.</span></div></div>
<div class="row">
<button class="btn ghost small" id="set-setpin">Set / change PIN</button>
<button class="btn ghost small" id="set-clearpin">Remove PIN</button>
<span class="dim" id="set-pinstate"></span>
</div>
</div>
<div class="card">
<h3>Wallet</h3>
<p class="hint">Your addresses and current balance. Keys stay in this browser.</p>
<label>Receive address <span class="dim" style="margin-left:6px">chipnet</span></label>
<div><code id="me-addr"></code> <button class="btn ghost small" data-copy="me-addr">Copy</button></div>
<label style="margin-top:14px">Token address <span class="dim" style="margin-left:6px">holds your name certificates</span></label>
<div><code id="me-taddr"></code> <button class="btn ghost small" data-copy="me-taddr">Copy</button></div>
<div class="row between">
<span class="dim" id="me-info"></span>
<span class="row" style="margin:0">
<a class="btn ghost small" href="https://tbch.googol.cash/" target="_blank" rel="noopener">Faucet →</a>
<a class="btn ghost small" href="https://chipnet.imaginary.cash/faucet" target="_blank" rel="noopener">Faucet 2 →</a>
</span>
</div>
<div class="kv" style="margin-top:14px"><div class="k">Spendable</div><div class="v" id="w-sats"></div><div class="k">UTXOs</div><div class="v" id="w-utxos"></div><div class="k">Watched addresses</div><div class="v" id="w-watched"></div><div class="k">Chain height</div><div class="v" id="stat-height"></div></div>
</div>
<div class="card">
<h3>Reading, language &amp; help</h3>
<p class="hint">Font pill and language picker live in the top bar; both are remembered per browser. The technical documentation is at <a href="./docs" target="_blank" rel="noopener">sirius-x/docs</a>.</p>
</div>
<div class="card">
<h3>This device</h3>
<p class="hint">Sign out keeps the encrypted wallet on this device so you can unlock it later. Forget removes it entirely — you will need your recovery phrase to come back.</p>
<div class="row">
<button class="btn ghost small" id="set-signout">Sign out</button>
<button class="btn danger small" id="set-forget">Forget wallet on this device</button>
</div>
<div class="msg" id="set-msg"></div>
</div>
</div>
</main>
</div>
<!-- TLD-policy editor modal — signs a TUPD against the TREG NFT. -->
<div class="modal" id="tld-editor">
<div class="sheet">
<button class="x" id="tld-ed-close" title="close">×</button>
<h3>Policy for <span id="tld-ed-name" style="color:var(--acid);font-family:var(--mono)">.—</span></h3>
<p class="sub">Set policy for names registered under this TLD. Only your key can sign this TUPD;
the transaction fee is a few cents in chain dust. Leave a field blank to omit that policy
(defaults apply — open policy, tier pricing).</p>
<label>price <span class="field-hint">USD per name — flat, shown to every buyer; blank = length tiers. You receive 90% of each sale.</span></label>
<input type="text" id="tld-ed-price" placeholder="7" inputmode="decimal">
<label>listing <span class="field-hint">off hides the TLD from search and blocks new registrations until you switch it back on</span></label>
<select id="tld-ed-hidden">
<option value="">On — listed, names for sale</option>
<option value="1">Off — hidden, not for sale</option>
</select>
<label>min_len <span class="field-hint">reject names shorter than N chars</span></label>
<input type="text" id="tld-ed-minlen" placeholder="1">
<label>fee_bps <span class="field-hint">service fee owner takes, in basis points (500 = 5%)</span></label>
<input type="text" id="tld-ed-feebps" placeholder="500">
<label>policy <span class="field-hint">open · frozen · reserved-only</span></label>
<input type="text" id="tld-ed-policy" placeholder="open">
<label>reserved <span class="field-hint">space-separated labels only owner can mint</span></label>
<input type="text" id="tld-ed-reserved" placeholder="admin root bank">
<label>renewal_period <span class="field-hint">days between renewals, 0 = never expire</span></label>
<input type="text" id="tld-ed-renewal" placeholder="0">
<label>renewal_fee <span class="field-hint">renewal price in sats, 0 = free</span></label>
<input type="text" id="tld-ed-renewalfee" placeholder="0">
<label>site <span class="field-hint">where the TLD's own landing lives</span></label>
<input type="text" id="tld-ed-site" placeholder="https://silentmode.st/…">
<div class="budget" id="tld-ed-budget">payload: <b><span id="tld-ed-budget-used">0</span></b> / <span id="tld-ed-budget-max">?</span> bytes</div>
<div class="steps-log" id="tld-ed-log"></div>
<div class="msg" id="tld-ed-msg"></div>
<div class="actions">
<button class="btn ghost" id="tld-ed-cancel">Cancel</button>
<button class="btn acid" id="tld-ed-save">Save policy →</button>
</div>
</div>
</div>
<!-- PIN setup modal (Settings) -->
<div class="modal" id="pin-modal">
<div class="sheet" style="max-width:440px">
<button class="x" id="pin-close" title="close">×</button>
<h3>Set a PIN</h3>
<p class="sub">46 digits. Encrypts your recovery phrase under this PIN on this device. Three wrong PINs clear it and fall back to your password.</p>
<label>PIN</label><input type="text" id="pin-1" inputmode="numeric" pattern="[0-9]*" maxlength="6" autocomplete="off">
<label>Repeat PIN</label><input type="text" id="pin-2" inputmode="numeric" pattern="[0-9]*" maxlength="6" autocomplete="off">
<div class="msg" id="pin-msg"></div>
<div class="actions"><button class="btn ghost" id="pin-cancel">Cancel</button><button class="btn acid" id="pin-save">Save PIN →</button></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 type="importmap">
{ "imports": { "@bitauth/libauth": "https://silentmode.st/js/libauth.js?v=20260920usd" } }
</script>
<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>
<script src="./js/pricing.js?v=20260920bits"></script>
<script type="module" src="./js/dashboard.js?v=20260921usd4"></script>
<script defer src="./js/theme.js?v=20260921mob"></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 defer src="./js/site-footer.js?v=20260917market"></script>
<script type="module" src="./js/register-flow.js?v=20260920usd"></script>
<script defer src="./js/profile-menu.js?v=20260921mob"></script>
</body>
</html>