Commit graph

41 commits

Author SHA1 Message Date
Local Dev
6378e179b6 fix(sirius-x/register-flow): inline render actually writes to the inline mount
renderSignInInline() reassigned the module-level 'sheet' variable to the
host page's container, but render() had been shadowing that with a
separate 'mountTarget' constant captured at module init — so every step
kept writing into the modal sheet instead of the inline container.
Portal.html therefore showed an empty #signin-inline while the tabs +
form rendered off-screen inside the (closed) modal.

Drop mountTarget entirely and let render() write directly into 'sheet'.
'sheet' is already the reassignable target for both modal and inline
paths, and renderSignInInline / close() already keep it in sync.
2026-09-08 13:06:16 +02:00
Local Dev
14cc83dfae feat(registrar): 90/10 revenue split — TLD owner earns from name mints
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).
2026-09-08 02:42:16 +02:00
Local Dev
7687b115f9 fix(sirius-x/portal): use shared modal instead of stale inline sign-in cards
/sirius-x/portal.html?mode=import was landing users on the old three-card
inline sign-in UI (New / Import / WizardConnect each as its own form).
The new UX is: one tabbed modal, everywhere. Portal was the one page
still shipping the legacy cards.

Replaces the whole <section id='signin'> with a single launcher card
('🔑 Sign in or create wallet' → opens the shared modal). The old
handlers (, ,  etc.) are
comment-blocked out; new script uses window.siriusSignInWallet().

?mode=new|import|wc|unlock auto-opens the modal at that tab (the same
handler dropdown items use). If the user arrives with a siriusProfile
but no in-memory wallet (e.g., they signed in on another page), portal
opens the modal at Unlock (or Import when no saved wallet). Sign-out
delegates to the shared signOutUi(). Cross-tab and same-tab profile
changes both re-adopt.

register-flow.js: finishSignIn now sets window.siriusWallet so portal
(and any other page loaded in the same tab) can pick the wallet up
without re-prompting for a password. In-memory only — reload/nav clears
it, and the profile listener falls through to Unlock.
2026-09-08 02:35:56 +02:00
Local Dev
109e9e7351 feat(sirius-x): admin TLD hide/unhide + tabbed sign-in modal (4 direct actions)
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.
2026-09-08 02:19:41 +02:00
Local Dev
e19226cbbb feat(sirius-x): choice-first wallet UX, Bitcoin Cash Domain Names in Theseus copy
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.
2026-09-08 01:43:35 +02:00
Local Dev
afeae356aa feat(sirius-x): 🔓 Unlock my wallet in nav dropdown when a saved wallet exists
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).
2026-09-08 00:24:54 +02:00
Local Dev
bce4aa3529 feat(sirius-x): pencil Register icon + TLD mint via shared modal
Two UX polishes:

1. Register-tab icon flipped from 🪪 (identification-card emoji, renders
   as a hollow box in system-ui fonts without extended emoji) to ✏️
   (pencil), which reads as 'edit/create' and ships in every emoji font
   worth targeting. Changed across the nav on all 8 pages plus the
   footer injector's Product column. Kept the Register nav item — six
   items total in the nav, and from any subpage it's one click to the
   search on landing.

2. tld.html no longer duplicates the wallet-choice + mint flow inline.
   The Register button on a search result now hands the label off to
   the shared register-flow.js modal — same modal that name registration
   uses — via a new window.siriusRegisterTld(label, {serviceFeeSats})
   entry point.

   register-flow.js grew:
   - startTldFlow / window.siriusRegisterTld: sets state.tld and walks
     the modal through wallet-choice → Fund → stepConfirmTld → stepRegisterTld
     → stepDoneTld
   - stepConfirmTld: shows label + fee + owner, no per-name quote
   - stepRegisterTld: dispatches to registerTldWithBuiltInWallet or
     registerTldWithExternalWallet based on state.wallet/state.session
   - stepDoneTld: 'X is yours' with txid + certificate id + operator
     address, no record editor (a TLD certificate has no records to
     set immediately)
   - stepWallet / stepExternalConfirm branch on state.tld so the modal
     heading and the WC-confirm path route correctly

   tld.html trimmed: removed the entire signin-section + mint-section
   plus their inline handlers (~250 lines gone). Now just search +
   registered-TLDs list + a delegator to the shared modal. If a user
   is already signed in via the wallet dropdown, the modal recognises
   the saved wallet ('Unlock my browser wallet' button appears) instead
   of asking them to sign in again on this page.
