Building a Solana Copy Trading Bot with Geyser Wallet Tracking
Effective copy trading on Solana requires detecting a target wallet's transaction within the same slot it confirms and replaying the swap with adjusted size before price impact shifts — a challenge that requires Geyser streaming rather than polling. This tutorial covers target wallet selection heuristics, on-chain copy logic in Rust, and slippage guard rules to avoid copying into exit liquidity.
Building a Solana copy trading bot with Geyser wallet tracking is the only viable approach if you want same-slot execution — polling RPC with getSignaturesForAddress introduces 400–800ms of lag that evaporates your edge entirely. The core loop is: stream account notifications, parse the swap in microseconds, submit your own transaction before the next leader rotation. Everything downstream — wallet selection, sizing, slippage — is just layering risk controls on top of that fast path.
Why Polling RPC Will Not Work
Solana produces a new block roughly every 400ms. By the time getSignaturesForAddress returns a confirmed signature, the target transaction has already settled, price impact from their swap has moved the pool, and you are buying into the new price. On high-volume tokens this gap is material — a 50k SOL wallet buying into a thin Raydium pool can shift price 2–8% in a single transaction.
Geyser eliminates that gap. A Geyser plugin (either self-hosted or via a provider like Triton or Helius) pushes account updates and transaction notifications over a persistent gRPC or websocket stream the moment the validator processes them. You receive the notification in the same slot the target transaction lands, sometimes before it even reaches finality. That is the window you need.
Target Wallet Selection and Scoring
Not all profitable wallets are worth copying. The failure mode is selecting a wallet with a great 30-day PnL that is actually running an exit strategy — they accumulate quietly, then sell into their own buyers, which is exactly who you become if you copy blindly.
A practical selection filter uses four signals:
- Win rate on new tokens — wallets with >60% profitable new-token entries over 90+ days, excluding tokens they held pre-listing
- Average hold time — 15 minutes to 6 hours is the sweet spot; sub-5-minute holds suggest sniping that won't replay well with copy latency
- Position concentration — avoid wallets that put >40% of SOL balance into a single trade; that is lottery behavior, not edge
- Exit pattern analysis — parse their historical sells: wallets that consistently sell in tranches (25%/50%/25%) have better risk habits than those who dump 100% in one transaction
Tools like Cielo Finance and on-chain data from Helius's transaction enrichment API let you pull this history programmatically. Score wallets weekly and rotate the active copy list.
Geyser Subscription and Transaction Parsing
Subscribe at the account level for each target wallet, not at the program level. Program-level subscriptions flood you with every DEX interaction across all users. With account-level subscriptions you only process transactions that actually touch your target.
// Subscribe to a target wallet's account updates
let request = SubscribeRequest {
accounts: HashMap::from([(
"copy_target".to_string(),
SubscribeRequestFilterAccounts {
account: vec![target_pubkey.to_string()],
owner: vec![],
filters: vec![],
},
)]),
..Default::default()
};
When a notification arrives, you need to classify the transaction within single-digit milliseconds. Parse the inner instructions to identify the program invoked (Raydium CLMM, Orca Whirlpool, Jupiter aggregator) and extract the input/output mint pair and the SOL or USDC amount. Jupiter swaps require unpacking the self-transfer inner instruction to read the actual amounts — the top-level instruction just routes.
A critical detail: filter for finalized vs confirmed commitment depending on your risk tolerance. Confirmed (32 validators) arrives faster but has a small reorg risk. For low-cap tokens where speed matters, confirmed is correct. For tokens with thin liquidity where a reorg would leave you holding an orphan position, wait for finalized.
Copy Execution Logic and Sizing
The copy transaction should use the same DEX and pool as the target, not Jupiter re-routing. Jupiter's quote API adds 20–60ms of latency and may route through a different pool, giving you different price impact math. Build the instruction directly against the pool the target used — you can extract the pool address from their instruction data.
Sizing is where most copy bots lose money slowly. Never copy 1:1 in absolute SOL terms. A 500 SOL whale buying 20 SOL into a pool barely moves price; you following with 20 SOL when you have 10 SOL total is a different risk profile. The two approaches that hold up in production:
- Fixed fraction of balance: copy X% of your available balance regardless of what the target did. Simple, self-limiting.
- Relative sizing: scale your position as
(your_balance / target_balance) * target_position_size, capped at a hard maximum. This preserves proportional exposure but requires accurate target balance data.
Cap individual copy positions at 2–3% of your total capital. A single bad copy trade should not hurt.
Slippage Guards and Anti-Manipulation Rules
This is where copy bots get exploited. A wallet can establish a position, broadcast a highly visible buy to known copiers, then immediately sell into the copied demand. The signature is a rapid sell within 1–3 slots of the initial buy notification — if you see the target sell within 10 seconds of a buy you copied, that wallet is likely farming your copy flow.
Implement these guards before submitting a copy transaction:
- Minimum pool liquidity: skip any swap where the target pool has less than $100k TVL at copy time — thin pools amplify your price impact catastrophically
- Price impact ceiling: simulate your own transaction before sending; if your copy introduces >1.5% price impact, skip or reduce size
- Token age filter: skip tokens less than 2 hours old unless the target wallet has a strong track record on new launches specifically
- Slippage tolerance: set 0.5–1% for liquid pools, 2–3% for mid-cap tokens; never use unlimited slippage regardless of urgency
Our Solana copytrading bot service pairs these guards with a Telegram kill-switch — you can pause any target wallet with a single command without touching the running process.
Jito Bundles for Priority and MEV Protection
Submit copy transactions through Jito rather than standard RPC. Standard transactions enter the mempool where sandwich bots can front-run you. A Jito bundle lets you specify your transaction alongside a tip, and the Jito validator includes it atomically — no sandwiching possible, and you can attach a priority fee that ensures inclusion within the current slot.
The economics: a Jito tip of 0.001 SOL (~$0.15 at current prices) is negligible against any meaningful copy position. Do not skip the tip trying to save cost; you will lose far more to missed inclusions or sandwiches than you save on tips.
At TierZero we wire every copy engine to Jito by default. You can review the broader services catalog for how this fits into the larger Solana tooling stack.
Latency Budget in Practice
On a well-configured setup with a Geyser provider co-located with a Jito validator, the timeline looks like this:
| Stage | Typical latency |
|---|---|
| Geyser notification → received | 5–15ms |
| Transaction parse + classify | 1–3ms |
| Sizing + simulation | 10–30ms |
| Jito bundle submit → included | 200–400ms (next slot) |
Total from target confirmation to your copy landing: 250–450ms on average, which is within the same or next slot. Anything beyond 800ms and you are consistently arriving two slots late — at that point you need to examine your parse logic, not your submission path.
If you want this stack built and production-ready without the weeks of iteration, reach out via the contact page — we scope, build and hand over copy-trading systems including Geyser subscriptions, Rust execution engines, slippage guards and Telegram control panels.
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