Back to Skills
binance/binance-skills-hubReview behavior before running

SKILL DETAIL

binance-wallet-tracker

binance/binance-skills-hub/binance-wallet-tracker

Wallet tracking and monitoring on Binance Web3. Monitor token/trade activity for private groups or public Smart Money/KOL data. Four domains: (A) Discovery — consensus, pioneer, leaderboard diff, token buyer lookup, time-window summaries, similar wallets; (B) Evaluation — token risk (tokenRiskLevel ≥ 3), group rhythm, follow list assessment, token heat; (C) Replay — 4h summary, Accumulation/Distribution, sector rotation, anomaly orders, round-trip, first-mover/leader-follower, wake-up, bot-like; (D) Management — group create/rename, batch import, label update, link, follow list; (E) Real-time — WebSocket push for Smart Money, KOL, wallet-level, and address-level trade events. Trigger on: wallet tracker, monitoring, consensus, pioneer, accumulation, Distribution, Sector Rotation, Anomaly Large Order, round-trip, first-mover, wake-up, bot-like, token risk, token heat, group profile, similar wallets, group management, address import, follow list, real-time push, WebSocket — even without "tracker" explicitly.

Installs · 253View source

Installation

npx skills add https://github.com/binance/binance-skills-hub --skill binance-wallet-tracker

Skill files

SKILL.md

Last synced · Oct 26, 2026

references/analytics.md›
# Wallet Tracker — 9 Analysis Scenarios

Built-in analysis patterns for `tracker tx query` data. Each scenario defines detection rules, algorithm, and output format.

**Data source**: All scenarios operate on the trade records returned by `baw tracker tx query --json`. Fetch the full dataset first, then apply analysis client-side.

**⚠️ Critical**: `ts` field is in **seconds** (10-digit Unix timestamp), not milliseconds. All time-delta calculations (10min window, <1h round-trip, >72h wake-up) must use seconds. Multiply by 1000 only if converting to JS `Date` objects.

**Common prerequisite**: The A3 API does NOT accept `ca` or `address` as filter parameters. The Skill must fetch all records via `tx query`, then filter by matching `ca` (contract address) or `address` (wallet) to enable single-token or single-address focus scenarios.

---

## 1. Rhythm — per-address trading rhythm

**Purpose**: Profile each address's trading pattern — frequency, buy/sell ratio, average ticket, active hours.

**Algorithm**:
```
Group records by `address`:
  count = total records
  buys = records where tradeSideCategory ∈ {11, 19}
  sells = records where tradeSideCategory ∈ {21, 29}
  mean_usd = mean(txUsdValue)
  active_hours = histogram of ts by hour-of-day
  intervals = sorted diffs between consecutive ts
  median_interval = median(intervals)
```

**Output**:
```
📊 Group Trading Rhythm

Address: {address} ({label})
  Total Trades: {count} | Buy: {buys} | Sell: {sells}
  Mean Amount: ${mean_usd} | Median Interval: {median_interval}min
  Active Hours: {top3_active_hours}
```

---

## 2. Anomaly — Large Order Detection

**Purpose**: Detect abnormally large transactions.

**Detection rule**: `txUsdValue > 3 × mean(txUsdValue for same address) AND txUsdValue > 500`

**Algorithm**:
```
1. Group records by `address`
2. Compute mean(txUsdValue) per address
3. Flag records where txUsdValue > 3 × mean AND txUsdValue > 500
```

**Output**:
```
⚠️ Anomaly Large Order

{ts} | {address} ({label}) | {tradeSide} {tokenName} | ${txUsdValue}
  (Mean ${mean_usd}, {multiplier}×Mean)
```

---

## 3. Co-buy — Consensus Buying

**Purpose**: Detect coordinated buying of the same token within a short window.

**Detection rule**: Same `ca`, ≥3 distinct addresses buying within 10-minute window.

**Algorithm**:
```
1. Filter records: tradeSideCategory ∈ {11, 19} (buys)
2. Group by `ca`
3. For each token, sort buy records by `ts`
4. Sliding window: find any 10-min window (600s) with ≥3 distinct addresses
```

**Output**:
```
🔥 Consensus Buy

{tokenName} ({ca}) | {n}consensus | Window: {window_start} - {window_end}
  Buyers: {addr1} ${v1}, {addr2} ${v2}, {addr3} ${v3}
```

---

## 4. Round-trip — Quick In-and-Out

**Purpose**: Detect addresses that buy and sell the same token within 1 hour.

**Detection rule**: Same `address`, same `ca`, buy followed by sell, time gap < 1h.

**Algorithm**:
```
1. Group records by (address, ca)
2. Sort by `ts`
3. Find pairs where: first is buy (11/19), second is sell (21/29), gap < 3600s (1h)
4. Compute profit = (sellPrice - buyPrice) / buyPrice
```

**Output**:
```
⚡ Round-Trip

{address} ({label}) | {tokenName} ({ca})
  Buy: {buy_ts} @ ${buy_price}
  Sell: {sell_ts} @ ${sell_price}
  Holding: {holding_minutes}min | Profit: {profit_pct}%
```

---

## 5. Rotation — Sector Rotation

**Purpose**: Detect capital flowing from one set of tokens to another across time windows.

**Detection rule**: Compare token top-N by volume between two consecutive time windows.

**Algorithm**:
```
1. Split records into two windows: first half and second half (by ts median)
2. For each window, compute token volume ranking (sum txUsdValue by ca)
3. exiting = top tokens in window1 not in window2 top
4. entering = top tokens in window2 not in window1 top
5. intersection = tokens in both windows' top
```

**Output**:
```
🔄 Sector Rotation

Exiting Tokens: {exiting_tokens} (window1 top but not in window2)
Entering Tokens: {entering_tokens} (window2 top but not in window1)
Persistent Hot: {intersection} (in both windows)
```

---

## 6. First-mover — Pioneer Buying

**Purpose**: Identify the earliest buyer of each token.

**Detection rule**: For each `ca`, find the address with the earliest buy `ts`.

**Algorithm**:
```
1. Filter records: tradeSideCategory ∈ {11, 19} (buys)
2. Group by `ca`
3. For each token, find record with minimum `ts`
4. That address is the first-mover for that token
```

**Output**:
```
🎯 First BuyAddress

{tokenName} ({ca}) | First Buy: {address} ({label}) @ {first_buy_ts}
  Buy Price: ${price} | Current Price: ${current_price}
```

