From aedc5b5d7ac5ccf779770af437d030959abd0199 Mon Sep 17 00:00:00 2001 From: PabloMansanet Date: Thu, 28 May 2026 12:46:33 +0200 Subject: [PATCH 1/2] Add fork test --- ccip-sdk/src/evm/fork.test.data.ts | 16 +++++++++++ ccip-sdk/src/evm/fork.test.ts | 44 +++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/ccip-sdk/src/evm/fork.test.data.ts b/ccip-sdk/src/evm/fork.test.data.ts index 80602ae8..fb77cd15 100644 --- a/ccip-sdk/src/evm/fork.test.data.ts +++ b/ccip-sdk/src/evm/fork.test.data.ts @@ -414,3 +414,19 @@ export const TON_TO_SEPOLIA: ForkTestMessage[] = [ 'failed data-only (gasLimit=1) from TON, ready for manual exec — problematic API path', }, ] + +// ── Solana Devnet → Sepolia (SVM → EVM) ── + +export const SOLANA_DEVNET_TO_SEPOLIA: ForkTestMessage[] = [ + // FAILED — ready for manual exec; API reports version "1.6.2" which does not match + // the CCIPVersion enum values ("1.6.0" etc.), causing the API-driven manual-exec + // codepath to mishandle the lane version in ccip-sdk versions prior to 1.7.1. + { + messageId: '0xacb7f265a4d02eb1b902c6f171655aabd4b6c7c1d5b4519bee0b261fc2a88c5f', + txHash: 'ZHKdh1vcqUVedGtF38feWhKq46kB3d8j3SNTZYXUBDF51bArDVmhDuSSod9oBvwYKEjrm2PqtjDDXpsBvbfbA85', + status: MessageStatus.Failed, + version: '1.6', + description: + 'failed from Solana Devnet, ready for manual exec — API reports version "1.6.2"', + }, +] diff --git a/ccip-sdk/src/evm/fork.test.ts b/ccip-sdk/src/evm/fork.test.ts index 46087058..26c067d9 100644 --- a/ccip-sdk/src/evm/fork.test.ts +++ b/ccip-sdk/src/evm/fork.test.ts @@ -8,6 +8,7 @@ import { Instance } from 'prool' import { createPublicClient, http } from 'viem' import '../aptos/index.ts' // register Aptos chain family for cross-family message decoding +import '../solana/index.ts' // register Solana chain family for cross-family message decoding import '../ton/index.ts' // register TON chain family for cross-family message decoding import { CCIPAPIClient } from '../api/index.ts' import { LaneFeature } from '../chain.ts' @@ -16,7 +17,12 @@ import { NetworkType } from '../networks.ts' import { CCTP_FINALITY_FAST, getUsdcBurnFees } from '../offchain.ts' import { type ExecutionInput, ExecutionState, MessageStatus } from '../types.ts' import { interfaces } from './const.ts' -import { FUJI_TO_SEPOLIA, SEPOLIA_TO_FUJI, TON_TO_SEPOLIA } from './fork.test.data.ts' +import { + FUJI_TO_SEPOLIA, + SEPOLIA_TO_FUJI, + SOLANA_DEVNET_TO_SEPOLIA, + TON_TO_SEPOLIA, +} from './fork.test.data.ts' import { EVMChain } from './index.ts' import { ViemTransportProvider } from './viem/client-adapter.ts' @@ -1510,6 +1516,42 @@ describe('EVM Fork Tests', { skip, timeout: 180_000 }, () => { sepoliaWithApi.provider.destroy() }) + + // Solana Devnet → Sepolia message whose lane.version reported by the API is "1.6.2". + // The CCIPVersion enum only knows "1.6.0", so the API-driven manual-exec codepath + // must normalize patch-level versions to avoid breaking downstream handling + // (e.g. leaf hasher selection in calculateManualExecProof). + it('should execute a Solana-source message via API-driven path (Solana Devnet -> Sepolia)', async () => { + assert.ok(sepoliaInstance, 'sepolia anvil should be running') + + const msg = SOLANA_DEVNET_TO_SEPOLIA[0]! + + const stagingApi = new CCIPAPIClient('https://api.ccip.cldev.cloud', { logger: testLogger }) + const sepoliaProvider = new JsonRpcProvider( + `http://${sepoliaInstance.host}:${sepoliaInstance.port}`, + ) + const sepoliaWithApi = await EVMChain.fromProvider(sepoliaProvider, { + apiClient: stagingApi, + logger: testLogger, + }) + const w = new Wallet(ANVIL_PRIVATE_KEY, sepoliaProvider) + + const execution = await sepoliaWithApi.execute({ + messageId: msg.messageId, + wallet: w, + gasLimit: 500_000, + }) + + console.log( + ` executed ${msg.messageId.slice(0, 10)}… via API (Solana source) → state=${execution.receipt.state}`, + ) + assert.equal(execution.receipt.messageId, msg.messageId, 'receipt messageId should match') + assert.ok(execution.log.transactionHash, 'should have tx hash') + assert.ok(execution.log.blockTimestamp > 0, 'should have timestamp') + assert.equal(execution.receipt.state, ExecutionState.Success) + + sepoliaWithApi.provider.destroy() + }) }) describe('ViemTransportProvider — revert data forwarding', () => { From 7d4ce89dbf548a76d554342453bd5a79efe02cc9 Mon Sep 17 00:00:00 2001 From: PabloMansanet Date: Thu, 28 May 2026 12:54:34 +0200 Subject: [PATCH 2/2] Linter pass --- ccip-sdk/src/evm/fork.test.data.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ccip-sdk/src/evm/fork.test.data.ts b/ccip-sdk/src/evm/fork.test.data.ts index fb77cd15..3ab284c0 100644 --- a/ccip-sdk/src/evm/fork.test.data.ts +++ b/ccip-sdk/src/evm/fork.test.data.ts @@ -423,10 +423,10 @@ export const SOLANA_DEVNET_TO_SEPOLIA: ForkTestMessage[] = [ // codepath to mishandle the lane version in ccip-sdk versions prior to 1.7.1. { messageId: '0xacb7f265a4d02eb1b902c6f171655aabd4b6c7c1d5b4519bee0b261fc2a88c5f', - txHash: 'ZHKdh1vcqUVedGtF38feWhKq46kB3d8j3SNTZYXUBDF51bArDVmhDuSSod9oBvwYKEjrm2PqtjDDXpsBvbfbA85', + txHash: + 'ZHKdh1vcqUVedGtF38feWhKq46kB3d8j3SNTZYXUBDF51bArDVmhDuSSod9oBvwYKEjrm2PqtjDDXpsBvbfbA85', status: MessageStatus.Failed, version: '1.6', - description: - 'failed from Solana Devnet, ready for manual exec — API reports version "1.6.2"', + description: 'failed from Solana Devnet, ready for manual exec — API reports version "1.6.2"', }, ]