dex-execution
Solana DEX swap execution via Jupiter aggregator including quoting, transaction building, signing, and confirmation
What this skill does
# DEX Execution — Solana Swap Execution via Jupiter
Execute token swaps on Solana through Jupiter, the dominant DEX aggregator routing across Raydium, Orca, Meteora, Phoenix, Lifinity, and 20+ other venues.
## Overview
Jupiter aggregates liquidity across all major Solana DEXes to find optimal swap routes. A single swap may split across multiple pools and hop through intermediate tokens to minimize price impact. The Jupiter v6 API handles route discovery, transaction building, and fee optimization — your code handles quoting, user confirmation, signing, and submission.
**Base URL**: `https://quote-api.jup.ag/v6`
## Execution Pipeline
Every swap follows this seven-step pipeline. Never skip steps 2-3 (display and confirm).
### Step 1 — Get Quote
```python
import httpx
params = {
"inputMint": "So11111111111111111111111111111111111111112", # SOL
"outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", # USDC
"amount": 1_000_000_000, # 1 SOL in lamports
"slippageBps": 50, # 0.5%
}
resp = httpx.get("https://quote-api.jup.ag/v6/quote", params=params)
quote = resp.json()
```
### Step 2 — Display Quote to User
Always show these fields before proceeding:
| Field | Source |
|---|---|
| Input amount | `quote["inAmount"]` (in token decimals) |
| Output amount | `quote["outAmount"]` |
| Minimum received | `quote["otherAmountThreshold"]` |
| Price impact | `quote["priceImpactPct"]` |
| Route | `quote["routePlan"]` — DEXes used |
| Slippage | The `slippageBps` you requested |
### Step 3 — Require User Confirmation
```
⚠️ SWAP PREVIEW
Selling: 1.000 SOL
Buying: ~142.50 USDC
Min recv: 141.79 USDC (0.5% slippage)
Impact: 0.01%
Route: Raydium V4 → USDC
Proceed? [y/N]
```
**NEVER proceed without explicit "yes" from the user.**
### Step 4 — Build Transaction
```python
swap_body = {
"quoteResponse": quote,
"userPublicKey": "YourPubkeyBase58...",
"wrapAndUnwrapSol": True,
"dynamicComputeUnitLimit": True,
"prioritizationFeeLamports": "auto",
}
resp = httpx.post("https://quote-api.jup.ag/v6/swap", json=swap_body)
swap_data = resp.json()
swap_tx = swap_data["swapTransaction"] # base64-encoded transaction
```
### Step 5 — Sign Transaction
```python
import base64
from solders.transaction import VersionedTransaction
from solders.keypair import Keypair
raw_tx = base64.b64decode(swap_tx)
tx = VersionedTransaction.from_bytes(raw_tx)
keypair = Keypair.from_base58_string(os.environ["WALLET_PRIVATE_KEY"])
tx.sign([keypair])
```
### Step 6 — Submit Transaction
```python
rpc_url = os.environ.get("SOLANA_RPC_URL", "https://api.mainnet-beta.solana.com")
signed_bytes = bytes(tx)
payload = {
"jsonrpc": "2.0", "id": 1,
"method": "sendTransaction",
"params": [
base64.b64encode(signed_bytes).decode(),
{"encoding": "base64", "skipPreflight": False,
"maxRetries": 3, "preflightCommitment": "confirmed"}
],
}
resp = httpx.post(rpc_url, json=payload)
sig = resp.json()["result"]
print(f"Submitted: https://solscan.io/tx/{sig}")
```
### Step 7 — Confirm Transaction
```python
import time
for attempt in range(30):
payload = {
"jsonrpc": "2.0", "id": 1,
"method": "getSignatureStatuses",
"params": [[sig], {"searchTransactionHistory": False}],
}
resp = httpx.post(rpc_url, json=payload)
status = resp.json()["result"]["value"][0]
if status and status.get("confirmationStatus") in ("confirmed", "finalized"):
print(f"Confirmed at slot {status['slot']}")
break
time.sleep(2)
else:
print("Transaction not confirmed within 60s — check explorer")
```
## Jupiter API v6 Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
| `/quote` | GET | Get best-price quote with routing |
| `/swap` | POST | Build a swap transaction from a quote |
| `/swap-instructions` | POST | Get individual instructions (advanced) |
| `/price?ids=token1,token2` | GET | Simple price lookup (v2) |
| `/tokens` | GET | List all supported tokens |
See `references/jupiter_api.md` for full parameter and response documentation.
## Key Parameters
### Slippage (`slippageBps`)
| Token Type | Recommended Range | Notes |
|---|---|---|
| SOL, USDC, major tokens | 50-100 (0.5-1%) | Stable liquidity |
| Mid-cap tokens | 100-300 (1-3%) | Variable liquidity |
| PumpFun / meme tokens | 500-2000 (5-20%) | Thin books, high volatility |
| New launches (<1h old) | 1000-3000 (10-30%) | Extreme volatility |
### Dynamic Slippage
Set `dynamicSlippage: true` in the swap request to let Jupiter auto-adjust slippage based on current market conditions. Preferred for most use cases.
### Priority Fees (`prioritizationFeeLamports`)
Priority fees determine transaction ordering within a block.
| Level | microLamports | When to Use |
|---|---|---|
| Low | 10,000-50,000 | Normal conditions |
| Medium | 50,000-200,000 | Moderate congestion |
| High | 200,000-1,000,000 | High congestion / time-sensitive |
| Urgent | 1,000,000-5,000,000 | Meme coin launches, NFT mints |
| Auto | `"auto"` | Jupiter estimates for you |
Use `"auto"` for most cases. For fine-grained control, query Helius `getPriorityFeeEstimate`.
### Other Parameters
- **`onlyDirectRoutes`**: Skip multi-hop routing. Faster but may get worse price.
- **`asLegacyTransaction`**: Use legacy format instead of versioned transactions. Required for some older wallets.
- **`maxAccounts`**: Limit accounts in transaction (default 64). Lower values reduce route options but improve confirmation reliability.
- **`platformFeeBps`**: Integrator fee in basis points. Taken from output amount.
- **`wrapAndUnwrapSol`**: Auto wrap/unwrap SOL ↔ wSOL (default true).
- **`dynamicComputeUnitLimit`**: Auto-set compute budget based on simulation.
## Priority Fee Estimation
```python
# Using Helius getPriorityFeeEstimate
helius_url = f"https://mainnet.helius-rpc.com/?api-key={HELIUS_KEY}"
payload = {
"jsonrpc": "2.0", "id": 1,
"method": "getPriorityFeeEstimate",
"params": [{"accountKeys": [input_mint, output_mint],
"options": {"recommended": True}}],
}
resp = httpx.post(helius_url, json=payload)
fee = resp.json()["result"]["priorityFeeEstimate"]
```
## Transaction Confirmation Strategy
See `references/transaction_lifecycle.md` for the full Solana transaction lifecycle.
1. **Submit** with `skipPreflight: False` to catch obvious errors
2. **Poll** `getSignatureStatuses` every 2 seconds for up to 60 seconds
3. **If not confirmed**: rebuild transaction with fresh blockhash and retry (max 3 attempts)
4. **Blockhash expiry**: transactions expire ~60 seconds after blockhash was fetched
5. **Final check**: verify token balance changed as expected
## Error Handling
| Error | Cause | Recovery |
|---|---|---|
| `"Slippage tolerance exceeded"` | Price moved beyond slippageBps | Increase slippage or retry |
| `"Insufficient funds"` | Not enough input token or SOL for fees | Check balance before quoting |
| `"Transaction expired"` | Blockhash too old | Rebuild with fresh blockhash |
| `"Transaction simulation failed"` | Various — check logs | Parse simulation logs for root cause |
| `"Too many accounts"` | Route uses too many accounts | Set `maxAccounts` lower or use `onlyDirectRoutes` |
| HTTP 429 | Rate limited | Back off and retry with exponential delay |
| HTTP 400 `"No route found"` | No liquidity path exists | Check token mints are correct, try larger slippage |
## Safety Requirements
> **These are non-negotiable requirements for any execution code.**
1. **ALWAYS show quote details** (amounts, price impact, route) before execution
2. **ALWAYS require explicit user confirmation** — never auto-execute
3. **Default to simulation mode** — do not sign or submit unless explicitly enabled
4. **Never store or log private keys** — load from env vars, use immediately, discard
5. **Never use 100% slippage** — this is a common scam/exploit vector
6. **Verify token addresses** — confirm mints matchRelated in Web3
xaut-trade
IncludedBuy or sell XAUT (Tether Gold) on Ethereum. Supports market orders (Uniswap V3) and limit orders (UniswapX). Wallet modes: Foundry keystore or WDK. Delegates non-XAUT intents to registered skills (e.g. Polymarket prediction markets, Hyperliquid trading). Triggers: buy XAUT, XAUT trade, swap USDT for XAUT, sell XAUT, swap XAUT for USDT, limit order, limit buy XAUT, limit sell XAUT, check limit order, cancel limit order, XAUT when, create wallet, setup wallet, polymarket, prediction market, bet on, odds on, hyperliquid, perp, perpetual, long, short, open long, open short, close position, leverage.
qfc-openclaw-skill
IncludedQFC blockchain interaction — wallet, faucet, chain queries, staking, epoch & finality, AI inference
gate-dex-trade
IncludedExecutes on-chain token swaps via Gate DEX. Use when user wants to swap, buy, sell, exchange, or convert tokens, or bridge cross-chain. Covers full swap flow: price quotes, transaction build, signing, and submission. Do NOT use for read-only data lookups or wallet account management.
hunch
IncludedDiscover, bet on, track, and settle Hunch prediction markets in natural language. Trigger when a user wants to bet, take a position, or get odds on a crypto outcome — token market-cap milestones and flips, launchpad races (Bankr vs pump.fun volume / #1-days / launches over a cap), token head-to-head outperformance, mcap strike-ladders, and up/down price rounds. Also trigger on "what can I bet on about $TOKEN", "odds on …", "take YES/NO on …", "show my Hunch bets", "did my market resolve". Settles in USDC on Base via x402 (≤ $10 / bet); every bet returns an on-chain proof.
opensea
IncludedQuery NFT data, trade on the Seaport marketplace, and swap ERC20 tokens across Ethereum, Base, Arbitrum, Optimism, Polygon, and more.
polymarket
IncludedTrade on Polymarket prediction markets (CLOB V2) from a Privy EOA wallet. Search markets, place/cancel orders, manage positions. No private key handling. Use when the user wants to bet on event outcomes (e.g. "buy YES at 0.65 on the ceasefire market", "what are my open positions", "close my Trump bet").