---

## 7. Leader-follower — Follower Delay

**Purpose**: Measure how quickly followers copy the first-mover.

**Detection rule**: After first-mover buys, compute median delay for subsequent buyers.

**Algorithm**:
```
1. For each ca, identify first-mover (scenario 6)
2. Find all subsequent buys for same ca (sorted by ts)
3. Delays = [follower_ts - first_mover_ts for each follower]
4. Median delay = median(delays)
```

**Output**:
```
👥 Leader + Followers

{tokenName} ({ca})
  Leader: {first_mover_address} @ {leader_ts}
  Follower Count: {n_followers}
  Median Follower Delay: {median_delay}min
  Delay Distribution: <5min: {n1} | 5-30min: {n2} | >30min: {n3}
```

---

## 8. Wake-up — Dormant Wallet Activation

**Purpose**: Detect addresses that were inactive for >72h then suddenly trade again.

**Detection rule**: Gap between consecutive transactions for same address > 72h.

**Algorithm**:
```
1. Group records by `address`
2. Sort by `ts`
3. Compute intervals between consecutive records
4. Flag addresses where any interval > 259200s (72h)
5. The record after the gap is the "wake-up" trade
```

**Output**:
```
😴➡️⚡ Wake-Up

{address} ({label})
  Last Trade: {last_ts} ({days_ago}days ago)
  Current Trade: {wake_ts} | {tradeSide} {tokenName} | ${txUsdValue}
  Sleep Days: {sleep_days}
```

---

## 9. Bot-like — Bot Activity Detection

**Purpose**: Detect addresses exhibiting automated trading patterns.

**Detection rule**: Three evidence pieces — low interval variance + high night ratio + low amount dispersion.

**Algorithm**:
```
1. Group records by `address`
2. Compute:
   a. Interval variance: std(intervals) / mean(intervals) — low = bot-like
   b. Night ratio: fraction of trades between 00:00-06:00 UTC — high = bot-like
   c. Amount dispersion: std(txUsdValue) / mean(txUsdValue) — low = bot-like
3. Bot score = (1 if interval_cv < 0.3 else 0) +
              (1 if night_ratio > 0.4 else 0) +
              (1 if amount_cv < 0.5 else 0)
4. If bot_score ≥ 2, flag as bot-like
```

**Output**:
```
🤖 Bot-Like

{address} ({label}) | Bot score: {score}/3
  IntervalCV: {interval_cv} (Low if < 0.3, else Normal)
  Night Ratio: {night_ratio} (High if > 0.4, else Normal)
  AmountCV: {amount_cv} (Low if < 0.5, else Normal)
  Evidence: {evidence_list}
```

---

## Scenario Composition

Multiple scenarios can be combined for comprehensive analysis:

- **4h Comprehensive Summary**: Run rhythm + anomaly + co-buy + rotation on 4h data window
- **Group Profile**: Run rhythm for all addresses → summarize group behavior
- **Token Heat**: Run co-buy + first-mover + leader-follower for a specific token (filter by ca client-side)

### Data Fetching Strategy

Since `tx query` returns all records without pagination, fetch once and apply all scenarios in memory. For large groups, consider filtering by `--trade-side` to reduce dataset size before analysis.
references/cli.md›
# binance-wallet-tracker — CLI Reference

Complete reference for all `baw tracker` subcommands (excluding leaderboard — see `binance-leaderboard` skill).

**Invocation pattern**: `baw tracker <subcommand> [options] --json`
**Auth**: Commands with `--group-id` require `agentSessionId`. Commands with `--tag-type` (SMY/KOL data) require no auth. `--tag-type` and `--group-id` are mutually exclusive.

---

## `tracker token query` — Token Monitor

```bash
# Private — own group data (must specify --group-id or --tag-type)
baw tracker token query -c 56 --group-id 1 --json
baw tracker token query -c 56 --group-id 1 --period 4h --json

# Public — SMY/KOL data
baw tracker token query -c 56 --tag-type kol --json        # KOL
baw tracker token query -c CT_501 --tag-type smy --json    # Smart Money
```

### Parameters

| Param | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `-c, --chain-id` | string | yes | — | Chain ID |
| `--group-id` | number | no | — | Target group; omit to query all own groups (private mode) |
| `--tag-type` | string | no | — | `kol` / `smy` (public mode; omit for private own-group mode) |
| `--token-size` | int | no | `70` | Max tokens to return |
| `--period` | enum | no | `24h` | `1m` / `5m` / `1h` / `4h` / `24h` |
| `--filter-risk` | flag | no | — | Filter risk tokens |

**Private mode**: use `--group-id` (or omit both to query all own groups). **Public mode**: use `--tag-type kol` or `--tag-type smy` (no `--group-id`).

### Return Fields

| Field | Type | Description |
|-------|------|-------------|
| `tokenName` | string | Token name |
| `ca` | string | Contract address |
| `tokenIconUrl` | string | Token icon URL |
| `protocol` | number | Protocol type (may be absent in private mode) |
| `launchTime` | number | Token launch timestamp (ms) — use for pioneer sorting |
| `price` | string | Current price |
| `marketCap` | string | Market cap |
| `volume` | string | Trading volume |
| `priceChangeRate` | string | Price change rate (%) |
| `tokenDecimals` | number | Token decimals |
| `tokenRiskLevel` | int | Risk level 0-5 (≥3 = high risk) |
| `rwaType` | number | RWA type |
| `addressList` | array | Per-address flow data (see below) |
| `tokenTag` | object | Token tag map |
| `consensusCount` | number | **CLI-aggregated**: `addressList.length` (consensus count) |
| `netInflow` | number | **CLI-aggregated**: Σ `addressList[].inflow` (net inflow) |
| `countBuy` | number | **CLI-aggregated**: Σ `addressList[].buyCount` (accumulation count) |
| `countSell` | number | **CLI-aggregated**: Σ `addressList[].sellCount` (distribution count) |

**CLI aggregation**: The API does not return top-level `traderNum`, `inFlow`, `countBuy`, or `countSell`. The CLI aggregates these from `addressList[]` and exposes them as `consensusCount`, `netInflow`, `countBuy`, `countSell` on each token object. Use these aggregated fields directly for Accumulation vs Distribution analysis.

### Per-Address Fields

