Decoding Whales on Ethereum using GoldRush - Part 3

Rajdeep Singha
Content Writer
Actual patterns whales, institutions, and smart money leave behind on-chain on your webapp

Tracking whale wallets isn’t just about watching big numbers move on Etherscan. When done systematically, it becomes a decision-making framework — one that helps traders anticipate risk, validate conviction, and react faster than the market.

This final part focuses on how whale tracking is actually used, where it breaks, and where it’s headed next.

1. Real-World Power: How On-Chain Intelligence Is Used

On-chain data becomes valuable only when it changes decisions. Whale tracking delivers that value across four practical areas.

1.1 Trading Strategy Augmentation: On-Chain as the Co-Pilot

Technical Analysis (TA) shows what already happened.
On-chain data shows what’s happening right now.

When a price chart hints at a breakout or breakdown, whale wallet behavior can confirm or invalidate the setup:

  • Are large wallets withdrawing tokens from exchanges? → Accumulation

  • Are they sending assets to exchanges? → Potential distribution

  • Are they reducing DeFi exposure? → Risk-off behavior

Instead of blindly trusting indicators, traders use whale flows as a real-time confirmation layer, turning average TA setups into high-conviction trades.

This is exactly where wallet-level monitoring (like the Covalent-based system below) fits in — tracking balances, transfers, and recent transactions of known high-impact wallets.

1.2 Early Trend & Narrative Detection

Narratives always start on-chain before they go viral.

Before Twitter threads, before news articles, capital moves first.

By monitoring:

  • Which wallets are accumulating specific tokens

  • Where large holders are reallocating funds

  • Which protocols are seeing consistent inflows

Traders can detect emerging themes — Layer 2 rotations, DeFi migrations, or new protocol adoption — while prices are still quiet.

This isn't a prediction.
It’s following the capital before attention arrives.

1.3 Risk Management: Seeing Danger Before It Hits

Whale tracking is just as powerful on defense.

Liquidation Risk
Large borrowers nearing liquidation thresholds often trigger cascading sell-offs. Tracking their wallets gives early warning before forced selling hits the market.

Manipulation Detection
Highly centralized token ownership is a red flag. On-chain data exposes whether price action is organic or driven by a small group rotating liquidity.

For institutions and serious traders, this transparency turns unknown risks into measurable signals.

1.4 Investor Sentiment Without the Noise

Unlike social media sentiment, on-chain metrics reflect real money decisions.

Metrics like:

  • NUPL (Net Unrealized Profit/Loss)

  • SOPR (Spent Output Profit Ratio)

Help determine whether the market is:

  • Panic selling

  • Quietly accumulating

  • Taking light profits

Whale signals become far more reliable when viewed in this broader context.

2. From Theory to Practice: Building a Whale Tracking System

To make on-chain intelligence actionable, you don’t need complex AI on day one.
You need clean data, fast access, and clear logic.

This implementation uses Covalent’s foundational API to monitor known whale wallets on Ethereum.

What This System Does

  • Tracks balances of known whale wallets

  • Fetches recent transactions and token transfers

  • Classifies activity as accumulation or distribution

  • Generates human-readable signals

Why Covalent

  • Unified, indexed blockchain data

  • Reliable historical + recent transaction access

  • Ideal for wallet-level intelligence systems

Your implementation focuses on clarity over complexity, which is exactly how production-grade intelligence systems start.

You’re not predicting the future — you’re observing behavior consistently.

Technical Implementation

Step 1: Environment Setup

Begin by installing Node.js (version 16+) and npm. Visit nodejs.org and download the LTS version. Verify installation:

node --version npm --version

Step 2: Project Initialization

2.1) Create a new directory for your project:

mkdir whale_detection cd whale_detection

What this does: Creates a new folder for your project and enters it. All your files will be organized here.

2.2) Initialize npm and install dependencies:

npm init -y npm install ws graphql-ws graphql axios ethers npm install dotenv

What this does:

  • npm init -y creates a package.json file (package configuration file) with default settings

  • npm install dotenv installs the dotenv package to safely load environment variables from .env file

2.3) Create a .env file in the root directory:

CHAIN=ETH_MAINNET COVALENT_API_KEY=Your_API_Key

What this does: Stores your Goldrush Streaming API key securely in a .env file. This file is ignored by Git (never committed) so your credentials stay private.

Obtain your Goldrush API key from goldrush.dev by registering as a developer. This key authenticates your requests to the Goldrush Streaming API.

Key Technologies

  • React 19: Latest React with modern hooks

  • Vite: Fast build tool and dev server

  • Tailwind CSS: Utility-first styling

  • Covalent’s SDK: Foundational API

  • Lucide React: Modern icon library