2026-09-08 00:10:11 +02:00
Local Dev
5e0c971c23 feat(sirius-x): inline wallet dropdown — no navigation, no portal detour
Wallet dropdown items (New / Import / WizardConnect) were navigating
to portal.html?mode=X and asking the user to click again on arrival.
That is 'the sign in landing page which is not functioning' from the
user's perspective — a whole redirect for one form.

Now every dropdown item opens the mint modal (register-flow.js) inline
at the matching step, on whatever page the user is on:
  New         -> stepCreate  ('Create your wallet' — password + generate)
  Import      -> stepImport  ('Import a recovery phrase' — textarea)
  WizardConnect -> stepExternal ('Open your wallet' — QR/URI)

register-flow.js grew a signInOnly mode: state.name is null, the step
Back buttons close instead of going to a wallet-choice step there is
no context for, and on wallet-loaded the flow writes siriusProfile
and shows a 'Signed in' confirmation instead of Fund -> Confirm -> Mint.

WC signInOnly keeps the session alive (state.session) so a later
record edit can reuse it without a fresh QR handshake.

profile-menu.js: menu items became <a data-action='new|import|wc'>
and the click handler lazy-loads register-flow.js on demand — the
docs/brand/theseus pages don't ship it in their initial payload, so
their nav pill loads it the first time a wallet button is clicked and
caches it for subsequent opens. Falls back to portal.html?mode=X if
the module can't load. Cache-buster bumped so cached copies pick up
the new behavior.

Importmap for @bitauth/libauth added to docs/, brand/, theseus/ so
the bundle's bare specifier resolves when register-flow.js is
lazy-loaded from those pages.

Verified end-to-end on the live docs page: all three dropdown items
open the modal inline at the correct step, no console errors, no
navigation.
2026-09-07 23:52:12 +02:00
Local Dev
94bf3bcf68 feat(sirius-x): merge register.html into landing via shared mint flow
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.
2026-09-07 22:36:02 +02:00
Local Dev
b25fc40b0d feat(sirius-x/nav): use theseus.x compass SVG in Theseus button, not emoji
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.
2026-09-07 22:17:33 +02:00
Local Dev
57d7167900 feat(sirius-x): consistent top nav order, Theseus.X branding on theseus subpage
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)
2026-09-07 22:05:45 +02:00
Local Dev
e4277832dd 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
Local Dev
e5bcdc0f46 feat(sirius-x): slim top nav + beautiful multi-column footer on landing
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.
2026-09-07 21:54:06 +02:00
Local Dev
45d733f263 feat(sirius-x): inline search on landing, immediate feedback on register
Landing hero previously had a redirect-form (type → click Search → jump
to register.html). Users read that as broken because typing did nothing.
Now the landing runs the same availability check inline: hits
/api/labels/<label> once (server-side cross-TLD lookup from the cached
index), cross-checks against the client TLDS list, and paints result
cards for every TLD with an 'available/taken' badge and either a
Register button (linking to register.html?q=<label> for the wallet
flow) or a 'view' link to the existing name via the public gateway.

