Skip to content

implement CCIPAPIClient.getExecutionInput#155

Open
andrevmatos wants to merge 8 commits intomainfrom
api/get_execution_input
Open

implement CCIPAPIClient.getExecutionInput#155
andrevmatos wants to merge 8 commits intomainfrom
api/get_execution_input

Conversation

@andrevmatos
Copy link
Collaborator

@andrevmatos andrevmatos commented Feb 26, 2026

  • API method is ready, and capable of using /execution-inputs API endpoint for both v1 and v2 messages
  • use it in dest.execute({ messageId })
  • use it in manual-exec when given a messageId
    • lift requirement for a source RPC in this case
  • manual execution samples from CLI, completely WITHOUT source:
    • v1
    • v2: using staging api; failed on receiver, but executed

@andrevmatos andrevmatos self-assigned this Feb 26, 2026
@vercel
Copy link

vercel bot commented Feb 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ccip-tools-ts Ready Ready Preview, Comment Feb 27, 2026 9:44pm

Request Review

PabloMansanet
PabloMansanet previously approved these changes Feb 27, 2026
Copy link
Contributor

@PabloMansanet PabloMansanet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, just two minor comments. I'll handle the fork test early Monday.

@andrevmatos andrevmatos force-pushed the api/get_execution_input branch from 7d3e5c2 to 76310cf Compare February 27, 2026 21:11
@andrevmatos andrevmatos marked this pull request as ready for review February 27, 2026 21:11
@andrevmatos andrevmatos requested a review from a team as a code owner February 27, 2026 21:11
@github-actions
Copy link

github-actions bot commented Feb 27, 2026

Coverage Report

ℹ tests 687
ℹ suites 211
ℹ pass 685
ℹ fail 0
ℹ cancelled 0
ℹ skipped 2
ℹ todo 0
ℹ duration_ms 63395.872389

> @chainlink/ccip-cli@1.0.0 test
> node --test

(node:4439) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
▶ lane-latency command
  ✔ should output JSON format correctly (5.862305ms)
  ✔ should resolve chain IDs to chain selectors (0.760962ms)
  ✔ should use custom API URL when provided (0.815233ms)
  ✔ should output log format correctly (0.802079ms)
  ✔ should handle chain IDs as input (0.665282ms)
  ✔ should handle chain selectors as input (0.661464ms)
  ✔ should throw CCIPApiClientNotAvailableError when --no-api flag is set (1.2069ms)
  ✔ should work normally when --no-api flag is false (1.352353ms)
  ▶ CCIP_API environment variable integration
    ✔ should respect CCIP_API=false environment variable (0.650483ms)
  ✔ CCIP_API environment variable integration (0.839178ms)
✔ lane-latency command (15.29749ms)
▶ e2e command show EVM
  ▶ pretty format (default)
    ✔ should show complete CCIP transaction details EVM to EVM (9570.374448ms)
  ✔ pretty format (default) (9571.433991ms)
  ▶ json format
    ✔ should output valid JSON with all expected fields (7434.359745ms)
  ✔ json format (7434.570841ms)
  ▶ log format
    ✔ should output in log format with object assignments (7624.107785ms)
  ✔ log format (7624.422077ms)
  ▶ verbose flag
    ✔ should work with verbose flag enabled (8321.937698ms)
  ✔ verbose flag (8322.146771ms)
  ▶ error handling
    ✔ should handle invalid transaction hash gracefully (5788.848008ms)
    ✔ should require transaction hash argument (1662.129336ms)
  ✔ error handling (7451.265536ms)
  ✔ should show complete CCIP transaction details EVM to Aptos (7939.855712ms)
  ✔ should show complete CCIP transaction details EVM to Solana (5317.340144ms)
✔ e2e command show EVM (53662.518753ms)
▶ e2e command show Solana
  ✔ should show complete CCIP transaction details Solana to EVM (7376.502278ms)
✔ e2e command show Solana (7376.757077ms)
▶ e2e command show Aptos
  ✔ should show complete CCIP transaction details Aptos to EVM (6804.432818ms)
✔ e2e command show Aptos (6804.604211ms)
﹣ e2e command show TON (0.056065ms) # SKIP
(node:4441) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
▶ formatCCIPError
  ✔ should return null for non-CCIPError instances (1.322547ms)
  ✔ should format CCIPError with code and message (0.450276ms)
  ✔ should include help section with recovery hint (0.155723ms)
  ✔ should include note section for transient errors (0.264478ms)
  ✔ should include retry timing for transient errors with retryAfterMs (0.312949ms)
  ✔ should not include note section for permanent errors (0.224081ms)
  ✔ should format error with structured output (0.247656ms)
  ✔ should include stack trace when verbose is true (0.347473ms)
  ✔ should not include stack trace when verbose is false (0.226526ms)
