Learn-skills.dev dex-execution
Solana DEX swap execution via Jupiter aggregator including quoting, transaction building, signing, and confirmation
git clone https://github.com/NeverSight/learn-skills.dev
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/agiprolabs/claude-trading-skills/dex-execution" ~/.claude/skills/neversight-learn-skills-dev-dex-execution && rm -rf "$T"
data/skills-md/agiprolabs/claude-trading-skills/dex-execution/SKILL.mdDEX 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
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 | (in token decimals) |
| Output amount | |
| Minimum received | |
| Price impact | |
| Route | — DEXes used |
| Slippage | The 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
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
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
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
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 |
|---|---|---|
| GET | Get best-price quote with routing |
| POST | Build a swap transaction from a quote |
| POST | Get individual instructions (advanced) |
| GET | Simple price lookup (v2) |
| GET | List all supported tokens |
See
references/jupiter_api.md for full parameter and response documentation.
Key Parameters
Slippage (slippageBps
)
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
)
prioritizationFeeLamportsPriority 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 | | Jupiter estimates for you |
Use
"auto" for most cases. For fine-grained control, query Helius getPriorityFeeEstimate.
Other Parameters
: Skip multi-hop routing. Faster but may get worse price.onlyDirectRoutes
: Use legacy format instead of versioned transactions. Required for some older wallets.asLegacyTransaction
: Limit accounts in transaction (default 64). Lower values reduce route options but improve confirmation reliability.maxAccounts
: Integrator fee in basis points. Taken from output amount.platformFeeBps
: Auto wrap/unwrap SOL ↔ wSOL (default true).wrapAndUnwrapSol
: Auto-set compute budget based on simulation.dynamicComputeUnitLimit
Priority Fee Estimation
# 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.
- Submit with
to catch obvious errorsskipPreflight: False - Poll
every 2 seconds for up to 60 secondsgetSignatureStatuses - If not confirmed: rebuild transaction with fresh blockhash and retry (max 3 attempts)
- Blockhash expiry: transactions expire ~60 seconds after blockhash was fetched
- Final check: verify token balance changed as expected
Error Handling
| Error | Cause | Recovery |
|---|---|---|
| Price moved beyond slippageBps | Increase slippage or retry |
| Not enough input token or SOL for fees | Check balance before quoting |
| Blockhash too old | Rebuild with fresh blockhash |
| Various — check logs | Parse simulation logs for root cause |
| Route uses too many accounts | Set lower or use |
| HTTP 429 | Rate limited | Back off and retry with exponential delay |
HTTP 400 | No liquidity path exists | Check token mints are correct, try larger slippage |
Safety Requirements
These are non-negotiable requirements for any execution code.
- ALWAYS show quote details (amounts, price impact, route) before execution
- ALWAYS require explicit user confirmation — never auto-execute
- Default to simulation mode — do not sign or submit unless explicitly enabled
- Never store or log private keys — load from env vars, use immediately, discard
- Never use 100% slippage — this is a common scam/exploit vector
- Verify token addresses — confirm mints match expected tokens before swapping
- Check price impact — warn if >2%, block if >10% unless user overrides
- Maintain SOL reserve — keep 0.05 SOL minimum for rent and future fees
See
references/safety_checklist.md for the complete pre/during/post execution checklist.
Integration with Other Skills
| Skill | Integration |
|---|---|
| Estimate optimal slippageBps based on token liquidity profile |
| Verify pool depth supports trade size before quoting |
| Calculate trade amount based on risk parameters |
| Enforce portfolio-level exposure limits before execution |
| Underlying API documentation for Jupiter endpoints |
| Priority fee estimation and transaction monitoring |
Files
References
— Complete Jupiter v6 API parameter and response referencereferences/jupiter_api.md
— Solana transaction lifecycle, priority fees, retry strategiesreferences/transaction_lifecycle.md
— Pre/during/post execution verification checklistreferences/safety_checklist.md
Scripts
— Fetch and display Jupiter swap quotes with route analysisscripts/get_quote.py
— Build and simulate swap transactions without submittingscripts/simulate_swap.py