Building a Solana Copy-Trade Bot That Tracks Alpha Wallets
Copy-trading on Solana means streaming transaction logs, filtering by target wallets, decoding swap instructions, and replaying them with minimal latency. This tutorial covers the full implementation pipeline.
Copy-trading on Solana is a latency game with an on-chain parsing problem attached. The wallets you want to follow execute in 400ms slots; your bot has to notice the transaction, decode the swap intent, size its own position, and land a confirmation — all before the price has moved enough to make the trade worthless. Getting that pipeline right is what separates a working system from an expensive experiment.
Streaming the Right Data Feed
The first decision is where you listen. logsSubscribe via the WebSocket JSON-RPC API is the standard starting point: you subscribe to log messages that mention your target wallet's public key and get notified on every slot where it appears. In practice this is too slow for high-frequency targets — the notification arrives after the transaction is already confirmed.
For production, you want a gRPC Geyser plugin feed from a co-located validator or a provider like Triton or Helius. Geyser emits account and transaction updates at the validator level, before block finalization. The difference in observed latency is roughly 80–120ms versus 300–500ms for WebSocket. On a volatile token that gap is often the entire profit window.
Subscribe to TransactionSubscribe with commitment: "processed" and filter by the account keys list rather than log strings. Parsing raw account keys is faster than regex-matching log output and avoids false positives from CPI calls that merely reference your target wallet without it being the fee payer or signer.
Decoding Swap Instructions
Most Solana swaps go through Jupiter aggregator, Raydium, Orca, or Meteora. Each has a distinct instruction discriminator — the first 8 bytes of the instruction data, which is a SHA-256 hash of the Anchor IDL namespace string.
For Jupiter v6, the route instruction discriminator is 0xe517cb977ae3ad2a. Once you identify it, parse the remaining bytes against the IDL to extract:
inputMintandoutputMint— the token pairinAmount— what the target wallet spentquotedOutAmount— what they expected to receiveslippageBps— their tolerance
You do not need to replicate their exact routing. What you need is the pair and the direction. Build your own quote from Jupiter's quote API or directly from on-chain pool state, size according to your own risk parameters, and submit independently. Copying someone else's routing path creates a dependency that will break the moment they switch aggregator versions.
Keep a small in-memory IDL cache keyed by program ID. Deserializing the IDL from disk or network on every transaction adds 5–15ms you cannot afford.
Sizing and Risk Controls
The alpha wallet's position size tells you very little about what yours should be. A wallet with 500 SOL might be risk-tolerant, diversified across twenty open positions, or running a strategy where this particular trade is a hedge. None of that context is visible on-chain.
Size from your own parameters: a fixed notional per trade, a fraction of your available capital, or a volatility-adjusted kelly fraction. The most common failure mode in copy-trade bots is over-sizing early winners and holding them past the wallet's actual exit — because the bot copied the entry but missed the exit due to a different transaction pattern or a multi-leg unwind.
Set hard stops: maximum notional per trade, maximum open positions, a cooldown after consecutive losses, and a circuit breaker if daily drawdown exceeds a threshold. These are not optional. The bot infrastructure we deploy at TierZero always includes these as mandatory parameters, not user-configurable suggestions.
Transaction Construction and Priority Fees
Your transaction needs to land in the next block or the price improvement you're chasing is gone. Compute budget matters here.
Set ComputeBudgetProgram.setComputeUnitPrice based on current network conditions. During quiet periods 1,000 microlamports/CU is sufficient. During high congestion you may need 100,000+. Query recent prioritization fees from getRecentPrioritizationFees on your RPC node and use the 75th percentile of fees that actually landed — not the maximum, which inflates your costs unnecessarily.
Use versioned transactions with address lookup tables (ALTs) where your swap route involves more than 4–5 accounts. A Raydium CLMM swap through Jupiter can reference 15+ accounts; without an ALT you exceed the 35-account limit on a legacy transaction.
Pre-build and cache your ALT references at startup rather than fetching them per-trade. Same with your payer keypair's recent blockhash — refresh it every 20–30 seconds rather than on every transaction to avoid the round-trip.
Handling Failures and Slippage
Transactions fail. RPC nodes return stale blockhashes. Priority fees undershoot and your transaction expires after 150 slots. Build explicit retry logic with exponential backoff capped at 2–3 attempts, then abandon and log rather than re-queuing indefinitely.
Slippage on your execution will differ from the target wallet's slippage because pool state changes between their confirmation and yours. Calibrate your slippage tolerance based on observed pool depth for the token tier you're tracking:
- Large-cap Solana tokens (SOL, JUP, WIF): 50–100bps is usually sufficient
- Mid-cap tokens: 150–300bps
- Low-liquidity targets: you probably should not be copy-trading these at all — the impact of your own order on a thin pool is a self-imposed tax
Monitor your realized slippage per trade over time. If you're consistently hitting the top of your tolerance, either the target wallet has an edge in routing that you're not replicating, or you're tracking wallets that operate in markets too thin for this strategy.
Monitoring the Target Wallet
Wallets worth tracking change behavior. An alpha wallet that was running a momentum strategy in Q1 may have rotated to a completely different edge by Q3. Track their PnL over rolling windows — 7 days, 30 days — and pause the follower if their recent performance degrades beyond a threshold.
Keep a full audit log: target transaction signature, your replicated transaction signature, entry price, exit price, slippage, and final PnL. This data is what lets you tune the system, attribute performance to specific wallets, and drop underperformers from the follow list without guessing.
If you want to skip the implementation work and run copy-trade infrastructure that's already production-tuned, reach out to us at TierZero — we scope and deploy these systems end to end.
Building this for production?
We turn this architecture into tested, non-custodial software with monitoring, documentation and deployment support.
Related technical guides
Best Solana RPC for Trading Bots: Reproducible Latency Benchmark
Benchmark Helius, QuickNode, Triton and self-hosted Solana RPC endpoints with a reproducible Node.js harness for p50/p95/p99 latency, errors and slot freshness.
Read articleJupiter Legacy Swap v1/v6 Guide: Quote and Route Migration Notes
Understand legacy Jupiter v6 quote and route responses, then migrate new Solana integrations to the currently supported Jupiter Swap API.
Read articleSanctum and LST Arbitrage: Trading Solana Liquid Staking Tokens
Build a Solana LST arbitrage bot around Sanctum: capture jitoSOL, mSOL and INF peg deviations against SOL via Infinity pool routes and unstake tickets.
Read article