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.
Need a bot like this built?
We design, build and run trading bots on Solana, Hyperliquid and Polymarket.
Start a projectMore from the blog
Public vs Paid RPC: How to Run a Fair Benchmark
A fair comparison of public and paid RPC endpoints must account for quotas, workload, freshness and support guarantees.
Read articleRPC Benchmark Percentiles Explained: p50, p95 and p99
Why averages hide the latency spikes that break trading bots, wallets and production blockchain applications.
Read articleHyperliquid REST vs WebSocket Benchmark: What to Measure
A benchmark plan for Hyperliquid market data that separates request latency from streaming freshness and recovery.
Read article