import type { RpcConfig } from '../../types.js'; import type { HttpRequest } from '../http.js'; /** * An {@link HttpRequest} for a single JSON-RPC call, carrying the `id` that was * assigned when the request was built. Pass it back to * {@link JsonRpcProtocol.parseResponse} so the response is bound to the request * that asked for it. */ export interface JsonRpcHttpRequest extends HttpRequest { /** The JSON-RPC id sent in the body of this request. */ readonly id: number; } /** * An {@link HttpRequest} for a JSON-RPC batch, carrying the `id`s that were * assigned when the request was built, in call order. Pass them back to * {@link JsonRpcProtocol.parseBatchResponse}: ids must never be recomputed from * the protocol's counter, which any other call on the same instance advances * while this request is in flight. */ export interface JsonRpcBatchHttpRequest extends HttpRequest { /** The JSON-RPC ids sent in the body of this request, in call order. */ readonly ids: readonly number[]; } /** * Sans-I/O JSON-RPC protocol for Bitcoin Core. * * Builds {@link HttpRequest} descriptors for JSON-RPC method calls and * provides response parsing, without performing any I/O. * * **Security note:** Built requests include an `Authorization` header when * credentials are configured. Do not log or persist {@link HttpRequest} * objects without redacting the `Authorization` header. * * @example * ```ts * const protocol = new JsonRpcProtocol({ * host: 'http://localhost:18443', * username: 'user', * password: 'pass', * }); * * // Build a request descriptor (no I/O) * const req = protocol.buildRequest('getblockcount', []); * * // Execute with any HTTP client * const res = await fetch(req.url, req); * const json = await res.json(); * * // Parse the JSON-RPC response (throws on errors) * const blockCount = protocol.parseResponse(json, 'getblockcount', req.id); * ``` */ export declare class JsonRpcProtocol { readonly url: string; /** Whether this protocol instance has credentials configured. */ readonly hasAuth: boolean; private readonly _headers; private _id; constructor(cfg: RpcConfig); /** * Build an {@link HttpRequest} for a JSON-RPC method call. * The assigned id is returned on the descriptor for {@link parseResponse}. */ buildRequest(method: string, params: unknown[]): JsonRpcHttpRequest; /** * Build an {@link HttpRequest} for a JSON-RPC batch call. * Sends all calls in a single HTTP request per the JSON-RPC 2.0 spec. * The assigned ids are returned on the descriptor for * {@link parseBatchResponse}. */ buildBatchRequest(calls: Array<{ method: string; params: unknown[]; }>): JsonRpcBatchHttpRequest; /** * Parse a JSON-RPC response payload, throwing {@link BitcoinRpcError} * if the response contains an error. * * Pass `expectedId` (from {@link buildRequest}) to bind the response to the * request that asked for it. A payload carrying no `id`, or a null one * (which Bitcoin Core sends when it could not parse the request), is * accepted: an endpoint able to fabricate ids can fabricate `result` just as * easily, so the check guards against responses crossed in transit rather * than against a dishonest node. */ parseResponse(payload: { id?: unknown; result?: unknown; error?: { code: number; message: string; }; }, method: string, expectedId?: number): unknown; /** * Parse a JSON-RPC batch response payload. * Returns results in the same order as the original calls. * * `ids` must be the ids {@link buildBatchRequest} assigned to this batch. * They cannot be derived from the protocol's counter at parse time: it is * shared and mutable, so any call built while this batch is in flight shifts * it and each response is then matched to the wrong call. */ parseBatchResponse(payloads: Array<{ id: number; result?: unknown; error?: { code: number; message: string; }; }>, calls: Array<{ method: string; params: unknown[]; }>, ids: readonly number[]): unknown[]; /** * Return a copy of the headers with the Authorization value redacted. * Use this for logging or debugging. */ redactedHeaders(): Record; } //# sourceMappingURL=protocol.d.ts.map