Commit graph

12 commits

Author SHA1 Message Date
Local Dev
a9f2974194 navigate.st: fuzzy search fallback + hide syskypo.de from suggestions
/api/search/ now catches typos with a bounded-Levenshtein pass against
each label — max edit distance 1|2|3 depending on query length. Fuzzy
hits are labeled `matchType:"fuzzy"` and always rank below real matches
(scores 40|25|10 vs 100|70|50), so exact matches never get displaced by
a near-miss. Client shows a "closest name we found" header when the
whole result set is fuzzy, and a subtle amber "did you mean" badge per
row. Verified: hlelo → hello.bch, silntmode → silentmode.{bch,x},
pouakidis → poutakidis.de, and silentmode still returns label-exact
first with fuzzy hidden.

syskypo.de is now excluded from /api/search/ results (still reachable
via /api/name/ and /bns/…): it's a mirror of poutakidis-content and
was cluttering suggestions. Swapped it out of the placeholder too.
2026-09-06 19:58:58 +02:00
Local Dev
32dd9ff2ff feat(gateway,hephaestus): forward proxied headers + trust Silent Mode CA
Two pieces from testing "login through hephaestus.x":

1. bns-gateway (public-gateway.mjs, ip: case) — forward the upstream's
   response headers, not just content-type. The old code stripped Location,
   Set-Cookie, and everything else, so redirects from a proxied hostname
   died silently in the browser ("Temporary Redirect" body with no Location
   header). Header set now respects RFC 7230 hop-by-hop exclusions and
   drops Content-Length (we may rewrite HTML for baseHref).

2. Hephaestus stack:
   - forgejo/Dockerfile: tiny extension of the official image that copies
     the Silent Mode Argonautica root CA into the OS trust store, so
     Forgejo's Go client can validate hephaestus.x's cert on OIDC discovery
     calls. Deliberately no `USER git` at the end — parent's s6-overlay
     needs to init as root.
   - docker-compose.yml: switch to `build: ./forgejo` and add
     `extra_hosts: - "hephaestus.x:host-gateway"` so Forgejo can resolve
     hephaestus.x back to the host's Caddy.

Both changes are inert at the moment because Forgejo's ROOT_URL is back at
code.silentmode.st (browsers-without-BCNR-resolvers couldn't complete
OAuth through hephaestus.x because session cookies don't cross origins —
the working UX has the "Sign in with wallet" button on hephaestus.x
delegate to code.silentmode.st). Keep the infrastructure in place for when
Theseus/Ariadne adoption makes it viable to flip ROOT_URL properly.
2026-08-31 16:23:43 +02:00
Local Dev
ff76e4cf94 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
de696a8b9f gateway: /api/tlds sourced from TLD_BEACON snapshot, add /api/registry
- /api/tlds now calls buildTldSnapshot on the per-TLD-NFT beacon
  (Decentralized.DNS/DESIGN-tld-registry.md §3) instead of reading the
  legacy tlds.bch record. Every entry carries `certificate: true|false`
  so a name shop can distinguish covenanted, sellable TLDs from legacy
  ones that predate the certificate model. Ships a `legend` field
  explaining both, and hides intentionally-legacy TLDs (currently just
  `silentmode`, from an accidental REG) unless `?hidden=1`.
- /api/registry — bulk dump of every registered name for offline
  availability computation by registrar sites.
- Inline electrum client (~30 lines) so the endpoint can query an
  arbitrary scripthash — resolver-web's Electrum class is not exported.
  Prefers the local multi-beacon indexer at ws://127.0.0.1:50010 with
  public-pool fallback.
2026-08-29 16:43:27 +02:00
Local Dev
5b65be2483 gateway: auto-index directory paths for s3 records
silentmode.bch/tools/ was returning the Sia NoSuchKey XML because the
gateway only auto-appended index.html for the root path (/), not for
sub-directory paths (/tools/, /apps/, etc). Trailing-slash URLs now
resolve to <path>/index.html — matches Ariadne's bnsd.js which already
had the same rewrite on the client side.

Verified: /bns/silentmode.bch/tools/ returns 200 with the tools page
(was 404 NoSuchKey).

Fixes the user-reported "download link on silentmode.bch/tools/#theseus
shows an XML NoSuchKey error" — the browser was requesting /tools/
(trailing slash from the URL path), gateway looked up bucket key
bns/silentmode/tools/ which doesn't exist, forwarded the S3 error.

Deployed on the VPS (/opt/bns-gateway/) with the in-place edit path
that keeps the same-dir import shape there (repo has ../lib/, VPS has
./resolver-web.js — the two file layouts intentionally differ).
2026-08-29 13:27:42 +02:00
Local Dev
f77c6558ee navigate.st: Theseus-home-style landing — search + quick links + install CTA
Adds a unified /api/search/<q> endpoint to the gateway and rebuilds
navigate.st's search box + featured cards around the new "6 curated names,
everything else via search" IA.

