Skip to content

fix(sdk): viem adapters accept wagmi's strongly-typed clients#127

Draft
aelmanaa wants to merge 1 commit intomainfrom
fix/viem-adapter-wagmi-types
Draft

fix(sdk): viem adapters accept wagmi's strongly-typed clients#127
aelmanaa wants to merge 1 commit intomainfrom
fix/viem-adapter-wagmi-types

Conversation

@aelmanaa
Copy link
Collaborator

@aelmanaa aelmanaa commented Feb 3, 2026

This pull request enhances the viem adapter support in the SDK, making it fully compatible with wagmi and RainbowKit clients, including OP Stack chains. The changes introduce new structural types (ViemClientLike, ViemWalletClientLike) to ensure broad compatibility with various client implementations, improve runtime validation, and update documentation and tests to reflect these improvements.

Viem Adapter Compatibility Improvements:

  • The SDK's fromViemClient and viemWallet adapters now accept any viem-compatible client, including those from wagmi and RainbowKit, by using new structural types (ViemClientLike, ViemWalletClientLike). This resolves previous TypeScript incompatibilities and makes the SDK work seamlessly with OP Stack chains and multi-chain setups. [1] [2] [3] [4] [5] [6] [7] [8]

  • Improved runtime validation in both fromViemClient and viemWallet to ensure that required properties like chain.id and account.address are present, providing clearer error messages for misconfigured clients. [1] [2] [3] [4]

Documentation Updates:

  • Expanded the documentation in docs/sdk/index.md to include integration examples for wagmi and RainbowKit, demonstrating usage with OP Stack chains and multi-chain configurations.

Testing Enhancements:

  • Added comprehensive tests to verify structural type acceptance, including support for minimal clients, frozen objects (wagmi pattern), and proper error handling for missing or invalid chain properties. [1] [2]

Changelog Update:

  • Updated the changelog to note that viem adapters now accept wagmi/RainbowKit clients, including OP Stack chains.

Version Bump:

  • Bumped the CLI version to reflect the new changes.

@aelmanaa aelmanaa requested a review from a team as a code owner February 3, 2026 12:23
@vercel
Copy link

vercel bot commented Feb 3, 2026

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

Project Deployment Actions Updated (UTC)
ccip-tools-ts Error Error Feb 4, 2026 0:58am

Request Review

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

👋 aelmanaa, thanks for creating this pull request!

To help reviewers, please consider creating future PRs as drafts first. This allows you to self-review and make any final changes before notifying the team.

Once you're ready, you can mark it as "Ready for review" to request feedback. Thanks!

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

Coverage Report