Step 3: Project Structure

whales_part3/

├── server/

│   └── index.js        # Express API server

├── client/

│   ├── src/

│   │   ├── App.jsx     # Main React component

│   │   ├── main.jsx    # Entry point

│   │   └── index.css   # Styling

│   ├── public/

│   │   └── whale.svg   # Favicon

│   ├── index.html

│   ├── vite.config.js

│   └── package.json

Now , our Package.json should look like this :

"name": "whale-watcher-client", "private": true, "version": "1.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { "@vitejs/plugin-react": "^4.2.1", "vite": "^5.0.0" }

Let’s first set up our server
server/index.js

import express from "express"; import cors from "cors"; import axios from "axios"; import dotenv from "dotenv"; dotenv.config(); const app = express(); const PORT = process.env.PORT || 3001; app.use(cors()); app.use(express.json()); const API_KEY = process.env.COVALENT_API_KEY; const CHAIN = "eth-mainnet"; // Whale wallet addresses to monitor const WHALE_WALLETS = [ { address: "0x28C6c06298d514Db089934071355E5743bf21d60", name: "Binance Hot Wallet" }, { address: "0x21a31Ee1afC51d94C2eFcCAa2092aD1028285549", name: "Binance Cold Wallet" }, { address: "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d", name: "Kraken" }, { address: "0x267be1C1D684F78cb4F6a176C4911b741E4Ffdc0", name: "Kraken 4" }, ]; // Health check app.get("/api/health", (req, res) => { res.json({ status: "ok", message: "Whale API Server is running" }); }); // Get all whale wallets app.get("/api/whales", (req, res) => { res.json(WHALE_WALLETS); }); // Get whale wallet balances app.get("/api/balances/:address", async (req, res) => { const { address } = req.params; const url = `https://api.covalenthq.com/v1/${CHAIN}/address/${address}/balances_v2/`; try { const { data } = await axios.get(url, { auth: { username: API_KEY, password: "" }, }); res.json(data.data); } catch (error) { console.error("Error fetching balances:", error.response?.data || error.message); res.status(500).json({ error: "Failed to fetch balances" }); } }); // Get recent transactions for whale wallet app.get("/api/transactions/:address", async (req, res) => { const { address } = req.params; const url = `https://api.covalenthq.com/v1/${CHAIN}/address/${address}/transactions_v3/`; try { const { data } = await axios.get(url, { auth: { username: API_KEY, password: "" }, }); res.json(data.data); } catch (error) { console.error("Error fetching transactions:", error.response?.data || error.message); res.status(500).json({ error: "Failed to fetch transactions" }); } }); // Get token transfers for analysis app.get("/api/transfers/:address", async (req, res) => { const { address } = req.params; const url = `https://api.covalenthq.com/v1/${CHAIN}/address/${address}/transfers_v2/`; try { const { data } = await axios.get(url, { auth: { username: API_KEY, password: "" }, }); res.json(data.data); } catch (error) { console.error("Error fetching transfers:", error.response?.data || error.message); res.status(500).json({ error: "Failed to fetch transfers" }); } }); // Analyze whale activity app.get("/api/analyze/:address", async (req, res) => { const { address } = req.params; const url = `https://api.covalenthq.com/v1/${CHAIN}/address/${address}/transactions_v3/`; try { const { data } = await axios.get(url, { auth: { username: API_KEY, password: "" }, }); const transactions = data.data; if (!transactions?.items) { return res.json({ error: "No transactions found" }); } const recentTxs = transactions.items.slice(0, 10); let depositCount = 0; let withdrawCount = 0; let totalValue = 0; recentTxs.forEach((tx) => { if (tx.value) { totalValue += parseFloat(tx.value) / 1e18; } if (tx.from_address?.toLowerCase() === address.toLowerCase()) { depositCount++; } else { withdrawCount++; } }); let signal = "neutral"; let message = "Neutral activity pattern"; if (depositCount > withdrawCount) { signal = "bearish"; message = "More outgoing than incoming → Potential distribution/selling"; } else if (withdrawCount > depositCount) { signal = "bullish"; message = "More incoming than outgoing → Accumulation pattern"; } res.json({ depositCount, withdrawCount, totalValue, txCount: recentTxs.length, signal, message, }); } catch (error) { console.error("Error analyzing:", error.response?.data || error.message); res.status(500).json({ error: "Failed to analyze whale activity" }); } }); app.listen(PORT, () => { console.log(`🐋 Whale API Server running on http://localhost:${PORT}`); });