Gateway (Argus/src/gateway/public-gateway.mjs): /api/search/<q> iterates the
cached full-index Map and scores every match — label-exact (100) beats
label-substring (70) beats h-record content substring (50). Content search
strips HTML tags before matching and returns a ±40/60-char snippet around
each hit. Results sorted by score then name, capped at 50, exposes a
`truncated` flag. Same 30-second cache the record picker + /api/labels/
already use — no extra fetch on the hot path. s3/ip content search awaits
Helios v1 (deferred by design).

Client (navigate.st/index.html): submit now routes three ways —
  <label>.<tld…>   → /bns/<name> straight, no API call
  everything else  → /api/search/<q>, render ranked panel
    ‣ 0 hits            → "not on chain — Register at Sirius · Search the web"
    ‣ 1 label-exact hit → auto-redirect (fast path preserved)
    ‣ otherwise         → results panel with match-type badge, snippet, mark-
                          highlighted query term
The old bare-label /api/labels/ path is retired from navigate.st (the endpoint
stays live — Sirius registration availability still uses it).

Featured cards on the main page are now the six user-selected names:
hello.bch, coinspectrum.x, silentmode.x, theseus.x, game.x, deviant.x.
Three are already on chain (hello.bch / coinspectrum.x / game.x) and render
as normal cards; three are not yet registered (silentmode.x / theseus.x /
deviant.x) and render as dashed "coming soon" pending cards — non-clickable,
faded, prevents 404s until they're actually minted via Sirius. The old 8-name
Quick Links grid is gone; "everything else via search" is now the story.

Deployed. Live search verified with poutakidis (1 hit → auto-redirect),
deviant (3 hits including a content match), xyzzynomatch (empty-state CTA).
Gateway rollback point at /opt/bns-gateway/public-gateway.mjs.bak.1787246702.
2026-08-20 20:44:09 +02:00
Local Dev
8228bda939 navigate.st: multi-TLD label search (gateway /api/labels/<label> + client picker)
Fixes the "type a bare label, find matches across every TLD" gap. Before this,
typing `poutakidis` in the navigate.st search box was silently pinned to
`.bch` (missing `poutakidis.de`); typing `coinspectrum` was likewise pinned
to `.bch` and missed the `.x` registration.

Gateway (Argus/src/gateway/public-gateway.mjs): new /api/labels/<label>
endpoint. Iterates the cached full-index Map (getIndex(), rebuilt every 30s)
and returns { label, matches: [{ name, tld, records, category }] } — bare
`<label>` entries are surfaced as `<label>.bch` in the response for clarity.
Zero cost on the live path — the label endpoint reuses the same index that
the record-picker already touches.

Client (navigate.st/index.html): three routes on submit —
  bare label      → /api/labels/<l>: 0 matches show "not registered, register at
                    Sirius"; 1 match redirects to /bns/<name>; 2+ matches show
                    an inline picker with a per-record-type badge (on-chain /
                    Sia / server / redirect).
  <label>.<tld…>  → /bns/<name> straight, no API call needed.
  free text       → DuckDuckGo, unchanged.

The picker + empty-state markup + CSS all live inside the single 15 KB page —
no external dependencies. On API failure the client falls back to the pre-fix
".bch guess" so the box stays useful if the gateway is unreachable.

Deployed. Live at https://navigate.st/api/labels/poutakidis (1 match, .de) and
https://navigate.st/api/labels/coinspectrum (2 matches, .bch + .x). Backup of
the previous VPS gateway at /opt/bns-gateway/public-gateway.mjs.bak.1787175583.
2026-08-20 00:28:00 +02:00
Local Dev
47601fcbdb gateway+Theseus: pin BNS ip-record fetch to on-chain tls fingerprint
Uncovered by the 2026-08-13 subdomain-inheritance fix: once
`checkers.game.x` correctly picked the parent's `ip` record instead of
`s3`, the ip branch itself failed. Two reasons:

  1. `fetch("http://<ip>/", { headers: { host: name } })` follows the
     site's :80→:443 redirect into `https://<name>.<tld>/`, which isn't
     in ICANN DNS → "fetch failed".
  2. The site's cert is signed by a per-machine BNS root, not a public
     CA; standard TLS validation rejects it.

Both are fixed by connecting to the IP with SNI = name, pinning the
presented cert's SHA-256 against the on-chain `tls` record, and only
then issuing the HTTPS request over the same socket. The on-chain
fingerprint is the trust anchor BNS uses everywhere else (see
Argus/src/lib/ca.js).

Gateway (public-gateway.mjs): new pinnedHttpsGet + httpGet + ipRequest
helpers; case "ip" delegates. No silent HTTP fallback on pin failure
(a mismatch means "not the site the chain says it is").

Theseus (main.js): parallel port of the same helpers, Tor-aware
(routes through SocksProxyAgent when Tor is on). serveBns's inner
serveIp() delegates to ipRequest.

