Node.js Usage
This guide shows you how to use the CoW Protocol SDK in Node.js environments, including backend services, scripts, and automation tools.Installation
Choose your preferred Ethereum library:Copy
Ask AI
npm install @cowprotocol/cow-sdk @cowprotocol/sdk-ethers-v6-adapter ethers dotenv
Environment Setup
Create a.env file to store your configuration:
.env
Copy
Ask AI
RPC_URL=https://sepolia.gateway.tenderly.co
PRIVATE_KEY=0x...
CHAIN_ID=11155111
Basic Script
Copy
Ask AI
import 'dotenv/config'
import { JsonRpcProvider, Wallet } from 'ethers'
import {
setGlobalAdapter,
SupportedChainId,
TradingSdk,
OrderKind,
WRAPPED_NATIVE_CURRENCIES,
} from '@cowprotocol/cow-sdk'
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
const RPC_URL = process.env.RPC_URL || 'https://sepolia.gateway.tenderly.co'
const PRIVATE_KEY = process.env.PRIVATE_KEY
const DEFAULT_SELL_AMOUNT = '0.1'
async function main() {
if (!PRIVATE_KEY) {
throw new Error('PRIVATE_KEY environment variable is required')
}
const chainId = SupportedChainId.SEPOLIA
// Setup provider and wallet
const provider = new JsonRpcProvider(RPC_URL, chainId)
const wallet = new Wallet(PRIVATE_KEY, provider)
// Setup CoW Protocol adapter
const adapter = new EthersV6Adapter({ provider, signer: wallet })
setGlobalAdapter(adapter)
// Initialize SDK
const sdk = new TradingSdk({
chainId,
appCode: 'NodeScript',
signer: wallet,
})
// Define tokens
const WETH = WRAPPED_NATIVE_CURRENCIES[chainId]
const USDC = {
address: '0xbe72E441BF55620febc26715db68d3494213D8Cb',
decimals: 18,
}
const owner = (await wallet.getAddress()) as `0x${string}`
const amount = Math.round(
Number(DEFAULT_SELL_AMOUNT) * 10 ** WETH.decimals
).toString()
const slippageBps = 50
console.log('Owner:', owner)
console.log('Getting quote...')
// Get quote
const quoteAndPost = await sdk.getQuote({
chainId,
kind: OrderKind.SELL,
owner,
amount,
sellToken: WETH.address,
sellTokenDecimals: WETH.decimals,
buyToken: USDC.address,
buyTokenDecimals: USDC.decimals,
slippageBps,
})
console.log('Quote received')
console.log('Buy amount:', quoteAndPost.quoteResults.amountsAndCosts.afterNetworkCosts.buyAmount)
// Post order
console.log('Posting order...')
const result = await quoteAndPost.postSwapOrderFromQuote({})
console.log('Order posted successfully!')
console.log('Order ID:', result.orderId)
console.log('Explorer:', `https://explorer.cow.fi/sepolia/orders/${result.orderId}`)
}
main().catch((error) => {
console.error('Error:', error)
process.exit(1)
})
Run the Script
Copy
Ask AI
ts-node index.ts
# or with tsx
npx tsx index.ts
Advanced Patterns
Automated Trading Bot
Create a simple trading bot that monitors prices:bot.ts
Copy
Ask AI
import { TradingSdk, OrderKind } from '@cowprotocol/cow-sdk'
class TradingBot {
constructor(private sdk: TradingSdk) {}
async monitorAndTrade() {
setInterval(async () => {
try {
const quote = await this.getQuote()
const price = this.calculatePrice(quote)
if (this.shouldTrade(price)) {
await this.executeTrade(quote)
}
} catch (error) {
console.error('Error in trading loop:', error)
}
}, 60000) // Check every minute
}
private async getQuote() {
return this.sdk.getQuote({
// ... quote parameters
})
}
private calculatePrice(quote: any): number {
const buyAmount = Number(quote.quoteResults.amountsAndCosts.afterNetworkCosts.buyAmount)
const sellAmount = Number(quote.quoteResults.orderToSign.sellAmount)
return buyAmount / sellAmount
}
private shouldTrade(price: number): boolean {
// Implement your trading logic
const targetPrice = 2000 // Example: WETH to USDC price
return price >= targetPrice
}
private async executeTrade(quote: any) {
const result = await quote.postSwapOrderFromQuote({})
console.log('Trade executed:', result.orderId)
}
}
// Usage
const bot = new TradingBot(sdk)
bot.monitorAndTrade()
Batch Order Processing
Process multiple orders efficiently:batch.ts
Copy
Ask AI
import { TradingSdk, OrderKind } from '@cowprotocol/cow-sdk'
interface OrderRequest {
sellToken: string
buyToken: string
sellAmount: string
slippageBps: number
}
async function processBatchOrders(
sdk: TradingSdk,
orders: OrderRequest[],
chainId: number,
owner: string
) {
const results = await Promise.allSettled(
orders.map(async (order) => {
const quote = await sdk.getQuote({
chainId,
kind: OrderKind.SELL,
owner,
amount: order.sellAmount,
sellToken: order.sellToken,
sellTokenDecimals: 18,
buyToken: order.buyToken,
buyTokenDecimals: 18,
slippageBps: order.slippageBps,
})
return quote.postSwapOrderFromQuote({})
})
)
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Order ${index} posted:`, result.value.orderId)
} else {
console.error(`Order ${index} failed:`, result.reason)
}
})
}
Order Monitoring
Monitor order status until fulfillment:monitor.ts
Copy
Ask AI
import { OrderBookApi } from '@cowprotocol/sdk-order-book'
async function waitForOrderFulfillment(
orderUid: string,
chainId: number,
maxWaitTime = 300000 // 5 minutes
) {
const orderBookApi = new OrderBookApi({ chainId })
const startTime = Date.now()
while (Date.now() - startTime < maxWaitTime) {
const order = await orderBookApi.getOrder(orderUid)
console.log(`Order status: ${order.status}`)
if (order.status === 'fulfilled') {
console.log('Order fulfilled!')
console.log('Executed buy amount:', order.executedBuyAmount)
console.log('Executed sell amount:', order.executedSellAmount)
return order
}
if (order.status === 'cancelled' || order.status === 'expired') {
throw new Error(`Order ${order.status}`)
}
// Wait 10 seconds before checking again
await new Promise(resolve => setTimeout(resolve, 10000))
}
throw new Error('Order fulfillment timeout')
}
// Usage
const result = await quoteAndPost.postSwapOrderFromQuote({})
await waitForOrderFulfillment(result.orderId, chainId)
Error Handling and Retries
Implement robust error handling:retry.ts
Copy
Ask AI
async function postOrderWithRetry(
sdk: TradingSdk,
params: any,
maxRetries = 3
) {
let lastError: Error
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
console.log(`Attempt ${attempt} of ${maxRetries}`)
const quote = await sdk.getQuote(params)
const result = await quote.postSwapOrderFromQuote({})
console.log('Order posted successfully')
return result
} catch (error) {
lastError = error as Error
console.error(`Attempt ${attempt} failed:`, error.message)
if (attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000 // Exponential backoff
console.log(`Retrying in ${delay}ms...`)
await new Promise(resolve => setTimeout(resolve, delay))
}
}
}
throw new Error(`Failed after ${maxRetries} attempts: ${lastError.message}`)
}
Logging and Monitoring
Add comprehensive logging:logging.ts
Copy
Ask AI
import { enableLogging } from '@cowprotocol/sdk-common'
// Enable SDK logging
enableLogging(true)
const sdk = new TradingSdk(
{
chainId,
appCode: 'NodeScript',
signer: wallet,
},
{
enableLogging: true,
}
)
// Custom logger
function logOrderDetails(order: any) {
console.log('\n=== Order Details ===')
console.log('Sell Token:', order.sellToken)
console.log('Buy Token:', order.buyToken)
console.log('Sell Amount:', order.sellAmount)
console.log('Buy Amount:', order.buyAmount)
console.log('Slippage:', order.slippageBps / 100, '%')
console.log('=====================\n')
}
Testing
Test your Node.js scripts:test.ts
Copy
Ask AI
import { describe, it, expect } from 'vitest'
import { TradingSdk } from '@cowprotocol/cow-sdk'
describe('Trading Bot', () => {
it('should create a valid quote', async () => {
const sdk = new TradingSdk({
chainId: 11155111,
appCode: 'Test',
})
const quote = await sdk.getQuoteOnly({
owner: '0x...',
kind: OrderKind.SELL,
// ... other params
})
expect(quote.amountsAndCosts.afterNetworkCosts.buyAmount).toBeDefined()
})
})
Production Considerations
- Use Environment Variables: Never hardcode private keys
- Implement Rate Limiting: Avoid API rate limits
- Add Health Checks: Monitor your bot’s health
- Use Proper Logging: Log all important events
- Handle Errors Gracefully: Implement retry logic
- Monitor Gas Prices: Optimize for network conditions
- Secure Private Keys: Use secure key management systems
Next Steps
- Learn about limit orders
- Explore order management
- Read about Trading SDK