Immediate feedback: 18 'checking…' placeholder cards paint the moment
the input event fires, so there is no dead period while the fetch is
in flight. Register.html got the same treatment — a 'Checking <label>
across every TLD…' line replaces the empty-state message during the
350ms debounce so the box never looks unresponsive.
2026-09-07 21:33:01 +02:00
Local Dev
cf04b583aa feat(sirius-x): public tld.html — search + mint a TLD end-to-end
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).
2026-09-07 20:39:11 +02:00
Local Dev
1cca60c4df fix(sirius-x): profile-menu URLs, landing search, empty-wallet hint, drop Pantheon
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.
2026-09-07 20:32:14 +02:00
Local Dev
3e57b1bb31 feat(registrar): registerTldWithExternalWallet + wire into portal
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.
2026-09-07 01:39:16 +02:00
Local Dev
6dd8b141d4 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
Local Dev
36e0ab7593 fix(sirius-x/brand): thinner vertical arms on banner star
The banner star's inner-waist rectangle was 100x30 (x∈[850..950],
y∈[300..330]) — much wider than tall, which made the vertical arms
look bloated compared to the razor-thin horizontal arms. Bring the
inner waist to 30x30 (x∈[885..915]) so vertical and horizontal arms
taper at the same rate. Matches favicon/logo/avatar, which were
already built with symmetric inner squares.
2026-09-07 01:24:28 +02:00
Local Dev
6ce9de33a0 feat(sirius-x/portal): New wallet card, siriusProfile state, ?mode= deep-links
Closes the loop between the nav's profile dropdown and portal.html:

- Adds a 🆕 New wallet card that calls BuiltInWallet.create() to generate
  a fresh BIP-39 phrase in the browser. The phrase is shown once for the
  user to write down; sign-in only unlocks after they tick the 'I have
  written this down' acknowledgement. Copy button included.
- Sign-in (both New and Import paths) now writes localStorage.siriusProfile
  = { address, tokenAddress, signedInAt } so any page on the same origin
  can render 'signed in' state. Sign-out clears the key and also resets
  the New wallet card so a re-sign-in starts clean.
- Handles ?mode=new|import|wc from the profile dropdown's deep-links:
  scrolls the matching card into view and briefly outlines it in acid so
  the user knows which one they were sent to.

profile-menu.js:
- Re-renders the dropdown on every open() call rather than caching the
  first paint, so a sign-in that happens *after* the script's initial
  run (same tab: portal.html; other tabs: storage event) reflects in the
  nav without needing a full reload.
- Listens for the storage event (cross-tab) and a custom
  'siriusProfileChanged' event (same-tab) — portal.html fires that on
  every writeProfile/clearProfile call.
