import { type BytesLike, type JsonRpcApiProvider, type Log, type TransactionReceipt } from 'ethers'; import type { PickDeep, SetFieldType, SetRequired } from 'type-fest'; import { type ChainContext, type GetBalanceOpts, type LaneFeatures, type LogFilter, type TokenPoolRemote, type TokenPrice, type TokenTransferFeeOpts, type TotalFeesEstimate, Chain } from '../chain.ts'; import { type ExtraArgs } from '../extra-args.ts'; import type { LeafHasher } from '../hasher/common.ts'; import { type CCIPExecution, type CCIPMessage, type CCIPRequest, type CCIPVerifications, type ChainTransaction, type CommitReport, type ExecutionReceipt, type Lane, type NetworkInfo, type WithLogger, ChainFamily } from '../types.ts'; import { type EVMEndBlockTag } from './logs.ts'; import { type UnsignedEVMTx } from './types.ts'; export type { UnsignedEVMTx }; /** * EVM chain implementation supporting Ethereum-compatible networks. * * Provides methods for sending CCIP cross-chain messages, querying message * status, fetching fee quotes, and manually executing pending messages on * Ethereum Virtual Machine compatible chains. * * @example Create from RPC URL * ```typescript * import { EVMChain } from '@chainlink/ccip-sdk' * * const chain = await EVMChain.fromUrl('https://rpc.sepolia.org') * console.log(`Connected to: ${chain.network.name}`) * ``` * * @example Query messages in a transaction * ```typescript * const requests = await chain.getMessagesInTx('0xabc123...') * for (const req of requests) { * console.log(`Message ID: ${req.message.messageId}`) * } * ``` */ export declare class EVMChain extends Chain { static readonly family: "EVM"; static readonly decimals = 18; provider: JsonRpcApiProvider; private noncesPromises; /** * Cache of current nonces per wallet address. * Used internally by {@link sendMessage} and {@link execute} to manage transaction ordering. * Can be inspected for debugging or manually adjusted if needed. */ nonces: Record; /** * Creates a new EVMChain instance. * @param provider - JSON-RPC provider for the EVM network. * @param network - Network information for this chain. */ constructor(provider: JsonRpcApiProvider, network: NetworkInfo, ctx?: ChainContext); /** * Expose ethers provider's `listAccounts`, if provider supports it */ listAccounts(): Promise; /** * Get the next nonce for a wallet address and increment the internal counter. * Fetches from the network on first call, then uses cached value. * @param address - Wallet address to get nonce for * @returns The next available nonce */ nextNonce(address: string): Promise; /** * Creates a JSON-RPC provider from a URL. * @param url - WebSocket (wss://) or HTTP (https://) endpoint URL. * @returns A ready JSON-RPC provider. */ static _getProvider(url: string, abort?: AbortSignal): Promise; /** * Creates an EVMChain instance from an existing provider. * @param provider - JSON-RPC provider instance. * @param ctx - context containing logger. * @returns A new EVMChain instance. */ static fromProvider(provider: JsonRpcApiProvider, ctx?: ChainContext): Promise; /** * Creates an EVMChain instance from an RPC URL. * * @param url - WebSocket (wss://) or HTTP (https://) endpoint URL. * @param ctx - Optional context containing logger and API client configuration. * @returns A new EVMChain instance connected to the specified network. * @throws {@link CCIPChainNotFoundError} if chain cannot be identified from chainId * * @example * ```typescript * // HTTP connection * const chain = await EVMChain.fromUrl('https://rpc.sepolia.org') * * // With custom logger * const chain = await EVMChain.fromUrl(url, { logger: customLogger }) * ``` */ static fromUrl(url: string, ctx?: ChainContext): Promise; /** {@inheritDoc Chain.getBlockTimestamp} */ getBlockTimestamp(block: EVMEndBlockTag): Promise; /** {@inheritDoc Chain.getTransaction} */ getTransaction(hash: string | TransactionReceipt): Promise; /** {@inheritDoc Chain.getLogs} */ getLogs(filter: SetFieldType): AsyncIterableIterator; /** {@inheritDoc Chain.getMessagesInBatch} */ getMessagesInBatch>(request: R, range: Pick, opts?: Pick): Promise; /** {@inheritDoc Chain.typeAndVersion} */ typeAndVersion(address: string): Promise<[type: string, version: string, typeAndVersion: string, suffix?: string | undefined]>; /** * Decodes a CCIP message from a log event. * @param log - Log event with topics and data. * @returns Decoded CCIPMessage or undefined if not a valid CCIP message. * @throws {@link CCIPLogDataInvalidError} if log data is not valid bytes * @throws {@link CCIPMessageDecodeError} if message cannot be decoded */ static decodeMessage(log: { topics?: readonly string[]; data: unknown; }): CCIPMessage | undefined; /** * Decodes commit reports from a log event. * @param log - Log event with topics and data. * @param lane - Lane info (required for CCIP v1.5 and earlier). * @returns Array of CommitReport or undefined if not a valid commit event. * @throws {@link CCIPLogDataInvalidError} if log data is not valid bytes * @throws {@link CCIPVersionRequiresLaneError} if CCIP v1.5 event but no lane provided */ static decodeCommits(log: { topics?: readonly string[]; data: unknown; }, lane?: Omit): CommitReport[] | undefined; /** * Decodes an execution receipt from a log event. * @param log - Log event with topics and data. * @returns ExecutionReceipt or undefined if not a valid execution event. * @throws {@link CCIPLogDataInvalidError} if log data is not valid bytes */ static decodeReceipt(log: { topics?: readonly string[]; data: unknown; }): ExecutionReceipt | undefined; /** * Decodes extra arguments from a CCIP message. * @param extraArgs - Encoded extra arguments bytes. * @returns Decoded extra arguments with tag, or undefined if unknown format. */ static decodeExtraArgs(extraArgs: BytesLike): (import("../extra-args.ts").EVMExtraArgsV1 & { _tag: "EVMExtraArgsV1"; }) | (import("../extra-args.ts").GenericExtraArgsV3 & { _tag: "GenericExtraArgsV3"; }) | (import("../extra-args.ts").SVMExtraArgsV1 & { _tag: "SVMExtraArgsV1"; }) | (import("../extra-args.ts").EVMExtraArgsV1 & { allowOutOfOrderExecution: boolean; } & { _tag: "EVMExtraArgsV2"; }) | (import("../extra-args.ts").EVMExtraArgsV1 & { allowOutOfOrderExecution: boolean; } & { tokenReceiver: string; receiverObjectIds: string[]; } & { _tag: "SuiExtraArgsV1"; }) | undefined; /** * Encodes extra arguments for a CCIP message. * @param args - Extra arguments to encode. * @returns Encoded extra arguments as hex string. */ static encodeExtraArgs(args: ExtraArgs | undefined): string; /** * Converts bytes to a checksummed EVM address. * @param bytes - Bytes to convert (must be 20 bytes or 32 bytes with leading zeros). * @returns Checksummed EVM address. * @throws {@link CCIPAddressInvalidEvmError} if bytes cannot be converted to a valid EVM address */ static getAddress(bytes: BytesLike): string; /** * Validates a transaction hash format for EVM */ static isTxHash(v: unknown): v is `0x${string}`; /** * Gets lane configuration from an OnRamp contract. * @param onRamp - OnRamp contract address. * @returns Lane configuration. * @throws {@link CCIPContractTypeInvalidError} if contract doesn't have destChainSelector */ getLaneForOnRamp(onRamp: string): Promise; /** * {@inheritDoc Chain.getRouterForOnRamp} * @throws {@link CCIPVersionUnsupportedError} if OnRamp version is not supported */ getRouterForOnRamp(onRamp: string, destChainSelector: bigint): Promise; /** * {@inheritDoc Chain.getLaneFeatures} */ getLaneFeatures(opts: { router: string; destChainSelector: bigint; token?: string; }): Promise>; /** * {@inheritDoc Chain.getRouterForOffRamp} * @throws {@link CCIPVersionUnsupportedError} if OffRamp version is not supported */ getRouterForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise; /** {@inheritDoc Chain.getNativeTokenForRouter} */ getNativeTokenForRouter(router: string): Promise; /** {@inheritDoc Chain.getOffRampsForRouter} */ getOffRampsForRouter(router: string, sourceChainSelector: bigint): Promise; /** {@inheritDoc Chain.getOnRampForRouter} */ getOnRampForRouter(router: string, destChainSelector: bigint): Promise; /** * {@inheritDoc Chain.getOnRampsForOffRamp} * @throws {@link CCIPVersionUnsupportedError} if OffRamp version is not supported */ getOnRampsForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise; /** * Fetch the CommitStore set in OffRamp config (CCIP v1.5 and earlier). * For CCIP v1.6 and later, it should return the offRamp address. * * @param offRamp - OffRamp contract address * @returns Promise resolving to CommitStore address * * @example Get commit store * ```typescript * const commitStore = await dest.getCommitStoreForOffRamp(offRampAddress) * // For v1.6+, commitStore === offRampAddress * ``` * @throws {@link CCIPVersionUnsupportedError} if OffRamp version is not supported * @internal */ getCommitStoreForOffRamp(offRamp: string): Promise; /** {@inheritDoc Chain.getTokenForTokenPool} */ getTokenForTokenPool(tokenPool: string): Promise; /** {@inheritDoc Chain.getTokenInfo} */ getTokenInfo(token: string): Promise<{ decimals: number; symbol: string; name: string; }>; /** {@inheritDoc Chain.getBalance} */ getBalance(opts: GetBalanceOpts): Promise; /** * Gets the leaf hasher for computing Merkle proofs on the destination chain. * @param lane - Lane configuration. * @param ctx - Context object containing logger. * @returns Leaf hasher function. * @throws {@link CCIPSourceChainUnsupportedError} if source chain is not EVM for v1.2/v1.5 * @throws {@link CCIPHasherVersionUnsupportedError} if lane version is not supported */ static getDestLeafHasher({ sourceChainSelector, destChainSelector, onRamp, version }: Lane, ctx?: WithLogger): LeafHasher; /** * Gets any available OnRamp for the given router. * @param address - Router or OnRamp contract address. * @returns OnRamp contract address. */ _getSomeOnRampFor(address: string): Promise; /** * {@inheritDoc Chain.getTokenAdminRegistryFor} * @throws {@link CCIPContractNotRouterError} if address is not a Router, OnRamp, or OffRamp */ getTokenAdminRegistryFor(address: string): Promise; /** * Gets the FeeQuoter contract address for a given Router or Ramp. * @internal * @param address - Router or Ramp contract address. * @returns FeeQuoter contract address. * @throws {@link CCIPContractNotRouterError} if address is not a Router, OnRamp, or OffRamp * @throws {@link CCIPVersionFeatureUnavailableError} if contract version is below v1.6 */ getFeeQuoterFor(address: string): Promise; /** {@inheritDoc Chain.getFee} */ getFee({ router, destChainSelector, message, }: Parameters[0]): Promise; /** * Detect whether a token pool is a USDC/CCTP pool via typeAndVersion, then resolve * the CCTPVerifier address and fetch source/dest CCTP domain IDs. * * @param tokenPool - The token pool address to check. * @param destChainSelector - Destination chain selector for getDomain(). * @param ccvs - Cross-chain verifier addresses from extraArgs (fallback for verifier discovery). * @returns Source and dest CCTP domain IDs, or undefined if not a USDC pool. */ private detectUsdcDomains; /** * Given a candidate address, check if it's a CCTPVerifier or VersionedVerifierResolver * and return the actual verifier address (resolving through the resolver if needed). */ private resolveVerifier; /** {@inheritDoc Chain.getTokenPrice} */ getTokenPrice(opts: { router: string; token: string; timestamp?: number; }): Promise; /** {@inheritDoc Chain.getTotalFeesEstimate} */ getTotalFeesEstimate(opts: Parameters[0]): Promise; /** * Generates unsigned EVM transactions for sending a CCIP message. * * @param opts - Send message options with sender address for populating transaction fields. * @returns Unsigned EVM transaction set containing 0 or more token approval txs * (if needed at the time of generation), followed by a ccipSend TransactionRequest. * * @remarks * When a token in `tokenAmounts` has `ZeroAddress` as its address, the corresponding * amount is included as native `value` in the `ccipSend` transaction instead of * going through the ERC-20 approve flow. */ generateUnsignedSendMessage(opts: Parameters[0]): Promise; /** * {@inheritDoc Chain.sendMessage} * @throws {@link CCIPWalletInvalidError} if wallet is not a valid Signer */ sendMessage(opts: Parameters[0]): Promise; /** * {@inheritDoc Chain.generateUnsignedExecute} * @returns array containing one unsigned `manuallyExecute` TransactionRequest object * @throws {@link CCIPVersionUnsupportedError} if OffRamp version is not supported */ generateUnsignedExecute(opts: Parameters[0]): Promise; /** * {@inheritDoc Chain.execute} * @throws {@link CCIPWalletInvalidError} if wallet is not a valid Signer. * @throws {@link CCIPExecTxNotConfirmedError} if execution transaction fails to confirm. * @throws {@link CCIPExecTxRevertedError} if execution transaction reverts. */ execute(opts: Parameters[0]): Promise; /** * Parses raw data into typed structures. * @param data - Raw data to parse. * @returns Parsed data. */ static parse(data: unknown): Record | undefined; /** * Get the supported tokens for a given contract address. * @param registry - Router, OnRamp, OffRamp or TokenAdminRegistry contract address. * @param opts - Optional parameters. * @returns An array of supported token addresses. */ getSupportedTokens(registry: string, opts?: { page?: number; }): Promise; /** * {@inheritDoc Chain.getRegistryTokenConfig} * @throws {@link CCIPTokenNotConfiguredError} if token is not configured in registry */ getRegistryTokenConfig(registry: string, token: string): Promise<{ administrator: string; pendingAdministrator?: string; tokenPool?: string; }>; /** * Fetches the token pool configuration for an EVM token pool contract. * * @param tokenPool - Token pool contract address. * @param feeOpts - Optional parameters to also fetch token transfer fee config: * - `destChainSelector` — destination chain selector. * - `finality` — requested finality ('finalized', 'safe', or block depth number). * - `tokenArgs` — hex-encoded bytes passed to the pool contract. * @returns Token pool config containing token, router, typeAndVersion, and optionally * finalityDepth, finalitySafe, and tokenTransferFeeConfig. * * @remarks * For pools with version \>= 2.0, also returns `finalityDepth` and `finalitySafe` for * Faster-Than-Finality (FTF) and FCR support. Pre-2.0 pools omit these fields. * When `feeOpts` is provided and the pool is v2.0+, also fetches token transfer fee config. */ getTokenPoolConfig(tokenPool: string, feeOpts?: TokenTransferFeeOpts): Promise>, 'typeAndVersion'>>; /** * Fetches remote chain configurations for an EVM token pool contract. * * @param tokenPool - Token pool address on the current chain. * @param remoteChainSelector - Optional chain selector to filter results to a single destination. * @returns Record mapping chain names to {@link TokenPoolRemote} configs. * * @remarks * Handles 3 pool version branches: * - v1.5: single remote pool via `getRemotePool`, standard rate limiters. * - v1.6: multiple remote pools via `getRemotePools`, standard rate limiters. * - v2.0+: multiple remote pools plus FTF (Faster-Than-Finality) rate limiters * (`fastOutboundRateLimiterState` / `fastInboundRateLimiterState`). * * @throws {@link CCIPTokenPoolChainConfigNotFoundError} if remote token is not configured for a chain. */ getTokenPoolRemotes(tokenPool: string, remoteChainSelector?: bigint): Promise>; /** * {@inheritDoc Chain.getFeeTokens} * @throws {@link CCIPVersionUnsupportedError} if OnRamp version is not supported */ getFeeTokens(address: string): Promise<{ [k: string]: { decimals: number; symbol: string; name: string; }; }>; /** {@inheritDoc Chain.getVerifications} */ getVerifications(opts: Parameters[0]): Promise; /** {@inheritDoc Chain.getExecutionReceipts} */ getExecutionReceipts(opts: Parameters[0]): AsyncIterableIterator; /** {@inheritDoc Chain.estimateReceiveExecution} */ estimateReceiveExecution(opts: Parameters>[0]): Promise; } //# sourceMappingURL=index.d.ts.map