Limit Orders
Limit orders allow you to specify an exact buy amount you want to receive for selling your tokens. Unlike market orders, limit orders won’t execute until the price reaches your specified level.
What are Limit Orders?
A limit order lets you:
- Set a specific price (buy amount) for your trade
- Wait for favorable market conditions
- Avoid slippage from market movements
- Have orders valid for extended periods (up to 1 year)
Basic Limit Order
import { TradingSdk, OrderKind, SupportedChainId } from '@cowprotocol/cow-sdk'
const sdk = new TradingSdk({
chainId: SupportedChainId.MAINNET,
appCode: 'MyApp',
signer: wallet,
})
// Post a limit order
const result = await sdk.postLimitOrder({
chainId: SupportedChainId.MAINNET,
kind: OrderKind.SELL,
sellToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH
sellTokenDecimals: 18,
buyToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
buyTokenDecimals: 6,
sellAmount: '1000000000000000000', // 1 WETH
buyAmount: '2000000000', // 2000 USDC (minimum)
slippageBps: 0, // No slippage for limit orders
})
console.log('Limit order created:', result.orderId)
Complete Example with Ethers
import { JsonRpcProvider, Wallet } from 'ethers'
import {
setGlobalAdapter,
SupportedChainId,
TradingSdk,
OrderKind,
} from '@cowprotocol/cow-sdk'
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
const RPC_URL = 'https://eth.llamarpc.com'
const PRIVATE_KEY = '0x...'
async function createLimitOrder() {
const chainId = SupportedChainId.MAINNET
// Setup
const provider = new JsonRpcProvider(RPC_URL, chainId)
const wallet = new Wallet(PRIVATE_KEY, provider)
const adapter = new EthersV6Adapter({ provider, signer: wallet })
setGlobalAdapter(adapter)
const sdk = new TradingSdk({
chainId,
appCode: 'LimitOrderExample',
signer: wallet,
})
const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
// Create limit order: Sell 1 WETH for at least 2000 USDC
const result = await sdk.postLimitOrder({
chainId,
kind: OrderKind.SELL,
sellToken: WETH,
sellTokenDecimals: 18,
buyToken: USDC,
buyTokenDecimals: 6,
sellAmount: '1000000000000000000', // 1 WETH
buyAmount: '2000000000', // 2000 USDC minimum
slippageBps: 0,
})
console.log('Limit order ID:', result.orderId)
console.log('View at: https://explorer.cow.fi/orders/' + result.orderId)
}
createLimitOrder()
Advanced Settings
Custom Validity Period
Set how long the order should remain valid:
const result = await sdk.postLimitOrder(
{
// ... order parameters
},
{
validTo: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7, // Valid for 7 days
}
)
Partially Fillable Orders
Allow your order to be filled in multiple transactions:
const result = await sdk.postLimitOrder(
{
// ... order parameters
},
{
additionalParams: {
partiallyFillable: true,
},
}
)
Add custom metadata to your order:
const result = await sdk.postLimitOrder(
{
// ... order parameters
},
{
appData: {
metadata: {
quote: {
slippageBips: 0,
},
orderClass: {
orderClass: 'limit',
},
},
},
}
)
Key Differences from Swaps
| Feature | Market Order (Swap) | Limit Order |
|---|
| Execution | Immediate | When price condition is met |
| Slippage | May have slippage | No slippage (fixed price) |
| Buy Amount | Estimated | Exact minimum |
| Validity | Minutes | Up to 1 year |
| Order Type | market | limit |
Checking Order Status
After creating a limit order, monitor its status:
import { OrderBookApi } from '@cowprotocol/sdk-order-book'
const orderBookApi = new OrderBookApi({ chainId })
const order = await orderBookApi.getOrder(result.orderId)
console.log('Status:', order.status) // 'open', 'filled', 'cancelled', 'expired'
console.log('Executed amount:', order.executedSellAmount)
Cancelling a Limit Order
Off-chain Cancellation (Free)
const cancellation = await sdk.offChainCancelOrder({
chainId,
orderUid: result.orderId,
})
console.log('Order cancelled')
On-chain Cancellation
For presigned orders, you need an on-chain transaction:
const tx = await sdk.cancelOrderOnChain({
chainId,
orderUid: result.orderId,
})
await tx.wait()
console.log('Order cancelled on-chain')
Best Practices
- Set Realistic Prices: Ensure your limit price is achievable based on market conditions
- Check Allowances: Verify token approval before posting the order
- Monitor Orders: Track order status to know when they execute
- Use Appropriate Validity: Don’t set overly long validity periods for volatile markets
- Consider Fees: Factor in network costs when setting buy amounts
Example: Buy Order
Create a limit order to buy tokens:
const result = await sdk.postLimitOrder({
chainId,
kind: OrderKind.BUY, // Buying exact amount
sellToken: USDC,
sellTokenDecimals: 6,
buyToken: WETH,
buyTokenDecimals: 18,
sellAmount: '2000000000', // Max 2000 USDC to spend
buyAmount: '1000000000000000000', // Buy exactly 1 WETH
slippageBps: 0,
})
Error Handling
try {
const result = await sdk.postLimitOrder(params)
console.log('Order created:', result.orderId)
} catch (error) {
if (error.message.includes('InsufficientAllowance')) {
console.error('Need to approve tokens first')
} else if (error.message.includes('InsufficientBalance')) {
console.error('Not enough tokens')
} else {
console.error('Order creation failed:', error)
}
}
Next Steps
- Learn about order management
- Explore React integration
- Read about creating limit orders
Last modified on March 4, 2026