/** * Reachability verdicts: one per hosted node, and the host-level roll-up the * dashboard badge shows. Heuristics over the mapping table, not a dial-back — * libp2p AutoNAT is a later ticket. */ import type { DirectReachability, NodeReachability, NodeVerdict, PortRoute } from './types.js'; export interface NodeVerdictInput { tcp: PortRoute; /** Null for a handle persisted by an older build without a WebSocket port. */ ws: PortRoute | null; /** Whether a public host part exists: a DDNS hostname, or a public IPv4. */ hostKnown: boolean; cgnatDetected: boolean; upnpEnabled: boolean; gatewayFound: boolean; /** The address a user forwards to; null when no gateway was found. */ lanAddress: string | null; } export interface NodeVerdictResult { verdict: NodeVerdict; reason: string | null; } /** * `unreachable` when either port has no usable route or the host part is * unknown; otherwise `manual` when either port is forwarded by hand, `direct` * when the ports are reached as-is (public mode, with the firewall reminder as * the reason), else `mapped`. A UPnP route under CGNAT is not usable: the * router's mapping is on a carrier-private address. */ export declare function evaluateNodeReachability(input: NodeVerdictInput): NodeVerdictResult; /** * Host roll-up: `cgnat` when CGNAT is detected and no node is reachable * through a manual route; `unknown` with no running nodes; `reachable` when * every running node is `mapped`/`manual`/`direct`; else `unreachable`. */ export declare function evaluateHostReachability(nodes: ReadonlyArray>, cgnatDetected: boolean): DirectReachability;