From 687891c8d711de6d6f78cfc1e24c8cbe5b11cbb4 Mon Sep 17 00:00:00 2001 From: highlander Date: Sat, 18 Jul 2026 18:13:37 -0300 Subject: [PATCH] fix(rest): chain firmware gate threw 'json is not defined' when it fired MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit requireChainSupport was defined at server scope but returns via the per-request json() closure (CORS + audit logging), so the moment the firmware gate actually fired — observed on POST /addresses/hive — it threw ReferenceError instead of the intended 501. Latent on the solana/tron/ton routes too. Moved inside the request scope; tsc had been flagging the out-of-scope name all along (rest-api baseline 66 → 65 errors). --- projects/keepkey-vault/src/bun/rest-api.ts | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/projects/keepkey-vault/src/bun/rest-api.ts b/projects/keepkey-vault/src/bun/rest-api.ts index d8041c1b..28ab9a17 100644 --- a/projects/keepkey-vault/src/bun/rest-api.ts +++ b/projects/keepkey-vault/src/bun/rest-api.ts @@ -1136,16 +1136,6 @@ export function startRestApi(engine: EngineController, auth: AuthStore, port = 1 } /** Return 501 if firmware doesn't meet the chain's minFirmware requirement. */ - function requireChainSupport(chainId: string): Response | null { - const chain = CHAINS.find(c => c.id === chainId) - if (!chain?.minFirmware) return null - const fw = engine.getDeviceState().firmwareVersion - if (!fw || !isChainSupported(chain, fw)) { - return json({ error: `${chain.symbol} requires firmware ≥ ${chain.minFirmware} (device has ${fw ?? 'unknown'})` }, 501) - } - return null - } - /** Normalize showDisplay to boolean (undefined → false). */ function showDisplay(requested: boolean | undefined): boolean { return requested ?? false @@ -1258,6 +1248,20 @@ export function startRestApi(engine: EngineController, auth: AuthStore, port = 1 return resp } + // Firmware gate for chain routes. Lives INSIDE the request scope because + // it returns via the per-request json() helper (CORS + audit logging) — + // defined at server scope it threw "json is not defined" the moment the + // gate actually fired (observed on POST /addresses/hive). + function requireChainSupport(chainId: string): Response | null { + const chain = CHAINS.find(c => c.id === chainId) + if (!chain?.minFirmware) return null + const fw = engine.getDeviceState().firmwareVersion + if (!fw || !isChainSupported(chain, fw)) { + return json({ error: `${chain.symbol} requires firmware ≥ ${chain.minFirmware} (device has ${fw ?? 'unknown'})` }, 501) + } + return null + } + // ── MCP agent bridge (EPIC_mcp_agent_bridge.md, keepkey-client) ── // LOOPBACK + LOCAL-AGENT ONLY, handled BEFORE the shared CORS/OPTIONS // path below so /mcp owns its own preflight and never inherits the