ℹ tests 654
ℹ suites 198
ℹ pass 654
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 64268.31902
-------------------------------|---------|----------|---------|---------|---------------------------
File                           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s         
-------------------------------|---------|----------|---------|---------|---------------------------
All files                      |    66.4 |    79.33 |    54.3 |    66.4 |                           
 ccip-cli/src                  |   86.45 |    83.33 |      50 |   86.45 |                           
  index.ts                     |   86.45 |    83.33 |      50 |   86.45 | 72-76,82-83,88-93         
 ccip-cli/src/commands         |   51.21 |    77.47 |      54 |   51.21 |                           
  index.ts                     |     100 |      100 |     100 |     100 |                           
  lane-latency.ts              |   67.74 |     87.5 |   33.33 |   67.74 | 23-37,44-51,85-91         
  manual-exec.ts               |   19.73 |      100 |       0 |   19.73 | 37-101,108-118,120-226    
  parse.ts                     |   41.79 |      100 |       0 |   41.79 | 22-26,33-40,42-67         
  send.ts                      |   11.42 |      100 |       0 |   11.42 | 30-131,138-145,147-315    
  show.ts                      |   90.35 |    63.82 |      60 |   90.35 | ...20-126,132-134,143-144 
  supported-tokens.ts          |   22.48 |      100 |       0 |   22.48 | ...94-186,188-243,245-258 
  token.ts                     |   22.72 |      100 |       0 |   22.72 | 24-53,60-67,69-132        
  types.ts                     |     100 |      100 |     100 |     100 |                           
  utils.ts                     |   85.27 |    80.83 |      92 |   85.27 | ...16-534,541-549,559-565 
 ccip-cli/src/providers        |   53.63 |       75 |   17.39 |   53.63 |                           
  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.49 |    72.09 |      80 |   81.49 | 49-50,188-227             
  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                  |   93.84 |    86.95 |   89.23 |   93.84 |                           
  chain.ts                     |   91.17 |    78.78 |   58.33 |   91.17 | ...08,787,846-855,974-984 
  commits.ts                   |     100 |    88.88 |     100 |     100 | 35,52                     
  execution.ts                 |   85.33 |      100 |      75 |   85.33 | 129-150                   
  explorer.ts                  |     100 |      100 |     100 |     100 |                           
  extra-args.ts                |     100 |    85.71 |     100 |     100 | 120,149                   
  gas.ts                       |   90.98 |       50 |     100 |   90.98 | 76-81,103-107             
  http-status.ts               |     100 |      100 |     100 |     100 |                           
  index.ts                     |     100 |      100 |     100 |     100 |                           
  offchain.ts                  |     100 |      100 |     100 |     100 |                           
  requests.ts                  |   86.71 |    80.21 |    87.5 |   86.71 | ...24,332,358-359,363-364 
  supported-chains.ts          |     100 |      100 |     100 |     100 |                           
  types.ts                     |     100 |      100 |     100 |     100 |                           
  utils.ts                     |   95.93 |    90.22 |     100 |   95.93 | ...99,663-664,680,745-753 
 ccip-sdk/src/api              |   97.21 |    77.19 |     100 |   97.21 |                           
  index.ts                     |   97.21 |    77.19 |     100 |   97.21 | ...23-224,304-305,369-370 
 ccip-sdk/src/aptos            |   58.02 |    69.93 |   59.37 |   58.02 |                           
  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                     |   59.14 |    74.07 |   61.36 |   59.14 | ...29-764,768-870,874-885 
  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                     |   69.72 |      100 |       0 |   69.72 | 25-32,77-101              
  utils.ts                     |     100 |      100 |     100 |     100 |                           
 ccip-sdk/src/errors           |   79.81 |    77.07 |    48.3 |   79.81 |                           
  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               |   71.85 |    72.66 |   45.53 |   71.85 | ...19,1727-1736,1744-1753 
  utils.ts                     |   94.52 |    78.57 |     100 |   94.52 | 16,18,23,25               
 ccip-sdk/src/evm              |   66.86 |    78.63 |    62.5 |   66.86 |                           
  const.ts                     |     100 |      100 |     100 |     100 |                           
  errors.ts                    |   82.48 |    78.46 |     100 |   82.48 | ...55-157,188-195,198-216 
  gas.ts                       |   97.98 |    53.84 |     100 |   97.98 | 71-72,74                  
  hasher.ts                    |     100 |     87.5 |     100 |     100 | 122                       
  index.ts                     |   58.99 |    85.94 |    56.6 |   58.99 | ...45,1452-1501,1538-1545 
  logs.ts                      |   33.99 |    46.66 |      25 |   33.99 | ...13-214,229-258,274-302 
  messages.ts                  |     100 |      100 |     100 |     100 |                           
  offchain.ts                  |   80.97 |    53.33 |      75 |   80.97 | ...51-153,157-171,197-202 
 ccip-sdk/src/evm/viem         |   81.22 |    92.85 |   69.23 |   81.22 |                           
  client-adapter.ts            |     100 |    92.85 |     100 |     100 | 49                        
  index.ts                     |     100 |      100 |     100 |     100 |                           
  wallet-adapter.ts            |   67.91 |     92.3 |   55.55 |   67.91 | ...7,54-74,92-125,132-158 
 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/solana           |   53.09 |    70.38 |   55.17 |   53.09 |                           
  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                     |   71.89 |    76.64 |   64.15 |   71.89 | ...89,1493-1517,1521-1542 
  logs.ts                      |   74.19 |    27.27 |     100 |   74.19 | ...,50-51,53-54,56-88,119 
  offchain.ts                  |   78.87 |     64.7 |      50 |   78.87 | ...,96-97,110-111,126-142 
  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.62 |    77.77 |   54.54 |   54.62 | ...37-350,392-455,461-476 
 ccip-sdk/src/sui              |    31.5 |    90.19 |   15.51 |    31.5 |                           
  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.37 |    94.87 |   14.63 |   37.37 | ...71-872,876-877,881-882 
  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              |   72.34 |    83.33 |   54.41 |   72.34 |                           
  exec.ts                      |     100 |      100 |     100 |     100 |                           
  hasher.ts                    |   77.95 |    77.77 |      75 |   77.95 | 99-107,155-186            
  index.ts                     |   70.47 |    75.47 |    41.3 |   70.47 | ...04,1111-1112,1119-1120 
  logs.ts                      |     100 |    98.43 |     100 |     100 | 56                        
  types.ts                     |   78.41 |    69.23 |   66.66 |   78.41 | ...-76,94,121-134,136-139 
  utils.ts                     |   60.88 |    83.72 |    87.5 |   60.88 | ...55-261,269-327,329-332 