✔ formatCCIPError (5.039044ms)
ℹ tests 28
ℹ suites 12
ℹ pass 28
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 68037.591464
-------------------------------|---------|----------|---------|---------|---------------------------
File                           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s         
-------------------------------|---------|----------|---------|---------|---------------------------
All files                      |    71.6 |     77.2 |   57.74 |    71.6 |                           
 ccip-cli/src                  |   83.63 |    77.77 |      50 |   83.63 |                           
  index.ts                     |   83.63 |    77.77 |      50 |   83.63 | ...64,86-90,96-97,102-107 
 ccip-cli/src/commands         |   54.35 |     72.3 |    54.9 |   54.35 |                           
  index.ts                     |     100 |      100 |     100 |     100 |                           
  lane-latency.ts              |    75.7 |     90.9 |   33.33 |    75.7 | 41-51,58-65,99-105        
  manual-exec.ts               |    27.6 |      100 |       0 |    27.6 | 61-114,121-131,133-248    
  parse.ts                     |   57.14 |      100 |       0 |   57.14 | 46-50,57-64,66-91         
  send.ts                      |   16.29 |      100 |       0 |   16.29 | 52-153,160-167,169-356    
  show.ts                      |   88.76 |     62.5 |      60 |   88.76 | ...78-180,189-190,230-231 
  supported-tokens.ts          |   21.72 |      100 |       0 |   21.72 | ...99-195,197-252,254-267 
  token.ts                     |   22.72 |      100 |       0 |   22.72 | 24-53,60-67,69-132        
  types.ts                     |     100 |      100 |     100 |     100 |                           
  utils.ts                     |   85.29 |    73.38 |    92.3 |   85.29 | ...85-595,603-611,621-627 
 ccip-cli/src/providers        |   53.76 |    75.51 |   17.39 |   53.76 |                           
  aptos.ts                     |   53.65 |      100 |       0 |   53.65 | ...70,78-85,91-92,101-123 
  evm.ts                       |   46.03 |      100 |       0 |   46.03 | 20,31-63                  
  index.ts                     |   81.65 |    72.72 |      80 |   81.65 | 50-51,190-229             
  solana.ts                    |   50.42 |      100 |       0 |   50.42 | ...-71,79-85,89-90,99-117 
  sui.ts                       |   64.28 |      100 |       0 |   64.28 | 10-14                     
  ton.ts                       |   14.58 |      100 |       0 |   14.58 | 22-144                    
 ccip-sdk/src                  |   94.92 |    86.73 |   94.28 |   94.92 |                           
  chain.ts                     |   93.94 |    80.39 |   73.33 |   93.94 | ...44,1051,1140,1273-1283 
  commits.ts                   |     100 |    94.73 |     100 |     100 | 52                        
  execution.ts                 |   92.19 |     92.3 |     100 |   92.19 | 130-137,149-156           
  explorer.ts                  |     100 |      100 |     100 |     100 |                           
  extra-args.ts                |     100 |    86.66 |     100 |     100 | 169,204                   
  gas.ts                       |   88.81 |       50 |     100 |   88.81 | 100-111,133-137           
  http-status.ts               |     100 |      100 |     100 |     100 |                           
  index.ts                     |     100 |      100 |     100 |     100 |                           
  offchain.ts                  |   92.97 |    83.78 |     100 |   92.97 | ...37,157,172-174,176-182 
  requests.ts                  |   90.76 |    83.33 |     100 |   90.76 | ...64-368,433-434,438-439 
  supported-chains.ts          |     100 |      100 |     100 |     100 |                           
  types.ts                     |     100 |      100 |     100 |     100 |                           
  utils.ts                     |   95.55 |    90.26 |     100 |   95.55 | ...70,734-735,751,816-824 
 ccip-sdk/src/api              |   82.08 |    79.68 |   86.66 |   82.08 |                           
  index.ts                     |   82.08 |    79.68 |   86.66 |   82.08 | ...50-351,415-416,464-564 
 ccip-sdk/src/aptos            |    56.5 |    69.69 |   56.66 |    56.5 |                           
  exec.ts                      |   29.31 |      100 |       0 |   29.31 | 18-58                     
  hasher.ts                    |   76.31 |       80 |   66.66 |   76.31 | 19-38,52-58               
  index.ts                     |   58.02 |    75.34 |   59.52 |   58.02 | ...84-719,723-825,829-840 
  logs.ts                      |   78.52 |    57.44 |      75 |   78.52 | ...90-196,200-233,264-268 
  send.ts                      |    25.2 |      100 |       0 |    25.2 | 10-51,62-79,92-123        
  token.ts                     |   23.75 |       75 |     100 |   23.75 | 35-156                    
  types.ts                     |   65.62 |      100 |       0 |   65.62 | 25-32,64-88               
 ccip-sdk/src/errors           |   87.23 |     77.4 |   47.54 |   87.23 |                           
  CCIPError.ts                 |     100 |      100 |     100 |     100 |                           
  codes.ts                     |     100 |      100 |     100 |     100 |                           
  index.ts                     |     100 |      100 |     100 |     100 |                           
  recovery.ts                  |     100 |      100 |     100 |     100 |                           
  specialized.ts               |   84.46 |    72.72 |   44.82 |   84.46 | ...73,3294-3303,3324-3333 
  utils.ts                     |   94.44 |    81.48 |     100 |   94.44 | 15,17,22,24               
 ccip-sdk/src/evm              |   81.09 |    70.45 |   81.57 |   81.09 |                           
  const.ts                     |     100 |      100 |     100 |     100 |                           
  errors.ts                    |   86.42 |    79.22 |     100 |   86.42 | ...12-113,159-161,202-220 
  extra-args.ts                |   94.44 |    61.66 |     100 |   94.44 | ...82-183,208-209,326-338 
  fork.test.data.ts            |     100 |      100 |     100 |     100 |                           
  gas.ts                       |      98 |    53.84 |     100 |      98 | 72-73,75                  
  hasher.ts                    |     100 |    72.72 |     100 |     100 | 108,134,164               
  index.ts                     |   73.94 |    74.38 |   81.13 |   73.94 | ...75,1492-1533,1581-1588 
  logs.ts                      |   34.32 |    68.42 |      25 |   34.32 | ...13-214,229-258,275-302 
  messages.ts                  |   91.81 |    46.15 |     100 |   91.81 | ...47-248,257-258,282-283 
  offchain.ts                  |   56.25 |      100 |       0 |   56.25 | 10-16                     
  types.ts                     |     100 |    93.33 |     100 |     100 | 18                        
 ccip-sdk/src/evm/viem         |   77.72 |       92 |   69.23 |   77.72 |                           
  client-adapter.ts            |     100 |     92.3 |     100 |     100 | 48                        
  index.ts                     |     100 |      100 |     100 |     100 |                           
  wallet-adapter.ts            |   63.09 |     90.9 |   55.55 |   63.09 | ...6,53-73,91-124,131-157 
 ccip-sdk/src/hasher           |   94.29 |    78.94 |     100 |   94.29 |                           
  common.ts                    |     100 |      100 |     100 |     100 |                           
  hasher.ts                    |     100 |    66.66 |     100 |     100 | 19                        
  index.ts                     |     100 |      100 |     100 |     100 |                           
  merklemulti.ts               |   93.43 |       78 |     100 |   93.43 | ...59-260,306-307,315-316 
 ccip-sdk/src/shared           |   88.05 |    69.23 |     100 |   88.05 |                           
  bcs-codecs.ts                |   87.87 |    66.66 |     100 |   87.87 | 75-87,104-106             
  constants.ts                 |     100 |      100 |     100 |     100 |                           
 ccip-sdk/src/solana           |   52.77 |    69.06 |   54.76 |   52.77 |                           
  cleanup.ts                   |   12.22 |      100 |       0 |   12.22 | 29-229                    
  exec.ts                      |    9.43 |      100 |       0 |    9.43 | ...68-343,345-384,386-498 
  hasher.ts                    |   96.58 |    81.81 |     100 |   96.58 | 67-70                     
  index.ts                     |   72.93 |    74.01 |    64.7 |   72.93 | ...10,1514-1538,1542-1563 
  logs.ts                      |   74.19 |    27.27 |     100 |   74.19 | ...,50-51,53-54,56-88,119 
  offchain.ts                  |   62.22 |      100 |       0 |   62.22 | 29-45                     
  patchBorsh.ts                |   65.06 |    57.14 |      75 |   65.06 | 30-49,65-66,72-78         
  send.ts                      |   13.93 |      100 |       0 |   13.93 | ...57-246,259-325,327-366 
  types.ts                     |   74.46 |      100 |       0 |   74.46 | 36-47                     
  utils.ts                     |   54.27 |    77.77 |   54.54 |   54.27 | ...40-353,395-458,464-479 
 ccip-sdk/src/sui              |   31.59 |    88.88 |   17.85 |   31.59 |                           
  discovery.ts                 |   15.13 |      100 |       0 |   15.13 | 20-36,49-185,188-218      
  events.ts                    |   19.85 |      100 |       0 |   19.85 | ...18-275,280-398,407-428 
  hasher.ts                    |   98.16 |    66.66 |     100 |   98.16 | 33,49                     
  index.ts                     |    37.6 |    92.85 |   17.94 |    37.6 | ...61-862,866-867,871-872 
  objects.ts                   |   19.04 |      100 |       0 |   19.04 | ...04-119,133-183,194-336 
 ccip-sdk/src/sui/manuallyExec |   39.46 |      100 |       0 |   39.46 |                           
  encoder.ts                   |   47.67 |      100 |       0 |   47.67 | 42-86                     
  index.ts                     |    34.3 |      100 |       0 |    34.3 | 48-137                    
 ccip-sdk/src/ton              |   74.08 |    82.35 |   64.78 |   74.08 |                           
  exec.ts                      |     100 |      100 |     100 |     100 |                           
  hasher.ts                    |   77.95 |    77.77 |      75 |   77.95 | 99-107,155-186            
  index.ts                     |   69.74 |    75.86 |   52.27 |   69.74 | ...06,1213-1214,1221-1222 
  logs.ts                      |     100 |    98.43 |     100 |     100 | 56                        
  send.ts                      |   96.39 |    73.91 |     100 |   96.39 | 38-45                     
  types.ts                     |   77.94 |    69.23 |   66.66 |   77.94 | ...-73,91,118-131,133-136 
  utils.ts                     |   60.88 |    83.33 |    87.5 |   60.88 | ...55-261,269-327,329-332 
