On-Chain Whale Flow Analysis Tutorial
Master on-chain whale flow analysis to spot large capital movements as they happen. Learn to read the Smart Money whale event feed — large wallet swaps and transfers across 8 EVM and Solana chains — aggregate flows by event type and significance, surface the biggest movements, and group activity by chain. Every example below runs against the public /v1/whales/events endpoint (no API key required).
What Are On-Chain Whale Flows?
On-chain whale flows track large wallet movements recorded directly on the blockchain — token swaps and sizable transfers made by high-value addresses. When significant capital moves on-chain, it often precedes or confirms shifts in market pressure. Smart Money monitors these movements across Ethereum, BSC, Avalanche, Polygon, Arbitrum, Base, Optimism, and Solana, then exposes them as a single near-real-time event feed.
This is not centralized-exchange (CEX) hot-wallet deposit/withdrawal tracking by named exchange. It is raw on-chain whale activity: each event is a real transaction with a chain, token, USD size, and significance rating you can verify on a block explorer via its tx_hash.
Flow Fundamentals
- Whale Event: A single large on-chain transaction (swap or transfer)
- event_type: The kind of movement — e.g.
swap, transfer, large_tx
- amount_usd: USD size of the movement (use this for ranking and aggregation)
- significance: Severity tag —
low, medium, high, or critical
- chain: Which of the 8 supported chains the event occurred on
The Whale Events Endpoint
All examples use one public endpoint. Try it directly from your terminal — no key needed:
# Most recent whale events across all chains
curl "https://api.smartmoneyapi.com/v1/whales/events?limit=3"
# Recent events on a single chain (last 24h)
curl "https://api.smartmoneyapi.com/v1/whales/events?chain=ethereum&limit=3&hours=24"
Query parameters: chain (ethereum, bsc, avalanche, polygon, arbitrum, base, optimism, solana — omit for all chains), limit (default ~50), hours (lookback window), and offset (for pagination). A response looks like this:
{
"events": [
{
"chain": "ethereum",
"address": "0xd43ee7e3d108e5299a753afce2a60e3afa2e7cba",
"event_type": "large_tx",
"token": "ETH",
"amount": 932.30,
"amount_usd": 1665302.17,
"tx_hash": "0x07d07b06860d5fe5afd6f25907d5daa465930cc2ec8e5ba6179b6bcb8f95a809",
"block": 25327093,
"timestamp": 1781576927,
"to_address": "0xceb69f6342ece283b2f5c9088ff249b5d0ae66ea",
"significance": "critical"
}
],
"count": 1,
"total": 692335,
"offset": 0,
"limit": 1,
"hours": 24,
"chain": "ethereum",
"updated": 1781576927
}
Aggregating Flows
The most useful first step is to pull recent events and aggregate amount_usd by event_type and by significance. This turns the raw feed into a snapshot of where the largest capital is moving.
import requests
from collections import defaultdict
BASE = 'https://api.smartmoneyapi.com/v1'
def analyze_whale_flows(chain=None, hours=24, limit=200):
"""Fetch recent whale events and aggregate by type and significance."""
params = {'limit': limit, 'hours': hours}
if chain:
params['chain'] = chain
# Public endpoint — no API key required
resp = requests.get(f'{BASE}/whales/events', params=params)
data = resp.json()
events = data['events']
scope = chain or 'all chains'
print(f"Whale Flows - {scope} (last {hours}h)")
print("=" * 60)
print(f"Events returned: {data['count']} | Total in window: {data['total']:,}")
# Aggregate USD volume by event_type
by_type = defaultdict(float)
by_sig = defaultdict(float)
total_usd = 0.0
for ev in events:
usd = ev.get('amount_usd') or 0.0
by_type[ev['event_type']] += usd
by_sig[ev['significance']] += usd
total_usd += usd
print(f"\nTotal USD moved (sampled): ${total_usd:,.0f}")
print("\nBy event type:")
for etype, usd in sorted(by_type.items(), key=lambda x: -x[1]):
print(f" {etype:<12} ${usd:,.0f}")
print("\nBy significance:")
for sig in ('critical', 'high', 'medium', 'low'):
if sig in by_sig:
print(f" {sig:<10} ${by_sig[sig]:,.0f}")
return events
analyze_whale_flows(hours=24)
analyze_whale_flows(chain='ethereum', hours=24)
Per-Chain Breakdown
To compare activity across networks, pull events per chain (or pull the combined feed and group by the chain field). This shows which networks are seeing the most whale capital move.
def compare_chain_flows(hours=24, limit=500):
"""Group recent whale USD volume by chain from the combined feed."""
resp = requests.get(
f'{BASE}/whales/events',
params={'limit': limit, 'hours': hours}
)
events = resp.json()['events']
by_chain = defaultdict(lambda: {'usd': 0.0, 'count': 0})
for ev in events:
c = ev['chain']
by_chain[c]['usd'] += ev.get('amount_usd') or 0.0
by_chain[c]['count'] += 1
print(f"Whale Flow by Chain (last {hours}h, sampled)")
print("=" * 60)
for chain, stats in sorted(by_chain.items(), key=lambda x: -x[1]['usd']):
print(f" {chain:<10} ${stats['usd']:>15,.0f} ({stats['count']} events)")
compare_chain_flows(hours=24)
Surfacing the Largest Movements
Rank events by amount_usd to find the single biggest whale movements in the window — these are the ones most worth a closer look on a block explorer.
def top_movements(chain=None, hours=24, limit=500, top_n=5):
"""Return the largest whale movements by USD size."""
params = {'limit': limit, 'hours': hours}
if chain:
params['chain'] = chain
events = requests.get(f'{BASE}/whales/events', params=params).json()['events']
ranked = sorted(events, key=lambda e: e.get('amount_usd') or 0, reverse=True)
print(f"Top {top_n} whale movements (last {hours}h)")
for ev in ranked[:top_n]:
print(f" ${ev['amount_usd']:>14,.0f} {ev['chain']:<9} "
f"{ev['event_type']:<10} {ev['token']:<6} "
f"[{ev['significance']}] {ev['tx_hash']}")
top_movements(hours=24, top_n=5)
Polling for New Events
The feed updates continuously. Poll it on an interval and react to events above a USD threshold or at high/critical significance. (There is no public WebSocket — use periodic polling.)
const BASE = 'https://api.smartmoneyapi.com/v1';
class WhaleFlowMonitor {
constructor() {
this.seen = new Set(); // tx_hash dedupe
this.alerts = [];
}
async poll(chain = null, hours = 1, usdThreshold = 1_000_000) {
const params = new URLSearchParams({ limit: '100', hours: String(hours) });
if (chain) params.set('chain', chain);
// Public endpoint — no API key required
const resp = await fetch(`${BASE}/whales/events?${params}`);
const data = await resp.json();
for (const ev of data.events) {
if (this.seen.has(ev.tx_hash)) continue;
this.seen.add(ev.tx_hash);
const big = (ev.amount_usd || 0) >= usdThreshold;
const severe = ev.significance === 'high' || ev.significance === 'critical';
if (big || severe) this.alertEvent(ev);
}
}
alertEvent(ev) {
const usd = (ev.amount_usd / 1e6).toFixed(2);
const msg = `WHALE FLOW: $${usd}M ${ev.event_type} of ${ev.token} on `
+ `${ev.chain} [${ev.significance}] tx ${ev.tx_hash}`;
console.log(msg);
this.alerts.push(msg);
}
}
// Poll every 60s for events >= $1M or high/critical significance
const monitor = new WhaleFlowMonitor();
setInterval(() => monitor.poll(null, 1, 1_000_000), 60000);
Flow-Based Signals
Patterns to watch in the whale event feed:
Key Signal Patterns
- Critical-Significance Cluster: Several
critical events on one chain in a short window = outsized capital in motion
- Large-Tx Spike: A jump in
large_tx USD volume vs. the prior window = elevated whale activity
- Swap Concentration: Heavy
swap volume into or out of a single token = directional rotation
- Cross-Chain Surge: Whale USD volume rising across multiple chains at once = broad-based positioning
- Single Mega-Movement: One transaction dominating the top-N ranking = a holder worth tracking by address
Advanced Analysis
Combine the whale event feed with other public Smart Money datasets for a fuller picture. /v1/whale-consensus gives per-symbol directional bias from tracked whale positions, and /v1/onchain/metrics provides market-structure context (TVL, stablecoin supply, DEX volume from DeFiLlama).
def combined_flow_analysis(chain='ethereum', hours=24):
"""Combine on-chain whale events with whale-consensus bias."""
# 1) Recent whale event volume on the chain
events = requests.get(
f'{BASE}/whales/events',
params={'chain': chain, 'hours': hours, 'limit': 300}
).json()['events']
chain_usd = sum(e.get('amount_usd') or 0 for e in events)
# 2) Per-symbol directional bias (public consensus endpoint)
consensus = requests.get(f'{BASE}/whale-consensus').json()
print(f"Whale Flow Analysis - {chain} (last {hours}h)")
print(f" Sampled whale USD volume: ${chain_usd:,.0f}")
print(f" Events sampled: {len(events)}")
print(f"\n Consensus bias snapshot: {consensus}")
combined_flow_analysis('ethereum', hours=24)
Pro Insight: The strongest read comes from cross-referencing a cluster of critical whale events on one chain with the directional bias from /v1/whale-consensus for the same asset. Agreement between raw on-chain movement and aggregated positioning is a higher-conviction signal than either alone.
Monitor On-Chain Whale Flows
Track large wallet movements across 8 EVM and Solana chains in near real time. Aggregate by event type and significance, surface the biggest transactions, and act on whale activity as it lands on-chain.
View API Plans