/** * `createApi()` — Fastify server factory for the runtime HTTP API. * * Wires the Fastify instance with: * - `POST /signals` — supervised intake route (scanner-registry gated). * - `GET /audit` — MCP audit-query proxy scoped to one wallet. * - `GET /health` — three-state readiness + per-runtime queue depth. * * Returns the Fastify instance, the mutable readiness flag, and the boot * timestamp. The lifecycle layer (S5) calls `fastify.listen()` and flips * `readiness.setOk()` / `readiness.setDraining()` around start/stop. * * This module owns only wiring — no business logic. All route logic * delegates to the shared handlers in `handlers/`. */ import { type FastifyInstance } from "fastify"; import { createReadiness } from "./readiness.js"; import type { RuntimeHandle } from "../runtime/run.js"; import type { Logger } from "../utils/logger.js"; import type { ApiConfig } from "./config.js"; import type { IntakeContext } from "./intake/intake-context.js"; import type { IntakeSignal, IntakeTickFacts } from "./intake/types.js"; /** * Dependencies passed to {@link createApi}. */ export interface CreateApiDeps { /** Live runtime handles maintained by the plugin, keyed by lowercased address. */ runtimeHandles: Map; /** Validated `api` config block (host, port, maxItemsPerSignalsRequest). */ apiConfig: ApiConfig; /** Logger instance — forwarded to shared handlers for structured error logging. */ logger: Logger; /** * Plugin version string read from `openclaw.plugin.json` at boot. * Exposed in `GET /health` so callers can correlate requests with deployments. */ version: string; /** * Optional shared intake context (registry/record/liveness). When supplied, * the supervised intake `/signals` route is mounted. */ intakeContext?: IntakeContext; /** * Called for each signal that passes the acceptance pipeline. Receives the * signal, a correlation id, and the scanner_id that posted the signal. * Only used when `intakeContext` is present. */ onAccepted?: (signal: IntakeSignal, correlationId: string, scannerId: string) => void; /** * Called for each scaffold `/errors` POST that resolves to a known scanner, * with the scanner_id and the raw error body. Records the failed tick into * scanner run telemetry. Only used when `intakeContext` is present; defaults to * a no-op (which is what made the `/errors` boundary silent before B1 Task 2). */ onError?: (scannerId: string, error: Record) => void; /** * Called once per producer tick, from whichever of the two intake routes that tick took, with * the facts the producer measured about the run itself. Feeds the live per-tick level and * nothing else. Only used when `intakeContext` is present; defaults to a no-op. */ onTick?: (scannerId: string, tick: IntakeTickFacts) => void; } /** * Artifacts returned by {@link createApi}. * * Ownership: * - `fastify` — call `.listen()` and `.close()` in the lifecycle layer (S5). * - `readiness` — call `setOk()` after `.listen()` resolves; `setDraining()` * before `.close()` during graceful shutdown. * - `bootedAt` — Unix epoch ms recorded when `createApi()` was called; * used by `GET /health` to compute `uptime_ms`. */ export interface ApiArtifacts { fastify: FastifyInstance; readiness: ReturnType; bootedAt: number; } /** * Create and configure the Fastify HTTP server. * * Does NOT start listening. Call `artifacts.fastify.listen(...)` from the * lifecycle layer (S5) after `createApi()` returns. * * Error handler behaviour: * - `400` (schema validation), `413` (body too large), `415` (wrong * content-type) are passed through as `INVALID_REQUEST` with the original * Fastify message so callers can read the validation detail. * - All other errors are logged and returned as `500 / UNAVAILABLE`. * * Request timeout strategy (resolved in S5): * A single server-wide `requestTimeout: 30_000` covers all routes. * A single server-wide ceiling covers all routes. The 30s ceiling is driven * entirely by `/audit` (MCP round-trip); `/signals` and `/health` both * complete in well under 1s in practice. If per-route enforcement becomes * necessary, add an `onRequest` hook in this file. * * @param deps Dependencies injected by the plugin entry point. * @returns `{ fastify, readiness, bootedAt }`. */ export declare function createApi(deps: CreateApiDeps): ApiArtifacts; //# sourceMappingURL=server.d.ts.map