DEX Swap & Broadcast
Execute token swaps on-chain via OKX DEX Aggregator API (v6). Use this skill when a user wants to: 1. Build a complete swap flow: get swap calldata -> sign transaction -> broadcast to chain 2. Execute token-to-token swaps with slippage protection, MEV protection, and Jito tips (Solana) 3. Integrate OKX DEX swap + broadcast into applications, bots, or scripts This skill covers the FULL lifecycle: /swap endpoint (get tx data) + /broadcast-transaction endpoint (submit signed tx). For quote-only (no execution), use the okx-dex-quote skill instead.
安装 / 下载方式
TotalClaw CLI推荐
totalclaw install clawskills:aaronllee~easy-swapcURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/clawskills%3Aaaronllee~easy-swap/file -o easy-swap.mdGit 仓库获取源码
git clone https://github.com/openclaw/skills/commit/b9ddbbd5ffd3540e20ac355f8f8e59e627b32326# OKX DEX Swap & Broadcast Skill
## Overview
This skill generates production-ready code for the **complete on-chain swap flow** using the OKX DEX Aggregator:
```
┌─────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐
│ Quote │ ──▶ │ Swap │ ──▶ │ Sign │ ──▶ │ Broadcast │
│ (optional│ │ API Call │ │ Tx │ │ to Chain │
│ preview)│ │ │ │ │ │ │
└─────────┘ └──────────┘ └──────────┘ └───────────┘
```
**Two API endpoints involved:**
| Step | Endpoint | Method | Purpose |
|------|----------|--------|---------|
| Swap | `/api/v6/dex/aggregator/swap` | GET | Get transaction calldata for the swap |
| Broadcast | `/api/v6/dex/pre-transaction/broadcast-transaction` | POST | Submit signed transaction to the chain |
**Key features:**
- Full swap lifecycle with transaction signing
- Auto-slippage calculation based on market conditions
- MEV (sandwich attack) protection on ETH, BSC, SOL, BASE
- Jito tips for Solana priority transactions
- Token approval handling (ERC-20 approve)
- Commission/referral fee splitting
- Price impact protection with configurable thresholds
## Prerequisites
### Required Credentials
- `OKX_ACCESS_KEY` — API key
- `OKX_SECRET_KEY` — Secret key for HMAC signing
- `OKX_PASSPHRASE` — Account passphrase
### Wallet Requirements
- **EVM chains**: Private key or a signer (e.g., web3.py Account, ethers.js Wallet)
- **Solana**: Keypair for transaction signing
- The wallet must have sufficient balance of the `fromToken` and native token for gas
### Environment
- **Python**: `requests`, `web3` (for EVM signing), `solders` / `solana-py` (for Solana)
- **Node.js**: `axios`, `ethers` (for EVM signing), `@solana/web3.js` (for Solana)
## Workflow
### Step 1: Call the Swap API
**Endpoint:**
```
GET https://web3.okx.com/api/v6/dex/aggregator/swap
```
**Required parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `chainIndex` | String | Yes | Chain ID (e.g., `1` = Ethereum, `501` = Solana) |
| `amount` | String | Yes | Amount in raw units with decimals (e.g., `1000000` for 1 USDT) |
| `swapMode` | String | Yes | `exactIn` (default) or `exactOut` |
| `fromTokenAddress` | String | Yes | Sell token contract address |
| `toTokenAddress` | String | Yes | Buy token contract address |
| `slippagePercent` | String | Yes | Slippage tolerance (e.g., `0.5` = 0.5%). EVM: 0-100, Solana: 0 to <100 |
| `userWalletAddress` | String | Yes | User's wallet address that will sign and send the tx |
**Important optional parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `approveTransaction` | Boolean | Set `true` to get ERC-20 approval calldata in response |
| `approveAmount` | String | Custom approval amount (raw units). If omitted, approves exact swap amount |
| `swapReceiverAddress` | String | Recipient address if different from sender |
| `feePercent` | String | Commission fee %. Max 3% (EVM) / 10% (Solana) |
| `fromTokenReferrerWalletAddress` | String | Wallet to receive fromToken commission |
| `toTokenReferrerWalletAddress` | String | Wallet to receive toToken commission |
| `autoSlippage` | Boolean | Auto-calculate optimal slippage (overrides `slippagePercent`) |
| `maxAutoslippagePercent` | String | Cap for auto-slippage |
| `priceImpactProtectionPercent` | String | Max price impact allowed (0-100, default 90) |
| `gasLevel` | String | `slow`, `average` (default), or `fast` |
| `gaslimit` | String | Custom gas limit in wei (EVM only) |
| `dexIds` | String | Restrict to specific DEX IDs (comma-separated) |
| `excludeDexIds` | String | Exclude specific DEX IDs (comma-separated) |
| `directRoute` | Boolean | Single-pool routing only (Solana only) |
| `disableRFQ` | String | Disable time-sensitive RFQ liquidity sources |
| `callDataMemo` | String | Custom 64-byte hex data to include on-chain |
**Solana-specific parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `computeUnitPrice` | String | Priority fee (like gasPrice on EVM) |
| `computeUnitLimit` | String | Compute budget (like gasLimit on EVM) |
| `tips` | String | Jito tips in SOL (min 0.0000000001, max 2). Set `computeUnitPrice=0` when using tips |
**Swap API response structure:**
```json
{
"code": "0",
"data": [{
"routerResult": {
"chainIndex": "1",
"fromToken": { "tokenSymbol": "USDC", "decimal": "6", ... },
"toToken": { "tokenSymbol": "WBTC", "decimal": "8", ... },
"fromTokenAmount": "100000000000",
"toTokenAmount": "90281915",
"tradeFee": "1.35",
"estimateGasFee": "1248837",
"priceImpactPercent": "0.07",
"dexRouterList": [...]
},
"tx": {
"from": "0x77660f...",
"to": "0x5E1f62...",
"value": "0",
"data": "0xf2c42696...",
"gas": "1248837",
"gasPrice": "557703374",
"maxPriorityFeePerGas": "500000000",
"minReceiveAmount": "90191633",
"slippagePercent": "0.1",
"signatureData": [...]
}
}],
"msg": ""
}
```
**Key fields in `tx` object:**
| Field | Description |
|-------|-------------|
| `from` | Sender wallet address |
| `to` | OKX DEX router contract address |
| `data` | Transaction calldata (the swap instruction) |
| `value` | Native token amount to send (in wei). `"0"` for ERC-20 swaps |
| `gas` | Estimated gas limit (already padded +50%) |
| `gasPrice` | Gas price in wei |
| `maxPriorityFeePerGas` | EIP-1559 priority fee |
| `minReceiveAmount` | Minimum output at max slippage |
| `signatureData` | Approval calldata (if `approveTransaction=true`) or Jito tips calldata |
### Step 2: Handle Token Approval (EVM Only)
For ERC-20 tokens (not native ETH/BNB), you need to approve the DEX router to spend your tokens BEFORE the swap.
**When `approveTransaction=true` in the request:**
The response `tx.signatureData` contains the approval info:
```json
{
"approveContract": "0x40aA958dd87FC8305b97f2BA922CDdCa374bcD7f",
"approveTxCalldata": "0x095ea7b3..."
}
```
**Approval flow:**
1. Parse `signatureData` to get `approveContract` and `approveTxCalldata`
2. Send an approval transaction: `to=approveContract`, `data=approveTxCalldata`
3. Wait for approval tx to be confirmed
4. Then send the swap transaction
**IMPORTANT**: For native tokens (ETH, BNB, etc. using `0xeeee...eeee`), no approval is needed.
### Step 3: Sign the Transaction
**EVM chains (Python / web3.py):**
```python
tx_params = {
"from": tx_data["from"],
"to": tx_data["to"],
"value": int(tx_data["value"]),
"data": tx_data["data"],
"gas": int(tx_data["gas"]),
"gasPrice": int(tx_data["gasPrice"]),
"nonce": w3.eth.get_transaction_count(wallet_address),
"chainId": chain_id,
}
signed = w3.eth.account.sign_transaction(tx_params, private_key)
signed_tx_hex = signed.raw_transaction.hex()
```
**EVM chains (Node.js / ethers.js):**
```javascript
const tx = {
from: txData.from,
to: txData.to,
value: txData.value,
data: txData.data,
gasLimit: txData.gas,
gasPrice: txData.gasPrice,
nonce: await provider.getTransactionCount(walletAddress),
chainId: chainId,
};
const signedTx = await wallet.signTransaction(tx);
```
**Solana:**
Use `solders` or `@solana/web3.js` to deserialize, sign, and serialize the transaction from `tx.data`.
### Step 4: Broadcast the Signed Transaction
**Endpoint:**
```
POST https://web3.okx.com/api/v6/dex/pre-transaction/broadcast-transaction
```
**IMPORTANT**: This is a POST request with a JSON body (unlike the GET-based swap/quote endpoints).
**Request body:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `signedTx` | String | Yes | The hex-encoded signed transaction string |
| `chainIndex` | String | Yes | Chain ID (e.g., `"1"` for Ethereum) |
| `address` | String | Yes | Sender wallet address |
| `extraData` | String | No | JSON string with extra options (see below) |
**extraData opt