The VPS hosts multiple projects (Silent Mode gateway, mail, BNS indexer, per-project s3d instances), not just Coinspectrum — rename the VPS folder and update all cross-refs (VPS, Email, Storage, DEPLOY, packaging prompt) to match the hostname change on the box. Also add Storage/SIA-STORAGE-ROADMAP.md capturing the design for an end-user Sia-storage product: two-tier trust model (Sovereign / Managed), BCH-CashScript payment + Google-style free-tier inactivity policy, identity model with Vultisig-style threshold recovery, and the decisions made so far. CLIENT-OPTIONS.md gets a scoping note so future readers know "hosted proxy = never" is about operator credentials, not end-user tiers.
5.3 KiB
Theseus gotchas
Non-obvious things sessions keep re-deriving. If you found this file because something broke in a way that felt spooky, the answer is probably here.
build.files in package.json is EXPLICIT
electron-builder ships only what's listed in build.files. Every runtime-
loaded HTML/preload/module MUST be there. A missing entry causes the
loadFile("foo.html") in a WebContentsView to silently open blank in the
packaged app — visually indistinguishable from "the button does nothing".
npm start (dev) never catches this because it reads from the source tree
directly. Only a real npm run dist + install exposes it.
Every time you add a new WebContentsView or loadFile, add its HTML and
preload to the files array. Sanity check after building:
node -e "const b = require('fs').readFileSync('dist-public/win-unpacked/resources/app.asar'); for (const n of ['engine-picker.html','popover.html','downloads.html','engine-picker-preload.js','popover-preload.js','downloads-preload.js']) console.log(n, b.indexOf(Buffer.from(n)) >= 0 ? 'OK' : 'MISSING');"
This has bit us once (search-picker dropdown, shipped 6bbccf9c, blank
picker). Do not let it bite twice.
Building — admin terminal the first time
npm run dist needs an admin terminal on the machine's first Theseus
build so electron-builder's winCodeSign package can extract its
darwin/ symlinks (requires SeCreateSymbolicLink). Subsequent builds
reuse the cache under $LOCALAPPDATA/electron-builder/Cache/winCodeSign/
and don't need admin.
If DNS is misbehaving on the machine, pin these hosts in
C:\Windows\System32\drivers\etc\hosts before building so electron-builder
can fetch: github.com, codeload.github.com,
objects.githubusercontent.com, release-assets.githubusercontent.com.
Strip them after.
Reproducible builds
Set both before npm run dist:
SOURCE_DATE_EPOCH— freezes timestamps so a rebuild with no content changes produces the same hash. Bump per release, not per rebuild.CSC_IDENTITY_AUTO_DISCOVERY=false— stops electron-builder searching for a signing cert (we don't sign; SECURITY.md rule 2).
Native <select> popup theme
Chromium's native <select> popup uses the page's color-scheme. When it's
"light dark" (both accepted), Chromium picks by the OS scheme — so a
dark-themed app on a light OS shows a light popup and vice versa.
Fix, currently in settings.html:
:root { color-scheme: dark; }
@media (prefers-color-scheme: light) { :root { color-scheme: light; } }
nativeTheme.themeSource (driven by settings.theme) sets
prefers-color-scheme, so this stays in sync automatically. Do not remove.
Chromium also respects select option { background; color } in the popup
on Windows — a belt-and-braces override alongside color-scheme.
The resolver in Theseus is resolver-web.mjs, not .js
Packaged builds ship Argus/src/lib/resolver-web.js as resolver-web.mjs
(see extraResources in package.json). Renamed because
resources/ has no adjacent package.json so a .js gets treated as
CommonJS and its exports fail. Dev reads the engine copy directly (Argus
is type: module so .js works there).
The resolver's electrum WS directIP fallback
main.js passes directIP: true to resolveHost so the engine
can dial the chipnet electrum servers by pinned IP if system DNS is dead.
Do not remove — this is what keeps .bch resolution working when the
adapter DNS is broken (a real failure mode we've hit).
Publishing new hashes end-to-end
- Build (see above).
- Update
../site/releases-manifest.jsonAND../site/tools/index.htmlAND../site/releases/index.htmlwith the fresh SHA-256s + release date. All three must match. - Deploy:
scp dist-public/*.exe ../site/releases-manifest.json silentmode:/opt/silent-mode/dl/ cd ../Argus && node src/lib/sia-upload.js ../site bns/silentmode - On-chain (wallet spend, user's action):
releases.silentmode.bchcurrently publishes{"u":"https://dl.silentmode.st/releases-manifest.json"}— a compacturecord because on-chain hashes wouldn't fit the 200-byte OP_RETURN. Only re-publish if the URL changes or if we ever put full hashes on-chain.
Sia upload from this machine fails without a hosts pin
node src/lib/sia-upload.js fails with getaddrinfo EAI_FAIL coinspectrum.duckdns.org unless the host is pinned in
C:\Windows\System32\drivers\etc\hosts:
195.184.247.106 coinspectrum.duckdns.org. This is a DNS quirk of the
machine, not a code bug — related to the strict-resolver behavior the
Ariadne daemon's EDNS fix addresses.
Deploy directory quirks
/opt/silent-mode/dl/is served asdl.silentmode.st— installers + manifest live here.silentmode.stproxies to Sia (bns/silentmode/) — the HTML pages live there.- The
bnsgateway does NOT auto-index directories.silentmode.st/apps/is a 404 (NoSuchKey); users must hit/apps/index.html. Fix upstream inbnsd.jsif it ever matters.
Firefox needs a restart after Ariadne CA install/rotation
Firefox only reads root CAs at startup. The Ariadne installer offers a
-CloseFirefox task by default when Firefox is running so this doesn't
bite. Chrome/Edge pick up the new root immediately.