-------------------------------|---------|----------|---------|---------|---------------------------

}

const messagesInBatch = raw.messageBatch.map(decodeMessage)
const message = messagesInBatch.find((message) => message.messageId === messageId)!
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the behaviour if the message is not found? (in runtime this will become undefined)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should NEVER not be found, if API is doing what it should; if it can't, then it's expected the API itself will return an HTTP error. It's basically an invariant of the function of the endpoint, that it should include the message we're looking in the batch for its messageId


const proof = calculateManualExecProof(messagesInBatch, lane, messageId, raw.merkleRoot, this)

const rawMessage = raw.messageBatch.find((message) => message.messageId === messageId)!
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the behaviour if the rawMessage is not found? (in runtime this will become undefined)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same. The message MUST be there, if the API does what it's supposed to; any error should be thrown at http response level

offRamp,
version: CCIPVersion.V2_0,
encodedMessage: raw.encodedMessage,
verifications: (raw.ccvData ?? []).map((ccvData, i) => ({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest some defensive coding in case there is a bug in the API, which will raise an error earlier instead of passing it throgh the layers (which will be harder to investigate) . imho, we should validate that ccvData.length === verifierAddresses.length

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'd say it's not sdk's responsibility to verify behavior of the API, but just to assume and use it. It's more or less the same with RPC: we must assume a correctly working data source layer, otherwise nothing will ever be able to be achieved here. At most, we validate for things that CAN happen in normal operation

destChainSelector: bigint
version: string
}
| object
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why object?

Copy link
Collaborator Author

@andrevmatos andrevmatos Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's linter lang for {}, but it doesn't like the empty type; the difference between this union and just making all those properties optional, is that it tells TS that, if any is present, all of them are, while optionals I'd need to check one by one

sourceChainSelector: raw.sourceChainSelector,
destChainSelector: raw.destChainSelector,
onRamp: raw.onramp,
version: raw.version as CCIPVersion,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you validate the value like we do for other part in the code (validateChainFamily / validateMessageStatus) just for the sake of defensive coding

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't do much validation; in this case, I'd argue we WANT this endpoint to support "unexpected" versions, as this may allow for things to continue working optimistically in case the SDK is outdated with CCIP's version

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I agree, we do some validation elsewhere, also coming from the API, so maybe we should do it here. I'll implement

CCIPTimeoutError,
CCIPUnexpectedPaginationError,
} from '../errors/index.ts'
import { decodeMessageV1 } from '../evm/messages.ts'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move decodeMessageV1 out of evm/messages.ts to another file that doesn't import ./const.ts? Otherwise it will pull ABI files in the bundle even for users who are not using EVM (even users who only use CCIPAPIClient)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, good catch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants