Skip to content

fix(cct-sdk): Harden Solana operation validation - #414

Merged
mervin-link merged 7 commits into
cct-sdkfrom
fix/refactor-ops
Sep 10, 2026
Merged

fix(cct-sdk): Harden Solana operation validation#414
mervin-link merged 7 commits into
cct-sdkfrom
fix/refactor-ops

Conversation

@mervin-link

Copy link
Copy Markdown
Collaborator

What

  • Bound Solana DeployToken.preMint to u64 maximum.
  • Reused base wallet execution preparation across legacy Solana operations.
  • Added duplicate collection validation for token pools, chain updates, and ALT additions
  • Added reusable Solana unique-value validators
  • Updated image-size lockfile resolution to patched @localnerve/image-size@2.1.2

Why

  • Prevent invalid Solana transactions, duplicate configuration entries, and vulnerable dependency resolution.

@mervin-link
mervin-link requested a review from a team as a code owner September 8, 2026 15:08
@vercel

vercel Bot commented Sep 8, 2026

Copy link
Copy Markdown

You must have Developer access to commit code to Chainlink Labs on Vercel. If you contact an administrator and receive Developer access, commit again to see your changes.

Learn more: https://vercel.com/docs/accounts/team-members-and-roles/access-roles#team-level-roles

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

CI Test Report

1 of 2574 tests did not pass (pass 2567, fail 1, cancelled 0, skipped 6) in 5m 54s

Failed suites: ccip-sdk/src/evm/integration.test.ts

Failed tests
test at ccip-sdk/src/evm/integration.test.ts:364:5
✖ should return fee tokens for a v1.5 OnRamp on base-sepolia (1813.268917ms)
  AssertionError [ERR_ASSERTION]: base-sepolia → chiado should be a legacy OnRamp
  + actual - expected
  
  + 'OnRamp'
  - 'EVM2EVMOnRamp'
  
      at TestContext.<anonymous> (file:///home/runner/work/ccip-tools-ts/ccip-tools-ts/ccip-sdk/src/evm/integration.test.ts:370:14)
      at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
      at async Test.run (node:internal/test_runner/test:1404:7)
      at async Suite.processPendingSubtests (node:internal/test_runner/test:969:7) {
    generatedMessage: false,
    code: 'ERR_ASSERTION',
    actual: 'OnRamp',
    expected: 'EVM2EVMOnRamp',
    operator: 'strictEqual',
    diff: 'simple'
  }
---------------------------------------|---------|----------|---------|---------|-------------------

Summary

ℹ tests 2574
ℹ suites 661
ℹ pass 2567
ℹ fail 1
ℹ cancelled 0
ℹ skipped 6
ℹ todo 0
ℹ duration_ms 354264.545924
Coverage report
File                                   | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------------------------------|---------|----------|---------|---------|-------------------
All files                              |   84.37 |    82.96 |    76.9 |   84.37 |                   
 ccip-cli/src                          |   90.42 |    59.25 |      75 |   90.42 |                   
  index.ts                             |   90.42 |    59.25 |      75 |   90.42 | ...73-174,180-185 
 ccip-cli/src/commands                 |   52.65 |    75.55 |    62.9 |   52.65 |                   
  index.ts                             |     100 |      100 |     100 |     100 |                   
  lane-latency.ts                      |   70.76 |    83.33 |   33.33 |   70.76 | ...,76-83,119-128 
  lane.ts                              |   86.98 |    68.42 |     100 |   86.98 | ...41-144,148-150 
  manual-exec.ts                       |   20.34 |      100 |       0 |   20.34 | ...39-149,151-347 
  parse.ts                             |    55.2 |      100 |       0 |    55.2 | 47-51,58-65,67-96 
  search.ts                            |   81.25 |      100 |       0 |   81.25 | 24-29             
  send.ts                              |   14.13 |      100 |       0 |   14.13 | ...09-237,239-552 
  show.ts                              |   75.68 |    63.75 |     100 |   75.68 | ...15-318,399-401 
  supported-tokens.ts                  |   17.93 |      100 |       0 |   17.93 | ...80-353,355-368 
  token.ts                             |   22.72 |      100 |       0 |   22.72 | ...3,60-67,69-132 
  types.ts                             |     100 |      100 |     100 |     100 |                   
  utils.ts                             |   87.89 |    79.59 |   96.66 |   87.89 | ...11-721,729-737 
 ccip-cli/src/commands/search          |   53.89 |    76.19 |    12.5 |   53.89 |                   
  messages.ts                          |   53.89 |    76.19 |    12.5 |   53.89 | ...36-258,260-295 
 ccip-cli/src/providers                |   53.37 |    86.45 |   21.73 |   53.37 |                   
  aptos.ts                             |   51.47 |      100 |       0 |   51.47 | ...,95-96,105-136 
  evm.ts                               |    36.3 |      100 |       0 |    36.3 | ...69-104,116-168 
  index.ts                             |   81.37 |    85.71 |    90.9 |   81.37 | ...20,290,344-392 
  solana.ts                            |   47.44 |      100 |       0 |   47.44 | ...02-103,112-137 
  sui.ts                               |    49.5 |      100 |       0 |    49.5 | ...57-258,267-301 
  ton.ts                               |   15.03 |      100 |       0 |   15.03 | 24-153            
 ccip-cli/src/providers/canton         |    85.4 |    77.89 |      68 |    85.4 |                   
  auth.ts                              |   82.41 |    73.01 |   53.33 |   82.41 | ...17-333,464-469 
  config.ts                            |   80.41 |    81.81 |     100 |   80.41 | 36-43,48-58       
  index.ts                             |     100 |      100 |     100 |     100 |                   
  wallet.ts                            |   92.93 |      100 |   85.71 |   92.93 | 172-184           
 ccip-sdk/src                          |   95.45 |     88.3 |    92.9 |   95.45 |                   
  chain.ts                             |   96.52 |    84.43 |   84.37 |   96.52 | ...2427,2460-2461 
  commits.ts                           |    90.9 |    81.25 |     100 |    90.9 | ...06,115-118,120 
  execution.ts                         |   93.13 |    88.23 |     100 |   93.13 | ...53-159,192-199 
  explorer.ts                          |     100 |      100 |     100 |     100 |                   
  extra-args.ts                        |     100 |    89.47 |     100 |     100 | 225,260,297,312   
  fetch.ts                             |   98.06 |    93.58 |   97.77 |   98.06 | ...-881,1127-1129 
  gas.ts                               |   85.14 |    86.04 |      75 |   85.14 | ...82-293,402-451 
  http-status.ts                       |     100 |      100 |     100 |     100 |                   
  index.ts                             |     100 |      100 |     100 |     100 |                   
  messages.ts                          |    79.2 |    47.16 |      40 |    79.2 | ...99-310,314-327 
  networks.ts                          |     100 |      100 |     100 |     100 |                   
  offchain.ts                          |   84.64 |    76.92 |     100 |   84.64 | ...18-227,236-237 
  requests.ts                          |    95.4 |    90.58 |     100 |    95.4 | ...54-655,680-685 
  supported-chains.ts                  |     100 |      100 |     100 |     100 |                   
  types.ts                             |     100 |      100 |     100 |     100 |                   
  utils.ts                             |    99.2 |    95.91 |     100 |    99.2 | ...12,217-218,220 
 ccip-sdk/src/api                      |   93.22 |    83.44 |   94.73 |   93.22 |                   
  index.ts                             |   93.22 |    83.44 |   94.73 |   93.22 | ...92-895,898-901 
 ccip-sdk/src/aptos                    |   78.76 |     78.4 |   76.19 |   78.76 |                   
  exec.ts                              |   29.31 |      100 |       0 |   29.31 | 18-58             
  hasher.ts                            |   75.89 |       80 |   66.66 |   75.89 | 17-36,50-56       
  index.ts                             |   68.84 |       80 |   67.44 |   68.84 | ...1072,1076-1087 
  logs.ts                              |   96.47 |    77.84 |    92.3 |   96.47 | ...1442-1444,1731 
  send.ts                              |    25.6 |      100 |       0 |    25.6 | ...2,63-80,93-125 
  token.ts                             |   23.75 |       75 |     100 |   23.75 | 35-156            
  types.ts                             |   65.97 |      100 |       0 |   65.97 | 26-33,65-89       
 ccip-sdk/src/canton                   |   45.32 |    76.16 |   31.66 |   45.32 |                   
  amount.ts                            |   92.59 |       70 |     100 |   92.59 | 22-23             
  ccv-addresses.ts                     |     100 |    91.07 |     100 |     100 | 13,30,64,67       
  defaults.ts                          |   99.28 |    90.24 |     100 |   99.28 | 93                
  events.ts                            |   45.38 |     52.5 |   23.52 |   45.38 | ...15-527,533-542 
  index.ts                             |   34.89 |    58.82 |   12.82 |   34.89 | ...2614,2617-2619 
  types.ts                             |   95.26 |      100 |      50 |   95.26 | 55-62             
  update-id.ts                         |   98.11 |    88.88 |     100 |   98.11 | 52                
 ccip-sdk/src/canton/authentication    |   93.05 |    79.31 |    92.3 |   93.05 |                   
  authorization-code.ts                |   89.83 |    84.31 |    90.9 |   89.83 | ...58-376,432-443 
  client-credentials.ts                |   91.28 |       75 |     100 |   91.28 | ...92-196,198-202 
  index.ts                             |    96.8 |       75 |     100 |    96.8 | 168-173           
  metadata.ts                          |   81.89 |    44.44 |      50 |   81.89 | ...55,73-78,93-94 
  static.ts                            |     100 |      100 |     100 |     100 |                   
  token-source.ts                      |   98.88 |    77.77 |     100 |   98.88 | 165-166           
  types.ts                             |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/canton/client            |    57.4 |    60.86 |   22.85 |    57.4 |                   
  client.ts                            |   55.62 |    59.09 |   22.85 |   55.62 | ...37-756,771-791 
  index.ts                             |     100 |      100 |     100 |     100 |                   
 ...dk/src/canton/explicit-disclosures |   74.81 |    69.35 |    55.1 |   74.81 |                   
  acs.ts                               |   87.36 |     69.1 |      90 |   87.36 | ...20,568,606-607 
  eds.ts                               |   54.34 |      100 |       0 |   54.34 | ...86-393,397-402 
 ccip-sdk/src/canton/token-metadata    |   61.37 |      100 |       0 |   61.37 |                   
  client.ts                            |   61.37 |      100 |       0 |   61.37 | 111-178,185-189   
 ...dk/src/canton/transfer-instruction |    52.4 |      100 |       0 |    52.4 |                   
  client.ts                            |    52.4 |      100 |       0 |    52.4 | 104-197,204-208   
 ccip-sdk/src/cct                      |     100 |    96.87 |     100 |     100 |                   
  errors.ts                            |     100 |       96 |     100 |     100 | 203               
  operation.ts                         |     100 |      100 |     100 |     100 |                   
  query.ts                             |     100 |      100 |     100 |     100 |                   
  token-manager.ts                     |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/cct/evm                  |   96.63 |    96.09 |   61.64 |   96.63 |                   
  index.ts                             |   95.37 |      100 |      44 |   95.37 | ...1381,1413-1416 
  operation.ts                         |     100 |      100 |     100 |     100 |                   
  query.ts                             |     100 |      100 |     100 |     100 |                   
  submit.ts                            |     100 |    79.16 |     100 |     100 | 28,52,68-69,87    
  validate.ts                          |     100 |      100 |     100 |     100 |                   
 .../cct/evm/artifacts/bytecode/V2_0_0 |     100 |      100 |     100 |     100 |                   
  burn-from-mint-token-pool.ts         |     100 |      100 |     100 |     100 |                   
  burn-mint-token-pool.ts              |     100 |      100 |     100 |     100 |                   
  burn-with-from-mint-token-pool.ts    |     100 |      100 |     100 |     100 |                   
  cross-chain-token.ts                 |     100 |      100 |     100 |     100 |                   
  erc20-lockbox.ts                     |     100 |      100 |     100 |     100 |                   
  lock-release-token-pool.ts           |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/cct/evm/lockbox          |     100 |      100 |     100 |     100 |                   
  contracts.ts                         |     100 |      100 |     100 |     100 |                   
 ...sdk/src/cct/evm/lockbox/operations |     100 |      100 |     100 |     100 |                   
  authorize-callers.ts                 |     100 |      100 |     100 |     100 |                   
  deploy-lockbox.ts                    |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/cct/evm/token            |   98.93 |     62.5 |   83.33 |   98.93 |                   
  contracts.ts                         |   98.93 |     62.5 |   83.33 |   98.93 | 51-52             
 ...k/src/cct/evm/token-admin-registry |     100 |      100 |     100 |     100 |                   
  contracts.ts                         |     100 |      100 |     100 |     100 |                   
 ...vm/token-admin-registry/operations |     100 |      100 |     100 |     100 |                   
  accept-admin.ts                      |     100 |      100 |     100 |     100 |                   
  get-supported-tokens.ts              |     100 |      100 |     100 |     100 |                   
  get-token-admin-registry.ts          |     100 |      100 |     100 |     100 |                   
  register-admin.ts                    |     100 |      100 |     100 |     100 |                   
  set-pool.ts                          |     100 |      100 |     100 |     100 |                   
  transfer-admin.ts                    |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/cct/evm/token-pool       |     100 |      100 |     100 |     100 |                   
  contracts.ts                         |     100 |      100 |     100 |     100 |                   
  rate-limit.ts                        |     100 |      100 |     100 |     100 |                   
  remote-pool.ts                       |     100 |      100 |     100 |     100 |                   
 .../src/cct/evm/token-pool/operations |   99.82 |    97.57 |     100 |   99.82 |                   
  add-remote-pool.ts                   |     100 |      100 |     100 |     100 |                   
  apply-allowlist-updates.ts           |     100 |    96.29 |     100 |     100 | 229               
  apply-chain-updates.ts               |     100 |      100 |     100 |     100 |                   
  deploy-token-pool.ts                 |     100 |    85.71 |     100 |     100 | 83-86             
  get-token-pool-remotes.ts            |     100 |      100 |     100 |     100 |                   
  get-token-pool-state.ts              |   98.61 |       95 |     100 |   98.61 | 282-285           
  remove-remote-pool.ts                |     100 |      100 |     100 |     100 |                   
  set-chain-rate-limiter-configs.ts    |     100 |    97.05 |     100 |     100 | 112               
  set-dynamic-config.ts                |     100 |      100 |     100 |     100 |                   
  set-rate-limit-admin.ts              |     100 |      100 |     100 |     100 |                   
  set-remote-pool.ts                   |     100 |      100 |     100 |     100 |                   
  transfer-ownership.ts                |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/cct/evm/token/operations |     100 |      100 |     100 |     100 |                   
  deploy-token.ts                      |     100 |      100 |     100 |     100 |                   
  get-burners.ts                       |     100 |      100 |     100 |     100 |                   
  get-minters.ts                       |     100 |      100 |     100 |     100 |                   
  is-burner.ts                         |     100 |      100 |     100 |     100 |                   
  is-minter.ts                         |     100 |      100 |     100 |     100 |                   
  mint.ts                              |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/cct/solana               |   99.74 |    97.03 |   98.03 |   99.74 |                   
  index.ts                             |   99.67 |      100 |   97.22 |   99.67 | 258-259,2425-2430 
  operation.ts                         |     100 |      100 |     100 |     100 |                   
  query.ts                             |     100 |      100 |     100 |     100 |                   
  serialize.ts                         |     100 |     92.3 |     100 |     100 | 27                
  submit.ts                            |     100 |    81.81 |     100 |     100 | 31,48,53,72       
  validate.ts                          |     100 |    98.34 |     100 |     100 | 284,391           
 ccip-sdk/src/cct/solana/programs      |     100 |      100 |     100 |     100 |                   
  alt.ts                               |     100 |      100 |     100 |     100 |                   
  fee-quoter.ts                        |     100 |      100 |     100 |     100 |                   
  router.ts                            |     100 |      100 |     100 |     100 |                   
  token-pool.ts                        |     100 |      100 |     100 |     100 |                   
  token.ts                             |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/cct/solana/token         |     100 |      100 |     100 |     100 |                   
  constants.ts                         |     100 |      100 |     100 |     100 |                   
 ...rc/cct/solana/token-admin-registry |     100 |      100 |     100 |     100 |                   
  constants.ts                         |     100 |      100 |     100 |     100 |                   
 ...na/token-admin-registry/operations |   99.61 |    98.75 |     100 |   99.61 |                   
  accept-admin.ts                      |     100 |      100 |     100 |     100 |                   
  append-to-lookup-table.ts            |     100 |      100 |     100 |     100 |                   
  create-lookup-table.ts               |     100 |      100 |     100 |     100 |                   
  get-supported-tokens.ts              |     100 |      100 |     100 |     100 |                   
  get-token-admin-registry.ts          |     100 |      100 |     100 |     100 |                   
  index.ts                             |     100 |      100 |     100 |     100 |                   
  ...override-pending-administrator.ts |     100 |      100 |     100 |     100 |                   
  register-admin.ts                    |   97.95 |    94.44 |     100 |   97.95 | 212-216           
  set-pool.ts                          |     100 |      100 |     100 |     100 |                   
  transfer-admin.ts                    |     100 |      100 |     100 |     100 |                   
 ...c/cct/solana/token-pool/operations |   99.63 |    98.49 |     100 |   99.63 |                   
  accept-ownership.ts                  |     100 |      100 |     100 |     100 |                   
  append-remote-pool-addresses.ts      |     100 |      100 |     100 |     100 |                   
  apply-chain-updates.ts               |     100 |    98.43 |     100 |     100 | 149               
  configure-allowlist.ts               |     100 |      100 |     100 |     100 |                   
  create-token-multisig.ts             |    95.9 |     92.5 |     100 |    95.9 | ...01-102,104-109 
  delete-chain-remote-config.ts        |     100 |      100 |     100 |     100 |                   
  deploy-token-pool.ts                 |     100 |      100 |     100 |     100 |                   
  edit-chain-remote-config.ts          |     100 |      100 |     100 |     100 |                   
  get-token-pool-remotes.ts            |     100 |      100 |     100 |     100 |                   
  get-token-pool-state.ts              |     100 |      100 |     100 |     100 |                   
  index.ts                             |     100 |      100 |     100 |     100 |                   
  init-chain-remote-config.ts          |     100 |      100 |     100 |     100 |                   
  provide-liquidity.ts                 |     100 |      100 |     100 |     100 |                   
  remove-from-allowlist.ts             |     100 |      100 |     100 |     100 |                   
  set-can-accept-liquidity.ts          |     100 |      100 |     100 |     100 |                   
  set-chain-rate-limit.ts              |   99.11 |    96.15 |     100 |   99.11 | 64-65             
  set-rate-limit-admin.ts              |     100 |      100 |     100 |     100 |                   
  set-rebalancer.ts                    |     100 |      100 |     100 |     100 |                   
  transfer-ownership.ts                |     100 |      100 |     100 |     100 |                   
  withdraw-liquidity.ts                |     100 |      100 |     100 |     100 |                   
 ...dk/src/cct/solana/token/operations |     100 |    98.39 |     100 |     100 |                   
  approve-token.ts                     |     100 |      100 |     100 |     100 |                   
  create-token-account.ts              |     100 |      100 |     100 |     100 |                   
  deploy-token.ts                      |     100 |      100 |     100 |     100 |                   
  get-token-info.ts                    |     100 |       70 |     100 |     100 | 69,80-81          
  index.ts                             |     100 |      100 |     100 |     100 |                   
  mint-tokens.ts                       |     100 |      100 |     100 |     100 |                   
  set-token-authority.ts               |     100 |      100 |     100 |     100 |                   
  update-metadata-authority.ts         |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/errors                   |   90.42 |    77.16 |   59.55 |   90.42 |                   
  CCIPError.ts                         |     100 |      100 |     100 |     100 |                   
  codes.ts                             |     100 |      100 |     100 |     100 |                   
  index.ts                             |     100 |      100 |     100 |     100 |                   
  pure.ts                              |     100 |       75 |     100 |     100 | 32                
  recovery.ts                          |     100 |      100 |     100 |     100 |                   
  specialized.ts                       |   88.26 |    73.91 |   57.36 |   88.26 | ...3636,3659-3668 
  utils.ts                             |   94.44 |    81.48 |     100 |   94.44 | 15,17,22,24       
 ccip-sdk/src/evm                      |   92.88 |    82.43 |   93.16 |   92.88 |                   
  const.ts                             |   98.66 |    92.85 |     100 |   98.66 | 122-123           
  errors.ts                            |   91.98 |    81.57 |     100 |   91.98 | ...85,239-242,247 
  extra-args.ts                        |    94.5 |    61.01 |     100 |    94.5 | ...11-212,328-340 
  fork.test.data.ts                    |     100 |      100 |     100 |     100 |                   
  gas.ts                               |   98.19 |    63.15 |     100 |   98.19 | 90-91,93          
  hasher.ts                            |     100 |     92.3 |     100 |     100 | 135               
  index.ts                             |   88.32 |    80.57 |    90.9 |   88.32 | ...2716,2871-2902 
  logs.ts                              |   99.16 |    92.02 |      90 |   99.16 | 69-70,75-76       
  messageCodec.ts                      |     100 |      100 |     100 |     100 |                   
  messages.ts                          |     100 |      100 |     100 |     100 |                   
  offchain.ts                          |    87.5 |    71.42 |     100 |    87.5 | 13-14             
  simulate.ts                          |     100 |    94.82 |     100 |     100 | 109-111,425       
  types.ts                             |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/evm/viem                 |   79.76 |    90.62 |   69.23 |   79.76 |                   
  client-adapter.ts                    |     100 |       90 |     100 |     100 | 48,74             
  index.ts                             |     100 |      100 |     100 |     100 |                   
  wallet-adapter.ts                    |   63.09 |     90.9 |   55.55 |   63.09 | ...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 | ...06-307,315-316 
 ccip-sdk/src/shared                   |   85.32 |    84.33 |   82.35 |   85.32 |                   
  bcs-codecs.ts                        |   79.07 |    60.86 |   66.66 |   79.07 | ...42-252,260-269 
  codec.ts                             |    94.3 |    93.22 |     100 |    94.3 | 139-140,178-186   
  constants.ts                         |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/solana                   |   79.13 |    75.73 |   84.34 |   79.13 |                   
  cleanup.ts                           |   26.95 |    66.66 |   33.33 |   26.95 | ...59-101,114-227 
  exec.ts                              |   69.11 |    62.96 |   66.66 |   69.11 | ...69-473,513-514 
  extra-args.ts                        |   59.49 |    76.47 |      60 |   59.49 | 86-122,132-190    
  fork.test.data.ts                    |     100 |      100 |     100 |     100 |                   
  gas.ts                               |   92.06 |    68.57 |     100 |   92.06 | ...,81-90,170-171 
  hasher.ts                            |   96.49 |    81.81 |     100 |   96.49 | 64-67             
  index.ts                             |   83.03 |    78.91 |   87.03 |   83.03 | ...2129,2133-2166 
  logs.ts                              |   87.79 |    74.07 |     100 |   87.79 | ...50-151,163-164 
  offchain.ts                          |     100 |      100 |     100 |     100 |                   
  patchBorsh.ts                        |   78.31 |       50 |     100 |   78.31 | ...47,65-66,72-78 
  send.ts                              |    77.6 |    33.33 |      80 |    77.6 | ...52-360,403-442 
  signatures-cache.ts                  |   79.78 |    71.15 |    87.5 |   79.78 | ...51-260,274-275 
  token-admin-registry.ts              |     100 |    96.29 |     100 |     100 | 27                
  types.ts                             |     100 |      100 |     100 |     100 |                   
  utils.ts                             |   81.56 |     77.1 |   83.33 |   81.56 | ...87-588,625-640 
 ccip-sdk/src/sui                      |   73.18 |    70.66 |   81.14 |   73.18 |                   
  discovery.ts                         |   47.37 |    48.27 |      60 |   47.37 | ...34-782,785-819 
  events.ts                            |   89.83 |    72.67 |     100 |   89.83 | ...19-626,685-698 
  exec.ts                              |   30.71 |      100 |       0 |   30.71 | 37-89,101-153     
  hasher.ts                            |   98.19 |    66.66 |     100 |   98.19 | 35,51             
  index.ts                             |   76.12 |    70.47 |   79.68 |   76.12 | ...2314,2330-2331 
  logs.ts                              |   97.89 |    74.02 |     100 |   97.89 | ...62-165,186-187 
  objects.ts                           |    54.6 |    83.33 |   83.33 |    54.6 | ...57-313,324-467 
  types.ts                             |     100 |      100 |     100 |     100 |                   
 ccip-sdk/src/sui/manuallyExec         |   53.36 |       75 |      50 |   53.36 |                   
  encoder.ts                           |    83.9 |    66.66 |     100 |    83.9 | 51-58,73-77,82    
  index.ts                             |   33.82 |      100 |       0 |   33.82 | 47-136            
 ccip-sdk/src/ton                      |      86 |    80.53 |   88.28 |      86 |                   
  exec.ts                              |     100 |      100 |     100 |     100 |                   
  extra-args.ts                        |   98.66 |    72.72 |     100 |   98.66 | 156-157,222       
  hasher.ts                            |   78.07 |    77.77 |      75 |   78.07 | 100-108,156-187   
  index.ts                             |   84.81 |     79.6 |   79.03 |   84.81 | ...2111,2118-2119 
  logs.ts                              |   93.84 |    83.43 |     100 |   93.84 | ...09-616,672-675 
  send.ts                              |   95.52 |    66.66 |     100 |   95.52 | 37-44,188         
  ton-cache.ts                         |     100 |    96.55 |     100 |     100 | 102               
  types.ts                             |   91.24 |    81.25 |     100 |   91.24 | ...61-63,71-74,92 
  utils.ts                             |    63.1 |    77.77 |    90.9 |    63.1 | ...37-395,397-400 
 scripts                               |   87.95 |    63.38 |     100 |   87.95 |                   
  test-endpoints.ts                    |   97.98 |    72.72 |     100 |   97.98 | 137-139           
  useResource.ts                       |   83.57 |    61.66 |     100 |   83.57 | ...81-286,301-302 
---------------------------------------|---------|----------|---------|---------|-------------------

@aelmanaa

aelmanaa commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

✅ APPROVE-WITH-NITS — 0 blockers, 0 correctness majors

Summary: Correct (mechanical refactor + new input validations are grounded on-chain), type-safe (tsc green), green (all non-metaplex tests pass). Extracts 3 reusable dedup validators (validateUniquePublicKeys, validateUniqueChainSelectors, validateUniqueHexBytes) into neutral validate.ts and rewires ~8 Solana ops to adopt the pre-existing base helper prepareWalletExecution.

Key Verification:

  • Mechanical refactor is faithful — prepareWalletExecution is pre-existing (added feat(cct-sdk): Add edit chain remote config solana op #340, used by ~7 ops); this brings 8 stragglers in line. Removed inline code is byte-for-byte the helper body.
  • Shared-util pattern correct: validators live in neutral validate.ts (parity with EVM), no op imports another op's logic, no public-API widening.
  • Type-safe: tsc -p tsconfig.build.json --noEmit → 0 errors.
  • Grounded on-chain: new dedup checks mirror the Solana programs (duplicate allowlist entries revert AllowlistKeyAlreadyExisted, duplicate remoteChainSelector reverts on PDA init).

Live Devnet Proofs:

  • Rewired deployTokenPool executes on-chain: pool deployed, tx 2ooCAfc2…, err: null.
  • New dedup rejections fire: deployTokenPool allowlist [A,A]CCTParamsInvalidError "must not contain duplicate addresses"; applyChainUpdates duplicate selectors → error (with index [1]).
  • CI gate: npm ci exit 0, lint ✓, typecheck ✓. (One note: selectors.ts out of date — this is trunk-wide drift, not from this PR; npm run generate fixes it.)

⚠️ One real issue: packaging (comment 1 below) — the commit bundles ~5 behavior changes under a "refactor" label. Before merge: split/relabel and apply the index-naming DX fix (comment 2).

@aelmanaa

aelmanaa commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

[COMMENT 1/4] 🔴 Major (Packaging) — "Refactor" commit bundles 5 behavior changes

Problem: This single commit labeled "fix: refactor solana ops" quietly bundles multiple behavior changes, none flagged or separately justified:

  1. append-to-lookup-table.ts:172,183-193 — Guard changed from .every(...) to .some(...)

    • OLD: Proceeds if ALL canonical CCIP addresses already in ALT → duplicates allowed
    • NEW: Rejects if ANY canonical CCIP address already in ALT
    • Also new: Loop rejecting additionalAddresses already in ALT or duplicated
    • Impact: Inputs that previously reached submission now reject
  2. deploy-token-pool.ts — New allowlist dedup validation (rejects [A,A])

  3. apply-chain-updates.ts — New chain-selector dedup validation (rejects duplicate remoteChainSelector)

  4. edit-chain-remote-config.ts — New remote-pool-address hex dedup validation

  5. deploy-token.tspreMint now bounded to [1n, U64_MAX] with message change

    • OLD message: "must be a positive bigint"
    • NEW message: "must be a bigint between 1 and 18446744073709551615"
    • Impact: SDK consumers asserting on the old message break silently

Grounding: All are defensible (new checks mirror on-chain program behavior or established EVM policy), but they're behavior changes that deserve their own commits with rationales.

Live-Proven Behavior Differences (real op code, OLD vs NEW):

Input OLD (cct-sdk) NEW (branch)
preMint = 2^300 (valid bigint, > U64_MAX) passes CCTParamsInvalidError "must be a bigint between 1 and 18446744073709551615"
ALT holds 1 of 10 canonical CCIP addresses passes (would duplicate) CCTParamsInvalidError "lookup table already contains canonical CCIP addresses"
remotePoolAddresses = ["abab","abab"] passes CCTParamsInvalidError "must not contain…"

Fix: Split the commit into:

  1. refactor(cct-sdk): Extract wallet-execution prep + reusable validators (mechanical, no behavior change)
  2. fix(cct-sdk): Bound DeployToken.preMint to u64 maximum (+ changelog the message change)
  3. fix(cct-sdk): Reject partial canonical CCIP address blocks in ALT (append-to-lookup-table guard change)
  4. fix(cct-sdk): Add duplicate collection validation to pool/chain operations (the 3 dedup additions)

Changelog action: If the preMint message change lands, update CHANGELOG.md with the SDK impact (version bump?).

Locations:

  • deploy-token.ts:257
  • append-to-lookup-table.ts:172,183-193
  • deploy-token-pool.ts:117
  • apply-chain-updates.ts:231,237
  • edit-chain-remote-config.ts

@aelmanaa

aelmanaa commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

[COMMENT 2/4] 🔴 Major (DX) — Inconsistent error parameter naming in dedup validators

Problem: The three new dedup validators blame errors differently, making some duplicates hard to identify:

Current Behavior:

Validator Input Error Message Impact
validateUniqueChainSelectors [sel, sel, sel2] "remoteChainSelectorsToRemove[1]: must not contain duplicate chain selectors" Good — tells caller which index is the duplicate
validateUniquePublicKeys [A, A, B] "allowlist: must not contain duplicate addresses" Hard to debug — caller must eyeball whole array
validateUniqueHexBytes ["abab", "abab"] "remotePoolAddresses: must not contain duplicate hex values" Hard to debug — caller must eyeball whole array

Live Example (Proven Above):

Input: deployTokenPool allowlist [A, A, B]
OLD error: "Invalid deployTokenPool parameter "allowlist": must not contain duplicate addresses"
                                              ^^^^^^^^^ — no index, caller guesses which is duplicate

Fix: Update validateUniquePublicKeys and validateUniqueHexBytes to iterate and throw at ${param}[${i}], matching the selector validator:

// validate.ts:98 — validateUniquePublicKeys
export function validateUniquePublicKeys(
  operation: string,
  param: string,
  publicKeys: PublicKey[],
): void {
  const seen = new Set<string>()
  for (const [i, pk] of publicKeys.entries()) {
    const key = pk.toBase58()
    if (seen.has(key)) {
      throw new CCTParamsInvalidError(
        operation,
        `${param}[${i}]`,  // ← ADD: name the offending index
        'must not contain duplicate addresses'
      )
    }
    seen.add(key)
  }
}

Cost: Updates to 3 test assertions (replace bare param with indexed param or .startsWith):

  • deploy-token-pool.test.ts — assert 'allowlist[1]' instead of 'allowlist'
  • configure-allowlist.test.ts — assert 'add[1]' instead of 'add'
  • remove-from-allowlist.test.ts — assert 'remove[1]' instead of 'remove'

Recommendation: Apply the fix and update test assertions in the same commit (comment 1: as part of the dedup-addition split).

Locations:

  • validate.ts:98 (validateUniquePublicKeys)
  • validate.ts:130 (validateUniqueHexBytes)
  • Test updates: deploy-token-pool.test.ts, configure-allowlist.test.ts, remove-from-allowlist.test.ts

@aelmanaa

aelmanaa commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

[COMMENT 3/4] 🟡 Low (DX) — Wording inconsistency in dedup error messages

Problem: The three dedup validators use inconsistent nouns for what they're checking:

validateUniqueChainSelectors   "must not contain duplicate chain selectors"
validateUniquePublicKeys       "must not contain duplicate addresses"
validateUniqueHexBytes         "must not contain duplicate hex values"  // ← too generic

When validateUniqueHexBytes is called for remotePoolAddresses, the message says "duplicate hex values" instead of "duplicate remote pool addresses" — losing the semantic domain the caller passed in.

Impact: Minimal — the message is technically correct (they are hex values), but less actionable than peer validators.

Fix: Update the message to name the domain concept:

// validate.ts:130
export function validateUniqueHexBytes(operation: string, param: string, values: Buffer[]): void {
  if (new Set(values.map((value) => value.toString('hex'))).size !== values.length) {
    throw new CCTParamsInvalidError(
      operation,
      param,
      // ← e.g., if param='remotePoolAddresses', this becomes "must not contain duplicate remote pool addresses"
      `must not contain duplicate ${param.includes('Pool') ? 'remote pool addresses' : 'addresses'}`
    )
  }
}

OR (simpler — let the caller provide context in the error):

Simply update the call sites to pre-pend the semantic noun:

// edit-chain-remote-config.ts — pass clearer context
validateUniqueHexBytes(this.name, 'remotePoolAddresses (hex)', params.remotePoolAddresses)

Then the message becomes: "remotePoolAddresses (hex): must not contain duplicate hex values" — still not perfect, but the caller knows what was validated.

Recommendation: Apply the simpler approach (let validators keep generic messages, but rename the param passed to them if needed for clarity). This avoids hardcoding business logic into validate.ts.

Location: validate.ts:130 (validateUniqueHexBytes message and/or call sites in edit-chain-remote-config.ts)

@aelmanaa

aelmanaa commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

[COMMENT 4/4] 🔵 Nits — JSDoc and documentation gaps

(a) validateUniqueChainSelectors silently skips non-bigint entries

Current JSDoc:

/**
 * Asserts bigint chain selectors do not contain duplicates.
 * @throws CCTParamsInvalidError if a chain selector is duplicated.
 */
export function validateUniqueChainSelectors(...): void

Problem: The function iterates with if (typeof selector === 'bigint' && seen.has(selector)) — it silently skips non-bigint entries and only detects duplicates if they're both bigint. Today this is safe because every selector is re-validated downstream by validateBigInt, but future reuse could inherit a silent gap.

Fix: Add a one-line JSDoc note:

/**
 * Asserts bigint chain selectors do not contain duplicates.
 * @remarks Silently ignores non-bigint entries; relies on downstream `validateBigInt` for type safety.
 * @throws CCTParamsInvalidError if a chain selector is duplicated.
 */

Location: validate.ts:106

(b) Ops don't document the new dedup rejections

The new dedup validators aren't surfaced in op @remarks, so TypeDoc readers discover them only on runtime failure.

Fix: Add one-line @remarks to affected op classes:

// token-pool/operations/deploy-token-pool.ts
/**
 * Initializes a Solana token pool, optionally configuring an allowlist.
 * @remarks The allowlist must not contain duplicate addresses.
 */
export class DeployTokenPool extends SolanaOperation { ... }

// token-pool/operations/apply-chain-updates.ts
/**
 * Applies chain configuration updates to a Solana token pool.
 * @remarks Chain selectors to add and remove must not contain duplicates.
 */
export class ApplyChainUpdates extends SolanaOperation { ... }

Locations:

  • deploy-token-pool.ts (class JSDoc)
  • apply-chain-updates.ts (class JSDoc)
  • configure-allowlist.ts (class JSDoc — if not already documented)
  • remove-from-allowlist.ts (class JSDoc — if not already documented)

(c) DeployToken preMint documentation incomplete

Current JSDoc:

/** Initial supply in base units. Requires preMintRecipient. */
preMint?: bigint

Problem: The new validation adds a [1n, U64_MAX] range, but the field doc doesn't mention it — --help and TypeDoc readers won't know the bounds.

Fix: Update the field JSDoc:

/**
 * Initial supply in base units, between 1 and 2^64 - 1 (u64 maximum).
 * Requires preMintRecipient if provided.
 */
preMint?: bigint

Location: deploy-token.ts (BaseDeployTokenParams.preMint field JSDoc)

These are all documentation-only polish — the code is correct, but these will help future maintainers and SDK users.

@mervin-link mervin-link changed the title fix(cct-sdk): Refactor Solana ops fix(cct-sdk): Harden Solana operation validation Sep 9, 2026
@mervin-link

Copy link
Copy Markdown
Collaborator Author

✅ APPROVE-WITH-NITS — 0 blockers, 0 correctness majors

Summary: Correct (mechanical refactor + new input validations are grounded on-chain), type-safe (tsc green), green (all non-metaplex tests pass). Extracts 3 reusable dedup validators (validateUniquePublicKeys, validateUniqueChainSelectors, validateUniqueHexBytes) into neutral validate.ts and rewires ~8 Solana ops to adopt the pre-existing base helper prepareWalletExecution.

Key Verification:

  • Mechanical refactor is faithful — prepareWalletExecution is pre-existing (added feat(cct-sdk): Add edit chain remote config solana op #340, used by ~7 ops); this brings 8 stragglers in line. Removed inline code is byte-for-byte the helper body.
  • Shared-util pattern correct: validators live in neutral validate.ts (parity with EVM), no op imports another op's logic, no public-API widening.
  • Type-safe: tsc -p tsconfig.build.json --noEmit → 0 errors.
  • Grounded on-chain: new dedup checks mirror the Solana programs (duplicate allowlist entries revert AllowlistKeyAlreadyExisted, duplicate remoteChainSelector reverts on PDA init).

Live Devnet Proofs:

  • Rewired deployTokenPool executes on-chain: pool deployed, tx 2ooCAfc2…, err: null.
  • New dedup rejections fire: deployTokenPool allowlist [A,A]CCTParamsInvalidError "must not contain duplicate addresses"; applyChainUpdates duplicate selectors → error (with index [1]).
  • CI gate: npm ci exit 0, lint ✓, typecheck ✓. (One note: selectors.ts out of date — this is trunk-wide drift, not from this PR; npm run generate fixes it.)

⚠️ One real issue: packaging (comment 1 below) — the commit bundles ~5 behavior changes under a "refactor" label. Before merge: split/relabel and apply the index-naming DX fix (comment 2).

@aelmanaa Addressed all your comments.

@mervin-link
mervin-link merged commit 2cd49b2 into cct-sdk Sep 10, 2026
2 of 4 checks passed
@mervin-link
mervin-link deleted the fix/refactor-ops branch September 10, 2026 07:02
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