So , the server was setup . And we can run : npm run server , then we can see our server running at
https://localhost:3001
Now, Lets move towards our client

Client / App.jsx

import { useState, useEffect } from 'react' const WHALE_WALLETS = [ { address: "0x28C6c06298d514Db089934071355E5743bf21d60", name: "Binance Hot Wallet" }, { address: "0x21a31Ee1afC51d94C2eFcCAa2092aD1028285549", name: "Binance Cold Wallet" }, { address: "0xDFd5293D8e347dFe59E90eFd55b2956a1343963d", name: "Kraken" }, { address: "0x267be1C1D684F78cb4F6a176C4911b741E4Ffdc0", name: "Kraken 4" }, ] function formatAddress(addr) { return `${addr.slice(0, 6)}...${addr.slice(-4)}` } function formatNumber(num, decimals = 2) { if (num >= 1e9) return (num / 1e9).toFixed(decimals) + 'B' if (num >= 1e6) return (num / 1e6).toFixed(decimals) + 'M' if (num >= 1e3) return (num / 1e3).toFixed(decimals) + 'K' return num.toFixed(decimals) } function App() { const [selectedWallet, setSelectedWallet] = useState(WHALE_WALLETS[0]) const [balances, setBalances] = useState(null) const [transactions, setTransactions] = useState(null) const [analysis, setAnalysis] = useState(null) const [loading, setLoading] = useState({ balances: false, transactions: false, analysis: false }) const [error, setError] = useState(null) useEffect(() => { fetchAllData() }, [selectedWallet]) async function fetchAllData() { setError(null) setLoading({ balances: true, transactions: true, analysis: true }) try { const [balRes, txRes, analysisRes] = await Promise.all([ fetch(`/api/balances/${selectedWallet.address}`), fetch(`/api/transactions/${selectedWallet.address}`), fetch(`/api/analyze/${selectedWallet.address}`) ]) if (!balRes.ok || !txRes.ok || !analysisRes.ok) { throw new Error('Failed to fetch data') } const [balData, txData, analysisData] = await Promise.all([ balRes.json(), txRes.json(), analysisRes.json() ]) setBalances(balData) setTransactions(txData) setAnalysis(analysisData) } catch (err) { setError(err.message) } finally { setLoading({ balances: false, transactions: false, analysis: false }) } } return ( <div className="app"> <header className="header"> <h1><span>🐋</span> Whale Watcher</h1> <p>Real-time monitoring of major cryptocurrency whale wallets</p> </header> <div className="wallet-selector"> {WHALE_WALLETS.map((wallet) => ( <button key={wallet.address} className={`wallet-btn ${selectedWallet.address === wallet.address ? 'active' : ''}`} onClick={() => setSelectedWallet(wallet)} > <span className="wallet-name">{wallet.name}</span> <span>{formatAddress(wallet.address)}</span> </button> ))} </div> {error && <div className="error">⚠️ {error}</div>} <div className="dashboard"> {/* Analysis Card */} <div className="card analysis-card"> <div className="card-header"> <span className="icon">📊</span> <h2>Whale Activity Analysis</h2> </div> {loading.analysis ? ( <div className="loading"> <div className="spinner"></div> <span>Analyzing whale activity...</span> </div> ) : analysis ? ( <> <div className="analysis-grid"> <div className={`stat-box ${analysis.signal}`}> <div className="label">Outgoing (Last 10)</div> <div className="value">{analysis.depositCount}</div> </div> <div className={`stat-box ${analysis.signal}`}> <div className="label">Incoming (Last 10)</div> <div className="value">{analysis.withdrawCount}</div> </div> <div className="stat-box neutral"> <div className="label">Total ETH Moved</div> <div className="value">{formatNumber(analysis.totalValue, 4)}</div> </div> <div className="stat-box neutral"> <div className="label">Transactions</div> <div className="value">{analysis.txCount}</div> </div> </div> <div className={`signal-banner ${analysis.signal}`}> <span className="signal-icon"> {analysis.signal === 'bullish' ? '🐂' : analysis.signal === 'bearish' ? '🐻' : 'ℹ️'} </span> <span>{analysis.message}</span> </div> </> ) : ( <div className="empty">No analysis data available</div> )} </div> {/* Balances Card */} <div className="card"> <div className="card-header"> <span className="icon">💰</span> <h2>Token Holdings</h2> </div> {loading.balances ? ( <div className="loading"> <div className="spinner"></div> <span>Loading balances...</span> </div> ) : balances?.items ? ( <div className="token-list"> {balances.items .filter(item => item.quote > 1000) .slice(0, 15) .map((token, i) => { const balance = parseFloat(token.balance) / Math.pow(10, token.contract_decimals) return ( <div key={i} className="token-item"> <div className="token-info"> <div className="token-logo"> {token.logo_url ? ( <img src={token.logo_url} alt={token.contract_ticker_symbol} /> ) : ( token.contract_ticker_symbol?.slice(0, 2) || '?' )} </div> <div> <div className="token-name">{token.contract_ticker_symbol || 'Unknown'}</div> <div className="token-balance">{formatNumber(balance)}</div> </div> </div> <div className="token-value"> <div className="token-usd">${formatNumber(token.quote)}</div> </div> </div> ) })} </div> ) : ( <div className="empty">No balance data available</div> )} </div> {/* Transactions Card */} <div className="card"> <div className="card-header"> <span className="icon">📜</span> <h2>Recent Transactions</h2> </div> {loading.transactions ? ( <div className="loading"> <div className="spinner"></div> <span>Loading transactions...</span> </div> ) : transactions?.items ? ( <div className="tx-list"> {transactions.items.slice(0, 15).map((tx, i) => { const isOutgoing = tx.from_address?.toLowerCase() === selectedWallet.address.toLowerCase() const value = parseFloat(tx.value || 0) / 1e18 const date = tx.block_signed_at ? new Date(tx.block_signed_at).toLocaleDateString() : 'N/A' return ( <div key={i} className="tx-item"> <div className={`tx-direction ${isOutgoing ? 'out' : 'in'}`}> {isOutgoing ? '↗️' : '↙️'} </div> <div className="tx-details"> <div className={`tx-type ${isOutgoing ? 'out' : 'in'}`}> {isOutgoing ? 'Outgoing' : 'Incoming'} </div> <div className="tx-hash">{formatAddress(tx.tx_hash)}</div> </div> <div className="tx-amount"> <div className="tx-eth">{value.toFixed(4)} ETH</div> <div className="tx-date">{date}</div> </div> </div> ) })} </div> ) : ( <div className="empty">No transaction data available</div> )} </div> </div> </div> ) } export default App

