How to Swap Tokens
This guide will walk you through the process of getting optimal swap quotes and executing secure transactions using the DuckyDux API.
DuckyDux automatically finds the best route across multiple DEXs including Uniswap, Curve and more to get you the best possible price.
Get a Swap Quote
DuckyDux provides intelligent multi-path routing to find the optimal swap route across multiple liquidity sources.
cURL
curl "https://api.duckydux.com/v1/swap/quote" \
-G \
-d "sources=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" \
-d "sinks=0x6B175474E89094C44Da98b954EedeAC495271d0F" \
-d "supplies=1000000000000000000" \
-d "demands=-1" \
-d "slippage=0.5" \
-d "sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" \
-d "check_approvals=true"| Parameter | Description | Example |
|---|---|---|
sources | Token addresses you’re selling | 0xEee... (ETH) |
sinks | Token addresses you’re buying | 0x6B1... (DAI) |
supplies | Amounts to sell in the token’s smallest unit (e.g., wei for ETH). | 1000000000000000000 |
demands | Desired amounts to buy (-1 for unlimited) | -1 |
slippage | Slippage tolerance (%) | 0.5 |
sender | Transaction sender address | 0xd8d... |
check_approvals | Include approval transactions | true |
Understanding the Quote Response
The API returns detailed routing information and transaction data:
{
"routes": [
{
"amount": "1000000000000000000",
"route": [...], // Multi-hop routing details
"price": "2847.125",
"minOutput": "2832.556875000000000000",
"usdInput": 2847.12,
"usdOutput": 2832.56,
"cost": 14.56,
"gas": 180000
}
],
"approvals": [...], // If approval needed
"txs": [...], // Transaction data
"gasPrice": "20000000000"
}Always verify the minOutput amount and gas costs before proceeding with the transaction.
Handle Token Approvals
When swapping ERC20 tokens, you may need to approve the DuckyDux router to spend your tokens.
Check Response
If check_approvals=true was set in your quote request, approval transactions will be automatically included in the response:
{
"approvals": [
{
"token": {
"addr": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"symbol": "USDC",
"decimals": 6
},
"amount": "1000000",
"tx": {
"to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"data": "0x095ea7b3...",
"gas": 46000
}
}
]
}Execute the Swap
Security Best Practice: For maximum security and MEV protection, bundle approval and swap transactions together. Avoid sending approval transactions separately as this exposes your intent to MEV bots.
Common Swap Scenarios
ETH to ERC20
The simplest swap type - no approvals needed:
// ETH → USDC swap
const quote = await fetch(
'https://api.duckydux.com/v1/swap/quote?' +
new URLSearchParams({
sources: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
sinks: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
supplies: '1000000000000000000', // 1 ETH
demands: '-1',
slippage: '0.5',
sender: userAddress,
})
)ERC20 to ERC20
Requires token approval - use bundling for security:
DuckyDux automatically handles complex routing through multiple DEXs to find the best price for ERC20-to-ERC20 swaps.
// USDC → DAI swap with approval check
const quote = await fetch(
'https://api.duckydux.com/v1/swap/quote?' +
new URLSearchParams({
sources: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
sinks: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI
supplies: '1000000', // 1 USDC (6 decimals)
demands: '-1',
slippage: '0.5',
sender: userAddress,
check_approvals: 'true',
})
)
// If approval needed, bundle with swap for security
if (quote.approvals.length > 0) {
// Send as bundle - see "Using Transaction Bundles" guide
}Multi-token Swap
Advanced scenario with multiple sources or sinks:
// Swap multiple tokens to ETH
const sources = [
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
'0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI
]
const sinks = ['0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'] // ETH
const supplies = ['1000000', '1000000000000000000'] // 1 USDC, 1 DAI
const demands = ['-1']
const params = new URLSearchParams()
sources.forEach(source => params.append('sources', source))
sinks.forEach(sink => params.append('sinks', sink))
supplies.forEach(supply => params.append('supplies', supply))
demands.forEach(demand => params.append('demands', demand))
params.append('slippage', '1.0')
params.append('sender', userAddress)
params.append('check_approvals', 'true')
const quote = await fetch(`https://api.duckydux.com/v1/swap/quote?${params}`)