feat(grin): proxy scans through grin-lws (default) with grin-wallet fallback

Add a GrinLwsClient (a faithful mirror of the XMR LwsClient) + GrinLwsConfig
(enabled when GRIN_LWS_URL is set). /wallet/grin/scan now defaults to grin-lws
when configured and returns derivation paths (key_id/n_child) + spendability,
letting the wallet skip its client-side output-identify search.

Money-safety: the restore-depth/PoW gate runs once and is terminal (never
masked by fallback); grin-lws is trusted only when provably synced
(scanned_height + margin >= tip), otherwise the scan falls back to the
authoritative grin-wallet scan_rewind_hash; a grin-lws transport error also
falls back; grin-wallet errors propagate as 503. No path ever synthesizes an
empty/zero balance.

Off unless GRIN_LWS_URL is configured (prod grin behavior unchanged until
pointed at a grin-lws instance). Capabilities advertise `grin_lws`.
openapi.json regenerated.
This commit is contained in:
jwinterm
2026-07-09 16:26:23 -04:00
parent a7c4bbd238
commit 4d1d9006bc
10 changed files with 596 additions and 3 deletions
+10
View File
@@ -107,6 +107,16 @@ GRIN_NODE_API_PASS=
GRIN_NODE_FOREIGN_API_URL=http://127.0.0.1:3413/v2/foreign
GRIN_NODE_FOREIGN_API_SECRET=
# ── Grin light-wallet-server (grin-lws) — optional add-on to the Grin chain ─
# When GRIN_LWS_URL is set (and FEATURE_GRIN is on) the Grin scan proxies to
# grin-lws first, trusting it only when it is provably synced to the tip, and
# otherwise falling back to the authoritative grin-wallet scan. Leave GRIN_LWS_URL
# empty to use grin-wallet only. GRIN_LWS_ADMIN_URL / GRIN_LWS_ADMIN_KEY reach
# grin-lws's bearer-gated admin API (optional).
GRIN_LWS_URL=
GRIN_LWS_ADMIN_URL=
GRIN_LWS_ADMIN_KEY=
# ── Wallet restore (import) policy ────────────────────────────────────────
# How far back a wallet may ask THIS instance to scan on import. The backfill
# cost lands on your LWS/node, so it is your call; it is advertised via