2026-09-07 00:15:43 +02:00
Local Dev
e59a2a01b5 feat(sirius-x): host name-registration flow on sirius.x itself
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.
2026-09-06 22:32:23 +02:00
Local Dev
56e25d7938 sirius.x: fix electrum listunspent + profile dropdown across all 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.
2026-09-06 18:53:17 +02:00
Local Dev
e7d9921b26 sirius.x/admin: operator-only panel for TLD minting + registry view
/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.
2026-09-06 18:46:45 +02:00
Local Dev
132e12e7a8 sirius.x/portal: register a TLD in-browser (M1.5 — chipnet, USD-priced)
Sign-in view grows a "Register a new TLD" card. User picks a label (validated
against [a-z0-9-]{1,16} and normalised as they type), sees live sats price
computed from a USD field via a static chipnet oracle rate (250,000 sats/USD
≈ $400/BCH), can check availability against navigate.st/api/tlds, then submit
a TREG signed with the built-in wallet — same code path seed-tld-beacon.mjs
uses server-side, but via the browser-exported registerTldWithBuiltInWallet.

  * Live price display recalculates on USD-input change; service fee is
    paid to REGISTRAR.serviceFee.address (same fee address name registrations
    use — no per-TLD split yet since that's mainnet covenant territory).
  * Check-availability polls the live /api/tlds endpoint before the user
    commits sats to a doomed TREG.
  * Progress log streams the shared onProgress steps
    ("checking-availability", "signing", "broadcast: <txid>") so users can
    tell whether the transaction actually left the browser.
  * Chipnet rate + form default of $5 make full-flow tests possible from
    the operator wallet (~1.25M sats each); users can override the USD to
    $0.01 for cheap iteration during testing.

UI verified end-to-end (label sanitisation, price recalc, availability
check against real API, buttons gate correctly on wallet state). Full
sign+broadcast requires a funded wallet — operator can verify.

Next: real oracle (CoinGecko / Kraken feed) + tiered pricing by label
length + admin panel for changing the rate config.
2026-09-06 18:18:41 +02:00
Local Dev
1065739aee sirius.x/theseus: delegate downloads + versions + hashes to theseus.x
The Theseus subpage on sirius.x had a hardcoded v0.0.4 with pinned download
URLs and pinned hashes — went stale within days (current is v0.3.5). Since
theseus.x is now the canonical Theseus site with its own /#download and
/#verify sections that its operator keeps current, delegate:

  * Download section shrunk to a single 'Open theseus.x downloads' CTA.
    Removed hardcoded version, per-build cards, size estimates. Added a
    short note explaining why (sirius.x won't try to shadow theseus.x's
    release notes).
  * Verify section: sha256sum placeholder now takes '<downloaded-file>'
    instead of a specific filename; hash-check link points at
    theseus.x/#verify where the current release's hashes live.

Sirius.x/theseus becomes a small landing that says 'what Theseus is + how
it works' (evergreen); theseus.x owns everything version-sensitive.
2026-09-06 01:45:54 +02:00
Local Dev
2b22a663bb docs/sirius.x: dual-host recipe + auto-backup + reusable mirror script
/sirius-x/docs/#host — Pattern C section extended with:
  * "The dual-host recipe, end to end" — four-step publish sequence: edit
    locally → scp to VPS → sia-upload → verify both.
  * "Auto-backup: one command, both mirrors" — a Bash wrapper any operator
    can drop into their repo to publish to both mirrors atomically.
  * "Automate the reverse — VPS → Sia periodic backup" — a cron snippet
    for setups whose primary publish is straight-to-VPS.
  * Note on which mirror is authoritative (chain record decides).

scripts/mirror-bcnr-site.sh — general-purpose implementation of the
recipe. Takes local-dir, ssh-dest, sia-bucket-key + optional verify URLs.
Exit codes distinguish scp failure vs sia-upload failure vs verify
failure so a CI/hook can react. Trims trailing slash from Sia bucket key
so sia-upload.js doesn't produce "bns/x//file" paths.
2026-09-04 23:44:10 +02:00
Local Dev
12188d5c1f sirius.x/portal: M1 — record editor (view → edit → sign UPD → broadcast)
Each owned-name row gets an Edit button. Click → modal with editable fields
for the five most-used records (h / s3 / ip / tls / u), pre-populated from
the current on-chain values. Save signs a UPD transaction with the
in-browser wallet (same code path as sirius/register.html:
BNS.setRecordsWithBuiltInWallet) and broadcasts it.

Live payload-budget indicator shows bytes-used vs bytes-available (from
BNS.payloadBudget for op=UPD); Save disables when the record set exceeds
the 200-byte on-chain envelope so users don't waste a broadcast on a
too-large payload. Progress log inside the modal streams every step
("resolving", "signing", "broadcast: <txid>") from the shared onProgress
callback.

UI verified end-to-end in-browser (synthetic /api/holdings intercept):
modal opens, fields populate, budget calculates live, over-budget disables
Save, Cancel closes. Actual sign+broadcast needs a wallet that owns names —
operator can verify with their seed; the code path is the one register.html
has been using for months.

M1 shipped; M2 (Sia file upload) and M3 (Markdown site builder) are next.
WizardConnect wiring for external-wallet UPDs is a follow-up — the built-in
path is what this session's wallet-unlock flow already supports.
2026-08-31 21:44:20 +02:00
Local Dev
9bf9d8cc67 sirius.x: pantheon section + nav link — seven sibling .x names
The seven .x names now on chipnet: silentmode.x, sirius.x, theseus.x,
hephaestus.x, prometheus.x, helios.x, hermes.x. New #pantheon section on
the landing lists each with dot-badge, one-line description, and a link
that goes through the silentmode.st BCNR gateway so every browser reaches
them regardless of resolver install.
2026-08-31 21:25:33 +02:00
Local Dev
287bde6b0a sirius.x/docs: link concrete Forgejo URLs for INSTRUCTIONS.md (repo now public) 2026-08-31 15:22:45 +02:00
Local Dev
7cad03f1cd sirius.x/docs: add "Host your name" recipe + serve INSTRUCTIONS.md over http
/sirius-x/docs/#host walks through three patterns for actually shipping a site
under a BCNR name:
  * Pattern A — Sia only (what silentmode.bch uses): sia-upload command,
    bucket-path convention (bns/<label>/), chain record with trailing slash
    so the gateway auto-indexes.
  * Pattern B — Your own server: ip + tls records, chain-pinned TLS trust.
  * Pattern C — Dual host: Sia primary + VPS mirror (what sirius.x itself
    uses), with the nginx location snippet needed on the operator's box.

Also copied INSTRUCTIONS.md to /sirius-x/docs/INSTRUCTIONS.md (served as
plain text) so any session — including ones without a SilentMode checkout —
can read the full operator runbook via a public URL, no clone required.
The copy is gitignored; treat root INSTRUCTIONS.md as authoritative and
re-copy on deploy. Runbook section on docs page now lists three access
paths (browser, clone, planned Forgejo mirror at code.silentmode.st).
2026-08-31 14:56:27 +02:00
Local Dev
13be3577be sirius.x: /brand/ kit — logo, mono, avatar, banner, favicon, palette
brand/ ships every reusable mark plus a browseable kit page:
  * logo.svg — full colour wordmark (star + sirius.x, .x in acid green)
  * logo-mono.svg — currentColor version for print / one-colour merch
  * favicon.svg — 64×64 rounded square, scales cleanly to 16×16
  * avatar.svg — 512×512 square, hard corners (platforms round-mask)
  * banner.svg — 1200×630 OG / Twitter Card canvas, crop-tolerant layout
  * index.html — brand-kit page: asset previews + download links, full
    colour palette with names/hex, typography sample, do/don't guidance,
    MIT-attribution notice.

Nav: added 🎨 Brand link to every sirius.x page (landing, portal, docs,
theseus). og:image on every page updated to point at /brand/banner.svg
instead of the wordmark logo — social crawlers get a proper 1200×630
banner with title, tagline, and mark instead of a thin logo strip.

Kept /assets/favicon.svg and /assets/logo.svg in place so existing
external references (Nostr metadata, third-party embeds) don't break.
2026-08-31 05:44:25 +02:00
Local Dev
adeeae4cd4 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
Local Dev
32fdaac1ed sirius.x: branding — SVG favicon, wordmark logo, OpenGraph + Twitter Card
assets/favicon.svg — 4-point sparkle star in acid green on a rounded dark
square. Scales cleanly at any size (16px tab icon through Retina). Uses the
Silent Mode palette so it recognisably reads as Silent Mode family.
assets/logo.svg — the same star + "sirius.x" wordmark with the .x accented in
acid green. Used as the og:image; can also be inlined as a brand mark.

Every page (landing / docs / portal / theseus) gets:
  * <link rel="icon"> + <link rel="mask-icon"> pointing at favicon.svg
  * og:type, og:site_name, og:title, og:description, og:url, og:image
  * twitter:card + twitter:title/description on the landing (summary card)

Absolute paths (/sirius-x/assets/…) so subpages get the same brand mark
without per-page path juggling.
2026-08-31 04:30:53 +02:00
Local Dev
7889755b66 electrum: wire wss://silentmode.st/electrum as first-choice (port 443 reachable)
Bns-indexer on VPS was only exposed on port 50011 via nginx, which corporate
firewalls, mobile carriers, and many VPNs block. Added an nginx location on
443 that proxies to the same 127.0.0.1:50010, giving us a browser-friendly
WSS endpoint on the standard HTTPS port.

  * lib/electrum.js CHIPNET_ELECTRUM: wss://silentmode.st/electrum listed
    first (used by registrar.connect() + everything that depends on it).
  * lib/resolver-web.js CHIPNET_ELECTRUM: same, kept in lockstep per the
    "change both together" comment.
  * bns-register.js bundle rebuilt to bake the new list.
  * portal.html imports the bundle with ?v= so Chrome's in-memory ES-module
    map doesn't serve a stale copy across tabs.

Portal now connects successfully; next remaining issue is that
bns-indexer only supports (server.version, get_history, transaction.get) —
`blockchain.scripthash.listunspent` for wallet address queries is not
implemented, so the "list your names" step fails there. Follow-up: add a
GET /api/holdings/<address> to public-gateway.mjs backed by the existing
BCHN electrum access, so the portal can pull holdings over plain HTTP.
2026-08-31 03:35:39 +02:00
Local Dev
c2784abe5b Sweep: mobile Ariadne updates, Deviant brand + sites, Hephaestus bootstrap, snappymail
Broad-scope commit sweeping in work from parallel sessions plus this session's
dev-only utilities. No single unifying theme — this is the "commit everything
that's ready" pass. Grouped by area below.

AriadneResolver / mobile
* Small updates to BchFetcher, Bns, MainActivity, AriadneVpnService, and the
  Android manifest — from a parallel mobile-resolver session.
* AriadneResolver/mobile/webpreview/ — new local dev webview (index.html +
  server.mjs) for iterating on the mobile UI without a device.

Email / SnappyMail
* Email/snappymail-plugin/silentmode-addresses — new SnappyMail plugin
  (README, CSS, PHP entry, JS) for surfacing @silentmode.st address
  management inside the webmail UI.

Hephaestus (Forgejo + auth-proxy)
* auth-proxy/src/oidc.ts + docker-compose.yml updates.
* scripts/bootstrap-auth.sh — idempotent script that registers the wallet
  auth-proxy as Forgejo's OIDC provider after `docker compose up -d`. All
  secrets read from .env — no literals in the script.

TheseusNavigator / dev tools
* dev/list-tlds.mjs — enumerate every registered BNS name grouped by TLD via
  our own indexer.
* dev/show-tlds-bch.mjs — dump the full records payload of the legacy
  tlds.bch name (kept as a diagnostic for the list-in-one-NFT era).

Deviant sites + brand
* site/deviant/ — new microsites (anthemus, potidaea, brand, mindmap, main
  index) plus the full brand kit under site/deviant/brand/ (logos, icons,
  palette, social exports as SVG source + PNG renders).
* site-sirius-x/portal.html — updates.

Coordination
* _coordination/sessions/mobile-resolver.md — parallel-session notes.

Deliberately excluded from this commit:
* scratchpad/ — this session's temp drafts (Sia doc mockups, tlds UPD payloads).
* TheseusNavigator/_prev/ — ~372 MB of prior release binaries; belongs in
  a separate artefacts store, not the git tree. Add to .gitignore next pass.
2026-08-30 10:38:49 +02:00
Local Dev
1f331a298b sirius.x: pull the sign-in link to the far right of the top nav
Standard header pattern — brand + main nav on the left, the account action on
the right. New .portal class does margin-left:auto plus a subtle acid tint so
it reads as a button, not another nav item. Applied on all four pages
(landing, docs, portal, theseus); the label is '🔑 Sign in' everywhere
(portal.html itself still marks it .here).
2026-08-29 22:22:37 +02:00
Local Dev
bd4b4602e0 sirius.x: extract docs to /docs/, cross-link portal + theseus navs
The landing kept expanding whenever documentation was added inline. Moving it
to its own subdirectory gives docs room to grow and keeps the landing to the
"try it / roadmap / verify" story it's supposed to be.

  * docs/index.html — TOC + eight sections (TLD registry, registration,
    records, resolver, mainnet pricing, tracker, verification, runbook).
    Reads on its own; no dependency on the landing.
  * index.html — #docs section shrunk to a one-paragraph call-to-action with a
    prominent "Open the docs →" button; nav Docs link now points at /docs/.
  * portal.html + theseus/index.html — nav Docs links updated to /docs/ (was
    ./#docs / ../#docs) so every subpage points at the standalone docs.
2026-08-29 22:00:37 +02:00
Local Dev
016095a604 sirius.x: portal (sign-in + names), Theseus subpage, drop .com public mention
* portal.html — sign in with a seed phrase (in-memory only, wiped on sign
    out), fetch owned NFT categories across all watched addresses, cross-join
    against BCNR buildIndex to show the wallet's names + records. Read-only
    for now; record edit (UPD) will piggyback on the register bundle's signing
    path. WizardConnect button stubbed with a "soon" pill — the adapter
    already exists in register.html and will be wired in the next pass.
  * theseus/index.html — download page for Theseus Navigator (v0.0.4) and
    Ariadne Resolver (Windows setup + Android APK). Same design system as the
    landing. Links to dl.silentmode.st for the actual binaries and to
    silentmode.st/releases for the manifest.
  * index.html — nav now has 🧭 Theseus and 🔑 Portal chips; "Try it" section
    adds cards for the portal and Theseus.
  * site/tlds/ — .com row removed from the public table; count updated to 14;
    supersedes the "held by operator" language per operator direction.
  * site-sirius-x/index.html — softened ICANN-adjacent note.

All routes verified live: silentmode.st/{tlds,sirius-x,sirius-x/portal.html,
sirius-x/theseus,bns/sirius.x} return 200. Sia mirror updated for all three
new/changed sirius.x pages.
2026-08-29 21:57:33 +02:00
Local Dev
2a8f841b1c sirius.x: gitignore the generated git-mirror artifacts (bundle + bare tree) 2026-08-29 21:15:25 +02:00
Local Dev
5c8f7aa4f9 sirius.x: replace roadmap stub with live git-clone URL
The bare git tree serves over dumb-HTTP from silentmode.st/sirius-x/repo/silent-mode.git;
verified with `git clone` end-to-end. Bundle URL added too as an alternative for
environments where dumb-HTTP is blocked.

Still MVP: read-only. Push requires either Forgejo, git-http-backend + auth on
nginx, or SSH — all separate track per operator direction.
2026-08-29 21:09:36 +02:00
Local Dev
36794c91d2 sirius.x: initial landing page (docs + registration hub)
Register the name (chipnet), upload the page to Sia, mirror on VPS. Content
consolidates existing docs (silentmode.st/tlds/, INSTRUCTIONS.md) into one
canonical entry point and names the deferred pieces — wallet portal, Sirius
Studio site editor, decentralized git remote — as roadmap items.

  * name: sirius.x, REG txid 15bec52981fa82f9fa1c966600204112b7478a821f8384e0c8fecaea375215e9
  * records set via UPD: {"s3":"bns/sirius.x/"}
  * mirrors live: https://silentmode.st/sirius-x/ (VPS, immediate) and Sia
    bucket bns/sirius.x/ (BCNR route via navigate.st/bns/sirius.x/ pending
    Sia propagation to the gateway's s3d)
2026-08-29 19:44:50 +02:00