Commit Graph
5 Commits
Author SHA1 Message Date
jwinterm f48373282f electrum: make the fallback privacy tradeoff visible to operators
Falling back to public Electrum is a PRIVACY decision, not just an availability
one: the queries carry user addresses. It is easy to miss because the failover
is silent and correct, so the only symptom is that balances keep working. Our own
LTC Fulcrum was dead for 11 days with every lookup going to third parties, and
nothing surfaced it.

- startup: log how many third-party fallbacks are configured and how to fail
  closed instead, so the posture is visible in the operator's own logs
- .env.example: state the tradeoff at the setting, with both choices spelled out
  rather than a default presented as obviously correct
- OPERATOR_SETUP: same note where an operator configures chains

Also expands the shipped fallback lists (BTC 3 -> 8, LTC 4 -> 7), which is both
more resilience and a wider spread of which server sees any given query.
2026-08-02 20:56:32 -04:00
jwinterm a455c60ed0 docs: operator console guide + fix example recipes + document all env vars
- New docs/operations/CONSOLE.md: reaching /admin, NIP-98 login, the
  defaults->env->DB precedence model, per-section runtime-safe vs
  restart-required table, expected_versions concurrency, restart_apply_mode
  (with the systemd Restart=always requirement for auto), clearing a DB
  override. Linked from README + OPERATOR_SETUP.
- All six example recipes gained an explicit chain-enablement block
  (FEATURE_XMR/WOW on, BTC/LTC/GRIN off) so they no longer hard-fail
  Config::validate in production (default-on chains with empty sources).
- Documented all 16 previously-undocumented env vars in .env.example
  (RESTART_APPLY_MODE, TOR_ADMIN_ONION, DEPLOYMENT_MODE, TIP_SHARE_BASE_URL,
  ...); RELAY.md gained the premium-post policy + RELAY_WRITE_ALLOWLIST_NPUBS;
  ADMIN_PUBKEYS noted as reserved/inert.
2026-07-19 15:52:07 -04:00
jwinterm 17bb7bcc20 docs(relay): packaging (deploy/relay) + operator guide + .env.example
Completes the operator side of the relay integration:

- deploy/relay/: reference docker-compose + config.toml for a locked-down
  nostr-rs-relay wired to the backend's gRPC admission (host networking so the
  loopback admission socket stays private). Clearly marked a template to pin/
  verify against the operator's nostr-rs-relay version.
- docs/operations/RELAY.md: what it is (inbox relay, not the only relay), the
  admission architecture, the three write policies + NIP-13 PoW, bundled vs
  external, verification, and the seam's modularity. Linked from OPERATOR_SETUP.
- .env.example: the RELAY_* block (all off/placeholder).

Backend relay integration (config → seam → policy → gRPC admission →
capabilities → NIP-05 → packaging/docs) is now complete. Client DM stack next.
2026-07-02 07:06:36 -04:00
jwinterm d3dd3fc113 fix(admin): create-admin-wallet fully bootstraps a fresh instance (latch + compose)
create-admin-wallet registered a pending admin key but never latched setup, so on
a fresh instance it left the bootstrap half-open and a later `setup` collided with
it (setup's guard only checked for an ACTIVE admin; the cli key was pending).

- New atomic Database::create_admin_key_bootstrapping: under the admin-keys
  advisory lock, insert the pending generated key AND latch `locked` (unless
  already validly locked), append audit, commit — one transaction. Fails CLOSED on
  a tampered latch (defers to reset-setup) instead of silently healing it.
- bootstrap_admin (setup) now refuses on ANY live admin key (active OR pending),
  not just active, so setup composes with create-admin-wallet. The adopt-existing-
  deployment path (users but no admin keys) is unaffected: no live key -> proceeds.
- reset_setup now takes the same advisory lock (all latch writers serialize) and
  documents the live-key recovery path.
- CLI prints bootstrapped-vs-added and a terminating lost-secret recovery hint.
- Docs (README + OPERATOR_SETUP section 5): both mutually-exclusive bootstrap paths.

Adversarially reviewed (atomicity / lockout / regression — all ship). L1 test
extended: fresh-latch, no-relatch-when-locked, pending semantics, composition
guard, and tamper-refuse (fails closed + rolls back the key insert).
2026-07-02 03:19:32 -04:00
jwinterm a919ea7b52 docs(operator): OPERATOR_SETUP guide + fix .env.example peppers + README bootstrap
- .env.example: add the required at-rest identity secrets (SEED_FINGERPRINT_PEPPER,
  REFRESH_TOKEN_PEPPER, IP_SALT). They were missing, so `cp .env.example .env` on a
  fresh setup boot-failed closed on the first required-secret check.
- README: correct the first-admin bootstrap to `smirk-admin setup --pubkey`.
  create-admin-wallet registers a pending key but does not latch, so on a fresh
  instance it leaves the bootstrap uninitialized.
- docs/operations/OPERATOR_SETUP.md: full deployment guide — database, secrets,
  per-chain backends, run + verify, admin bootstrap, registration policy, and
  smoke-testing an instance (SMOKE_API_STYLE=namespaced).

Surfaced by a clean-room operator setup against a fresh instance.
2026-06-30 23:19:05 -04:00