import type { SetRequired } from 'type-fest'; import { type CCIPRequest, type ExecutionInput, type Lane, type Logger, type WithLogger } from '../types.ts'; import type { LaneLatencyResponse, MessageSearchFilters, MessageSearchPage, MessageSearchResult } from './types.ts'; export type { APICCIPRequestMetadata, APIErrorResponse, LaneLatencyResponse, MessageSearchFilters, MessageSearchPage, MessageSearchResult, } from './types.ts'; /** Default CCIP API base URL */ export declare const DEFAULT_API_BASE_URL = "https://api.ccip.chain.link"; /** Default timeout for API requests in milliseconds */ export declare const DEFAULT_TIMEOUT_MS = 30000; /** SDK version string for telemetry header */ export declare const SDK_VERSION = "1.6.2-9f3ceb6"; /** SDK telemetry header name */ export declare const SDK_VERSION_HEADER = "X-SDK-Version"; /** * Context for CCIPAPIClient initialization. */ export type CCIPAPIClientContext = WithLogger & { /** Custom fetch function (defaults to globalThis.fetch) */ fetch?: typeof fetch; /** Request timeout in milliseconds (defaults to 30000ms) */ timeoutMs?: number; }; /** * Client for interacting with the CCIP REST API. * * Can be used standalone or injected into Chain classes. * * @example Standalone usage * ```typescript * const api = CCIPAPIClient.fromUrl() * const latency = await api.getLaneLatency(sourceSelector, destSelector) * console.log(`Latency: ${latency.totalMs}ms`) * ``` * * @example With custom options * ```typescript * const api = CCIPAPIClient.fromUrl('https://custom.api.url', { * logger: myLogger, * fetch: myCustomFetch, * }) * ``` * * @example Error handling * ```typescript * try { * const latency = await api.getLaneLatency(sourceSelector, destSelector) * } catch (err) { * if (err instanceof CCIPHttpError) { * console.error(`API error ${err.context.status}: ${err.context.apiErrorMessage}`) * if (err.isTransient) { * // Retry after delay * } * } * } * ``` */ export declare class CCIPAPIClient { /** Base URL for API requests */ readonly baseUrl: string; /** Logger instance */ readonly logger: Logger; /** Request timeout in milliseconds */ readonly timeoutMs: number; /** Fetch function used for HTTP requests */ private readonly _fetch; /** * Creates a new CCIPAPIClient instance. * @param baseUrl - Base URL for the CCIP API (defaults to {@link DEFAULT_API_BASE_URL}) * @param ctx - Optional context with logger and custom fetch */ constructor(baseUrl?: string, ctx?: CCIPAPIClientContext); /** * Factory method for creating memoized CCIPAPIClient. * Should be preferred over constructor, to avoid multiple fetch/retry/rate-limits instances, * unless that's specifically required. * @param baseUrl - Base URL for the CCIP API * @param ctx - Optional context * @returns New CCIPAPIClient instance */ static fromUrl(baseUrl?: string, ctx?: CCIPAPIClientContext): CCIPAPIClient; /** * Performs a fetch request with timeout protection. * @param url - URL to fetch * @param operation - Operation name for error context * @returns Promise resolving to Response * @throws CCIPTimeoutError if request times out * @internal */ private _fetchWithTimeout; /** * Fetches estimated lane latency between source and destination chains. * * @param sourceChainSelector - Source chain selector (bigint) * @param destChainSelector - Destination chain selector (bigint) * @param numberOfBlocks - Optional number of block confirmations for latency calculation. * When omitted or 0, uses the lane's default finality. When provided as a positive * integer, the API returns latency for that custom finality value (sent as `numOfBlocks` * query parameter). * @param options - Optional request options. * - `signal` — an `AbortSignal` to cancel the request. * @returns Promise resolving to {@link LaneLatencyResponse} with totalMs * * @throws {@link CCIPLaneNotFoundError} when lane not found (404) * @throws {@link CCIPTimeoutError} if request times out * @throws {@link CCIPAbortError} if request is aborted via signal * @throws {@link CCIPHttpError} on other HTTP errors with context: * - `status` - HTTP status code (e.g., 500) * - `statusText` - HTTP status message * - `apiErrorCode` - API error code (e.g., "INVALID_PARAMETERS") * - `apiErrorMessage` - Human-readable error message from API * * @example Basic usage * ```typescript * const latency = await api.getLaneLatency( * 5009297550715157269n, // Ethereum mainnet * 4949039107694359620n, // Arbitrum mainnet * ) * console.log(`Estimated delivery: ${Math.round(latency.totalMs / 60000)} minutes`) * ``` * * @example Custom block confirmations * ```typescript * const latency = await api.getLaneLatency( * 5009297550715157269n, // Ethereum mainnet * 4949039107694359620n, // Arbitrum mainnet * 10, // 10 block confirmations * ) * ``` * * @example Handling specific API errors * ```typescript * try { * const latency = await api.getLaneLatency(sourceSelector, destSelector) * } catch (err) { * if (err instanceof CCIPHttpError && err.context.apiErrorCode === 'LANE_NOT_FOUND') { * console.error('This lane does not exist') * } * } * ``` */ getLaneLatency(sourceChainSelector: bigint, destChainSelector: bigint, numberOfBlocks?: number, options?: { signal?: AbortSignal; }): Promise; /** * Fetches a CCIP message by its unique message ID. * * @param messageId - The message ID (0x prefix + 64 hex characters, e.g., "0x1234...abcd") * @param options - Optional request options. * - `signal` — an `AbortSignal` to cancel the request. * @returns Promise resolving to {@link APICCIPRequest} with message details * * @throws {@link CCIPMessageIdNotFoundError} when message not found (404) * @throws {@link CCIPTimeoutError} if request times out * @throws {@link CCIPAbortError} if request is aborted via signal * @throws {@link CCIPHttpError} on HTTP errors with context: * - `status` - HTTP status code * - `statusText` - HTTP status message * - `apiErrorCode` - API error code (e.g., "INVALID_MESSAGE_ID") * - `apiErrorMessage` - Human-readable error message * * @example Basic usage * ```typescript * const request = await api.getMessageById( * '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' * ) * console.log(`Status: ${request.metadata.status}`) * console.log(`From: ${request.message?.sender}`) * ``` * * @example Handling not found * ```typescript * try { * const request = await api.getMessageById(messageId) * } catch (err) { * if (err instanceof CCIPMessageIdNotFoundError) { * console.error('Message not found, it may still be in transit') * } * } * ``` */ getMessageById(messageId: string, options?: { signal?: AbortSignal; }): Promise>; /** * Searches CCIP messages using filters with cursor-based pagination. * * @param filters - Optional search filters. Ignored when `options.cursor` is provided * (the cursor already encodes the original filters). * @param options - Optional pagination and request options: * - `limit` — max results per page. * - `cursor` — opaque token from a previous {@link MessageSearchPage} for the next page. * - `signal` — an `AbortSignal` to cancel the request. * @returns Promise resolving to a {@link MessageSearchPage} with results and pagination info. * * @remarks * A 404 response is treated as "no results found" and returns an empty page, * unlike {@link CCIPAPIClient.getMessageById} which throws on 404. * When paginating with a cursor, the `filters` parameter is ignored because * the cursor encodes the original filters. * * @throws {@link CCIPTimeoutError} if request times out. * @throws {@link CCIPAbortError} if request is aborted via signal. * @throws {@link CCIPHttpError} on HTTP errors (4xx/5xx, except 404 which returns empty). * * @see {@link MessageSearchFilters} — available filter fields * @see {@link MessageSearchPage} — return type with pagination * @see {@link CCIPAPIClient.searchAllMessages} — async generator that handles pagination automatically * @see {@link CCIPAPIClient.getMessageById} — fetch full message details for a search result * @see {@link CCIPAPIClient.getMessageIdsInTx} — convenience wrapper using `sourceTransactionHash` * * @example Search by sender * ```typescript * const page = await api.searchMessages({ * sender: '0x9d087fC03ae39b088326b67fA3C788236645b717', * }) * for (const msg of page.data) { * console.log(`${msg.messageId}: ${msg.status}`) * } * ``` * * @example Paginate through all results * ```typescript * let page = await api.searchMessages({ sender: '0x...' }, { limit: 10 }) * const all = [...page.data] * while (page.hasNextPage) { * page = await api.searchMessages(undefined, { cursor: page.cursor! }) * all.push(...page.data) * } * ``` * * @example Filter by lane and sender * ```typescript * const page = await api.searchMessages({ * sender: '0x9d087fC03ae39b088326b67fA3C788236645b717', * sourceChainSelector: 16015286601757825753n, * destChainSelector: 14767482510784806043n, * }) * ``` */ searchMessages(filters?: MessageSearchFilters, options?: { limit?: number; cursor?: string; signal?: AbortSignal; }): Promise; /** * Async generator that streams all messages matching the given filters, * handling cursor-based pagination automatically. * * @param filters - Optional search filters (same as {@link CCIPAPIClient.searchMessages}). * @param options - Optional request options: * - `limit` — per-page fetch size (number of results fetched per API call). The total * number of results is controlled by the consumer — break out of the loop to stop early. * - `signal` — an `AbortSignal` that, when aborted, cancels the next page fetch. * @returns AsyncGenerator yielding {@link MessageSearchResult} one at a time, across all pages. * * @throws {@link CCIPTimeoutError} if a page request times out. * @throws {@link CCIPAbortError} if a page request is aborted via signal. * @throws {@link CCIPHttpError} on HTTP errors (4xx/5xx, except 404 which yields nothing). * * @see {@link CCIPAPIClient.searchMessages} — for page-level control and explicit cursor handling * @see {@link CCIPAPIClient.getMessageById} — fetch full message details for a search result * * @example Iterate all messages for a sender * ```typescript * for await (const msg of api.searchAllMessages({ sender: '0x...' })) { * console.log(`${msg.messageId}: ${msg.status}`) * } * ``` * * @example Stop after collecting 5 results * ```typescript * const results: MessageSearchResult[] = [] * for await (const msg of api.searchAllMessages({ sender: '0x...' })) { * results.push(msg) * if (results.length >= 5) break * } * ``` */ searchAllMessages(filters?: MessageSearchFilters, options?: { limit?: number; signal?: AbortSignal; }): AsyncGenerator; /** * Fetches message IDs from a source transaction hash. * * @remarks * Uses {@link CCIPAPIClient.searchMessages} internally with `sourceTransactionHash` filter and `limit: 100`. * * @param txHash - Source transaction hash. * @param options - Optional request options. * - `signal` — an `AbortSignal` to cancel the request. * @returns Promise resolving to array of message IDs. * * @throws {@link CCIPMessageNotFoundInTxError} when no messages found (404 or empty). * @throws {@link CCIPUnexpectedPaginationError} when hasNextPage is true. * @throws {@link CCIPTimeoutError} if request times out. * @throws {@link CCIPAbortError} if request is aborted via signal. * @throws {@link CCIPHttpError} on HTTP errors. * * @example Basic usage * ```typescript * const messageIds = await api.getMessageIdsInTx( * '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' * ) * console.log(`Found ${messageIds.length} messages`) * ``` * * @example Fetch full details for each message * ```typescript * const api = CCIPAPIClient.fromUrl() * const messageIds = await api.getMessageIdsInTx(txHash) * for (const id of messageIds) { * const request = await api.getMessageById(id) * console.log(`${id}: ${request.metadata.status}`) * } * ``` */ getMessageIdsInTx(txHash: string, options?: { signal?: AbortSignal; }): Promise; /** * Fetches the execution input for a given message by id. * For v2.0 messages, returns `{ encodedMessage, verifications }`. * For pre-v2 messages, returns `{ message, offchainTokenData, proofs, ... }` with merkle proof. * * @param messageId - The CCIP message ID (32-byte hex string) * @param options - Optional request options. * - `signal` — an `AbortSignal` to cancel the request. * @returns Execution input with offRamp address and lane info * * @throws {@link CCIPMessageIdNotFoundError} when message not found (404) * @throws {@link CCIPTimeoutError} if request times out * @throws {@link CCIPAbortError} if request is aborted via signal * @throws {@link CCIPHttpError} on other HTTP errors * * @example * ```typescript * const api = CCIPAPIClient.fromUrl() * const execInput = await api.getExecutionInput('0x1234...') * // Use with dest.execute(): * const { offRamp, ...input } = execInput * await dest.execute({ offRamp, input, wallet }) * ``` */ getExecutionInput(messageId: string, options?: { signal?: AbortSignal; }): Promise; /** * Transforms raw API response to CCIPRequest with metadata. * Populates all derivable CCIPRequest fields from API data. * @internal */ _transformMessageResponse(text: string): SetRequired; } //# sourceMappingURL=index.d.ts.map