| Field | Type | Description |
|-------|------|-------------|
| `address` | string | Wallet address |
| `label` | string\|null | Address label |
| `buyCount` | number | Buy transaction count (use for Accumulation analysis) |
| `sellCount` | number | Sell transaction count (use for Distribution analysis) |
| `inflow` | number | Net inflow (positive = net buy) |
| `tokenQty` | number\|null | Holding quantity |
| `latestTxTime` | number | Latest transaction timestamp (ms) |
| `lastTrade` | number | Last trade timestamp (ms) |
| `addressLogoUrl` | string\|null | Address logo URL |

**`buyCount`/`sellCount` are returned directly** — no need to aggregate `tradeSideCategory`.

### Sorting (client-side)

The API does not provide server-side sort for consensus/inflow/volume/pioneer. Sort client-side using CLI-aggregated fields:
- **Consensus** (consensus): sort by `consensusCount` descending
- **Inflow** (Net Inflow): sort by `netInflow` descending
- **Volume** (volume): sort by `volume` (string field, parse to number) descending
- **Pioneer** (pioneer): sort by `launchTime` ascending, filter `consensusCount ≤ 2`

---

## `tracker tx query` — Trade Monitor

```bash
# Private — own group trade flow
baw tracker tx query -c 56 --group-id 1 --json

# Public — SMY/KOL trade flow
baw tracker tx query -c 56 --tag-type smy --json

# Filter by trade side
baw tracker tx query -c 56 --group-id 1 --trade-side 19 --json
```

### Parameters

| Param | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `-c, --chain-id` | string | yes | — | Chain ID |
| `--group-id` | number | no | — | Target group (private mode) |
| `--tag-type` | string | no | — | `kol` / `smy` (public mode; omit for private) |
| `--trade-side` | string | no | — | Comma-separated: `19`=buy, `11`=first-buy, `29`=sell, `21`=clear |
| `--min-value` | number | no | — | Min tx USD value |
| `--max-value` | number | no | — | Max tx USD value |
| `--filter-risk` | flag | no | — | Filter risk tokens |

**Private mode**: use `--group-id`. **Public mode**: use `--tag-type kol` or `--tag-type smy` (no `--group-id`).

### Return Fields

| Field | Type | Description |
|-------|------|-------------|
| `chainId` | string | Chain ID |
| `txHash` | string | Transaction hash |
| `logId` | string | Log ID (can locate a single tx) |
| `address` | string | Sender address |
| `label` | string\|null | Address label |
| `addressLogoUrl` | string\|null | Address logo URL |
| `toAddress` | string | Receiver address |
| `toLabel` | string\|null | Receiver label |
| `toAddressLogoUrl` | string\|null | Receiver address logo URL |
| `ts` | number | Timestamp (**seconds**, not ms — 10-digit Unix timestamp) |
| `tradeSideCategory` | int | `11`=first-buy, `19`=buy, `21`=clear, `29`=sell. **May include undocumented values** — filter defensively, don't assume only these four. |
| `txUsdValue` | string | Transaction USD value |
| `txNativeTokenQty` | string | Native token quantity traded |
| `nativePrice` | string | Native token price |
| `tokenPrice` | string | Price at trade time |
| `currentPrice` | string | Current price |
| `ca` | string | Token contract address |
| `tokenName` | string | Token name |
| `tokenIconUrl` | string | Token icon URL |
| `tokenDecimals` | number | Token decimals |
| `tokenSupply` | string | Token total supply |
| `marketCap` | string | Market cap |
| `launchTime` | number | Token launch time (ms) |
| `tokenRiskLevel` | int | Risk level 0-5 |
| `rwaType` | number | RWA type |
| `tokenTag` | object | Token tag map |

**Field availability**: Live-verified — all 26 fields above are returned by both private (own group) and public (SMY/KOL) modes via `baw tracker tx query`.

**No pagination** — returns all matching records in one response.

**ca/address filtering (Skill responsibility)**: The A3 API does NOT accept `ca` or `address` as filter parameters. The Skill must filter: fetch all records via `tx query`, then filter by matching `ca` (contract address) or `address` (wallet) in the results. This is the approach for the core scenario "who in a group is buying a specific token" — fetch the group's full trade flow, then filter by `ca`.

---

## `tracker follow` — Query Follow List

```bash
baw tracker follow -c 56 --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |

### Return Fields

Returns a map where key = followed address, value = `{label}`.

**Limitation**: Only queries the **current user's** follow list. No `address` param — cannot query other users' follow lists. Default sorted by follow time.

---

## `tracker ws` — WebSocket Real-Time Push

Subscribe to WSP WebSocket push events for real-time trade monitoring.

> **This is a state stream, not an alert stream.** The same `signalId` is pushed
> repeatedly with updated state (price, maxGain, exitRate) throughout its
> lifetime — live measurement shows the order of magnitude is tens to hundreds
> of pushes per signal. A single push does NOT mean a new buy signal. Consumers
> MUST dedupe by `signalId` (merge state across pushes) and treat
> `(chainId, contractAddress)` as the business-level identity for "is this a
> new position". Three push types: **initial** (first arrival — `status`,
> `exitRate`, `maxGain` are typically `null`; `signalTriggerTime` and
> `alertPrice` are carried — see [Signal field nullability](#signal-field-nullability)
> below), **state updates** (same `signalId`, refreshed fields), and **expiry**
> (`status=timeout` at T+120min — this is an overdue notice, not a new signal).
> Implementing "one push = one buy" will repeatedly open positions on the same
> token.

```bash
# Smart Money buy/sell signals (all chains)
baw tracker ws --smy --duration 15 --json

# KOL activity on BSC, 60s
baw tracker ws --kol -c 56 --duration 60 --json

# Chain-level wallet activity (multi-chain)
baw tracker ws --wallet BSC,SOL --duration 15 --json

# Specific address monitoring
baw tracker ws --address 0xabc... -c 56 --duration 15 --json

# Batch address monitoring from file
baw tracker ws --address-list addresses.txt -c 56 --duration 15 --json

# Monitor my followings' activity
baw tracker ws --following -c 56 --duration 15 --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `--smy` | flag | no | Listen to Smart Money events (all chains, no `-c` needed) |
| `--kol` | flag | no | Listen to KOL events (requires `-c`) |
| `--wallet` | string | no | Listen to chain-level events. Comma-separated chain names: `BSC,SOL,BASE,ETH` |
| `--following` | flag | no | Listen to current user's followings' trades (requires login + `-c`, mutually exclusive with other filters) |
| `--address` | string | no | Listen to specific address events (requires `-c`) |
| `--address-list` | string | no | Path to file with addresses (one per line, requires `-c`, max 100) |
| `-c, --chain-id` | string | conditional | Chain ID (required for `--kol`, `--address`, `--address-list`, `--following`) |
| `--duration` | number | yes* | Auto-disconnect after N seconds. Default 15. Omit only when the user explicitly requests an unlimited stream. Extract from user instruction when available (e.g. "monitor for 60 seconds" → `--duration 60`). |

