import type { IncomingMessage, ServerResponse } from 'node:http'; import { PayloadTooLargeError } from '@origintrail-official/dkg-core'; import type { DKGAgent } from '@origintrail-official/dkg-agent'; import type { DkgConfig } from '../config.js'; export interface PublishQuad { subject: string; predicate: string; object: string; graph: string; } export type PublishAccessPolicy = 'public' | 'ownerOnly' | 'allowList'; export interface PublishRequestBody { contextGraphId: string; quads: PublishQuad[]; privateQuads?: PublishQuad[]; accessPolicy?: PublishAccessPolicy; allowedPeers?: string[]; subGraphName?: string; } import type { CorsAllowlist } from './state.js'; export declare function isPayloadTooLargeError(err: unknown): err is PayloadTooLargeError; export declare function payloadTooLargeResponseBody(err: unknown): Record; export declare function resolveNameToPeerId(agent: DKGAgent, nameOrId: string): Promise; export declare function isPublishQuad(value: unknown): value is PublishQuad; export declare function parsePublishRequestBody(body: string): { ok: true; value: PublishRequestBody; } | { ok: false; error: string; }; export declare function jsonResponse(res: ServerResponse, status: number, data: unknown, corsOrigin?: string | null, extraHeaders?: Record): void; export declare function safeDecodeURIComponent(encoded: string, res: ServerResponse): string | null; export declare function safeParseJson(body: string, res: ServerResponse): Record | null; export declare function validateOptionalSubGraphName(subGraphName: unknown, res: ServerResponse): boolean; export declare function validateRequiredContextGraphId(contextGraphId: unknown, res: ServerResponse): boolean; export declare function normalizeContextGraphIdOrUri(contextGraphId: string): string; type ExistingContextGraphRow = { id?: unknown; uri?: unknown; creator?: unknown; curator?: unknown; accessPolicy?: unknown; onChainId?: unknown; isSystem?: unknown; subscribed?: unknown; synced?: unknown; }; /** * Resolve a write target to a known, canonical context graph id. * * The storage layer auto-materializes named graphs on first insert, so syntax * validation is not enough for mutation routes. This helper fail-closes before * callers reach agent/publisher/storage code that would create a shadow CG. */ export declare function resolveRequiredWriteContextGraphId(agent: { listContextGraphs(opts?: { callerAgentAddress?: string | null; }): Promise; contextGraphHasLocalContent?: (contextGraphId: string) => Promise; contextGraphExists?: (contextGraphId: string) => Promise; }, contextGraphId: unknown, res: ServerResponse, opts?: { callerAgentAddress?: string | null; requireLocalWritable?: boolean; allowLocalExactFallback?: boolean; }): Promise; export declare function validateEntities(entities: unknown, res: ServerResponse): boolean; export declare function validateConditions(conditions: unknown, res: ServerResponse): boolean; export declare const MAX_BODY_BYTES: number; export declare const SMALL_BODY_BYTES: number; export declare const MAX_UPLOAD_BYTES: number; /** * In-memory extraction job tracking record. Populated at import-file time * and queried by the extraction-status endpoint. Records are kept in a * bounded, TTL-pruned map keyed by the target assertion URI (which is * unique per agent × contextGraph × assertionName × subGraphName). */ export interface ImportFileExtractionPayload { status: "completed" | "skipped" | "failed"; tripleCount: number; pipelineUsed: string | null; mdIntermediateHash?: string; error?: string; } export declare function buildImportFileResponse(args: { assertionUri: string; fileHash: string; rootEntity?: string; detectedContentType: string; extraction: ImportFileExtractionPayload; }): { detectedContentType: string; extraction: { error?: string | undefined; mdIntermediateHash?: string | undefined; status: "failed" | "completed" | "skipped"; tripleCount: number; pipelineUsed: string | null; }; rootEntity?: string | undefined; assertionUri: string; fileHash: string; }; export declare function unregisteredSubGraphError(contextGraphId: string, subGraphName: string): string; export declare function readBody(req: IncomingMessage, maxBytes?: number): Promise; /** * Buffer variant of `readBody` that returns raw bytes. Use for binary payloads * like multipart/form-data uploads where `.toString()` would corrupt content. */ export declare function readBodyBuffer(req: IncomingMessage, maxBytes?: number): Promise; export declare function buildCorsAllowlist(config: DkgConfig, boundPort: number): CorsAllowlist; export declare function resolveCorsOrigin(req: IncomingMessage, allowlist: CorsAllowlist): string | undefined; export declare function corsHeaders(origin?: string | null): Record; export declare class HttpRateLimiter { private _max; private _exempt; private _hits; private _timer; constructor(requestsPerMinute: number, exemptPaths?: string[]); isAllowed(ip: string, pathname: string): boolean; destroy(): void; } export declare function isLoopbackClientIp(ip: string): boolean; export declare function isLoopbackRateLimitExemptPath(pathname: string): boolean; export declare function shouldBypassRateLimitForLoopbackTraffic(ip: string, pathname: string): boolean; export declare function isValidContextGraphId(id: string): boolean; /** * CLI-9 ( * scrub raw chain-revert payloads from error messages before they * reach the HTTP body. Providers (ethers, viem, hardhat) serialise * the same revert data under multiple keys: `data="0x…"`, `data=0x…`, * `errorData="0x…"`, `errorData=0x…`, and JSON `"data":"0x…"`. The * matching set here mirrors `enrichEvmError()` in * `packages/chain/src/evm-adapter.ts` so any selector that survived * decoding still gets redacted before reaching the operator. Note * that we redact AFTER `enrichEvmError` has had a chance to splice * the decoded custom-error name in — so the operator still sees the * human-readable error, just without the raw selector blob. */ export declare function sanitizeRevertMessage(raw: string): string; /** * CLI-7/9 helper: classify a thrown error as a "client mistake" (4xx) * vs an "infrastructure failure" (5xx). The vocabulary is conservative * — only well-known not-found / invalid-input / unreachable-peer * patterns map to 4xx; everything else stays 5xx so a real internal * problem still surfaces via the top-level catch. */ export declare function classifyClientError(msg: string): { status: 404; sanitized: string; } | { status: 400; sanitized: string; } | { status: 504; sanitized: string; } | null; export declare function shortId(peerId: string): string; export declare function sleep(ms: number): Promise; export declare function deriveBlockExplorerUrl(chainId?: string): string | undefined; export {}; //# sourceMappingURL=http-utils.d.ts.map