So ,  once you run : npm run dev

You will see detailed analysis of respective hot and cold wallets :

This , shows the wallet Analytics , and gives a detailed explanation of Token Holdings and Recent transaction on Binance Hot Wallet . So , with the help of this user can take decision on holding Tokens .

This , shows the wallet Analytics , and gives a detailed explanation of Token Holdings and Recent transaction on Binance Cold Wallet . So , with the help of this user can take decision on holding Tokens .

This shows , Karken Wallet has all the transactions outgoing , which can be an alert . And this wallet needs to be studied , with its holdings !


3. Challenges & Ethical Reality of Whale Tracking

Transparency brings power — and responsibility.

3.1 Data Noise & Evasion

Whales don’t sit still. They:

  • Split funds across wallets

  • Use OTC desks to avoid public detection

  • Rotate assets to mask intent

This means whale tracking is probabilistic, not absolute.
Signals must be interpreted, not blindly trusted.

3.2 Ethics of Transparency

Blockchain is public — but attribution isn’t trivial.

Linking wallets to real-world identities must be done carefully, transparently, and responsibly. The goal is market understanding, not surveillance.

As tools improve, ethical boundaries matter more, not less.

4. The Future: From Wallet Tracking to Predictive Intelligence

Your current system tracks what whales do.
The future is about understanding why — and what they’ll likely do next.

Where AI Comes In

  • Wallet clustering at scale

  • Behavioral classification (accumulators vs distributors)

  • Sequence-based pattern recognition

Instead of:

“Wallet X moved $1M”

Systems will say:

“Smart-money accumulation pattern detected across 12 wallets over 90 days.”

AI doesn’t replace on-chain intelligence — it compounds it.

5. Conclusion: The New Foundation of Market Insight

Ethereum’s transparency has permanently shifted the balance of information.

The edge today isn’t secret data — it’s interpretation, speed, and consistency.

Traders who win are those who:

  • Understand context, not just transfers

  • Build fast, reliable data pipelines

  • Track behavior, not hype

Decoding whale wallets isn’t optional anymore.
It’s the foundation of modern, data-driven trading in Web3.

And with systems like the one you’ve built, you’re no longer watching history —
you’re reading the market as it thinks.

Get Started

Get started with GoldRush API in minutes. Sign up for a free API key and start building.

Support

Explore multiple support options! From FAQs for self-help to real-time interactions on Discord.

Contact Sales

Interested in our professional or enterprise plans? Contact our sales team to learn more.