### Connection lifecycle

> **Requires CLI ≥ 1.9.1.** The built-in keepalive/reconnect below was added in `@binance/agentic-wallet` 1.9.1 (PR fe/web3-libs#235). On CLI 1.9.0 (currently the latest published), `--duration 0` has NO keepalive and NO reconnect — `onclose` rejects immediately. If you are on CLI < 1.9.1, you MUST implement your own connection-level reconnect (exponential backoff + re-SUBSCRIBE) even in `--duration 0` mode; the guidance in this section only applies once 1.9.1 is installed.

`--duration` selects two connection modes with different resilience semantics:

| Mode | Trigger | Behavior (CLI ≥ 1.9.1) |
|------|---------|----------|
| Bounded | `--duration N > 0` | Single connection. Auto-disconnects at N seconds. If the connection drops early, the command rejects (`TRACKER_WS_CONNECT_ERROR`) — callers needing resilience must wrap their own retry. |
| Unlimited | `--duration 0` / omitted | **Built-in keepalive + auto-reconnect.** A 30s app-level PING holds the connection; on close, the CLI reconnects with exponential backoff (5s start, ×2 per failure, cap 120s) and re-SUBSCRIBES automatically. Backoff resets to 5s on any received push. |

**For integrations wrapping `--duration 0` (CLI ≥ 1.9.1)**: the CLI handles connection-level care internally. Callers should NOT also implement connection-level reconnect/keepalive — that doubles up (e.g. an external "active rotation" that kills the process every 45min would terminate a healthy self-maintained connection; a watchdog that force-kills during CLI backoff would abort a pending reconnect). Keep only process-level supervision (restart on crash/exit) and let the CLI manage the WebSocket.

**On CLI < 1.9.1**: `--duration 0` has no keepalive and no reconnect. Callers MUST implement their own connection-level reconnect (exponential backoff + re-SUBSCRIBE) and keepalive, or accept that idle connections will be killed and one disconnect ends the stream. Do NOT follow the "do not also implement connection-level reconnect" guidance above on 1.9.0 — that would leave you with no reconnect at all.

### Filter Combinations

At least one of `--smy`, `--kol`, `--wallet`, `--following`, `--address`, `--address-list` is required. `--following` is mutually exclusive with all other filters. Multiple non-following filters can be combined (e.g. `--smy --kol -c 56` subscribes to both streams concurrently).

### JSON Output

In `--json` mode, only push message JSON is written to stdout — no meta info (streams, subKeys, connection status). This enables pipeline processing with `| jq`. In terminal mode, connection info and human-readable event summaries are printed.

Push message fields vary by stream type but typically include: `address`, `ticker`/`tokenName`, `tradeSide`, `txUsdValue`, `tokenPrice`, `timestamp`, `chainId`, `contractAddress`.

### Signal field nullability

For Smart Money signals, the **initial push** of a new `signalId` carries
`signalTriggerTime` and `alertPrice`/`alertMarketCap` (trigger-time data), but
`status`, `currentPrice`, `maxGain`, and `exitRate` are typically `null` — they
fill in on subsequent state-update pushes. `signalTriggerTime` is now reliably
present on first arrival and can be used directly to compute delivery latency.
Implications:

- **Do NOT fall back to `alertPrice` as a live entry price when `currentPrice` is null.** `alertPrice` is the historical trigger price; using it as a tradable price books an order that can't fill. Instead query the live market (`binance-web3-query-token-info` skill, `wallet/market/token/dynamic/info/ai`) and skip if unavailable.
- **Do NOT gate on `status` to decide whether a push is actionable.** `status` is `null` on ~99% of initial pushes (only `timeout`/`exitRate`/`outDecline` are set later). Filtering `if status not in ("valid", "active") → reject` will silently drop ~99% of real first pushes — the symptom looks identical to "no signals on this chain". Treat `status == null` as a fresh signal whose lifecycle state hasn't been assigned yet.
- **Merge fields across pushes by `signalId`.** The initial push carries `alertPrice`/`alertMarketCap`/`signalTriggerTime` while later pushes carry `currentPrice`/`maxGain`/`status`/`exitRate` — together they form the full signal state. See the field table in `binance-trading-signal/references/custom-signal.md` for which fields are nullable.
- **Render templates need null guards**: `Current:{currentPrice}` renders as `Current:None` for initial pushes. Guard with `currentPrice ?? 'pending'`.

### Fallback Filtering (`--following` with large lists)

When `--following` is used with a large follow list, the CLI may fall back to a broader chain-level wallet stream. Push events will then include trades from all wallets on the chain, not just the user's followings. If the user only wants their followed addresses' events, filter push messages by `address` against the follow list (`tracker follow -c <chainId> --json`). This filtering is optional — only apply it when the user specifically wants followed-address-only events.

---

## `tracker group list` — List Groups

```bash
baw tracker group list -c 56 --json
baw tracker group list -c 56 --no-all-group --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `--no-all-group` | flag | no | Exclude the "All" virtual group (default: includes All) |

### Return Fields

| Field | Type | Description |
|-------|------|-------------|
| `groupId` | number | Group ID |
| `groupName` | string | Group name |
| `addressCount` | number | Address count in group |
| `displayOrder` | number | Display order (All=-1, Default=0, others sequential) |

**Field name**: `displayOrder`. Sort groups by `displayOrder`: All=-1, Default=0, others sequential.

---

## `tracker group create` — Create Group

```bash
baw tracker group create -c 56 -n "Base-Sniper" --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `-n, --name` | string | yes | Group name |

### Return

`Long` — new group ID.

---

## `tracker group update` — Rename Group

```bash
baw tracker group update -c 56 -g 1 -n "NewName" --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `-g, --group-id` | number | yes | Group ID |
| `-n, --name` | string | yes | New group name |

### Return

`Void`.

---

## `tracker address search` — Fuzzy Search

```bash
baw tracker address search -c 56 -g 1 -a 0xabc --json
baw tracker address search -c 56 -g 1 --label "whale" --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `-g, --group-id` | number | yes | Group ID |
| `-a, --address` | string | no | Address keyword |
| `--label` | string | no | Label keyword |

### Return Fields

| Field | Type | Description |
|-------|------|-------------|
| `chainId` | string | Chain ID |
| `address` | string | Wallet address |
| `label` | string | Address label |
| `emoji` | string | Emoji tag |
| `color` | string | Color tag |
| `groupId` | number | Group ID |
| `groupName` | string | Group name |
| `isFollowed` | boolean | Whether the address is followed by current user |
| `addressLogoUrl` | string | Address logo URL |
| `genericAddressTagList` | array | Generic tags |
| `lastActiveTime` | number | Last active timestamp (ms) |
| `nativeTokenQty` | string | Native token quantity |

---

## `tracker address list` — Paginated List

```bash
baw tracker address list -c 56 -g 1 --page 1 --size 20 --json
```

### Parameters

| Param | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `-c, --chain-id` | string | yes | — | Chain ID |
| `--group-id` | number | yes | — | Group ID |
| `--address` | string | no | — | Address filter |
| `--label` | string | no | — | Label filter |
| `--page` | int | yes | `1` | Page number (from 1, min 1) |
| `--size` | int | no | `20` | Page size (max 100) |

### Return

Returns `{ total: number, rows: [...] }` where rows contain the same fields as search above.

---

## `tracker address add` — Add Single Address

Wraps `import` with `enforce=false` and single-item list.

```bash
baw tracker address add -c 56 -g 1 -a 0xabc --label "Whale1" --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `-g, --group-id` | number | no | Target group |
| `-a, --address` | string | yes | Wallet address |
| `--label` | string | no | Address label |

### Return

`Integer` — count of imported addresses (1 or 0).

---

## `tracker address batch` — Batch Import

```bash
baw tracker address batch -c 56 -g 1 -a 0xabc,0xdef --json
# Or with labels: -a '[{"address":"0xabc","label":"Whale1"},{"address":"0xdef"}]'
```

### Parameters

| Param | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `-c, --chain-id` | string | yes | — | Chain ID (single chain per call) |
| `-g, --group-id` | number | no | — | Target group |
| `-a, --addresses` | string | yes | — | Comma-separated addresses, or JSON array of `[{address, label?}]` |
| `--no-overwrite` | flag | no | — | Do not overwrite existing labels |

### Return

`Integer` — count of imported addresses.

**No new/exist/overwrite breakdown**: The API only returns a single Integer (imported count). The CLI cannot provide new/exist/overwrite breakdown. To track duplicates, compare the address list before/after import via `address list`.

**⚠️ `allowOverwrite` defaults to `true`** — existing labels are overwritten silently. Use `--no-overwrite` to get 409 conflicts instead.

**Cross-chain auto-dispatch**: CLI requires a single `-c` per call. When the user provides mixed EVM + Solana addresses, the Skill must classify by address format (EVM: `^0x[a-fA-F0-9]{40}$` → BSC/Base; Solana: Base58 → `CT_501`), group by chain, and call `batch` once per chain. Aggregate results across all chains.

---

## `tracker address update` — Update Label

```bash
baw tracker address update -c 56 -a 0xabc --label "NewLabel" --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `-a, --address` | string | yes | Wallet address |
| `--label` | string | no | New label |

**⚠️ `groupId` is deprecated** for `update`. Use `tracker address link` to change group.

### Return

`Void`.

---

## `tracker address link` — Link to Group

```bash
baw tracker address link -c 56 -a 0xabc -g 2 --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `-a, --address` | string | yes | Wallet address |
| `-g, --group-id` | number | no | Target group (null = default group) |

### Return

`Void`.

---

## `tracker address delete` — Delete Addresses

```bash
baw tracker address delete -c 56 -g 1 -a 0xabc,0xdef -y --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `-g, --group-id` | number | yes | Group ID |
| `-a, --addresses` | string | yes | Comma-separated addresses to delete |
| `-y, --yes` | flag | no | Skip confirmation prompt |

### Return

`Void`.

---

## `tracker address follow` — Follow Address

```bash
baw tracker address follow -c 56 -g 1 -a 0xabc --label "Follow1" --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `-g, --group-id` | number | no | Group ID |
| `-a, --address` | string | yes | Wallet address |
| `--label` | string | no | Label for the followed address |

### Return

Returns `{address, followed: true}`. `followed` is a boolean status flag.

---

## `tracker address unfollow` — Unfollow Address

```bash
baw tracker address unfollow -c 56 -a 0xabc --json
```

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `-c, --chain-id` | string | yes | Chain ID |
| `-a, --address` | string | yes | Wallet address |

### Return

Returns `{address, followed: false}`.
SKILL.md›
---
name: binance-wallet-tracker
description: |
  Wallet tracking and monitoring on Binance Web3. Monitor token/trade activity for private groups
  or public Smart Money/KOL data. Four domains: (A) Discovery — consensus, pioneer,
  leaderboard diff, token buyer lookup, time-window summaries, similar wallets; (B) Evaluation —
  token risk (tokenRiskLevel ≥ 3), group rhythm, follow list assessment, token heat; (C) Replay —
  4h summary, Accumulation/Distribution, sector rotation, anomaly orders, round-trip, first-mover/leader-follower,
  wake-up, bot-like; (D) Management — group create/rename, batch import, label update, link, follow list;
  (E) Real-time — WebSocket push for Smart Money, KOL, wallet-level, and address-level trade events.
  Trigger on: wallet tracker, monitoring, consensus, pioneer, accumulation, Distribution, Sector Rotation, Anomaly Large Order,
  round-trip, first-mover, wake-up, bot-like, token risk, token heat, group profile, similar wallets,
  group management, address import, follow list, real-time push, WebSocket — even without "tracker" explicitly.
metadata:
  author: binance-web3-team
  version: "1.3"
  requiredCliVersion: '1.9.1'
  openclaw:
    requires:
      bins:
        - baw
    install:
      - kind: node
        package: '@binance/agentic-wallet'
        bins: [baw]
        label: Install Binance Agentic Wallet CLI (npm)
---

# Binance Wallet Tracker Skill

On-chain wallet tracking and monitoring. Monitor token-level and trade-level activity for private groups or public Smart Money / KOL data. Includes 9 built-in analysis scenarios for replay and pattern detection.

## Prerequisites

This skill requires the `baw` CLI (`@binance/agentic-wallet` npm package). If `baw` is not found:

```bash
npm install -g @binance/agentic-wallet
```

Verify: `baw --version` should print `1.6.2` or higher. If installation fails or the user doesn't have Node.js, inform them that Node.js >= 18 is required.

## When to Use

### Discovery

| User intent | Command |
|-------------|---------|
| Consensus tokens (many buyers) | `tracker token query` → sort by `consensusCount` |
| Pioneer tokens (≤2 traders) | `tracker token query` → filter `launchTime` + `consensusCount ≤ 2` |
| Leaderboard diff (untracked wallets) | `leaderboard query` (leaderboard skill) + `tracker address list` → diff |
| Token-based buyer lookup | `tracker tx query` → client-side filter by `ca` |
| Time-window summary | `tracker token query --period 4h` + `tracker tx query` |
| Similar wallet discovery | `leaderboard analyze` (leaderboard skill) → archetype matching |

### Evaluation

| User intent | Command |
|-------------|---------|
| Token risk screening | `tracker token query` → filter `tokenRiskLevel ≥ 3` + `consensusCount ≥ 3` |
| Group rhythm profiling | `tracker tx query` → per-address rhythm analysis |
| Follow list assessment | `tracker follow` + `leaderboard analyze` (cross-skill) |
| Token heat analysis | `tracker tx query` → aggregate by `ca` |

### Replay

| User intent | Command |
|-------------|---------|
| 4h comprehensive summary | `tracker token query --period 4h` + `tracker tx query` |
| Accumulation vs distribution (Accumulation/Distribution) | `tracker token query` → `buyCount`/`sellCount` per address |
| Sector rotation | `tracker tx query` → compare token top across time windows |
| Anomaly large orders | `tracker tx query` → `anomaly` detection |
| Round-trip (Round-Trip) | `tracker tx query` → `round-trip` detection |
| First-mover + leader-follower | `tracker tx query` → `first-mover` + `leader-follower` |
| Wake-up detection | `tracker tx query` → `wake-up` detection |
| Bot-like behavior | `tracker tx query` → `bot-like` detection |

Full 9-scenario analysis rules: [`references/analytics.md`](references/analytics.md)

### Management

| User intent | Command |
|-------------|---------|
| Create / rename group | `tracker group create/update` |
| Batch import addresses | `tracker address batch` |
| Add single address | `tracker address add` |
|| Update label / link to group | `tracker address update -l` + `tracker address link` |
| Delete addresses | `tracker address delete` |
| Follow / unfollow address | `tracker address follow/unfollow` |
| View follow list | `tracker follow` |
| Search address (fuzzy) | `tracker address search` |

## Supported Chains

| Chain | chainId |
|-------|---------|
| BSC | `56` |
| Solana | `CT_501` |
| Base | `8453` |
| Ethereum | `1` |
| Robinhood | `4663` |

This table lists chains verified for tracker use; it is a subset of `baw wallet chains` (which returns all wallet-supported chains, e.g. Arbitrum 42161, Polygon 137). Before treating a chain as unsupported for tracking, probe it first — the wallet chain list is dynamic.

## Command Tree

```
baw tracker
  token query                # Token dimension monitor (private + --tag-type for public)
  tx query                   # Trade dimension monitor (private + --tag-type for public)
  follow                     # Query current user follow list (read-only, chainId only)
  ws                         # WebSocket real-time push (--smy/--kol/--wallet/--address/--following)
  group
    list                     # Group list
    create                   # Create group
    update                   # Rename group
  address
    search                   # Fuzzy search address
    list                     # Paginated address list
    add                      # Add single address (wraps import)
    batch                    # Batch import
    update                   # Update label (label only)
    link                     # Link to group (group/link)
    delete                   # Delete (supports batch)
    follow                   # Follow address
    unfollow                 # Unfollow
```

All commands support `--json` for structured output.

**`token query` and `tx query` require either `--group-id` (private group) or `--tag-type` (public KOL/SMY). Calling without either returns an error.**

**`--tag-type` accepts: `kol` (KOL), `smy` (Smart Money).**

## Token Monitor (A2)

```bash
# Private — own group data (must specify --group-id or --tag-type)
baw tracker token query -c 56 --group-id 1 --json
baw tracker token query -c 56 --group-id 1 --period 4h --json

# Public — SMY/KOL data
baw tracker token query -c 56 --tag-type kol --json   # KOL
baw tracker token query -c CT_501 --tag-type smy --json  # Smart Money
```

Returns per-token aggregated data: token name, CA, price, market cap, volume, `addressList[]` (per-address buy/sell/inflow), `launchTime`, `tokenRiskLevel`, `tokenTag`.

**Consensus computation**: The API does NOT return top-level `traderNum` or `inFlow`. The CLI aggregates `consensusCount` = `addressList.length`, `netInflow` = Σ `addressList[].inflow`, `countBuy`/`countSell` = Σ buy/sell counts. Use these fields directly.

**Per-address fields**: `address`, `label`, `buyCount`, `sellCount`, `inflow`, `tokenQty`, `latestTxTime`, `lastTrade`, `addressLogoUrl`.

Full parameter and return field reference: [`references/cli.md`](references/cli.md)

## Tx Monitor (A3)

```bash
# Private — own group trade flow
baw tracker tx query -c 56 --group-id 1 --json

# Public — SMY/KOL trade flow
baw tracker tx query -c 56 --tag-type smy --json

# Filter by trade side (19=buy, 11=first-buy, 29=sell, 21=clear)
baw tracker tx query -c 56 --group-id 1 --trade-side 19 --json
```

Returns per-trade records: `txHash`, `logId`, `address`, `ts`, `tradeSideCategory`, `txUsdValue`, `tokenPrice`, `currentPrice`, `ca`, `tokenName`, `marketCap`, `tokenRiskLevel`, `tokenTag`, plus optional `toAddress`, `toLabel`, `nativePrice`, `txNativeTokenQty`, `tokenDecimals`, `tokenSupply`, `launchTime`, `rwaType`.

**⚠️ Critical: `ts` is in SECONDS (not milliseconds)** — 10-digit Unix timestamp. All time-window calculations (round-trip <1h, wake-up >72h, co-buy 10min window) must use seconds. A2's `latestTxTime`/`launchTime` ARE in milliseconds (13-digit).

**No pagination** — returns all matching records in one response.

**ca/address filtering (Skill responsibility)**: The A3 API does NOT accept `ca` or `address` as filter parameters. The Skill handles this filtering: fetch all records from `tx query`, then filter by matching `ca` (contract address) or `address` (wallet) in the results. This enables the core scenario "who in a group is buying a specific token" — fetch the group's full trade flow, then filter by `ca`.

## Follow Query (A4)

```bash
# Query current user's follow list (chainId only)
baw tracker follow -c 56 --json
```

Returns a map where key = followed address, value = `{label}`.

**Limitation**: Only queries the **current user's** follow list. You cannot query another user's follow list. For "evaluate follow list" scenarios, combine with `binance-leaderboard` skill's `leaderboard analyze` to score each followed address.

## Group Management (B1)

```bash
# List groups (displayOrder: All=-1, Default=0, others sequential)
baw tracker group list -c 56 --json

# Create group
baw tracker group create -c 56 -n "Base-Sniper" --json

# Rename group
baw tracker group update -c 56 -g 1 -n "NewName" --json

# Note: group delete is not available in the CLI. Groups can only be created and renamed.
```

**Group fields**: `groupId`, `groupName`, `addressCount`, `displayOrder`. Sort groups by `displayOrder`: All=-1, Default=0, others sequential.

## Address Management (B2)

```bash
# Fuzzy search
baw tracker address search -c 56 -g 1 -a 0xabc --json

# Paginated list
baw tracker address list -c 56 -g 1 --page 1 --size 20 --json

# Single add (wraps import with enforce=false)
baw tracker address add -c 56 -g 1 -a 0xabc --label "Whale1" --json

# Batch import (comma-separated addresses or JSON array of {address,label})
baw tracker address batch -c 56 -g 1 -a 0xabc,0xdef --json
# Or with labels: -a '[{"address":"0xabc","label":"Whale1"},{"address":"0xdef"}]'

# Update label only (groupId is deprecated for update)
baw tracker address update -c 56 -a 0xabc --label "NewLabel" --json

# Link to another group
baw tracker address link -c 56 -a 0xabc -g 2 --json

# Delete (comma-separated addresses)
baw tracker address delete -c 56 -g 1 -a 0xabc,0xdef -y --json

# Follow / unfollow
baw tracker address follow -c 56 -g 1 -a 0xabc --label "Follow1" --json
baw tracker address unfollow -c 56 -a 0xabc --json
```

**Import defaults**: `allowOverwrite` defaults to `true` (overwrites existing label). `enforce` defaults to `false`. Use `--no-overwrite` to disable overwrite.

**Follow response**: Returns `{address, followed: true}` — NO `groupId` field. `followed` is a boolean status flag.

**Address search/list fields**: Returns `address`, `label`, `emoji`, `color`, `groupId`, `groupName`, `isFollowed`, `addressLogoUrl`, `genericAddressTagList`, `lastActiveTime`, `nativeTokenQty`.

Full parameter and return field reference: [`references/cli.md`](references/cli.md)

## Core Rules

### Consensus & Inflow Computation (A2)

The API does NOT return top-level `traderNum`, `inFlow`, `countBuy`, or `countSell` fields. The CLI aggregates these from `addressList[]` and exposes them as:
- **`consensusCount`** (Consensus) = `addressList.length`
- **`netInflow`** (Net Inflow) = Σ `addressList[].inflow`
- **`countBuy`** (accumulation count) = Σ `addressList[].buyCount`
- **`countSell`** (distribution count) = Σ `addressList[].sellCount`

Use these CLI-aggregated fields directly — no need to re-compute from `addressList`.

### Accumulation vs Distribution

`buyCount` and `sellCount` are returned per-address directly. No need to aggregate `tradeSideCategory` — use these fields directly for Accumulation/Distribution analysis.

### Client-Side Filtering (Skill responsibility)

The A2/A3 APIs do NOT accept `ca` or `address` as filter parameters. The `caList` param on A2 token/query is accepted but silently ignored by the backend. The Skill handles this filtering:
1. Fetch all records via `token query` or `tx query` (no ca/address filter)
2. Filter by matching `ca` (contract address) or `address` (wallet) in the results

This enables core scenarios like "who in a group is buying a specific token" — fetch the group's full trade flow, then filter by `ca`.

This affects: Find Buyers by Token (co-buy), token-based buyer lookup, and any scenario requiring single-token or single-address focus.

### Follow List Limitation (A4)

`tracker follow` only queries the **current user's** follow list (chainId only, no address param). You cannot evaluate another user's follow list. For "evaluate follow list" scenarios, combine with `binance-leaderboard` skill's `analyze` command.

### Group Field Names

`group list` returns `displayOrder`. Sort groups by `displayOrder`: All=-1, Default=0, others sequential.

**Follow Response Fields**

`address follow` response returns `{address, followed: true}`. `followed` is a boolean status flag.

### Write-Back Confirmation

After any write operation (create/update/delete/import/follow/unfollow/link), re-fetch the affected resource to confirm the operation succeeded — this guards against `agentSessionId` silent expiry and backend silent failures.

**Readback failure handling**: If readback shows the operation didn't take effect (e.g. address still exists after delete, group not found after create), tell the user "Operation may not have taken effect, please try again later" — never mention backend bugs, silent failures, or error codes.

### Destructive Operation Safety

Delete, link, and unfollow operations require `-y` flag (or interactive confirmation) before execution. Always confirm with the user before executing destructive operations.

### EVM Address Case Normalization (delete only)

The backend stores EVM addresses as lowercase (import API lowercases them), but `address/delete` does case-sensitive matching. If the user provides an EIP-55 mixed-case address (e.g. `0x52908400098527886E0F7030069857D03E3248B4`), delete will silently fail — return `success:true` without actually deleting. The CLI does NOT normalize; it passes through as-is.

**Skill responsibility**: Before calling `baw tracker address delete`, normalize EVM addresses to lowercase:
- EVM (`0x` + 40 hex): `address.toLowerCase()`
- Solana (Base58, case-sensitive): pass through as-is — do NOT lowercase

This is verified against QA: import with mixed case stores as lowercase, delete with lowercase succeeds, delete with mixed case returns `success:true` but address remains.

### Batch Import Behavior

`address batch` / `address add`:
- `allowOverwrite` defaults to `true` — existing labels are overwritten
- `enforce` defaults to `false` — skips validation enforcement
- Chain is specified by `-c` — CLI does NOT auto-detect address format
- **Cross-chain auto-dispatch (Skill responsibility)**: When the user provides a mixed list of EVM + Solana addresses, the Skill must:
  1. Classify each address by format:
     - EVM: matches `^0x[a-fA-F0-9]{40}$` → chainId `56` (BSC) or `8453` (Base) — determine by user context or ask
     - Solana: Base58, 32-44 chars, no `0x` prefix → chainId `CT_501`
  2. Group addresses by chain
  3. Call `baw tracker address batch -c <chainId>` once per group
  4. Aggregate results (new/exist/overwrite counts) across all chains

### Real-Time Monitoring (WebSocket)

| User intent | Command |
|-------------|---------|
| Real-time Smart Money buy/sell signals | `tracker ws --smy --duration 15` |
| Real-time KOL activity on a chain | `tracker ws --kol -c <chainId> --duration 15` |
| Chain-level wallet activity (multi-chain) | `tracker ws --wallet BSC,SOL --duration 15` |
| Monitor specific address trades | `tracker ws --address <addr> -c <chainId> --duration 15` |
| Batch address monitoring (file) | `tracker ws --address-list <file> -c <chainId> --duration 15` |
| Monitor my followings' activity | `tracker ws --following -c <chainId> --duration 15` |

`tracker ws` subscribes to WSP WebSocket push events. It streams real-time trade data (buys, sells, price changes) for the selected scope. In `--json` mode, only push messages are written to stdout (no meta info), enabling pipeline processing with `| jq`.

**`--duration` is required unless the user explicitly asks for an unlimited stream.** Extract the duration from the user's instruction when available (e.g. "monitor for 60 seconds" → `--duration 60`). If no duration is specified, default to `--duration 15`.

> **`--following` tip**: When the followed address list is large, the CLI may fall back to a broader chain-level stream. If the user only wants events for their followed addresses, filter push messages by `address` against the follow list (`tracker follow -c <chainId> --json`).

### Limitations

- **Token price change**: `token/query` may not reliably return `priceChangeRate` for all tokens. For reliable price data, use marketCap + risk + pioneer timing as proxy.
- **Time window filtering**: `token/query` has a `period` param (1m/5m/1h/4h/24h), but granular time-window queries (e.g., "past 4h") rely on client-side aggregation of `tx/query` `ts` fields.
- **A4 Follow read-only**: `tracker follow` only queries the current user's own follow list. Follow/unfollow writes use `address follow`/`unfollow` commands (B2).

## 9 Analysis Scenarios (A3)

Built-in analysis patterns for `tracker tx query` data. Full rules and algorithms: [`references/analytics.md`](references/analytics.md)

| Scenario | Detection Rule |
|----------|----------------|
| rhythm | Per-address count/buys/sells/mean_usd/active hours |
| anomaly | `txUsdValue > 3×mean` and `> 500` |
| co-buy | Same `ca`, ≥3 buyers within 10min window |
| round-trip | Same address same `ca`, buy→sell < 1h |
| rotation | Token top diff across time windows |
| first-mover | Earliest buyer of a `ca` |
| leader-follower | Median delay after first-mover |
| wake-up | New activity after >72h gap |
| bot-like | Low interval variance + high night ratio + low amount dispersion |

## Error Codes

Error codes are for internal lookup only — never show numeric codes or internal names to users. Translate to natural-language messages.

| Code | Internal Name | User-Facing Message |
|------|---------------|---------------------|
| 70001001 | TRACKER_API_ERROR | Query failed, please try again later |
| 70002001 | TRACKER_GROUP_NOT_FOUND | Group not found |
| 70002002 | TRACKER_GROUP_EXISTS | Group already exists |
| 70002003 | TRACKER_GROUP_LIMIT | Group limit reached |
| 70003001 | TRACKER_ADDRESS_NOT_FOUND | Address not found |
| 70003002 | TRACKER_ADDRESS_EXISTS | Address already exists |
| 70003003 | TRACKER_ADDRESS_INVALID | Invalid address format |

## Display Templates

**Consensus token**:
```
📊 Consensus Tokens Top 5
{tokenName} | Consensus: {consensusCount} | Net Inflow: ${netInflow} | Accumulation: {countBuy} | Distribution: {countSell} | Liquidity: {volume} | Risk: {riskLevel}
```

**Trade flow entry**:
```
{ts} | {label} | {tradeSideLabel} {tokenName} | ${txUsdValue} | Price: {tokenPrice} → {currentPrice}
```

**Group info**:
```
{groupName} ({addressCount}addresses)
```

## User-Facing Presentation

This skill serves end users, not developers. Internal field names, error codes, and CLI internals must never appear in user-facing output.

**1. Term Mapping (internal → user-facing)**

| Internal value | User-facing term | Notes |
|----------------|-------------------|-------|
| `tradeSideCategory: 11` | First Buy | |
| `tradeSideCategory: 19` | Buy | |
| `tradeSideCategory: 21` | Clear Position | |
| `tradeSideCategory: 29` | Sell | |
| `tradeSideCategory: other` | Unknown Trade Type | May include undocumented values |
| `tokenRiskLevel: 0-2` | Low Risk | |
| `tokenRiskLevel: 3-5` | High Risk | ≥3 = high risk |
| `groupId` | (omit) | Never show in user-facing output |
| `displayOrder` | (omit) | Never show in user-facing output |
| `ca` (in display) | (omit unless asked) | Use `{tokenName}` as primary identifier |
| `address` (in display) | `{label}` | Use label, not raw address |

Raw enum values (`19`, `11`, etc.) may appear in CLI syntax examples and internal lookup tables, but never in user-facing replies.

**2. Never expose internal identifiers**

- `groupId`, `displayOrder` — internal IDs, never shown to users
- Error codes (`70001001`, etc.) — translate to natural-language messages only
- Backend behavior details (e.g. delete silently failing on case mismatch, preset save not persisting) — never mention "backend bug" or "silent failure"; handle gracefully with readback

**3. Display template hygiene**

Use user-facing terms in all output. The `tradeSideCategory` field should be translated to its display term (Buy, Sell, etc.) — never show the raw numeric value. `tokenRiskLevel` should be shown as Low Risk/High Risk, not as a number. `groupId` and `displayOrder` should not appear in display templates.

## Full CLI Reference

- [`references/cli.md`](references/cli.md) — All commands with parameter tables, return field tables, and examples
- [`references/analytics.md`](references/analytics.md) — 9 analysis scenarios with detection rules and algorithms