Whale Watcher
Whale Watcher is WalletWall’s wallet intelligence workspace. It assembles multiple analytical layers for a single wallet address into one view: activity history, behavioral signals, AI-assisted narratives, token holdings, and protocol usage patterns.
Workspace layout
The workspace is organized into vertical sections:
- Wallet header with ENS, address, and observability badge
- 12-week activity heatmap
- Adversarial signals panel
- Narrative cards
- Quantum Exposure section
- WalletHoldingsStrip
- ProtocolAffinityBar
12-week activity heatmap
The heatmap visualizes per-day on-chain activity intensity over a 12-week rolling window. Each cell represents one day; color intensity corresponds to the intensity_score field from the Dune scheduled query.
The 12-week heatmap requires DUNE_QUERY_12WK_ACTIVE_WALLETS to be configured. Without it, the workspace falls back to displaying 48h activity data from DUNE_QUERY_48H_ACTIVE_WALLETS only. The full heatmap grid is not available in fallback mode.
While Dune data loads, the activity section shows a skeleton heatmap grid with the label “Indexing scheduled wallet activity.” and a syncing badge. The full grid renders once the scheduled query response is available.
Expected Dune row fields: address, label, category, tx_count_48h, unique_receivers_48h, usd_volume_48h, last_seen, activity_tier, activity_day, week_number, day_of_week, tx_count_day, unique_receivers_day, usd_volume_day, intensity_score, day_activity_tier.
Adversarial signals
Adversarial signals are behavioral exposure heuristics derived from wallet transaction history and the 12-week Dune activity data. They are computed by deriveAdversarialSignals() in src/lib/adversarial-heuristics.js.
These are deterministic, explainable heuristics. They are not findings of wrongdoing and do not imply intent, identity, or legal status.
| Signal key | Approved label | What it observes |
|---|
extractionStyleActivityRisk | extraction-style activity | A single large outgoing movement dominates observed outgoing volume |
counterpartyConcentrationRisk | counterparty concentration | Activity is concentrated among one or very few counterparties |
relayRoutingExposure | relay routing exposure | Incoming value is closely followed by outgoing value to different addresses |
activityRampRisk | activity ramp | Recent on-chain activity is sharply elevated relative to a prior baseline |
assetValueAmbiguityRisk | asset/value ambiguity | Token or value fields are ambiguous, missing, or unverifiable |
Each signal carries:
score (0.0–1.0)
confidence — reflects data completeness, not accusatory certainty
reason — observation language only (“resembles”, “may indicate”, “increases exposure”)
evidence — the underlying on-chain data fields that produced the score
Signals with score < 0.3 are computed but not displayed. When no signal meets the rendering threshold, the UI shows a low-noise empty state.
Narrative engine
Narrative cards are produced by the narrative engine (src/data/narratives/builder.js). The engine converts WalletSignal[] facts from the signal engine into structured NarrativeCard objects.
The narrative engine is deterministic — it templates from signal evidence fields and never invents numbers, protocols, or chains. An optional AI layer (api/analyze.js) may rewrite the prose but must leave evidence values unchanged.
AI narrative generation is optional. If no AI provider key (OPENROUTER_API_KEY, OPENAI_API_KEY, or ANTHROPIC_API_KEY) is configured, the workspace displays template-based narratives only.
Each narrative card shows:
- Headline (≤120 characters, derived from primary signal evidence)
- Body and key points
- Data source badges with freshness information
- Confidence level and caveats
WalletHoldingsStrip
The WalletHoldingsStrip displays the wallet’s token portfolio — either as balance-denominated positions or as trading exposure — depending on the Dune query shape configured.
WalletHoldingsStrip requires DUNE_QUERY_WALLET_PORTFOLIO to be configured. Wallets not present in the query result set silently show no holdings strip (inDataset: false).
Two query shapes are supported automatically:
| Shape | Required columns |
|---|
| Option A (balance) | wallet_address, token_symbol, token_address, balance, balance_usd |
| Option B (trading exposure) | wallet_address, token_symbol, token_address, total_traded_usd, trade_count, last_trade_at |
ProtocolAffinityBar
The ProtocolAffinityBar shows the fraction of the wallet’s on-chain volume that flowed through each DeFi protocol (Uniswap, Aave, Curve, etc.). It is derived from the baseline and live event data assembled by the signal engine.
Quantum section
The Quantum Exposure section in Whale Watcher renders two cards stacked vertically:
QuantumExposureCard — composite score ring, per-component breakdown, behavioral signals, source caveats, and the policy simulator.
QuantumVaultReadinessCard — recovery readiness signals, dormancy feed findings, and the Migration Path panel (MigrationPathPanel). The migration path is derived at render time from buildMigrationReadiness() (src/lib/migration-readiness.js) using the wallet’s exposure score, value at risk, dormancy, and wallet structure. It recommends one of: monitor, fresh-wallet, split-wallet, multisig, treasury-custody, or vault-prototype. When vault-prototype is recommended, the panel surfaces a vault candidate row and the WalletWall Vault research disclosure automatically.
See Quantum Intelligence for the full score specification, migration path table, and approved framing.
Signal engine dependency
Whale Watcher depends on the signal engine (src/data/signals/engine.js) to produce WalletSignal[] facts before narratives and the ProtocolAffinityBar can be rendered. The signal engine requires:
- A
HistoricalWalletBaseline from the Dune scheduled query (may be null — signals degrade gracefully)
- Live wallet events from Alchemy or Etherscan
See Signal Engine for the full taxonomy and confidence rules.