Install
openclaw skills install solana-easy-swapSwap any Solana token from chat. Say 'swap 1 SOL for USDC' and it handles everything — quoting, signing, sending, confirming. No API keys, no wallet extensions, no setup beyond a keypair. Powered by Jupiter. Use when a user wants to swap, trade, exchange, buy, or sell Solana SPL tokens, SOL, USDC, memecoins, or any token pair on Solana.
openclaw skills install solana-easy-swapSwap any Solana token from chat. Say "swap 1 SOL for USDC" and it handles everything — quoting, signing, sending, confirming. No API keys, no wallet extensions, no setup beyond a keypair. Powered by Jupiter.
First run: Install dependencies (automatic if install spec is supported, otherwise manual):
cd {baseDir} && npm install --production
Required env var:
SOLANA_KEYPAIR_PATH — path to a Solana keypair JSON file (standard solana-keygen format). This skill reads your keypair to sign transactions. Only use with a keypair you trust this skill to access.Optional env vars:
SOLANA_RPC_URL — custom RPC endpoint (default: https://api.mainnet-beta.solana.com)OSS_DEFAULT_SLIPPAGE_BPS — default slippage in basis points (default: 100 = 1%)OSS_PRIORITY_FEE_FLOOR — minimum priority fee in lamports (default: 50000)No API keys required. Jupiter is used unauthenticated.
| Token | Mint |
|---|---|
| SOL (wrapped) | So11111111111111111111111111111111111111112 |
| USDC | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| USDT | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB |
For other tokens, ask the user for the mint address.
node {baseDir}/scripts/swap.mjs prepare \
--from So11111111111111111111111111111111111111112 \
--to EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v \
--amount 1000000000 \
--slippage 100
Returns JSON:
{
"prepareId": "abc123",
"expectedOut": "150230000",
"minOut": "148727700",
"priceImpact": "0.01",
"expiresAt": "2025-02-13T20:00:00Z",
"summary": {
"from": "1 SOL",
"to": "~150.23 USDC",
"minReceived": "148.73 USDC",
"slippage": "1%",
"priceImpact": "0.01%",
"destination": "owner"
}
}
Always show the summary to the user and wait for confirmation before executing.
If priceImpact > 1%, warn the user explicitly.
After user confirms:
node {baseDir}/scripts/swap.mjs execute --prepareId abc123
Returns JSON:
{
"signature": "5UzV...",
"submittedAt": "2025-02-13T19:58:12Z"
}
node {baseDir}/scripts/swap.mjs status --signature 5UzV...
Returns JSON:
{
"state": "confirmed",
"slot": 123456789,
"confirmationStatus": "finalized"
}
States: submitted → confirmed | failed | expired | unknown
node {baseDir}/scripts/swap.mjs receipt --signature 5UzV...
Returns JSON with actual amounts swapped, fees, and a Solscan link.
All commands return JSON with error field on failure:
{
"error": {
"code": "INSUFFICIENT_SOL",
"message": "Not enough SOL for fees. Have 0.001, need ~0.006",
"retryable": false
}
}
Error codes and retry guidance:
| Code | Retry? | Action |
|---|---|---|
INVALID_INPUT | No | Fix the input |
INSUFFICIENT_SOL | No | Tell user they need more SOL |
KEYPAIR_NOT_FOUND | No | Check SOLANA_KEYPAIR_PATH is set |
KEYPAIR_INVALID | No | Check keypair file format |
PREPARE_EXPIRED | Yes | Run prepare again, re-confirm with user |
PREPARE_ALREADY_EXECUTED | No | This swap was already sent |
BACKEND_UNAVAILABLE | Yes | Wait 3s, retry prepare up to 2x |
BACKEND_QUOTE_FAILED | No | No route — tell user (bad pair or no liquidity) |
TX_EXPIRED | Yes | Run prepare again, re-confirm with user |
TX_BROADCAST_FAILED | Yes | Retry execute once (if not expired) |
TX_FAILED_ONCHAIN | No | Swap failed (e.g., slippage). Do NOT retry. |
RPC_UNAVAILABLE | Yes | Wait 3s, retry up to 2x |
prepare and wait for explicit "yes" / "go" / "confirm".TX_FAILED_ONCHAIN, the tx landed and failed — retrying sends a new tx.https://solscan.io/tx/{signature}--allowThirdParty flag.minOut.