archive/upstream/chasebuild-agent-skills/web3/skills/swap-planner/SKILL.md
This skill should be used when the user asks to "swap tokens", "trade ETH for USDC", "exchange tokens on Uniswap", "buy tokens", "sell tokens", "convert ETH to stablecoins", "find memecoins", "discover tokens", "research tokens", "tokens to buy", "find tokens to swap", "what should I buy", or mentions swapping, trading, researching, discovering, buying, or exchanging tokens on any Uniswap-supported chain. Supports both known token swaps and token discovery workflows (discovery uses keyword search and web search — there is no live "trending" feed). Generates deep links to execute swaps in the Uniswap interface.
npx skillsauth add 0xharryriddle/codex-field-kit swap-plannerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Plan and generate deep links for token swaps on Uniswap across all supported chains.
Runtime Compatibility: This skill uses
AskUserQuestionfor interactive prompts. IfAskUserQuestionis not available in your runtime, collect the same parameters through natural language conversation instead.
Plan token swaps by:
The generated link opens Uniswap with all parameters ready for execution.
Note: Browser opening (
xdg-open/open) may fail in SSH, containerized, or headless environments. Always display the URL prominently so users can copy and access it manually if needed.
File Access: This skill has read-only filesystem access. Never read files outside the current project directory unless explicitly requested by the user.
If the user wants to discover tokens rather than swap a known token (e.g., "find me a memecoin", "what's trending on Base"), help them explore before proceeding to the swap.
DexScreener search works best with specific terms:
# Search for tokens by name/category (e.g., "degen", "pepe", "ai agent")
curl -s "https://api.dexscreener.com/latest/dex/search?q=degen" | \
jq '[.pairs[] | select(.chainId == "base" and .dexId == "uniswap")] |
sort_by(-.volume.h24) | .[0:5] | map({
token: .baseToken.symbol,
address: .baseToken.address,
price: .priceUsd,
volume24h: .volume.h24,
liquidity: .liquidity.usd
})'
Good search terms: degen, pepe, ai, agent, meme, dog, cat, or specific token names
Get tokens with active promotions (limited selection):
# Get boosted/promoted tokens on a chain
curl -s "https://api.dexscreener.com/token-boosts/top/v1" | \
jq '[.[] | select(.chainId == "base")] | .[0:5] | map({
tokenAddress,
url
})'
For broad discovery ("what's trending"), use web search to find tokens, then verify with DexScreener:
# After finding a token address from web search, verify it exists
curl -s "https://api.dexscreener.com/token-pairs/v1/{network}/{address}" | \
jq '[.[] | select(.dexId == "uniswap")][0] | {
name: .baseToken.name,
symbol: .baseToken.symbol,
price: .priceUsd,
liquidity: .liquidity.usd,
volume24h: .volume.h24
}'
Network IDs: See references/chains.md for the full list with DexScreener and DefiLlama provider IDs. Common IDs: ethereum, base, arbitrum, optimism, polygon, bsc, avalanche, unichain.
DexScreener coverage varies by chain. Ethereum, Base, and Arbitrum have deep Uniswap data. Celo, Blast, Zora, and World Chain have limited Uniswap pool coverage — fewer results and potentially missing pairs. Fall back to DefiLlama for price data when DexScreener returns empty results (see references/data-providers.md).
Note: DexScreener's public API doesn't have a "trending" or "top gainers" endpoint. Token discovery uses keyword search (/latest/dex/search) and web search as a fallback. For general discovery, ask the user what type of token they're looking for and search by keyword.
For specific categories (memecoins, DeFi, gaming tokens), use web search:
"trending {category} {chain} {current_year}"
Example: "trending memecoins Base 2026"
Tokens discovered via WebSearch are UNTRUSTED. Before proceeding with any web-discovered token:
Never proceed with a web-discovered token without explicit user confirmation via AskUserQuestion.
After gathering token data, present options using AskUserQuestion:
{
"questions": [
{
"question": "Which token would you like to swap to?",
"header": "Token",
"options": [
{ "label": "MOLT ($23M mcap)", "description": "$5.9M liquidity, $7.8M 24h volume" },
{ "label": "CLANKER ($31M mcap)", "description": "$3.1M liquidity, established token" },
{ "label": "CLAWSTR ($13M mcap)", "description": "$2.1M liquidity, high volume spike" }
],
"multiSelect": false
}
]
}
Evaluate tokens before recommending:
| Metric | Low Risk | Medium Risk | High Risk | | ------------ | ---------- | ----------------- | --------- | | Market Cap | >$50M | $5M-$50M | <$5M | | Pool TVL | >$1M | $100k-$1M | <$100k | | 24h Volume | Consistent | Spiking unusually | Very low | | Contract Age | >30 days | 7-30 days | <7 days |
Always disclose risk level when presenting options. For high-risk tokens, explicitly warn about volatility and potential for loss.
When ANY of these conditions are met, you MUST use AskUserQuestion to warn the user and get explicit confirmation before generating a deep link:
Do NOT generate a deep link for high-risk tokens without explicit user acknowledgment via AskUserQuestion.
Extract from the user's request:
| Parameter | Required | Example | | ------------ | ----------------------- | ------------------------- | | Input token | Yes | ETH, USDC, token address | | Output token | Yes | USDC, WBTC, token address | | Amount | Yes | 1.5 ETH, $500 worth | | Chain | Yes (default: Ethereum) | Base, Arbitrum, etc. |
If any required parameter is missing, use AskUserQuestion with structured options:
For missing chain:
{
"questions": [
{
"question": "Which chain do you want to swap on?",
"header": "Chain",
"options": [
{ "label": "Base (Recommended)", "description": "Low gas fees, fast transactions" },
{ "label": "Ethereum", "description": "Main network, higher gas" },
{ "label": "Arbitrum", "description": "Low fees, Ethereum L2" },
{ "label": "Optimism", "description": "Low fees, Ethereum L2" }
],
"multiSelect": false
}
]
}
For missing output token (when input is ETH):
{
"questions": [
{
"question": "What token do you want to receive?",
"header": "Output",
"options": [
{ "label": "USDC", "description": "USD stablecoin" },
{ "label": "USDT", "description": "Tether stablecoin" },
{ "label": "DAI", "description": "Decentralized stablecoin" },
{ "label": "WBTC", "description": "Wrapped Bitcoin" }
],
"multiSelect": false
}
]
}
For missing amount:
{
"questions": [
{
"question": "How much do you want to swap?",
"header": "Amount",
"options": [
{ "label": "0.1 ETH", "description": "~$320" },
{ "label": "0.5 ETH", "description": "~$1,600" },
{ "label": "1 ETH", "description": "~$3,200" },
{ "label": "Custom amount", "description": "Enter specific amount" }
],
"multiSelect": false
}
]
}
Always use forms instead of plain text questions for better UX.
For token symbols, resolve to addresses using known tokens or web search:
Native tokens: Use NATIVE as the address parameter.
Common tokens by chain - see ../../references/chains.md for full list:
| Token | Ethereum | Base | Arbitrum |
| ----- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- |
| USDC | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 |
| WETH | 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 | 0x4200000000000000000000000000000000000006 | 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1 |
| WBTC | 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599 | N/A | 0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f |
For unknown tokens, use web search to find the contract address, then verify on-chain.
Input Validation (Required Before Any Shell Command):
Before interpolating user-provided values into any shell command, validate all inputs:
^0x[a-fA-F0-9]{40}$../../references/chains.md^[0-9]+\.?[0-9]*$);, |, $, `, &, (, ), >, <, \, ', ", newlines)Verify token contracts exist on-chain using curl (RPC call):
# Check if address is a contract using eth_getCode
# IMPORTANT: Validate token_address matches ^0x[a-fA-F0-9]{40}$ before use
curl -s -X POST "$rpc_url" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg addr "$token_address" '{"jsonrpc":"2.0","method":"eth_getCode","params":[$addr,"latest"],"id":1}')" \
| jq -r '.result'
If the result is 0x or empty, the address is not a valid contract.
Alternative with cast (optional, requires Foundry):
# Validate token_address matches ^0x[a-fA-F0-9]{40}$ before use
cast code "$token_address" --rpc-url "$rpc_url"
Note: The curl/RPC method above is preferred for broader compatibility. Only use cast if already available in the environment. This skill ONLY uses cast code for contract verification. Do not use any other cast subcommands. The PreToolUse hook in .claude/hooks/validate-forge-cast.sh enforces this programmatically.
RPC URLs by chain - see ../../references/chains.md for full list.
For unfamiliar tokens, use web search to research:
Include relevant findings in the summary.
Before generating the deep link, fetch current prices to estimate swap output. See references/data-providers.md for full API details.
Quick price lookup with DexScreener:
# Get token price and pool liquidity
curl -s "https://api.dexscreener.com/token-pairs/v1/{network}/{address}" | \
jq '[.[] | select(.dexId == "uniswap")][0] | {
price: .priceUsd,
liquidity: .liquidity.usd,
volume24h: .volume.h24
}'
Network IDs: ethereum, base, arbitrum, optimism, polygon, bsc, avalanche, unichain
Liquidity warnings:
| Pool TVL | Risk Level | Action | | ----------- | ---------- | ----------------------------- | | > $1M | Low | Proceed normally | | $100k - $1M | Medium | Note potential slippage | | < $100k | High | Warn user about slippage risk |
If API is unavailable, fall back to DefiLlama or web search for price estimates.
Construct the Uniswap swap URL:
https://app.uniswap.org/swap?chain={chain}&inputCurrency={input}&outputCurrency={output}&value={amount}&field=INPUT
URL Parameters:
| Parameter | Description | Values |
| ---------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| chain | Network name | ethereum, base, arbitrum, optimism, polygon, bnb, avalanche, celo, blast, zora, unichain, worldchain |
| inputCurrency | Input token | Address or NATIVE |
| outputCurrency | Output token | Address or NATIVE |
| value | Amount | Decimal number (e.g., 1.5) |
| field | Which field value applies to | INPUT or OUTPUT |
Format the response with:
Example output format:
## Swap Summary
| Parameter | Value |
| ---------------- | -------------------------- |
| From | 1 ETH |
| To | USDC |
| Chain | Base |
| Current Rate | ~3,200 USDC per ETH |
| Estimated Output | ~3,200 USDC |
| Pool Liquidity | $15.2M (Low slippage risk) |
### Notes
- Final amount depends on current market price
- Default slippage is 0.5% - adjust in Uniswap if needed
- Review all details in Uniswap before confirming
Opening Uniswap in your browser...
After displaying the summary, open the URL in the browser:
# Linux
xdg-open "https://app.uniswap.org/swap?chain=base&inputCurrency=NATIVE&outputCurrency=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&value=1&field=INPUT"
# macOS
open "https://app.uniswap.org/swap?..."
Environment limitations: Browser opening may fail in remote SSH, containerized, or headless environments. If xdg-open/open fails, display the full URL prominently so users can copy and paste it manually:
**[Click here to open in Uniswap](https://app.uniswap.org/swap?...)**
Or copy this URL: `https://app.uniswap.org/swap?...`
Always present the summary and URL so users can review and execute.
The deep link uses Uniswap's default slippage (0.5%). For volatile tokens or large trades, advise users to adjust slippage in the interface.
Gas costs vary by chain and network congestion. Base and Arbitrum typically have lower gas than Ethereum mainnet.
Always verify token contracts before generating links. Scam tokens often use similar names to legitimate tokens.
For large trades, warn users about potential price impact. Suggest splitting into smaller trades if impact would be significant.
All chains supported by the Uniswap interface:
ethereum)base)arbitrum)optimism)polygon)bnb)avalanche)celo)blast)zora)worldchain)unichain)../../references/chains.md - Chain IDs, RPC URLs, native tokens, common token addressesreferences/data-providers.md - DexScreener and DefiLlama APIs for prices and liquidityCommon swap scenarios:
development
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
testing
[EXPLICIT INVOCATION ONLY] Creates dependency-aware implementation plans optimized for parallel multi-agent execution.
testing
Only to be triggered by explicit super-swarm-spark commands.
development
Create and install Codex custom agent roles in ~/.codex/config.toml, generate role config files, enforce supported keys, and guide users through required role inputs (model, reasoning effort, developer_instructions).