import type { PublicKey } from '@solana/web3.js'; import type BN from 'bn.js'; import { type Addressable } from 'ethers'; import type { PickDeep } from 'type-fest'; import type { Chain, LogFilter } from './chain.ts'; import { ChainFamily } from './networks.ts'; import type { AnyMessage, CCIPMessage, CCIPRequest, ChainLog, ChainTransaction, Lane, LeanNumbers, MessageInput } from './types.ts'; type Normalized = T extends PublicKey | Addressable ? string : T extends BN ? bigint : T extends Array ? Array> : T extends ReadonlyArray ? ReadonlyArray> : T extends Record ? { [K in keyof T]: Normalized; } : T extends Readonly> ? { readonly [K in keyof T]: Normalized; } : T; /** Convert recursively a message or config record into normalized values */ export declare function normalizeDeep>(data: T, opts?: { sourceFamily?: ChainFamily; destFamily?: ChainFamily; }): Normalized; /** * Decodes hex strings, bytearrays, JSON strings and raw objects as CCIPMessages. * Does minimal validation, but converts objects in the format expected by ccip-tools-ts. * * @param data - Data to decode (hex string, Uint8Array, JSON string, or object) * @returns Decoded CCIPMessage * @throws {@link CCIPMessageDecodeError} if data cannot be decoded as a valid message * @throws {@link CCIPMessageInvalidError} if message structure is invalid or missing required fields * * @example * ```typescript * import { decodeMessage } from '@chainlink/ccip-sdk' * * // Decode from JSON string * const message = decodeMessage('{"header":{"sourceChainSelector":"123",...}') * * // Decode from hex-encoded bytes * const message = decodeMessage('0x...') * * console.log('Message ID:', message.messageId) * ``` */ export declare function decodeMessage(data: string | Uint8Array | Record): CCIPMessage; /** * Populates missing required fields (e.g. `extraArgs`) from AnyMessage. * @param message - Partial AnyMessage with at least receiver * @param dest - Destination chain family to build message for * @returns Original message or shallow copy with defaults for required fields */ export declare function buildMessageForDest(message: MessageInput, dest: ChainFamily): AnyMessage; /** * Resolve the lane for a decoded CCIP message. * * Shared helper used by {@link getMessagesInTx}, {@link getMessageById}, and * {@link getMessagesInRange} to build the {@link Lane} from a decoded message and log. * * @internal */ export declare function resolveLane(source: Chain, message: CCIPMessage, log: ChainLog): Promise; /** * Fetch all CCIP messages in a transaction. * @param source - Source chain instance * @param tx - ChainTransaction to search in * @returns CCIP requests (messages) in the transaction (at least one) * @throws {@link CCIPChainFamilyUnsupportedError} if chain family not supported for legacy messages * @throws {@link CCIPMessageNotFoundInTxError} if no CCIP messages found in transaction * * @see {@link getMessageById} - Search by messageId when tx hash unknown */ export declare function getMessagesInTx(source: Chain, tx: ChainTransaction): Promise; /** * Fetch a CCIP message by messageId from RPC logs (slow scan). * * This is the fallback implementation called by {@link Chain.getMessageById} * when the API client is unavailable or fails. * * @param source - Source chain to scan logs from * @param messageId - Message ID to search for * @param opts - Optional hints (onRamp address narrows search, page controls batch size) * @returns CCIPRequest matching the messageId * * @throws {@link CCIPMessageIdNotFoundError} if message not found after scanning all logs * * @example * * ```typescript * import { getMessageById, EVMChain } from '@chainlink/ccip-sdk' * * const source = await EVMChain.fromUrl('https://rpc.sepolia.org') * const request = await getMessageById(source, '0xabc123...', { * onRamp: '0xOnRampAddress...', * startTime: 1710000000, * }) * console.log(`Found: seqNr=${request.message.sequenceNumber}`) * ``` * * @internal */ export declare function getMessageById(source: Chain, messageId: string, opts?: Pick & { onRamp?: string; }): Promise; /** * Fetches all CCIP messages contained in a given commit batch. * @param source - The source chain. * @param request - The CCIP request containing lane and message info. * @param range - Object containing minSeqNr and maxSeqNr for the batch range. * @param opts - Optional log filtering parameters. * @returns Array of messages in the batch. * @throws {@link CCIPMessageBatchIncompleteError} if not all messages in the batch range could be found in source chain logs * @see {@link getVerifications} - Get commit report to determine batch range */ export declare function getMessagesInBatch>(source: C, request: R, { minSeqNr, maxSeqNr }: { minSeqNr: bigint; maxSeqNr: bigint; }, opts?: Parameters[0]): Promise; /** * Discover and decode CCIP messages within a block/slot/checkpoint range. * * This is the range-scanning equivalent of {@link getMessagesInTx}. It composes * {@link Chain.getLogs} and {@link ChainStatic.decodeMessage} to yield CCIP requests * in discovery order without requiring transaction hashes upfront. * * Results are yielded in native log order: (blockNumber, logIndex) ascending for EVM, * slot order for Solana. Non-CCIP logs in the range are silently skipped. * * @param source - Source chain to scan logs from * @param opts - {@link LogFilter} options. Key fields: * - `startBlock` / `endBlock` — block/slot range (endBlock supports `'finalized'` and `'latest'`) * - `address` — onRamp/router address (optional on EVM, required on Solana) * - `topics` — defaults to both CCIP message event names * - `page` — batch size for log pagination * @returns Async iterator of {@link CCIPRequest} objects in native log order * * @throws {@link CCIPChainFamilyUnsupportedError} if a pre-v1.6 message is found on a non-EVM chain * @throws {@link CCIPLogsAddressRequiredError} on Solana if `address` is not provided * * @example EVM — scan a block range for all CCIP messages * * ```typescript * const chain = await EVMChain.fromUrl('https://rpc.sepolia.org') * for await (const request of getMessagesInRange(chain, { * startBlock: 1000000, * endBlock: 1001000, * address: '0xOnRampAddress...', // optional on EVM, but recommended for public RPCs * })) { * console.log(`seqNr=${request.message.sequenceNumber} dest=${request.lane.destChainSelector}`) * } * ``` * * @example Solana — scan a slot range (address required) * * ```typescript * const chain = await SolanaChain.fromUrl('https://api.devnet.solana.com') * for await (const request of getMessagesInRange(chain, { * startBlock: 450000000, * endBlock: 450100000, * address: 'Ccip842gzYHh...', // router program address (required on Solana) * })) { * console.log(`seqNr=${request.message.sequenceNumber}`) * } * ``` * * @see {@link getMessagesInTx} - Per-transaction message discovery * @see {@link getMessagesInBatch} - Batch discovery by sequence number range */ export declare function getMessagesInRange(source: Chain, opts: LeanNumbers): AsyncIterableIterator; /** * Confirm a log tx is finalized or wait for it to be finalized. * * @param chain - Chain instance to check finality on * @param opts - Options containing the request, finality level, and optional cancel promise * @returns Some block info at or after tx finalization * * @throws {@link CCIPTransactionNotFinalizedError} if the transaction is not included (e.g., due to a reorg) * * @example Wait for message finality * ```typescript * const request = await source.getMessagesInTx(txHash) * try { * await waitFinalized(chain, { request: request[0] }) * console.log('Transaction finalized') * } catch (err) { * if (err instanceof CCIPTransactionNotFinalizedError) { * console.log('Transaction not yet finalized') * } * } * ``` */ export declare function waitFinalized(chain: C, { finality, abort, reorgSafetyBlocks, pollInterval, ...rest }: Parameters[0]): Promise> | undefined>; export {}; //# sourceMappingURL=requests.d.ts.map