Adapters
Connect CoW Protocol SDK with different Ethereum libraries
Overview
Adapters provide a unified interface for the CoW Protocol SDK to work with different Ethereum libraries. They abstract away library-specific implementations, allowing you to use your preferred web3 library while maintaining consistent SDK functionality.
Available Adapters
The SDK provides three official adapters:
Viem : Modern, lightweight TypeScript library
Ethers v6 : Latest version of the popular Ethers library
Ethers v5 : Legacy Ethers version for existing projects
ViemAdapter
The ViemAdapter connects the SDK to Viem , a modern TypeScript Ethereum library with excellent type safety and tree-shaking support.
Installation
npm install @cowprotocol/sdk-viem-adapter viem
Setup
import { createPublicClient , http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { setGlobalAdapter } from '@cowprotocol/cow-sdk'
// Create a public client (provider)
const publicClient = createPublicClient ({
chain: mainnet ,
transport: http ( 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY' ),
})
// Create an account from private key
const account = privateKeyToAccount ( '0x...' )
// Create the adapter
const adapter = new ViemAdapter ({
provider: publicClient ,
signer: account ,
})
// Set as global adapter
setGlobalAdapter ( adapter )
Using with WalletClient
If you already have a WalletClient (e.g., from Wagmi or RainbowKit):
import { createWalletClient , custom } from 'viem'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
const walletClient = createWalletClient ({
chain: mainnet ,
transport: custom ( window . ethereum ),
})
const adapter = new ViemAdapter ({
provider: publicClient ,
walletClient ,
})
EthersV6Adapter
The EthersV6Adapter integrates with Ethers.js v6, the latest major version with improved TypeScript support and modern JavaScript features.
Installation
npm install @cowprotocol/sdk-ethers-v6-adapter ethers@^6
Setup
import { JsonRpcProvider , Wallet } from 'ethers'
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
import { setGlobalAdapter } from '@cowprotocol/cow-sdk'
// Create provider
const provider = new JsonRpcProvider ( 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY' )
// Create wallet
const wallet = new Wallet ( '0x...' , provider )
// Create adapter
const adapter = new EthersV6Adapter ({
provider ,
signer: wallet ,
})
setGlobalAdapter ( adapter )
Using RPC URL Directly
You can pass an RPC URL string instead of a provider instance:
const adapter = new EthersV6Adapter ({
provider: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY' ,
signer: wallet ,
})
Browser Wallet Integration
import { BrowserProvider } from 'ethers'
const provider = new BrowserProvider ( window . ethereum )
const signer = await provider . getSigner ()
const adapter = new EthersV6Adapter ({
provider ,
signer ,
})
EthersV5Adapter
The EthersV5Adapter supports Ethers.js v5 for projects that haven’t migrated to v6.
Installation
npm install @cowprotocol/sdk-ethers-v5-adapter ethers@^5
Setup
import { ethers } from 'ethers'
import { EthersV5Adapter } from '@cowprotocol/sdk-ethers-v5-adapter'
import { setGlobalAdapter } from '@cowprotocol/cow-sdk'
// Create provider
const provider = new ethers . providers . JsonRpcProvider (
'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY'
)
// Create wallet
const wallet = new ethers . Wallet ( '0x...' , provider )
// Create adapter
const adapter = new EthersV5Adapter ({
provider ,
signer: wallet ,
})
setGlobalAdapter ( adapter )
Browser Integration (v5)
const provider = new ethers . providers . Web3Provider ( window . ethereum )
const signer = provider . getSigner ()
const adapter = new EthersV5Adapter ({
provider ,
signer ,
})
Adapter Interface
All adapters implement a common interface from @cowprotocol/sdk-common:
Common Methods
// Get network chain ID
await adapter . getChainId ()
// Get contract bytecode
await adapter . getCode ( address )
// Get transaction receipt
await adapter . getTransactionReceipt ( hash )
// Read contract data
await adapter . readContract ({
address: contractAddress ,
abi: contractAbi ,
functionName: 'balanceOf' ,
args: [ userAddress ],
})
// Get contract instance
const contract = adapter . getContract ( address , abi )
Signer Methods
// Access the signer
const signer = adapter . signer
// Get signer address
const address = await signer . getAddress ()
// Sign typed data (EIP-712)
const signature = await signer . signTypedData (
domain ,
types ,
message
)
// Send transaction
const tx = await signer . sendTransaction ({
to: recipientAddress ,
value: amount ,
})
Dynamic Signer Management
All adapters support changing the signer after initialization:
// Create adapter without signer
const adapter = new ViemAdapter ({ provider: publicClient })
setGlobalAdapter ( adapter )
// Later, set the signer
const account = privateKeyToAccount ( '0x...' )
adapter . setSigner ( account )
Choosing an Adapter
Starting a new project with modern TypeScript
Bundle size is a concern (Viem is smaller)
You want the best TypeScript experience
Using Next.js, Wagmi, or RainbowKit
Use EthersV6Adapter when...
You’re already using Ethers v6 in your project
You need the latest Ethers features
Migrating from v5 to v6
Use EthersV5Adapter when...
You have an existing project on Ethers v5
Dependencies require Ethers v5
You’re not ready to migrate to v6
Best Practices
Set Global Adapter Early Call setGlobalAdapter() before initializing any SDK classes to ensure all components use the correct adapter.
Reuse Adapter Instances Create one adapter instance and reuse it across your application to avoid unnecessary overhead.
Handle Provider Changes When users switch networks or accounts, update the adapter using setProvider() or setSigner() methods.
Type Safety Leverage TypeScript’s type inference with adapters for compile-time safety when working with contract ABIs.
Next Steps
Last modified on March 4, 2026