-------------------------------|---------|----------|---------|---------|---------------------------

Copy link
Collaborator

@andrevmatos andrevmatos left a comment

Choose a reason for hiding this comment

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

I don't think these changes are needed, nor they improve the type safety of the fromViemClient function and friends

Rationale: parameters types in typescript functions (e.g. Abc in function foo(a: Abc) work as "constraints": they force the caller to pass values whose type match the required, and allow you to access properties of Abc inside the function;

When you convert that to a template, e.g. function foo<A extends Abc>(a: A), nothing changes from the caller nor the function perspective; it works virtually the same as the previous case, constraint-wise; The difference is: now, the CONCRETE type A can assume a different type than Abc, as long as it matches the constraint of being Abc or a specialization of it, and this CONCRETE type can then be used in other places, namely in other parameters constraints, in return type position, usually allowing further specializations, like conditional types, type mappings, etc.

Inside the function, you still can only access the properties which are common from Abc, as in the first, non-templated example; providing a default (<A extends Abc = Abc> doesn't change it, only assigns a default type to the type A (which can be Abc itself, or something else which matches the constraint) in case it can't be inferred automatically from the parameters.

In your case here, you're converting the function to a template generic, but not using the template variables for anything. So, it's effectively the same constraint as it was before. From this, it looks like you should be able to use the specialized types from wagmi with the current version exactly the same; again, template generics are only useful to capture the "concrete" types, and allow you to use them in other positions and/or map them to something else; constraint-wise, it should be the same, and the simpler types should be preferred. Unless you have another reason for converting this to the generics.

PabloMansanet
PabloMansanet previously approved these changes Feb 4, 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.

Looks good and well documented 👍 from a surface reading, because I don't know enough about the TS generics to comment further.

So the need for it, I'm not sure about. I'll defer to Andre for that one.

@aelmanaa aelmanaa marked this pull request as draft February 4, 2026 10:31
Use structural interfaces (ViemClientLike, ViemWalletClientLike) instead
of strict viem generic types to solve type invariance issues with:
- RainbowKit's getDefaultConfig() clients
- Multi-chain configs mixing L1 and OP Stack chains (baseSepolia, optimism)
- Wagmi's strongly-typed PublicClient/WalletClient

The root cause was TypeScript type invariance: OP Stack chains have
`type: "deposit"` transactions that L1 chains don't have, causing
incompatible union types in viem's generic PublicClient<T, C>.

Changes:
- Add ViemClientLike and ViemWalletClientLike structural interfaces
- Update fromViemClient() and viemWallet() to use structural types
- Add comprehensive JSDoc with RainbowKit + OP Stack examples
- Add unit tests for structural type acceptance
- Add RainbowKit Integration section to docs

No breaking changes - existing code continues to work.
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