CoW SDK
Test coverage
🌐 Supported Networks
The SDK supports all CoW Protocol enabled networks:
- Ethereum (1) -
SupportedChainId.MAINNET
- Gnosis Chain (100) -
SupportedChainId.GNOSIS_CHAIN
- Arbitrum One (42161) -
SupportedChainId.ARBITRUM_ONE
- Base (8453) -
SupportedChainId.BASE
- Polygon (137) -
SupportedChainId.POLYGON
- Avalanche (43114) -
SupportedChainId.AVALANCHE
- Lens (232) -
SupportedChainId.LENS
- BNB (56) -
SupportedChainId.BNB
- Linea (59144) -
SupportedChainId.LINEA (Under development)
- Plasma (9745) -
SupportedChainId.PLASMA (Under development)
- Sepolia (11155111) -
SupportedChainId.SEPOLIA (Testnet)
🔗 Related Resources
Getting Started
Usage Examples
React Examples:
Node.js Examples:
Installation
pnpm add @cowprotocol/cow-sdk
yarn add @cowprotocol/cow-sdk
CoW SDK
Using CoW Protocol, you can perform swaps, limit orders, TWAP orders, and many other operations.
The @cowprotocol/cow-sdk provides tools at different abstraction levels, allowing you to conveniently implement basic scenarios while maintaining the flexibility to control all possible cases.
In most cases, you will only need to use the Trading SDK
SDK Components
Core
TradingSdk - Main tool for swap and limit orders with built-in quote fetching, order signing, and posting
OrderSigningUtils - Utilities for signing orders and cancellations using cryptographic algorithms
OrderBookApi - Provides the ability to retrieve orders and trades from the CoW Protocol order book, as well as add and cancel them
MetadataApi - API for accessing order metadata and additional information
Advanced
v6 → v7 Migration Guide
The versions are 99% backward compatible. The only difference is that in v7 you need to set an adapter corresponding to the library you use: Viem, Ethers6, or Ethers5.
Before (v6):
import { SupportedChainId, TradingSdk, MetadataApi, OrderBookApi } from '@cowprotocol/cow-sdk'
const options = {}
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: 'YOUR_APP_CODE',
}, options)
After (v7):
import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
const options = {}
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: 'YOUR_APP_CODE',
}, options, adapter)
Most other packages (e.g., MetadataApi or BridgingSdk) have a parameter to set an adapter.
You can also set an adapter using setGlobalAdapter:
import { setGlobalAdapter, CowShedSdk } from '@cowprotocol/cow-sdk'
const adapter = {...}
setGlobalAdapter(adapter)
const cowShedSdk = new CowShedSdk()
You will likely also need to bind the SDK to your app's account state.
When the account or network changes in the app/wallet, it should be updated in the SDK as well.
Here's an example for WAGMI (see examples/react/wagmi):
import { useAccount, usePublicClient, useWalletClient } from 'wagmi'
import { useEffect, useState } from 'react'
import { ViemAdapter, ViemAdapterOptions } from '@cowprotocol/sdk-viem-adapter'
import { tradingSdk } from '../cowSdk.ts'
import { setGlobalAdapter } from '@cowprotocol/cow-sdk'
export function useBindCoWSdkToWagmi(): boolean {
const { chainId } = useAccount()
const { data: walletClient } = useWalletClient()
const publicClient = usePublicClient()
const [isSdkReady, setIsSdkReady] = useState(false)
useEffect(() => {
if (!walletClient || !chainId) return
setGlobalAdapter(
new ViemAdapter({
provider: publicClient,
walletClient,
} as unknown as ViemAdapterOptions),
)
tradingSdk.setTraderParams({ chainId })
setIsSdkReady(true)
}, [publicClient, walletClient, chainId])
return isSdkReady
}
Basic Use Case
This example demonstrates the main use case of creating a swap and shows how to:
- Get a quote
- Verify amounts
- Adjust swap parameters
- Sign and post an order
import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: 'YOUR_APP_CODE',
}, {}, adapter)
const parameters: TradeParameters = {
kind: OrderKind.SELL,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000',
}
const { quoteResults, postSwapOrderFromQuote } = await sdk.getQuote(parameters)
const buyAmount = quoteResults.amountsAndCosts.afterSlippage.buyAmount
if (confirm(`You will receive at least: ${buyAmount}. Proceed?`)) {
const orderId = await postSwapOrderFromQuote()
console.log('Order created, ID:', orderId)
}
This example demonstrates the simplest way to trade on CoW Protocol.
For more advanced use cases, you can use additional parameters such as receiver, partiallyFillable, validTo, and others.
Refer to the Trading SDK documentation for comprehensive details.
Developer Attribution (UTM Tracking)
The SDK automatically includes UTM tracking in all orders to attribute trading volume to developers. Default parameters:
{
utmSource: 'cowmunity',
utmMedium: 'cow-sdk@7.1.6',
utmCampaign: 'developer-cohort',
utmContent: '',
utmTerm: 'js'
}
Customize or disable via advancedSettings.appData.metadata.utm:
await sdk.getQuote(parameters, {
appData: {
metadata: {
utm: { utmContent: 'my-integration-v2' }
}
}
})
await sdk.getQuote(parameters, {
appData: {
metadata: {
utm: {}
}
}
})
Note: Providing any utm field gives you full control - the SDK will not add defaults.
Tip: Use utmContent for graffiti without affecting your appCode. The appCode parameter tracks your integration on CoW Protocol's Dune dashboards, while utmContent is available for custom identifiers or experimentation - all while attributing your volume to SDK integrators' collective impact.
Adapters
The CoW SDK supports multiple blockchain adapters to work with different Web3 libraries. You need to install and configure one of the following adapters:
Available Adapters
- EthersV6Adapter - For ethers.js v6
- EthersV5Adapter - For ethers.js v5
- ViemAdapter - For viem
Installation
pnpm add @cowprotocol/sdk-ethers-v6-adapter ethers
pnpm add @cowprotocol/sdk-ethers-v5-adapter ethers@^5.7.0
pnpm add @cowprotocol/sdk-viem-adapter viem
Adapter Setup Examples
EthersV6Adapter
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
import { JsonRpcProvider, Wallet } from 'ethers'
const provider = new JsonRpcProvider('YOUR_RPC_URL')
const wallet = new Wallet('YOUR_PRIVATE_KEY', provider)
const adapter = new EthersV6Adapter({ provider, signer: wallet })
EthersV5Adapter
import { EthersV5Adapter } from '@cowprotocol/sdk-ethers-v5-adapter'
import { ethers } from 'ethers'
const provider = new ethers.providers.JsonRpcProvider('YOUR_RPC_URL')
const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY', provider)
const adapter = new EthersV5Adapter({ provider, signer: wallet })
ViemAdapter
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { http, createPublicClient, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const account = privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
const transport = http('YOUR_RPC_URL')
const provider = createPublicClient({ chain: sepolia, transport })
const adapter = new ViemAdapter({ provider, signer: account })
Low-Level SDK Usage Example
This example demonstrates low-level API usage with a practical scenario:
exchanging 0.4 GNO for WETH on the Gnosis Chain network.
We will perform the following operations:
- Get a quote
- Sign the order
- Send the order to the order book
- Get the data of the created order
- Get trades for the order
- Cancel the order (signing + sending)
import { OrderBookApi, OrderSigningUtils, SupportedChainId, OrderKind } from '@cowprotocol/cow-sdk'
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
import { JsonRpcProvider, Wallet } from 'ethers'
const account = 'YOUR_WALLET_ADDRESS'
const chainId = 100
const provider = new JsonRpcProvider('YOUR_RPC_URL')
const wallet = new Wallet('YOUR_PRIVATE_KEY', provider)
const adapter = new EthersV6Adapter({ provider, signer: wallet })
const quoteRequest = {
sellToken: '0x6a023ccd1ff6f2045c3309768ead9e68f978f6e1',
buyToken: '0x9c58bacc331c9aa871afd802db6379a98e80cedb',
from: account,
receiver: account,
sellAmountBeforeFee: (0.4 * 10 ** 18).toString(),
kind: OrderKind.SELL,
}
const orderBookApi = new OrderBookApi({ chainId: SupportedChainId.GNOSIS_CHAIN })
async function main() {
const { quote } = await orderBookApi.getQuote(quoteRequest)
const orderSigningResult = await OrderSigningUtils.signOrder(quote, chainId, adapter)
const orderId = await orderBookApi.sendOrder({ ...quote, ...orderSigningResult })
const order = await orderBookApi.getOrder(orderId)
const trades = await orderBookApi.getTrades({ orderId })
const orderCancellationSigningResult = await OrderSigningUtils.signOrderCancellations([orderId], chainId, adapter)
const cancellationResult = await orderBookApi.sendSignedOrderCancellations({
...orderCancellationSigningResult,
orderUids: [orderId],
})
console.log('Results:', { orderId, order, trades, orderCancellationSigningResult, cancellationResult })
}