Install
openclaw skills install butter-swap-skillButter Network DEX Aggregator for cross-chain token swaps. Get swap quotes, route transaction data, and cross-chain routing information. Use this skill whene...
openclaw skills install butter-swap-skillThis skill provides integration with Butter Router API for cross-chain token swaps. It aggregates DEX routes across multiple chains to find optimal swap paths.
BASE_URL=https://bs-router-v3.chainservice.io
All API endpoints use {BASE_URL} as the base.
All responses follow this structure:
{
"errno": 0,
"message": "success",
"data": [{ ... }] // data is an array
}
Note: The data field is always an array [{...}], not an object.
| errno | Meaning |
|---|---|
| 0 | Success |
| 2000 | Parameter error (e.g., missing entrance parameter) |
| 2003 | No Route Found (liquidity insufficient or pair not supported) |
| 2004 | Insufficient Liquidity (amount exceeds max) |
| other | Error (check message) |
Goal: Find out which blockchains are supported for cross-chain swaps.
Endpoint: GET /supportedChainInfo
Example:
curl -X GET "{BASE_URL}/supportedChainInfo"
Goal: Look up token details by contract address.
Endpoint: GET /findToken
Example:
curl -X GET "{BASE_URL}/findToken?address=0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
Response includes: chainId, address, name, symbol, decimals, usdPrice, image
Goal: Query optimal routes for cross-chain token swaps and get quote.
Endpoint: GET /route
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| fromChainId | number | Yes | Source chain ID (e.g., 1 for Ethereum, 56 for BSC) |
| toChainId | number | Yes | Destination chain ID |
| amount | string | Yes | Amount to swap (human readable, e.g., "100" for 100 USDT, NOT wei) |
| tokenInAddress | string | Yes | Input token address (use 0x0000000000000000000000000000000000000000 for native) |
| tokenOutAddress | string | Yes | Output token address on destination chain |
| type | string | No | "exactIn" or "exactOut" (default: exactIn) |
| slippage | number | No | Slippage in bps, default 100 (1%) |
| entrance | string | No | Router entrance (default: "agent") |
Example:
curl -X GET "{BASE_URL}/route?fromChainId=1&toChainId=56&amount=100&tokenInAddress=0xdAC17F958D2ee523a2206206994597C13D831ec7&tokenOutAddress=0x55d398326f99059fF775485246999027B3197955&type=exactIn&slippage=100&entrance=agent"
Note: Use human-readable amount (e.g., "100" for 100 USDT), NOT wei units. If the entrance parameter is not provided, it defaults to "agent".
Response includes:
hash: Route identifier for getting swap transactionamountIn / amountOut: Expected input/output amountsbridgeFee: Fee for bridginggasFee: Estimated gas costsrcChain / dstChain: Chain details with token addressesGoal: Assemble transaction data for executing a swap using the route hash.
Endpoint: GET /swap
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| hash | string | Yes | Route hash from /route response |
| from | string | Yes | Sender wallet address |
| receiver | string | Yes | Receiver address |
| slippage | number | no | Slippage in bps (100 = 1%, default: 100) |
Example:
curl -X GET "{BASE_URL}/swap?hash=0xabc123...&slippage=100&from=0x123...&receiver=0x456..."
Response includes:
to: Contract address to calldata: Calldata for the transactionvalue: Native token value to send (if any)chainId: Target chain IDGoal: Get route and swap transaction data in one call.
Endpoint: GET /routeAndSwap
Combines /route and /swap endpoints. Parameters are the same as /route plus from and receiver.
Example:
curl -X GET "{BASE_URL}/routeAndSwap?fromChainId=1&toChainId=56&amount=100&tokenInAddress=0xdAC17F958D2ee523a2206206994597C13D831ec7&tokenOutAddress=0x55d398326f99059fF775485246999027B3197955&type=exactIn&slippage=100&entrance=agent&from=0xA015d9e9206859c13201BB3D6B324d6634276534&receiver=0xA015d9e9206859c13201BB3D6B324d6634276534"
Response includes:
route: Same as /route responsetxParam: Transaction data (to, data, value, chainId)error: If swap fails, contains error details/supportedChainInfo to see available networks/findToken to get token addresses and decimals/route to get optimal route and expected output/swap for transaction dataUse /routeAndSwap to skip step 3-4 and get everything in one request.
| Chain | Chain ID |
|---|---|
| Ethereum | 1 |
| BSC | 56 |
| Polygon | 137 |
| Arbitrum | 42161 |
| Optimism | 10 |
| Base | 8453 |
| Avalanche | 43114 |
| Solana | 7560 |
This skill uses butter-router-mcp for tool-based access:
Query all supported blockchains.
Find token information by token address.
Query best routes for cross-chain token swap.
fromChainId: Source chain IDtoChainId: Destination chain IDamount: Amount in human readable format (e.g., "100" for 100 USDT, NOT wei)tokenInAddress: Input token address (use 0x000...0000 for native)tokenOutAddress: Output token addresstype: "exactIn" or "exactOut"slippage: Slippage in bps (default: 100 = 1%)entrance: Required, must be "agent"Important: The response data is an array that may contain multiple routes. You MUST handle this as follows:
data.length === 0: No routes found - inform userdata.length === 1: Use the single routedata.length > 1: Present all routes to user for selectionWhen multiple routes are available, display each route with:
hash: Route identifierbridgeFee: Bridge fee amount and symbolgasFee: Gas fee amount and symboldex: The DEX exchange path used (e.g., "UniV3 > PancakeV3")srcChain.totalAmountIn: Input amountdstChain.totalAmountOut: Output amount (after fees)minAmountOut: Minimum output amount (with slippage protection)Always include the dex field in the display - this shows which DEX or path was used for the swap.
Then ask user to select which route to use by entering the route number (1, 2, 3...).
After user selects a route, use the selected route's hash to call get_swap for transaction data.
When calling get_swap, ask user for slippage preference:
Assemble transaction data based on route hash.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| hash | string | Yes | - | Route hash from getRoute response |
| slippage | number | No | 100 | Slippage in bps (e.g., 100 = 1%) |
| from | string | Yes | - | Sender wallet address |
| receiver | string | Yes | - | Receiver address on destination chain |
| refundAddr | string | No | from | Refund address if transaction fails |
| feeToken | string | No | - | Address of token to pay protocol fees (optional) |
| destGasLimit | string | No | - | Custom gas limit for destination chain (optional) |
Display real transaction data to user, including:
to: Contract address to calldata: Full calldata (show full hex, not truncated)value: Native token value in hex and human readablechainId: Target chain IDmethod: Contract method name{
"errno": 0,
"message": "success",
"data": [
{
"hash": "0xcbb224a6ecb83a32a17643877941d27df226784be9688ba8f7833f256c5170ec",
"bridgeFee": { "amount": "0.449954", "symbol": "USDT" },
"gasFee": { "amount": "0.00006751415372", "symbol": "ETH" },
"dex": "UniV3 > PancakeV3",
"srcChain": {
"chainId": "1",
"totalAmountIn": "100.0",
"totalAmountOut": "100.0"
},
"dstChain": {
"chainId": "56",
"totalAmountIn": "99.550046",
"totalAmountOut": "99.550046"
},
"minAmountOut": { "amount": "99.550046", "symbol": "USDT" }
}
]
}
{
"errno": 0,
"message": "success",
"data": [
{
"to": "0xEE0319cF0BCa5d09333f9F6277743E8De31bD69A",
"data": "0x6e1537da000000000000000000000000766f3377497C66c31a5692A435cF3E72Dcc2d4Fc000000000000000000000000766f3377497C66c31a5692A435cF3E72Dcc2d4Fc...",
"value": "0x0f43fc2c04ee0000",
"chainId": "1",
"method": "swapAndBridge"
}
]
}
| errno | Message | Solution |
|---|---|---|
| 2000 | Parameter error: Missing entrance | Add entrance=Butter%2B parameter |
| 2003 | No Route Found | Try different token pair or chain |
| 2004 | Insufficient Liquidity | Amount exceeds max liquidity, reduce amount |
For detailed API documentation, visit: https://docs.butternetwork.io/butter-swap-integration/integration-guide