Solana wallet management and token trading via Jupiter aggregator. Check balances, view transaction history, swap tokens, and manage your Solana portfolio.
77
Quality
72%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advisory
Suggest reviewing before use
Optimize this skill with Tessl
npx tessl skill review --optimize ./public/skills/0xterrybit/solana-trader/SKILL.mdA comprehensive Solana wallet management and trading skill for Clawdbot. Manage your Solana portfolio, check balances, view transaction history, and swap tokens using Jupiter DEX aggregator.
| Variable | Description | Required |
|---|---|---|
SOLANA_KEYPAIR_PATH | Path to wallet keypair JSON file | Yes |
SOLANA_RPC_URL | Custom RPC endpoint (default: mainnet-beta) | No |
JUPITER_API_KEY | Jupiter API key for authenticated requests | No |
HELIUS_API_KEY | Helius API key for enhanced transaction data | No |
SHYFT_API_KEY | Shyft API key for transaction history | No |
QUICKNODE_RPC_URL | QuickNode RPC endpoint | No |
ALCHEMY_RPC_URL | Alchemy Solana RPC endpoint | No |
| Provider | Endpoint | Notes |
|---|---|---|
| Solana Foundation | https://api.mainnet-beta.solana.com | Official, rate limited |
| PublicNode | https://solana-rpc.publicnode.com | Privacy-first, fast |
| Ankr | https://rpc.ankr.com/solana | Free public endpoint |
| Project Serum | https://solana-api.projectserum.com | Community maintained |
⚠️ Rate Limits: Public endpoints typically limit to ~100 requests/10 seconds. For production or high-frequency trading, use a paid RPC provider.
Default behavior (no API keys configured):
SOLANA_RPC_URL if sethttps://api.mainnet-beta.solana.comhttps://solana-rpc.publicnode.comhttps://rpc.ankr.com/solanaWhen to upgrade to paid RPC:
If rate limited, ask user: "Would you like to configure a paid RPC provider? Options: Helius, QuickNode, Alchemy, Shyft"
This skill includes a small platform fee (0.2%) on swaps to support development. The fee is transparently disclosed to users before each swap.
| Variable | Value | Description |
|---|---|---|
PLATFORM_FEE_BPS | 20 | 0.2% platform fee (20 basis points) |
FEE_ACCOUNT | 8KDDpruBwpTzJLKEcfv8JefKSVYWYE53FV3B2iLD6bNN | Solana wallet to receive fees |
Fee Breakdown:
Example: On a 100 USDC swap output:
# Check wallet address
solana address --keypair "$SOLANA_KEYPAIR_PATH"
# Check Solana CLI config
solana config get
# Test RPC connection
solana cluster-versionIf you only have a private key (base58 string or byte array), convert it to keypair JSON:
From Base58 private key:
# Install solana-keygen if needed
# Your private key looks like: 5K1gR...xyz (base58 string)
echo "Enter your base58 private key:"
read -s PRIVATE_KEY
# Convert to keypair JSON (requires Node.js)
node -e "
const bs58 = require('bs58');
const key = bs58.decode('$PRIVATE_KEY');
console.log(JSON.stringify(Array.from(key)));
" > ~/.config/solana/imported-wallet.json
export SOLANA_KEYPAIR_PATH=~/.config/solana/imported-wallet.jsonFrom byte array (e.g., Phantom export):
# If you have a byte array like [12,34,56,...]
echo '[12,34,56,78,...]' > ~/.config/solana/imported-wallet.json
export SOLANA_KEYPAIR_PATH=~/.config/solana/imported-wallet.jsonFrom seed phrase (mnemonic):
# Use solana-keygen to recover
solana-keygen recover -o ~/.config/solana/recovered-wallet.json
# Enter your 12/24 word seed phrase when prompted
export SOLANA_KEYPAIR_PATH=~/.config/solana/recovered-wallet.json⚠️ Security: Never share your private key or seed phrase. Store keypair files with restricted permissions:
chmod 600 ~/.config/solana/*.json
solana balance --keypair "$SOLANA_KEYPAIR_PATH"spl-token accounts --owner $(solana address --keypair "$SOLANA_KEYPAIR_PATH")# Replace <MINT_ADDRESS> with token mint
spl-token balance <MINT_ADDRESS> --owner $(solana address --keypair "$SOLANA_KEYPAIR_PATH")# Get wallet address
WALLET=$(solana address --keypair "$SOLANA_KEYPAIR_PATH")
# Get SOL balance
SOL_BALANCE=$(solana balance --keypair "$SOLANA_KEYPAIR_PATH" | awk '{print $1}')
# Get all token accounts
spl-token accounts --owner $WALLETMultiple RPC providers supported. Default uses native Solana RPC (no API key required).
Option 1: Solana RPC (default, no API key)
WALLET=$(solana address --keypair "$SOLANA_KEYPAIR_PATH")
RPC_URL="${SOLANA_RPC_URL:-https://api.mainnet-beta.solana.com}"
curl -s -X POST "$RPC_URL" \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getSignaturesForAddress\",\"params\":[\"$WALLET\",{\"limit\":10}]}" | jq '.result[] | {signature: .signature, slot: .slot, blockTime: .blockTime}'Option 2: Helius (enhanced data, recommended for detailed history)
WALLET=$(solana address --keypair "$SOLANA_KEYPAIR_PATH")
curl -s "https://api.helius.xyz/v0/addresses/${WALLET}/transactions?api-key=${HELIUS_API_KEY:-demo}&limit=10" | jq '.[] | {signature: .signature, type: .type, timestamp: .timestamp, fee: .fee}'Option 3: Shyft (free tier available)
WALLET=$(solana address --keypair "$SOLANA_KEYPAIR_PATH")
curl -s "https://api.shyft.to/sol/v1/transaction/history?network=mainnet-beta&account=${WALLET}&tx_num=10" \
-H "x-api-key: ${SHYFT_API_KEY}" | jq '.result.transactions'Option 4: QuickNode
WALLET=$(solana address --keypair "$SOLANA_KEYPAIR_PATH")
curl -s -X POST "$QUICKNODE_RPC_URL" \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getSignaturesForAddress\",\"params\":[\"$WALLET\",{\"limit\":10}]}" | jq '.result'Option 5: Alchemy
WALLET=$(solana address --keypair "$SOLANA_KEYPAIR_PATH")
curl -s -X POST "$ALCHEMY_RPC_URL" \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getSignaturesForAddress\",\"params\":[\"$WALLET\",{\"limit\":10}]}" | jq '.result[] | {signature: .signature, slot: .slot, blockTime: .blockTime}'💡 Provider Selection: AI will auto-detect available API keys and use the best provider. If no keys configured, defaults to native Solana RPC.
# Replace <SIGNATURE> with transaction signature
solana confirm -v <SIGNATURE>
# Or via RPC for more details
RPC_URL="${SOLANA_RPC_URL:-https://api.mainnet-beta.solana.com}"
curl -s -X POST "$RPC_URL" \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getTransaction\",\"params\":[\"<SIGNATURE>\",{\"encoding\":\"jsonParsed\",\"maxSupportedTransactionVersion\":0}]}" | jq '.result'| Token | Symbol | Mint Address | Decimals |
|---|---|---|---|
| Wrapped SOL | SOL | So11111111111111111111111111111111111111112 | 9 |
| USD Coin | USDC | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | 6 |
| Tether | USDT | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB | 6 |
| Bonk | BONK | DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263 | 5 |
| Jupiter | JUP | JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN | 6 |
| Raydium | RAY | 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R | 6 |
| Pyth | PYTH | HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3 | 6 |
| Jito | JTO | jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL | 9 |
⚠️ CRITICAL: Always display swap details and wait for explicit user confirmation before executing any swap.
Convert human-readable amounts to raw units:
# Example: Quote for swapping 1 SOL to USDC
INPUT_MINT="So11111111111111111111111111111111111111112"
OUTPUT_MINT="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
AMOUNT="1000000000" # 1 SOL in lamports
SLIPPAGE_BPS="50" # 0.5% slippage
PLATFORM_FEE_BPS="20" # 0.2% platform fee
# Get quote with platform fee
QUOTE=$(curl -s "https://api.jup.ag/swap/v1/quote?inputMint=${INPUT_MINT}&outputMint=${OUTPUT_MINT}&amount=${AMOUNT}&slippageBps=${SLIPPAGE_BPS}&platformFeeBps=${PLATFORM_FEE_BPS}")
echo "$QUOTE" | jq '{
inputAmount: .inAmount,
outputAmount: .outAmount,
priceImpact: .priceImpactPct,
minimumReceived: .otherAmountThreshold,
platformFee: .platformFee
}'Parse and display to user:
IMPORTANT: Ask user "Do you want to proceed with this swap?" and wait for explicit confirmation ("yes", "proceed", "confirm") before continuing.
Display Format Example:
📊 Swap Preview:
├─ From: 1.0 SOL
├─ To: ~150.25 USDC (estimated)
├─ Price Impact: 0.01%
├─ Slippage: 0.5%
├─ Minimum Received: 149.50 USDC
├─ Platform Fee: 0.2% (~0.30 USDC)
└─ Network Fee: ~0.000005 SOL
⚠️ Confirm swap? (yes/no)After user confirms:
USER_PUBKEY=$(solana address --keypair "$SOLANA_KEYPAIR_PATH")
# Fee account for referral rewards
FEE_ACCOUNT="8KDDpruBwpTzJLKEcfv8JefKSVYWYE53FV3B2iLD6bNN"
# Save quote to file
echo "$QUOTE" > /tmp/jupiter_quote.json
# Request swap transaction with fee account
SWAP_RESPONSE=$(curl -s -X POST \
-H "Content-Type: application/json" \
"https://api.jup.ag/swap/v1/swap" \
-d "{
\"quoteResponse\": $(cat /tmp/jupiter_quote.json),
\"userPublicKey\": \"${USER_PUBKEY}\",
\"feeAccount\": \"${FEE_ACCOUNT}\",
\"dynamicComputeUnitLimit\": true,
\"prioritizationFeeLamports\": {
\"priorityLevelWithMaxLamports\": {
\"maxLamports\": 5000000,
\"priorityLevel\": \"high\"
}
}
}")
# Extract transaction
SWAP_TX=$(echo "$SWAP_RESPONSE" | jq -r '.swapTransaction')💡 Note: The
feeAccountreceives the platform fee in the output token. Make sure you have token accounts for common tokens (USDC, USDT, etc.) to receive fees.
# Decode base64 transaction
echo "$SWAP_TX" | base64 -d > /tmp/swap_tx.bin
# Sign with keypair (requires solana-cli)
solana transfer --from "$SOLANA_KEYPAIR_PATH" \
--blockhash $(solana block-height) \
--sign-only \
/tmp/swap_tx.bin
# Or use the raw transaction submission
curl -s -X POST "https://api.mainnet-beta.solana.com" \
-H "Content-Type: application/json" \
-d "{
\"jsonrpc\": \"2.0\",
\"id\": 1,
\"method\": \"sendTransaction\",
\"params\": [\"${SWAP_TX}\", {\"encoding\": \"base64\"}]
}"# ALWAYS confirm with user before sending!
RECIPIENT="<RECIPIENT_ADDRESS>"
AMOUNT="0.1" # SOL amount
# Display and confirm
echo "Sending ${AMOUNT} SOL to ${RECIPIENT}"
echo "Confirm? (yes/no)"
# After confirmation:
solana transfer --keypair "$SOLANA_KEYPAIR_PATH" "$RECIPIENT" "$AMOUNT"# ALWAYS confirm with user before sending!
RECIPIENT="<RECIPIENT_ADDRESS>"
TOKEN_MINT="<TOKEN_MINT_ADDRESS>"
AMOUNT="100" # Token amount
# Display and confirm
echo "Sending ${AMOUNT} tokens (${TOKEN_MINT}) to ${RECIPIENT}"
echo "Confirm? (yes/no)"
# After confirmation:
spl-token transfer --keypair "$SOLANA_KEYPAIR_PATH" "$TOKEN_MINT" "$AMOUNT" "$RECIPIENT"# Get SOL price in USDC
curl -s "https://api.jup.ag/price/v2?ids=So11111111111111111111111111111111111111112" | jq '.data.So11111111111111111111111111111111111111112.price'
# Get multiple token prices
curl -s "https://api.jup.ag/price/v2?ids=So11111111111111111111111111111111111111112,JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" | jq '.data'# Search token by symbol or name
curl -s "https://tokens.jup.ag/token/<MINT_ADDRESS>" | jq '{name: .name, symbol: .symbol, decimals: .decimals}'| Error | Cause | Solution |
|---|---|---|
| "Insufficient balance" | Not enough tokens | Check balance, reduce amount |
| "Slippage tolerance exceeded" | Price moved during swap | Get fresh quote, increase slippage |
| "Transaction expired" | Blockhash too old | Get fresh quote and retry |
| "Account not found" | Missing token account | Will be created automatically |
| "Route not found" | No liquidity | Try smaller amount or different pair |
If a transaction fails:
User: "What's my SOL balance?"
→ Run: solana balance --keypair "$SOLANA_KEYPAIR_PATH"
→ Report: "Your wallet has X.XXX SOL"User: "Swap 0.5 SOL for USDC"
→ Get Jupiter quote for 0.5 SOL → USDC (with platformFeeBps=20)
→ Display:
"📊 Swap Preview:
├─ From: 0.5 SOL
├─ To: ~75.50 USDC (estimated)
├─ Price Impact: 0.01%
├─ Minimum Received: 75.12 USDC
├─ Platform Fee: 0.2% (~0.15 USDC)
└─ Network Fee: ~0.000005 SOL
Confirm swap? (yes/no)"
→ Wait for "yes"
→ Execute swap with feeAccount
→ Report: "✅ Swap successful! TX: https://solscan.io/tx/..."User: "Send 10 USDC to ABC123..."
→ Display:
"Transfer Preview:
- Amount: 10 USDC
- To: ABC123...
- Network Fee: ~0.000005 SOL
Confirm transfer? (yes/no)"
→ Wait for "yes"
→ Execute transfer
→ Report: "✅ Transfer successful! TX: https://solscan.io/tx/..."45f9fac
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.