LESSON 6 OF 10·Expert11 min

Smart-Money Tracking: Follow the Wallets That Actually Win

How to identify and follow profitable Solana wallets on-chain — build a wallet PnL heuristic from raw RPC, detect smart-money entries into new Pump.fun tokens in real time, and filter out wash-trading farmers.

The edge that actually compounds isn’t predicting which token pumps — it’s watching the wallets that already win and reading their flow before the crowd does. Every buy is public. This is how you turn that public data into a signal you can build yourself.

What “smart money” means on-chain

A smart-money wallet is one with a measurable, repeatable edge: consistent realized profit, early entries into tokens that later run, and a win rate that survives a large sample. None of that is guesswork — it is all reconstructable from transaction history. The goal is a score per wallet, then a watchlist of the top of that distribution.

Build a wallet PnL heuristic

For any wallet, pull its signatures, decode the swaps, and net the SOL in vs. out per token. Realized PnL is the SOL you got back on sells minus the SOL you put in on buys, for positions you’ve closed.

SKETCH — REALIZED PnL PER TOKEN
import { Connection, PublicKey } from "@solana/web3.js";
const conn = new Connection(RPC);

async function walletPnl(wallet: string) {
  const sigs = await conn.getSignaturesForAddress(new PublicKey(wallet), { limit: 1000 });
  const byToken: Record<string, { inSol: number; outSol: number }> = {};

  for (const { signature } of sigs) {
    const tx = await conn.getParsedTransaction(signature, { maxSupportedTransactionVersion: 0 });
    // inspect pre/postTokenBalances + native SOL delta to classify buy vs sell,
    // attribute the SOL moved to the token mint on the other side of the swap
    // byToken[mint].inSol += solSpentOnBuy;  byToken[mint].outSol += solFromSell;
  }

  return Object.entries(byToken).map(([mint, v]) => ({
    mint, realizedSol: v.outSol - v.inSol, closed: v.outSol > 0,
  }));
}

Aggregate across tokens for three numbers that matter: net realized SOL, win rate (share of closed positions in profit), and median hold time. Rank wallets by a blend of these, not by any single one — a wallet with one lucky 100× and forty losses is noise.

Detect a smart-money entry in real time

Once you have a watchlist, the signal is convergence: when several tracked wallets independently buy the same fresh mint inside a short window, that’s a far stronger tell than any one wallet aping. Subscribe to their activity and fire when the count crosses a threshold.

CONVERGENCE SIGNAL
// Poll or use logsSubscribe on each tracked wallet.
// Maintain: mint -> Set<wallet> that bought it in the last N minutes.
// Alert when a mint’s set size >= K (e.g. 3 of your top-50 wallets).
if (buyers.get(mint)!.size >= 3) alert(`smart-money cluster on ${mint}`);

Seeding the watchlist

  • Take the top holders of the last 20 tokens that migrated and ran — read them straight off-chain (see the on-chain reading lesson).
  • Take early buyers (first 30 wallets) of past winners — earliness is a proxy for edge.
  • Let the PnL filter prune the list continuously; wallets rotate and decay.

Filtering out the fakes

Wash-trading farmers inflate their own PnL by trading between wallets they control. Detect them with a funding-graph check (covered in Sniper & Bundle Forensics): if a wallet’s “counterparties” are all funded from the same source as itself, its PnL is manufactured, not real.
  • Survivorship bias: seeding only from winners over-weights luck. Track wallets forward, not just backward.
  • Rotation: pros cycle wallets to stay unread. Re-derive your list weekly.
  • This is following, not front-running: you’re reading settled public flow, not intercepting anyone’s transaction.

FAQ

Isn't this just copy-trading?
It's the data layer under copy-trading. You're not blindly mirroring one wallet — you're scoring many, then acting only on convergence, which filters out any single wallet's mistakes.
Do I need an indexer?
For a small watchlist, raw RPC (getSignaturesForAddress + getParsedTransaction) is enough. At scale you'll want a provider with parsed-history endpoints or your own indexer, because per-tx parsing is heavy.
Can wallets hide their PnL?
They can obscure it with many wallets and CEX round-trips, but on-chain buys of a specific mint are always visible. Clustering (funding-graph) re-links split wallets more often than not.