Verified live: `curl -sI https://navigate.st/bns/checkers.game.x/`
returns 200 OK with the checkers game (1,179,215 bytes, apex
`game.x` unchanged, served from Sia).
2026-08-16 20:28:58 +02:00
Local Dev
c2578d4017 gateway: fix ip-record fetches (Host header) so coinspectrum.bch resolves
Symptom: pasting https://navigate.st/search?q=coinspectrum.bch (or the
new default-search-engine redirect from any browser) returned 404 from
nginx. Same for any BCNR name whose on-chain record uses ip (h / s3 / p
were fine).

Cause: the gateway's ip branch used fetch() with { headers: { host: name } }.
WHATWG fetch defines Host as a forbidden header, so undici silently
drops it and sends Host: <ip>. nginx has no server_name for a bare IP,
falls to the default server, 404s. The whole point of the ip record is
to reach a server_name that matches the BCNR name, so Host must be set.

Fix: use http.request from node:http (no forbidden-header list) with an
explicit Host header. Same behavior for every ip record; nothing changes
for h / s3 / p / u branches.

Live-patched on the VPS gateway and restarted the bns-gateway systemd
service. coinspectrum.bch now returns 200 (116 KB) via
navigate.st/bns/coinspectrum.bch/ and via the /search?q= redirect chain.

Argus/src/gateway/public-gateway.mjs mirrors the on-disk change on the
VPS at /opt/bns-gateway/public-gateway.mjs so future redeploys keep it.
2026-08-16 11:37:24 +02:00
Local Dev
b4a550ef41 Snapshot in-progress work: Ariadne mobile, Theseus password manager, Hephaestus
Several concurrent workstreams committed together as a checkpoint:

- Ariadne mobile resolver — BchFetcher/Bns/MainActivity resolution logic,
  AndroidManifest + build.ps1
- Theseus password manager — settings.html/chrome.html/settings-preload.js UI +
  main.js wiring + package.json resource; Argus password-vault.js, record-picker.js
  (+ tests) and resolver-web.d.ts
- Hephaestus — new BCH-wallet OIDC auth-proxy + Forgejo docker-compose and
  restic/S3 scripts (secrets referenced via env only; Hephaestus/.env is gitignored)
- Argus public-gateway.mjs updates
- Docs — root README, Email README/RUNBOOK, VPS access runbooks (Checkers/Deviant),
  site/hermes, WebsiteDev registry + faster-blocks, Failures/ AAAA-mangle writeup,
  Decentralized Storage map, coordination notes
- .gitignore — exclude /.keys/ and Hephaestus/.env
2026-08-14 23:17:18 +02:00
Local Dev
eb18108fb1 gateway: /search endpoint = universal "set as default search engine" fix
Adds handleSearch() to public-gateway.mjs: users add
  https://navigate.st/search?q=%s
as their browser's default search engine and typing bare "silentmode.bch"
in the URL bar (which Chromium and Firefox otherwise send to Google as a
search query, since .bch isn't in ICANN's TLD list) arrives here. Native
BNS TLDs (.bch, .p2p, .bit, .nav) 302 to the relay; anything else falls
through to DuckDuckGo so ordinary search still works.

Live on the VPS gateway at /opt/bns-gateway/public-gateway.mjs.
Nginx now proxies location = /search to 127.0.0.1:8700 as well.

Solves: bare "silentmode.bch" in Chrome/Edge went to Google. It now
resolves to the site via the relay in every browser.
2026-07-30 21:21:01 +02:00
Local Dev
a45320db7d Initial commit — Silent Mode baseline (2026-07-29)
Snapshot of the decentralized-web stack at the point of the resolver+Theseus
rebuild deploy. Includes:

- Argus (BNS engine + resolver daemon + Sia gateway)
- AriadneResolver (Windows Inno installer bundle + Android APK sources +
  Firefox extension)
- TheseusNavigator (Electron browser)
- site/ (silentmode.st content, deployed to Sia at bns/silentmode/)
- design docs, roadmap, protocol spec

Secrets excluded via .gitignore: Argus/sia-s3.json, Argus/wallets.json,
Argus/ca/*.key,*.crt. Build outputs, node_modules, and bundled runtimes
also excluded.

Shipped hashes on dl.silentmode.st at this commit:
  AriadneResolver-Setup-0.1.0.exe    5bcb216eef31ea28ed767e4134ab74bd5ac69dfbd365fd249e9e6938e55c986a
  TheseusNavigator-Setup-0.0.1.exe   7c735e88bad2da3347145adba3016c8f626a18b8422289c8c6ba471972e2952b
  TheseusNavigator-0.0.1-portable.exe 008fd84445babeabb401b2bca40ea9466b24b0e6d6c85104da7640c5c5c84521
  ariadne-v0.2.apk                   635c8f04d44ef855a8390b9eeddb8cd2d50622e81cc4e5004e8daffc1bb0425c
2026-07-29 13:54:34 +02:00