import { healthUtil, util, types as T } from "../deps.ts"; const API_BASE = "http://kamado-pool.embassy:8080"; const STARTING_GRACE_MS = 20_000; interface HealthPayload { ok: boolean; ckpool: boolean; bitcoin: boolean; submit_gap: number; zmq_stale: boolean; last_error?: string; } async function fetchHealth(effects: T.Effects): Promise { try { const res = await effects.fetch(`${API_BASE}/api/health`); return await res.json() as HealthPayload; } catch { return null; } } export const health: T.ExpectedExports.health = { "web": async (effects, duration) => { return healthUtil.checkWebUrl(`${API_BASE}/api/health`)(effects, duration); }, "ckpool": async (effects, duration) => { if (duration < STARTING_GRACE_MS) return util.errorCode(60, "Stratum server is starting…"); const h = await fetchHealth(effects); if (!h) return util.error("Kamado API is unreachable — service may be down."); if (h.ckpool) return util.ok; const detail = h.last_error ? ` (${h.last_error})` : ""; return util.error(`Stratum server is not responding${detail}.`); }, "bitcoin": async (effects, duration) => { if (duration < STARTING_GRACE_MS) return util.errorCode(60, "Bitcoin Core connection is starting…"); const h = await fetchHealth(effects); if (!h) return util.error("Kamado API is unreachable — service may be down."); if (h.bitcoin) return util.ok; const detail = h.last_error ? ` (${h.last_error})` : ""; return util.error(`Bitcoin Core RPC is unreachable${detail}.`); }, "submit-gap": async (effects, duration) => { if (duration < STARTING_GRACE_MS) return util.errorCode(60, "Block submission check is starting…"); const h = await fetchHealth(effects); if (!h) return util.error("Kamado API is unreachable — service may be down."); const gap = h.submit_gap ?? 0; if (gap === 0) return util.ok; return util.error( `${gap} block${gap === 1 ? "" : "s"} submitted to bitcoind but not confirmed — check Bitcoin Core logs.`, ); }, };