@ -40,25 +40,13 @@
h1 .g{color:var(--acid)}
.tag{color:var(--mut);font-size:1rem;max-width:600px;margin:0 auto}
h2{font-size:1.25rem;margin:0 0 .4rem}
h3{font-size:1rem;margin:0 0 .35rem}
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}
.field-hint{color:var(--dim);font-size:11.5px;margin-left:8px}
textarea,input[type=text],input[type=password]{
width:100%;padding:11px 13px;border-radius:10px;border:1px solid #ffffff22;background:#0e131b;
color:var(--ink);font-size:14px;font-family:inherit;outline:none
}
textarea{min-height:74px;resize:vertical;font-family:ui-monospace,monospace;font-size:13px}
textarea:focus,input:focus{border-color:#4b7bec}
.btn{display:inline-block;text-decoration:none;padding:10px 18px;border-radius:10px;background:#4b7bec;color:#fff;font-size:14px;border:none;cursor:pointer;font-family:inherit}
.btn.ghost{background:transparent;border:1px solid var(--line);color:var(--ink)}
.btn.acid{background:var(--acid);color:#0b0e14;font-weight:600}
.btn.small{padding:6px 12px;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:16px;align-items:center}
.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:ui-monospace,monospace;font-size:13px;word-break:break-all}
@ -70,44 +58,34 @@
.status.ok{border-left:3px solid var(--ok)}
.status.err{border-left:3px solid var(--taken);color:var(--taken)}
.status.warn{border-left:3px solid var(--warn);color:var(--warn)}
.hidden{display:none}
.err{color:var(--taken);font-size:13.5px;margin-top:10px}
.authbox{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px}
.authbox .card{margin:0}
.authbox h3{margin:0 0 .3rem;font-size:1rem}
.authbox p{margin:0;color:var(--mut);font-size:13px}
/* TLD search cell */
.search{max-width:600px;margin:1.5rem auto 0}
.searchrow{display:flex;gap:8px}
.searchrow input{flex:1;padding:14px 18px;font-size:17px;border-radius:12px;border:1px solid #ffffff22;background:#141a24;color:var(--ink)}
.searchrow input:focus{border-color:#4b7bec;outline:none }
.searchrow input{flex:1;padding:14px 18px;font-size:17px;border-radius:12px;border:1px solid #ffffff22;background:#141a24;color:var(--ink);font-family:inherit;outline:none}
.searchrow input:focus{border-color:#4b7bec}
.searchhint{font-size:12.5px;color:var(--mut);margin-top:8px;text-align:center}
.result-card{display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center;
background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px 18px;margin-top:12px}
.result-card .lbl{font-family:ui-monospace,monospace;font-size:18px;color:var(--ink)}
.result-card .lbl .dot{color:var(--acid)}
/* TLD registry table */
/* Registered-TLDs table */
table.tlds{width:100%;border-collapse:collapse;margin-top:1rem;font-size:13px}
table.tlds th,table.tlds td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--line);vertical-align:top}
table.tlds th{color:var(--mut);font-weight:500;font-size:11.5px;text-transform:uppercase;letter-spacing:.4px}
table.tlds .tld{font-family:ui-monospace,monospace;color:var(--acid);font-size:13.5px;font-weight:600}
table.tlds .cat{font-family:ui-monospace,monospace;color:var(--mut);font-size:11.5px;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Registration progress */
.steps-log{margin-top:12px;font-family:ui-monospace,monospace;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.ok{color:var(--ok)} .msg.err{color:var(--taken)}
footer{border-top:1px solid var(--line);padding:2rem 0 3rem;color:var(--dim);font-size:13px;text-align:center;margin-top:2.5rem}
< / style >
< script type = "importmap" >
{ "imports": { "@bitauth/libauth": "https://silentmode.st/js/libauth.js" } }
< / script >
< / head >
< body >
< nav class = "topnav" >
< a class = "brand" href = "./" > ⭐ < span class = "g" > Sirius.X< / span > < / a >
< a href = "./#try" > Try it< / a >
< a href = "./#search-input" > 🪪 Register< / a >
< a href = "./#search-input" > ✏️ Register< / a >
< a href = "./tld.html" class = "here" > 🌐 TLD< / 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" / > < circle cx = "32" cy = "32" r = "3" fill = "#0b0e14" / > < / svg > Theseus< / a >
< a href = "./portal.html" class = "portal" > 🔑 Sign in< / a >
@ -125,89 +103,17 @@
< section id = "search-section" >
< h2 > Search a TLD< / h2 >
< p class = "muted" > Type a label (a– z, 0– 9, hyphen; up to 16 chars). We check the on-chain TLD
registry live and, if the label is free, show a register button .< / p >
< p class = "muted" > Type a label (a– z, 0– 9, hyphen; up to 16 chars). Available TLDs get a Register
button that opens the shared wallet-choice modal — the same flow name registration uses .< / p >
< div class = "search" >
< div class = "searchrow" >
< input id = "q" placeholder = "your-tld" spellcheck = "false" autocomplete = "off" autofocus maxlength = "16" >
< / div >
< div class = "searchhint" > Available TLDs appear with a register button. Taken labels show which category holds them .< / div >
< div class = "searchhint" > Register minting to your token address; you become the registry operator .< / div >
< / div >
< div id = "result" > < / div >
< / section >
< section id = "signin-section" class = "hidden" >
< h2 > Sign in to mint< / h2 >
< p class = "muted" > The TLD certificate lands in the token address of the wallet that signs the mint —
that wallet becomes the registry operator.< / p >
< div class = "authbox" style = "margin-top:14px" >
< div class = "card" id = "card-new" >
< h3 > 🆕 New wallet< / h3 >
< p > Generate a fresh 12-word phrase in this tab. Nothing is saved — write it down before continuing.< / p >
< div class = "row" >
< button class = "btn acid" id = "new-btn" > Generate a phrase< / button >
< / div >
< div id = "new-phrase" class = "hidden" style = "margin-top:14px" >
< label > Your new recovery phrase< / label >
< textarea id = "new-seed" readonly > < / textarea >
< label style = "margin-top:10px;display:flex;gap:9px;align-items:flex-start;font-size:13.5px" >
< input type = "checkbox" id = "new-ack" style = "margin-top:3px" >
< span > I have written this phrase down. There is no reset if I lose it.< / span >
< / label >
< div class = "row" >
< button class = "btn acid" id = "new-signin-btn" disabled > Continue →< / button >
< button class = "btn ghost" id = "new-copy-btn" > Copy phrase< / button >
< / div >
< / div >
< div id = "new-err" class = "err hidden" > < / div >
< / div >
< div class = "card" id = "card-import" >
< h3 > 📥 Import a seed phrase< / h3 >
< p > Paste your 12- or 24-word phrase. It stays in memory only.< / p >
< label for = "seed" > Recovery phrase< / label >
< textarea id = "seed" placeholder = "word1 word2 … word12" spellcheck = "false" autocomplete = "off" > < / textarea >
< div class = "row" >
< button class = "btn acid" id = "signin-btn" > Continue →< / button >
< / div >
< div id = "signin-err" class = "err hidden" > < / div >
< / div >
< div class = "card" id = "card-wc" >
< h3 > 🔗 WizardConnect< / h3 >
< p > Cashonize 0.9+ or Paytaca. The wallet signs the mint on your device.< / p >
< div class = "row" >
< button class = "btn acid" id = "wc-btn" > Connect wallet< / button >
< / div >
< div id = "wc-uri-box" class = "hidden" style = "margin-top:14px" >
< label > Paste this into your WC-capable wallet:< / label >
< div style = "display:flex;gap:8px;align-items:center;margin-top:6px" >
< code id = "wc-uri" style = "flex:1;font-size:12px" > < / code >
< button class = "btn ghost small" id = "wc-copy" type = "button" > Copy< / button >
< / div >
< p class = "dim" style = "margin-top:8px" > Waiting for your wallet…< / p >
< div class = "row" > < button class = "btn ghost small" id = "wc-cancel" type = "button" > Cancel< / button > < / div >
< / div >
< div id = "wc-err" class = "err hidden" > < / div >
< / div >
< / div >
< / section >
< section id = "mint-section" class = "hidden" >
< h2 > Mint < span id = "mint-label" class = "mono" style = "color:var(--acid)" > —< / span > < / h2 >
< div class = "card" >
< div class = "status" id = "mint-wallet" > Signed in as < code id = "mint-addr" > —< / code > < / div >
< label > Service fee (USD) < span class = "field-hint" > chipnet placeholder rate; mainnet will use an oracle< / span > < / label >
< input type = "text" id = "mint-usd" value = "5" style = "max-width:200px" >
< div class = "status" id = "mint-price" > = < b > 0< / b > sats · rate < b > 0< / b > sats/USD< / div >
< div class = "row" >
< button class = "btn acid" id = "mint-submit" disabled > Register< / button >
< button class = "btn ghost small" id = "mint-back" > ← Back to search< / button >
< button class = "btn ghost small" id = "mint-signout" > Sign out< / button >
< / div >
< div class = "steps-log" id = "mint-log" > < / div >
< div id = "mint-msg" class = "msg" > < / div >
< / div >
< / section >
< section id = "listing" >
< h2 > Registered TLDs< / h2 >
< p class = "muted" > Fetched from the on-chain TLD registry via the public gateway. Refresh the page for the latest.< / p >
@ -222,31 +128,20 @@
< footer id = "site-footer" > < / footer >
< script type = "importmap" >
{ "imports": { "@bitauth/libauth": "https://silentmode.st/js/libauth.js" } }
< / script >
< script >
// Simple oracle stub: static chipnet rate for testing. Same number the
// portal uses. Mainnet swaps for a real price feed.
const CHIPNET_SATS_PER_USD = 250_000;
const DEFAULT_USD = 5;
< script type = "module" >
import * as BNS from "https://silentmode.st/js/bns-register.js?v=20260907tldext";
const $ = (id) => document.getElementById(id);
const esc = (s) => String(s).replace(/[& < >"']/g, (c) => ({"&":"& ","< ":"< ",">":"> ",'"':"" ","'":"' "}[c]));
const validLabel = (s) => /^[a-z0-9-]{1,16}$/.test(s);
const normLabel = (s) => String(s).toLowerCase().replace(/[^a-z0-9-]/g, "").slice(0, 16);
const $ = (id) => document.getElementById(id);
const esc = (s) => String(s).replace(/[& < >"']/g, (c) => ({"&":"& ","< ":"< ",">":"> ",'"':"" ","'":"' "}[c]));
// ---------- oracle stub ----------
// Same chipnet-only static rate as the portal. Mainnet swaps this for a real
// price feed; the sats output is what actually gets locked into the mint tx.
const CHIPNET_SATS_PER_USD = 250_000; // ~$400/BCH test rate
const usdToSats = (u) => {
const n = Number(String(u).replace(/[^\d.]/g, "")) || 0;
return Math.max(0, Math.round(n * CHIPNET_SATS_PER_USD));
};
// ---------- state ----------
let wallet = null; // built-in wallet or WC wrapper
let candidateLabel = null; // TLD label the user chose to register
// ---------- TLD list (live) ----------
async function loadTldList() {
// ---------- registered-TLD list ----------
let registeredTlds = null;
async function loadTldList() {
const status = $("tlds-status"), tbody = $("tlds-table").querySelector("tbody");
try {
const r = await fetch("https://navigate.st/api/tlds");
@ -260,313 +155,101 @@ async function loadTldList() {
$("tlds-table").style.display = "";
status.className = "status ok";
status.textContent = `${tlds.length} TLDs registered on chipnet.`;
return tlds.map((t) => t.tld);
registeredTlds = tlds.map((t) => t.tld);
refreshSearch();
} catch (e) {
status.className = "status err";
status.textContent = "Could not load TLD list: " + (e.message || e);
return null;
}
}
let registeredTlds = null;
loadTldList().then((list) => { registeredTlds = list; refreshSearch(); });
}
loadTldList();
// ---------- search + result ----------
function validLabel(s) { return /^[a-z0-9-]{1,16}$/.test(s); }
function normLabel(s) { return String(s).toLowerCase().replace(/[^a-z0-9-]/g, "").slice(0, 16); }
function renderResult(label, state) {
// ---------- search result renderer ----------
function renderResult(label, state) {
const res = $("result");
if (!label) { res.innerHTML = ""; return; }
if (state === "checking") {
res.innerHTML = `< div class = "result-card" >
< div class = "lbl" > < span class = "dot" > .< / span > ${esc(label)}< / div >
< span class = "badge b-check" > checking…< / span >
< span > < / span >
< / div > `;
< span class = "badge b-check" > checking…< / span > < span > < / span > < / div > `;
return;
}
if (state === "taken") {
res.innerHTML = `< div class = "result-card" >
< div class = "lbl" > < span class = "dot" > .< / span > ${esc(label)}< / div >
< span class = "badge b-taken" > taken< / span >
< span > < / span >
< / div >
< p class = "dim" style = "margin-top:8px" > Someone already minted < code > .${esc(label)}< / code > . Try a different label — TLDs are first-come, first-served.< / p > `;
< span class = "badge b-taken" > taken< / span > < span > < / span > < / div >
< p class = "dim" style = "margin-top:8px" > Someone already minted < code > .${esc(label)}< / code > . Try a
different label — TLDs are first-come, first-served.< / p > `;
return;
}
// available
res.innerHTML = `< div class = "result-card" >
< div class = "lbl" > < span class = "dot" > .< / span > ${esc(label)}< / div >
< span class = "badge b-ok" > available< / span >
< button class = "btn acid" id = "go-register" > Register .${esc(label)} →< / button >
< / div > `;
$("go-register").onclick = () => beginRegister(label);
}
}
let currentLabel = "";
function refreshSearch() {
// ---------- search wiring ----------
let currentLabel = "";
function refreshSearch() {
const raw = normLabel($("q").value);
currentLabel = raw;
if (!raw) { renderResult("", null); return; }
if (!validLabel(raw)) { renderResult(raw, "invalid"); return; }
// If we already have the registry snapshot, decide locally — no API round-trip.
if (registeredTlds !== null) {
renderResult(raw, registeredTlds.includes(raw) ? "taken" : "ok");
return;
}
renderResult(raw, "checking");
}
$("q").addEventListener("input", () => {
}
$("q").addEventListener("input", () => {
$("q").value = normLabel($("q").value);
refreshSearch();
});
$("q").addEventListener("keydown", (e) => {
});
$("q").addEventListener("keydown", (e) => {
if (e.key === "Enter" & & currentLabel & & registeredTlds & & !registeredTlds.includes(currentLabel)) {
beginRegister(currentLabel);
}
});
// ---------- flow: search → wallet → mint ----------
function beginRegister(label) {
candidateLabel = label;
$("mint-label").textContent = "." + label;
// Show the sign-in section if not signed in; otherwise straight to mint.
if (!wallet) {
$("signin-section").classList.remove("hidden");
$("signin-section").scrollIntoView({ behavior: "smooth", block: "start" });
} else {
showMintSection();
}
}
function showMintSection() {
$("signin-section").classList.add("hidden");
$("mint-section").classList.remove("hidden");
$("mint-addr").textContent = wallet.address;
updateMintPrice();
updateMintButton();
$("mint-section").scrollIntoView({ behavior: "smooth", block: "start" });
}
function backToSearch() {
$("mint-section").classList.add("hidden");
$("search-section").scrollIntoView({ behavior: "smooth", block: "start" });
}
$("mint-back").addEventListener("click", backToSearch);
// ---------- wallet: import ----------
$("signin-btn").addEventListener("click", async () => {
const raw = $("seed").value.trim();
const errBox = $("signin-err");
errBox.classList.add("hidden");
if (!raw) { errBox.textContent = "Paste your seed phrase to continue."; errBox.classList.remove("hidden"); return; }
const btn = $("signin-btn");
btn.disabled = true; btn.textContent = "Unlocking…";
try { wallet = await BNS.BuiltInWallet.fromMnemonic(raw); }
catch (e) {
errBox.textContent = "Could not unlock: " + (e.message || e);
errBox.classList.remove("hidden");
btn.disabled = false; btn.textContent = "Continue →";
return;
}
$("seed").value = "";
btn.disabled = false; btn.textContent = "Continue →";
writeProfile(wallet);
showMintSection();
});
// ---------- wallet: new ----------
$("new-btn").addEventListener("click", async () => {
const btn = $("new-btn"), errBox = $("new-err");
errBox.classList.add("hidden");
btn.disabled = true; btn.textContent = "Generating…";
try {
const fresh = await BNS.BuiltInWallet.create();
wallet = fresh;
$("new-seed").value = fresh.mnemonic;
$("new-phrase").classList.remove("hidden");
btn.textContent = "Phrase generated";
} catch (e) {
errBox.textContent = "Could not generate: " + (e.message || e);
errBox.classList.remove("hidden");
btn.disabled = false; btn.textContent = "Generate a phrase";
}
});
$("new-ack").addEventListener("change", (e) => { $("new-signin-btn").disabled = !e.target.checked; });
$("new-copy-btn").addEventListener("click", () => navigator.clipboard?.writeText($("new-seed").value));
$("new-signin-btn").addEventListener("click", () => {
if (!wallet) return;
$("new-seed").value = "";
$("new-phrase").classList.add("hidden");
writeProfile(wallet);
showMintSection();
});
// ---------- wallet: WC ----------
$("wc-btn").addEventListener("click", async () => {
const btn = $("wc-btn"), errBox = $("wc-err"), uriBox = $("wc-uri-box");
errBox.classList.add("hidden");
btn.disabled = true; btn.textContent = "Starting…";
let session;
try {
const mod = await import("https://silentmode.st/js/wizardconnect.js");
session = await mod.openWizardSession({
dappName: BNS.REGISTRAR.wizardConnect.dappName,
dappIcon: BNS.REGISTRAR.wizardConnect.dappIcon,
prefix: BNS.REGISTRAR.addressPrefix,
crypto: {
pubkeyToAddress: BNS.pubkeyToAddress,
pubkeyToLockingBytecode: BNS.pubkeyToLockingBytecode,
binToHex: BNS.binToHex,
txidOfHex: BNS.txidOfHex,
},
});
} catch (e) {
errBox.textContent = "Could not start WC: " + (e.message || e);
errBox.classList.remove("hidden");
btn.disabled = false; btn.textContent = "Connect wallet";
return;
}
$("wc-uri").textContent = session.qrUri ?? session.uri;
uriBox.classList.remove("hidden");
btn.textContent = "Waiting for wallet…";
try { await session.ready; }
catch (e) {
errBox.textContent = "Wallet did not approve: " + (e.message || e);
errBox.classList.remove("hidden");
uriBox.classList.add("hidden");
btn.disabled = false; btn.textContent = "Connect wallet";
try { await session.disconnect(); } catch {}
return;
}
const addrs = await session.getAddresses();
if (!addrs?.length) {
errBox.textContent = "Wallet returned no addresses.";
errBox.classList.remove("hidden");
uriBox.classList.add("hidden");
btn.disabled = false; btn.textContent = "Connect wallet";
try { await session.disconnect(); } catch {}
return;
}
wallet = {
source: "wc",
address: addrs[0],
tokenAddress: BNS.toTokenAddress(addrs[0]),
watchedAddresses: addrs,
session,
};
writeProfile(wallet);
uriBox.classList.add("hidden");
btn.disabled = false; btn.textContent = "Connect wallet";
showMintSection();
});
$("wc-cancel").addEventListener("click", async () => {
if (wallet?.session) { try { await wallet.session.disconnect(); } catch {} }
$("wc-uri-box").classList.add("hidden");
$("wc-btn").disabled = false; $("wc-btn").textContent = "Connect wallet";
});
$("wc-copy").addEventListener("click", () => navigator.clipboard?.writeText($("wc-uri").textContent));
// ---------- profile persistence (mirrors portal.html) ----------
function writeProfile(w) {
try {
localStorage.setItem("siriusProfile", JSON.stringify({
address: w.address, tokenAddress: w.tokenAddress,
source: w.source ?? "seed", signedInAt: Date.now(),
}));
} catch {}
window.dispatchEvent(new Event("siriusProfileChanged"));
}
function clearProfile() {
try { localStorage.removeItem("siriusProfile"); } catch {}
window.dispatchEvent(new Event("siriusProfileChanged"));
}
$("mint-signout").addEventListener("click", async () => {
if (wallet?.source === "wc" & & wallet.session) {
try { await wallet.session.disconnect(); } catch {}
}
wallet = null;
clearProfile();
$("mint-section").classList.add("hidden");
$("signin-section").classList.remove("hidden");
});
// ---------- mint ----------
function updateMintPrice() {
const usd = $("mint-usd").value.trim() || "0";
const sats = usdToSats(usd);
$("mint-price").innerHTML = `= < b > ${sats.toLocaleString()}< / b > sats · rate < b > ${CHIPNET_SATS_PER_USD.toLocaleString()}< / b > sats/USD (chipnet)`;
$("mint-submit").textContent = `Register .${candidateLabel} (~${sats.toLocaleString()} sats)`;
}
function updateMintButton() {
$("mint-submit").disabled = !wallet || !candidateLabel;
}
$("mint-usd").addEventListener("input", updateMintPrice);
$("mint-submit").addEventListener("click", async () => {
if (!wallet || !candidateLabel) return;
const sats = BigInt(usdToSats($("mint-usd").value.trim() || "0"));
const msg = $("mint-msg"); msg.textContent = ""; msg.className = "msg";
const log = $("mint-log"); log.className = "steps-log on"; log.innerHTML = "";
const push = (t) => { const d = document.createElement("div"); d.textContent = t; log.appendChild(d); log.scrollTop = log.scrollHeight; };
$("mint-submit").disabled = true;
$("mint-submit").textContent = "Signing…";
let el = null;
try {
el = await BNS.connect();
push("connected to chipnet");
const serviceFee = { address: BNS.REGISTRAR?.serviceFee?.address ?? null, sats };
const res = wallet.source === "wc"
? await BNS.registerTldWithExternalWallet(el, {
session: wallet.session, tld: candidateLabel, records: {},
serviceFee, tldListUrl: "https://navigate.st/api/tlds",
onProgress: push,
})
: await BNS.registerTldWithBuiltInWallet(el, {
wallet, tld: candidateLabel, records: {},
serviceFee, tldListUrl: "https://navigate.st/api/tlds",
onProgress: push,
// ---------- mint delegation ----------
// Register button hands the label off to the shared modal (register-flow.js
// — window.siriusRegisterTld). That modal owns the wallet-choice, fund,
// confirm, and mint steps — same UX as name registration.
function beginRegister(label) {
const call = () => window.siriusRegisterTld(label, {
serviceFeeSats: BigInt(DEFAULT_USD * CHIPNET_SATS_PER_USD),
});
push("broadcast: " + (res.txid || "(no txid)"));
msg.className = "msg ok";
msg.innerHTML = `✅ < b > .${esc(candidateLabel)}< / b > minted. Category < code > ${esc((res.category || "").slice(0, 16))}…< / code > < br >
The certificate now lives in your token address; names can be registered under it from
< a href = "./#search-input" > the name search< / a > .`;
$("mint-submit").textContent = "Registered ✓";
// Refresh the live TLD table so the new one shows up.
setTimeout(() => loadTldList().then((l) => { registeredTlds = l; refreshSearch(); }), 3500);
} catch (e) {
msg.className = "msg err";
const raw = String(e.message || e);
if (/wallet is empty/i.test(raw)) {
msg.innerHTML = `Failed: wallet is empty. Fund < code > ${esc(wallet.address)}< / code > with chipnet coins first — free from
< a href = "https://tbch.googol.cash/" target = "_blank" rel = "noopener" > tbch.googol.cash< / a > or
< a href = "https://chipnet.bch.ninja/faucet" target = "_blank" rel = "noopener" > chipnet.bch.ninja/faucet< / a > .`;
} else {
msg.textContent = "Failed: " + raw;
if (typeof window.siriusRegisterTld === "function") { call(); return; }
// Module still loading — retry until it lands.
const btn = $("go-register");
const orig = btn?.textContent;
if (btn) { btn.disabled = true; btn.textContent = "loading…"; }
const t = setInterval(() => {
if (typeof window.siriusRegisterTld === "function") {
clearInterval(t);
if (btn) { btn.disabled = false; btn.textContent = orig; }
call();
}
push("error: " + raw);
$("mint-submit").disabled = false;
updateMintPrice();
} finally {
try { el?.close?.(); } catch {}
}, 100);
}
});
// ---------- ?q= deep-link (from landing search too, if someone comes with a label ) ----------
(() => {
// ---------- ?q= deep-link (from landing links etc.) ----------
(() => {
const q = normLabel(new URLSearchParams(location.search).get("q") || "");
if (!q) return;
$("q").value = q;
// wait for registeredTlds to load
const wait = setInterval(() => {
if (registeredTlds === null) return;
clearInterval(wait);
refreshSearch();
setTimeout(() => $("q").scrollIntoView({ behavior: "smooth", block: "start" }), 100);
}, 150);
})();
})();
< / script >
< script type = "module" src = "./js/register-flow.js?v=20260908tld" > < / script >
< script defer src = "./js/site-footer.js?v=20260907rel" > < / script >
< script defer src = "./js/profile-menu.js?v=20260907inline" > < / script >
< / body >