Brand button was wrapping the whole "Sirius.X" label in <span class="g">,
so the entire name rendered acid green. Consistency across the ecosystem
is Sirius (ink) + .X (acid), like Theseus.X and Hephaestus.X. Split the
span across every page (index, tld, portal, admin, brand, docs, market,
storage, theseus/) so only the .X tail carries the acid tint.
Every Sirius.X page had a leftover
@media (min-width: 721px) { header.hero, .wrap { padding-left: calc(var(--sn-w) + 1.2rem) } }
that shifted the whole reading column right by the sidebar width. On a
1400px viewport that pushed the "Names on the chain" hero and every
section off-axis — the search input, the Try it cards, the Pantheon
grid all sat right of centre while the sidebar hogged the empty left
gutter. The sidenav is a pointer-events:none overlay at opacity 0.35
now, so text peeking under the semi-transparent rail is by design;
padding the content away from it defeats the whole point of an
overlay design and creates the shifted-body layout the user flagged
in the screenshot.
Removed on index, tld, docs, admin, brand and theseus/. Content
returns to the middle of the viewport regardless of sidebar width.
The IntersectionObserver-based spy only fired when a section entered a
narrow band 40–45% down the viewport. Short sections at the tail of a
page — Operator key and Roadmap on theseus.x/extensions, whatever came
last on the other pages — never made it into that band because the
page runs out of scroll before their top crosses 40%, so their sidebar
links stayed dim no matter how far the reader scrolled.
Rewrote the spy across every page with a sidebar (theseus.x home /
plug-ins / extensions and sirius.x home / tld / theseus / docs / admin
/ brand): it listens to window scroll, picks the last section whose
top has crossed 35% of the viewport, and — when the window is scrolled
to within 4px of the bottom — snaps to the final section regardless of
where its top is. Every link in the rail can now activate.
theseus.x/extensions also had the spy IIFE bundled with the manifest
loader in one <script> block near the middle of the page, so at run
time the parser hadn't yet reached the last three sections and only
Bundled/Community/Build were ever registered. Moved the spy to its own
<script> just before </body> so it sees every section that ships.
The market page had just moved to market/index.html and still referenced
market.js and pricing.js under their previous query strings, so browsers
kept the cached satoshi-priced versions. Tags are now in step across
every page. The gateway also sends cache-control max-age=120 for
everything it serves from Sia; those files carry no ETag, so browsers
were applying heuristic caching and holding old scripts for hours.
Every Sirius.X sub-page carried the old header shape — "Try it" and
"Register" living in the topnav next to the cross-site tabs — so
clicking Market or TLD reset the layout back to a state the index no
longer used. Rewrote each topnav to the site-only tabs (Sirius.X · TLD
· Market · Theseus.X · Sign in) and appended ".X" to the Theseus tab
so the ecosystem naming is consistent across pages.
Added the overlay side-nav to every page that carries named sections:
tld.html — Search · Registered
theseus/ — Download · How · Verify
docs/ — TLD registry · Register · Private TLDs ·
Market · Records · Signed records
admin/ — Sign in · Session · Mint TLD · Registry
brand/ — Logo · Avatar · Banner · Palette · Typography ·
Usage (section IDs added — the h2s were unnamed)
Same shape as the index and as Theseus.X: pointer-events:none overlay,
opacity 0.35 by default, ink + blurred backdrop on hover, acid green
on the active section, IntersectionObserver scroll-spy. Icon rail on
medium, bottom bar on mobile.
Pages without meaningful anchor targets (market/, portal.html,
studio.html, register.html) keep the trimmed topnav but no sidebar —
adding an empty rail would just be noise.
Star emoji swapped for the site's own 4-point sparkle mark — same SVG
that ships as the favicon — everywhere it appeared: the topnav brand,
the hero mark, the "you're here" pill on the family-of-.x panel, the
footer, register.html, portal.html, tld.html, market/, docs/, admin/,
brand/, storage/, theseus/, studio.html, site-footer.js. Anyone who
opens Sirius.X now sees the acid-green sparkle instead of a browser
star emoji.
Internal links normalised to no trailing slash — href="./theseus/"
became href="./theseus" (Theseus, docs, market, admin). Cleaner URLs
in the address bar and no double-slash redirect step on the mirrors.
theseus.x, sirius.x and hephaestus.x had a 1px border-bottom under the
sticky/fixed topnav that read as a visible separator between the
navigation and the page. The topnav's own translucent-blur backdrop is
enough of a distinction already — the line is redundant and, on the
theseus.x sidebar layout, made the top of the sidebar look like it was
overhanging the header.
theseus.x tabs also had a "Sirius .X" gap because the topnav <a> is a
flex container and the icon + "Sirius" text + ".X" span were three
flex items with a 6px gap between each. Wrapping the label in one
<span> collapses the gap to a single space between icon and label.
Sidebar border-right and mobile bottom-bar border-top also dropped —
the panel tint carries the boundary; a hard line was too heavy.
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.
TLD price tiers (pricing.js):
1 char $500 (was $10)
2 char $250 (was $8)
3 char $150 (was $6)
4-6ch $100 (was $5)
7-10ch $50 (was $5)
11+ch $25 (was $4)
Payment approval (register-flow.js):
New stepApprove(...) gates the actual sign+broadcast on an explicit
user gesture — PIN pad when a PIN blob exists on this device, wallet
password otherwise. Same "3 wrong PINs → wipe, fall back to password"
behavior as the sign-in unlock step. Wired between stepConfirm(Tld)?
and stepRegister(Tld)? so both name mints and TLD mints require
approval even when the wallet is already in memory.
tld.html fee card: reflects the new $25–$500 range instead of the
"≈ 1,250,000 sat · ≈ $5" placeholder.
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.
Every second-level name registration under a TLD now routes 90% of the
service fee to whoever holds that TLD's certificate on chain, with 10%
going to the platform address. That's the economic incentive for
minting a TLD: you earn from every name registered under it.
The mechanism, end to end:
1. resolver-web.js fetchTldMap now also records mintScriptHex — the
scriptPubKey of the TREG output that carries each TLD's NFT.
Exported so registrar can decode it into a cashaddr with libauth.
MVP: this is the ORIGINAL owner; NFT transfers after mint are not
traced yet (a follow-up will walk the chain of transfers).
2. registrar.js gains findTldOwnerAddress(client, tld) and
splitServiceFee(sats). The split constants live at the top of the
file (TLD_OWNER_SHARE_NUM/DEN = 90/100) so the ratio moves in one
place. Rounding: BigInt division favours the platform on odd sat
counts so the two shares always sum EXACTLY to the input.
3. quoteRegistration wraps the existing flow: it derives the TLD from
the name, looks up the TLD owner, and if the owner ≠ buyer it asks
buildRegistrationTx to add a second fee output. If the owner
couldn't be resolved (TLD not registered, decode failure) the full
fee stays on the platform address — the buyer still pays the same
amount either way.
4. register-tx.js buildRegistrationTx accepts tldFeeAddress/tldFeeSats
and, when set, emits an extra P2PKH output for the TLD owner. Sits
between the beacon dust and the platform-fee output; outputMap
records .tldOwnerFee so callers can find it. costs also carries
tldOwnerFeeSats and netCostSats includes it.
5. priceSummary in registrar-config splits the 'Service fee' row into
'Service fee — TLD owner (90%)' + 'Service fee — platform (10%)'
whenever tldOwnerFeeSats > 0, with a per-line note explaining
where the money goes.
Bundle: re-exported findTldOwnerAddress + splitServiceFee from
register-entry.js. Rebuilt bns-register.js (~34 kB) and deployed;
cache-buster bumped to ?v=20260908split on portal / admin /
register-flow.js.
Verified live: findTldOwnerAddress('.bch') returns the operator
cashaddr; quoteRegistration('tester42.bch') builds cleanly with a
9,000/1,000 split output pair on a 10,000-sat fee; priceSummary
renders both lines. No regressions on the TLD-mint flow (buyer IS
the TLD owner there — split short-circuits and it stays a single
fee output as before).
Two features:
1. Operator can hide TLDs from the public /api/tlds listing so hidden
TLDs stop appearing in name-search UIs. On-chain registrations
under a hidden TLD keep resolving — this is a UX filter, not
enforcement.
Gateway (public-gateway.mjs):
- Persistent HIDDEN_TLDS set backed by hidden-tlds.json next to
the service script
- GET /api/tld-visibility -> {hidden:[...]} (public)
- POST /api/tld-visibility -> updates the list (operator-gated by
Bearer BNS_OPERATOR_TOKEN env var; if unset, all writes refused
so we default-deny)
- /api/tlds filters out HIDDEN_TLDS; add ?include_hidden=1 to see
everything (used by the admin panel to show all rows)
- Operator token installed via systemd override on the VPS
Admin panel:
- New 'Operator token' card at the top of the TLD-registry section;
token stored in sessionStorage (not localStorage) so a full
browser close forgets it
- Each TLD row got a 'Hidden from public' checkbox that POSTs on
toggle and refreshes the table; failures roll back the checkbox
and surface the error next to the token field
2. Wallet dropdown restored to 4 direct actions
(Unlock / Create a wallet / Import a wallet / WizardConnect) and
the shared mint/sign-in modal grew a tab strip so users can switch
between the four wallet actions from any step without going back
to a choice screen.
register-flow.js:
- renderTabs(active) prepended to stepCreate/stepImport/stepUnlock/
stepExternal when signInOnly is set. Unlock tab only appears
when a saved wallet exists.
- Delegated click handler on the sheet routes tab clicks to the
matching step; switching away from a live WC session tears it
down first so we don't leak WebSockets.
profile-menu.js:
- Restored 4-item onboarding menu (Create/Import/WC plus Unlock
when saved). Each item is a direct entry point; the tabbed modal
lets the user pivot to any other option without closing.
Cache-buster bumped on all 8 sirius-x pages to ?v=20260908tabs.
Two changes:
1. Wallet dropdown simplified from three direct-action items into one
'Sign in or create wallet' launcher (plus 🔓 Unlock when a saved
wallet is present). The single item opens the shared modal at
stepWallet — the choice screen showing all four options (Unlock /
Create / Import / WizardConnect) as clear cards. Clicking a card
reveals its form. Users see the options first, then commit to a
path, instead of landing on a form for one path without seeing the
others.
register-flow.js's stepWallet grew a signInOnly-aware header ('Sign
in or create a wallet' / 'Pick one. Your keys stay in this browser')
so the choice screen reads as sign-in context, not a name mint.
startSignIn still accepts direct-mode entry points (new/import/wc/
unlock) for deep-links like portal.html?mode=X, but the nav dropdown
funnels to 'choose' for the choice-first experience.
2. Theseus subpage copy updated per request: 'native .bch / BCNR name
resolution built in' -> 'native Bitcoin Cash Domain Names resolution
built in'. Meta description mirrored.
Previously, the only way to unlock a wallet that had been saved in this
browser was to click Register (name or TLD), open the modal, and pick
'Unlock my browser wallet' from the wallet-choice step. From the nav
dropdown you could only start onboarding fresh (New / Import / WC).
profile-menu.js now checks localStorage for the BuiltInWallet's storage
key (bns.wallet.v1) at every render, and when a saved wallet is present
inserts a '🔓 Unlock my wallet' item at the top of the not-signed-in
dropdown — with a divider below it, so it reads as the primary action
and the Onboarding options stay available for adding a different wallet.
The dropdown click handler already lazy-loads register-flow.js and
calls window.siriusSignInWallet(action); register-flow.js's startSignIn
grew an 'unlock' mode that opens the modal directly at stepUnlock (the
password prompt). Same success path as every other sign-in: on unlock
success, siriusProfile is written and the modal closes with '✓ Signed
in' — the nav pill flips to the address without a reload.
Verified end-to-end on landing: saved wallet detected -> dropdown shows
Unlock as first item -> click -> password -> '✓ Signed in' -> pill
becomes 'qqyx49…zx8x seed ▾' with no reload. TLD mint from tld.html
also verified end-to-end: search 'e2etldtest' -> Register -> modal ->
Unlock -> password -> Fund -> Confirm (fee 1,250,000 sat + beacon dust
~1,300 sat) -> Register -> checking-availability -> loading-coins ->
'wallet is empty' (expected without chipnet funds; downstream code is
the same registerTldWithBuiltInWallet path the CLI uses).
Two UX polishes:
1. Register-tab icon flipped from 🪪 (identification-card emoji, renders
as a hollow box in system-ui fonts without extended emoji) to ✏️
(pencil), which reads as 'edit/create' and ships in every emoji font
worth targeting. Changed across the nav on all 8 pages plus the
footer injector's Product column. Kept the Register nav item — six
items total in the nav, and from any subpage it's one click to the
search on landing.
2. tld.html no longer duplicates the wallet-choice + mint flow inline.
The Register button on a search result now hands the label off to
the shared register-flow.js modal — same modal that name registration
uses — via a new window.siriusRegisterTld(label, {serviceFeeSats})
entry point.
register-flow.js grew:
- startTldFlow / window.siriusRegisterTld: sets state.tld and walks
the modal through wallet-choice → Fund → stepConfirmTld → stepRegisterTld
→ stepDoneTld
- stepConfirmTld: shows label + fee + owner, no per-name quote
- stepRegisterTld: dispatches to registerTldWithBuiltInWallet or
registerTldWithExternalWallet based on state.wallet/state.session
- stepDoneTld: 'X is yours' with txid + certificate id + operator
address, no record editor (a TLD certificate has no records to
set immediately)
- stepWallet / stepExternalConfirm branch on state.tld so the modal
heading and the WC-confirm path route correctly
tld.html trimmed: removed the entire signin-section + mint-section
plus their inline handlers (~250 lines gone). Now just search +
registered-TLDs list + a delegator to the shared modal. If a user
is already signed in via the wallet dropdown, the modal recognises
the saved wallet ('Unlock my browser wallet' button appears) instead
of asking them to sign in again on this page.
Wallet dropdown items (New / Import / WizardConnect) were navigating
to portal.html?mode=X and asking the user to click again on arrival.
That is 'the sign in landing page which is not functioning' from the
user's perspective — a whole redirect for one form.
Now every dropdown item opens the mint modal (register-flow.js) inline
at the matching step, on whatever page the user is on:
New -> stepCreate ('Create your wallet' — password + generate)
Import -> stepImport ('Import a recovery phrase' — textarea)
WizardConnect -> stepExternal ('Open your wallet' — QR/URI)
register-flow.js grew a signInOnly mode: state.name is null, the step
Back buttons close instead of going to a wallet-choice step there is
no context for, and on wallet-loaded the flow writes siriusProfile
and shows a 'Signed in' confirmation instead of Fund -> Confirm -> Mint.
WC signInOnly keeps the session alive (state.session) so a later
record edit can reuse it without a fresh QR handshake.
profile-menu.js: menu items became <a data-action='new|import|wc'>
and the click handler lazy-loads register-flow.js on demand — the
docs/brand/theseus pages don't ship it in their initial payload, so
their nav pill loads it the first time a wallet button is clicked and
caches it for subsequent opens. Falls back to portal.html?mode=X if
the module can't load. Cache-buster bumped so cached copies pick up
the new behavior.
Importmap for @bitauth/libauth added to docs/, brand/, theseus/ so
the bundle's bare specifier resolves when register-flow.js is
lazy-loaded from those pages.
Verified end-to-end on the live docs page: all three dropdown items
open the modal inline at the correct step, no console errors, no
navigation.
Register.html and the landing were running duplicate name-search UIs.
The register one was reported broken; the landing one already works
inline. Merged both into the landing:
- New js/register-flow.js — the full mint modal + wallet setup (Create /
Import / Unlock / WizardConnect / Fund / Confirm / Register / Point
it somewhere) extracted from register.html's <script type='module'>
and turned into a shared module. Injects its own scoped modal HTML +
CSS into the host page on load and exposes
window.siriusRegisterName(fullName) as its public entry point.
- Landing search results now have Register buttons that call the shared
flow directly. The whole 'search -> pick name -> mint' journey stays
on one page, no redirects, no duplicate search UI to maintain.
- register.html reduced to a redirect stub: preserves ?q= if present,
refreshes/JS-forwards to './' (landing), and shows a one-line
'Name search moved to the home page' fallback for JS-off users.
Old links keep working; no /register.html deep links are broken.
- All nav 'Register' entries now point at './#search-input' (or
'../#search-input' on subpages), scrolling straight to the landing
search box. Footer injector and every internal href updated the
same way. Zero live href='.../register.html' left in the tree.
Verified: register.html?q=hello redirects to /?q=hello; landing
search 'fresh42abc' -> Register button -> modal opens with
'Register fresh42abc.bch' at the wallet-choice step.
The nav's 'Theseus' link showed a generic 🧭 emoji, which renders
differently in every browser/OS and does not match theseus.x's
actual brand mark. Replaced with a small inline SVG of theseus.x's
compass (rounded dark square, N-half red, S-half acid) at 14x14 so
the button now carries theseus.x's real logo — recognisable and
identical everywhere.
Inlined the SVG rather than pointing at a shared asset so there's no
extra request per page and no relative-path arithmetic between root
and subdir pages. Applied to all 8 pages: landing, portal, register,
tld, theseus, docs, brand, admin.
Nav consistency: subpages had Try it → Theseus → Register → TLD while
the landing had Try it → Register → TLD → Theseus. Reordered every
page to the landing's order, so the top nav is identical everywhere:
Sirius.X | Try it | 🪪 Register | 🌐 TLD | 🧭 Theseus | 🔑 Sign in
(Admin adds its own 🛠 Admin between Theseus and Sign in since Admin
is the current page.)
Theseus subpage now carries Theseus.X's own branding: the compass
favicon (N-half red, S-half acid) copied from silentmode.st/bns/
theseus.x/assets/ lives under site-sirius-x/theseus/assets/, and the
subpage references it for <link rel=icon>, <link rel=mask-icon>, and
og:image. og:site_name flipped from 'Sirius.X' to 'Theseus Navigator'.
Hero mark swapped from the generic 🧭 emoji to the actual compass
SVG at 72px with a soft acid glow, so the page reads as Theseus at a
glance instead of borrowing Sirius's star.
Sign-in end-to-end verified on the live site:
- Landing dropdown → New wallet → portal auto-generates 12-word phrase
- Ack + Continue → me section revealed, siriusProfile written with
{address, tokenAddress, source: 'seed', signedInAt}
- Nav pill updates to 'qzc2vx…yn93 seed ▾' without reload
- Sign out → profile cleared, portal reset, pill back to 'Wallet ▾'
- Wallet address derives deterministically from the fresh mnemonic
(BuiltInWallet.create → deriveSeedFromBip39Mnemonic → HD path)
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.
Moved secondary destinations (Docs, Roadmap, Brand, Silent Mode) out
of the top nav and into a proper site footer on the landing:
Top nav (all pages) is now:
Sirius.X | Try it | 🪪 Register | 🌐 TLD | 🧭 Theseus | 🔑 Sign in
That's 6 items instead of 10, and every one is a primary action the
user takes on Sirius.X. Docs / Roadmap / Brand / Silent Mode read as
'learn more', not 'do a thing', so they belong in the footer.
Landing footer redesigned as a four-column grid:
- Brand column: star mark, wordmark, one-line pitch
- Product: Register / TLD / Portal / Theseus
- Learn: Docs / Roadmap / Pantheon / Brand kit
- Silent Mode: silentmode.st, TLD registry, theseus.x, hephaestus.x
Meta row at the very bottom: 'Alpha' badge + chipnet disclaimer on
the left, copyright + brand-kit link on the right. Cascades to 2-col
on tablet, 1-col on phone.
Subpages keep their existing minimal footers for now — the beautiful
footer is landing-only where it earns the real estate. Nav slim is
site-wide.
Missing user-facing surface: minting a TLD required either the portal
(sign in first, register second, tucked under 'Signed in') or the
operator-only admin panel. New tld.html is a public, single-purpose
page that lets anyone go straight from label to certificate.
Flow: type a label → live check against /api/tlds → 'Register .foo →'
appears → sign-in cards (New / Import / WizardConnect) revealed inline
→ mint section shows label, address, price → submit walks through
'connected → checking-availability → loading-coins → building →
signing → broadcasting → registered'.
Wire is proven end-to-end (search returns a registerable card for
free labels, wallet flow generates a valid seed, address, submit
reaches 'wallet is empty' with a friendly faucet hint for the
signed-in address). Downstream of loading-coins is the same build/
sign/broadcast path exercised by every name registration.
Dispatch on wallet.source uses registerTldWithExternalWallet when
signed in via WC, else registerTldWithBuiltInWallet. Live TLD table
under the search shows every currently registered TLD with its
category; refreshes on successful mint.
Nav: '🌐 TLD' added to all 7 pages between Register and Brand.
Landing's 'Register a TLD' card now points here (previously linked
to the operator admin, which locked out anyone who isn't operator).
Five UX fixes from a review pass:
1. profile-menu.js: dropdown links (New/Add/WC wallet, Admin) were
absolute /sirius-x/portal.html paths. That's fine on silentmode.st
but under the BCNR route (sirius.x/) the origin is different, so
the gateway forwarded to Sia which returned 'NoSuchKey' XML. Now
derive the base URL from the nav's own .portal anchor href — which
is already set per page with the right relative path — so it works
from the root, from subdirs, and under any BCNR gateway. Admin URL
is derived from the same base.
2. Landing hero got a search input. Submitting it normalises the
label ([a-z0-9-], 63 chars) and redirects to register.html?q=<label>.
register.html now honours ?q= on load: prefills the input, triggers
the parallel multi-TLD lookup, and scrolls into view. Single source
of truth stays in register.html; the landing just hands it a query.
3. Portal TLD-mint error path now special-cases 'wallet is empty' and
shows a friendlier message with the wallet's address and links to
two chipnet faucets, so the fix is one click away instead of a
guess.
4. Removed 'Pantheon' from every page's top nav — it's a section on
the landing that anyone scrolling will discover, and keeping it in
the nav crowded the bar.
5. Cache-buster ?v=20260907rel on the profile-menu.js script include
across all 7 pages so browsers that cached the pre-fix version
pick up the new one on next load.
Adds the external-wallet variant of registerTldWithBuiltInWallet so
WizardConnect users can mint TLDs from the sirius.x portal without
first importing a seed. Same transaction shape (TREG payload, TLD-
beacon output, service-fee output) — the wallet approves the mint
(and, if needed, a one-time prep signature to satisfy the vout-0
non-token genesis-input rule) on the user's own device.
Bundle: re-exported from src/web/register-entry.js and rebuilt
(bns-register.js: 33.3 kB, cache-buster bumped to ?v=20260907tldext
on portal.html / register.html / admin/index.html).
Portal: TLD-register submit now dispatches on wallet.source, calling
registerTldWithExternalWallet with wallet.session when the user is
signed in via WC. Removed the WC-disable guard and updated the card
copy to say TLD mints also go through the wallet's signing prompt.
Uses the same landOnChain helper as registerWithExternalWallet, so
wallet-broadcasts (walletBroadcasts:true sessions) and duplicate/
mempool responses are handled identically.
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.
Copies site/sirius/register.html to site-sirius-x/register.html with
paths rewritten to absolute silentmode.st URLs (js bundle, importmap,
shared.css, WizardConnect vendor) so the page works both from
silentmode.st/sirius-x/register.html and from sirius.x/register.html
via the BCNR gateway. Nav is swapped to the sirius.x layout with
profile-menu.js.
Landing, portal, docs, and theseus subpage now link locally with
./register.html instead of redirecting off to silentmode.st. Adds
'Register' to the top nav of all six sirius.x pages.
Sia and VPS mirrors updated for register.html and the six pages.
registrar.js: BNS.connect() now filters silentmode.st/electrum and
coinspectrum.duckdns.org:50011 out of the default electrum list. Those
endpoints are our own bns-indexer.js — beacon-only, serves get_history +
transaction.get but NOT listunspent for arbitrary scripthashes. Every
wallet op (getBalance, getUtxos, edit signing) needs listunspent, so
picking a beacon indexer first (which we did for best reachability) broke
every wallet unlock with "-32601 unsupported method: blockchain.
scripthash.listunspent". New `beaconOk: true` opts back in for pure-
resolution paths.
Rebuilt the browser bundle (site/js/bns-register.js) so the fix reaches
portal + admin + register.html + anything else that imports BNS.connect.
site-sirius-x/js/profile-menu.js: a small shared script that transforms
the "🔑 Sign in" nav pill into a dropdown menu on every sirius.x page.
Signed-out shows New wallet / Add wallet / WizardConnect + a link to the
sign-in page. Signed-in (reads localStorage 'siriusProfile') shows the
short address, My names, Admin, Sign out. Included via one <script defer>
tag on each of the 6 pages (landing / portal / admin / docs / theseus /
brand); dropdown CSS is inlined by the script itself so consumers don't
need a matching stylesheet.
Portal.html writing to localStorage.'siriusProfile' after sign-in is a
follow-up so the dropdown reflects state across pages — until then the
menu always shows the onboarding options.
/sirius-x/admin/ — sign in with the wallet ecosystem-known as operator to
mint a new TLD directly from the UI. Non-operator wallets see read-only
mode. The panel:
* Sign-in with seed phrase, wiped from memory on sign-out.
* Operator gate: address whitelist (chipnet, client-side; the covenant
countersignature enforces it on-chain once mainnet lands).
* TLD-registry table: fetched from GET /api/tlds, always visible.
* Mint form: label + records JSON → BNS.registerTldWithBuiltInWallet →
broadcast → auto-refresh registry.
* Progress log streams every step from onProgress callback.
* meta noindex,nofollow — operator surface, not for search discovery.
The "Register a TLD" card on the landing now links to /admin/ alongside
the "propose a TLD" affordance for public users.
Prereq: rebuilt bundle exports registerTldWithBuiltInWallet and
buildTldRegistrationTx (added by concurrent session). Bundle redeployed.