Skip to main content

Basic Swap Example

This example demonstrates how to create a basic swap order using the CoW Protocol SDK. We’ll swap WETH for USDC on Sepolia testnet.

Prerequisites

  • Node.js installed
  • A wallet with some testnet ETH
  • An Ethereum provider (RPC endpoint)

Installation

npm install @cowprotocol/cow-sdk ethers

Complete Example

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'

// Configuration
const RPC_URL = 'https://sepolia.gateway.tenderly.co'
const PRIVATE_KEY = '0x...' // Your private key
const DEFAULT_SELL_AMOUNT = '0.1' // WETH amount

async function main() {
  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 Trading SDK
  const sdk = new TradingSdk({
    chainId,
    appCode: 'MyApp',
    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 // 0.5% slippage

  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:', quoteAndPost.quoteResults)

  // Post the order
  console.log('Posting order...')
  const result = await quoteAndPost.postSwapOrderFromQuote({})
  console.log('Order posted successfully!')
  console.log('Order ID:', result.orderId)
}

main().catch((e) => {
  console.error(e)
  process.exit(1)
})

Understanding the Code

1. Setup the Adapter

The adapter connects the SDK to your Ethereum provider:
const adapter = new EthersV6Adapter({ provider, signer: wallet })
setGlobalAdapter(adapter)

2. Initialize the Trading SDK

const sdk = new TradingSdk({
  chainId: SupportedChainId.SEPOLIA,
  appCode: 'MyApp', // Your app identifier
  signer: wallet,
})

3. Get a Quote

Request a quote for the swap:
const quoteAndPost = await sdk.getQuote({
  chainId,
  kind: OrderKind.SELL, // Selling exact amount
  owner,
  amount,
  sellToken: WETH.address,
  sellTokenDecimals: WETH.decimals,
  buyToken: USDC.address,
  buyTokenDecimals: USDC.decimals,
  slippageBps: 50, // 0.5% slippage tolerance
})

4. Post the Order

const result = await quoteAndPost.postSwapOrderFromQuote({})
console.log('Order ID:', result.orderId)

Quote Results

The quote contains important information:
const { quoteResults } = quoteAndPost

// Get buy amount after fees
const buyAmount = quoteResults.amountsAndCosts.afterNetworkCosts.buyAmount

// Check network costs
const networkCosts = quoteResults.amountsAndCosts.networkCosts

// View order data
const orderData = quoteResults.orderToSign

Error Handling

Always wrap SDK calls in try-catch blocks:
try {
  const quoteAndPost = await sdk.getQuote(params)
  const result = await quoteAndPost.postSwapOrderFromQuote({})
} catch (error) {
  console.error('Swap failed:', error)
  // Handle specific error types
  if (error.message.includes('insufficient balance')) {
    console.error('Insufficient token balance')
  }
}

Next Steps

Last modified on March 4, 2026