wallet_classification is a daily wallet snapshot derived from stablecoin activity. This page documents every column and the exact cutoffs behind each classification. For how rows are selected and how to query efficiently, see the Overview.
Filter by chain on every query — the crosschain table spans 30+ chains and is clustered on snapshot_date. See the Overview for query patterns.
Table Columns
Unique Key: chain, address, snapshot_date
Identity & snapshot
| Column Name | Data Type | Description |
|---|
chain | VARCHAR | Blockchain the wallet was active on, lower case (e.g. ethereum). Always filter on this. |
address | VARCHAR | Wallet address. A wallet active on multiple chains appears as one row per chain. |
snapshot_date | DATE | The wallet’s most recent day of recorded stablecoin activity. Rolling 30-day metrics are computed as of this date. |
Size & balance
| Column Name | Data Type | Description |
|---|
balance_tier | VARCHAR | Size bucket based on the wallet’s maximum stablecoin balance ever held (see thresholds below). |
current_balance_usd | FLOAT | Stablecoin balance (USD) as of snapshot_date. On chains without native end-of-day balances this is reconstructed from net transfer flow and is best-effort. |
volume_30d_usd | FLOAT | Total stablecoin transfer volume (sent + received) in the rolling 30 days ending on snapshot_date. |
balance_tier cutoffs (by lifetime max stablecoin balance):
| Tier | Max balance (USD) |
|---|
whale | ≥ 1,000,000 |
large | ≥ 100,000 |
medium | ≥ 10,000 |
small | ≥ 1,000 |
micro | ≥ 25 |
dust | < 25 |
Wallet type
| Column Name | Data Type | Description |
|---|
wallet_type | VARCHAR | Consumer, Business, or Institutional — assigned by a layered rule set: attribution labels first, then behavioral patterns (cross-chain reach, volume-to-balance ratio, balance volatility, balance drawdown, token diversity), then a balance-tier fallback. Internal-only addresses resolve to Excluded. |
wallet_type blends signals, not a single threshold. As a rough guide: Institutional = very high volume, multi-chain reach, or large balances with high turnover; Business = high, steady throughput with a meaningful balance floor (≥ 1,000average30−daybalance,≥10,000 on Tron to account for high USDT velocity); Consumer = everything else with genuine end-user activity.
Lifecycle
| Column Name | Data Type | Description |
|---|
behavioral_segment | VARCHAR | Activity lifecycle stage (see thresholds below). |
combined_segment | VARCHAR | balance_tier + behavioral_segment, title-cased (e.g. Whale Active, Medium Dormant). Convenient single grouping key. |
behavioral_segment definitions:
| Segment | Definition |
|---|
new | First seen within the last 30 days |
active | Had activity within the last 30 days |
dormant | No activity in the last 30 days, but active within the last 90 |
churned | Last activity more than 90 days ago |
Activity metrics
| Column Name | Data Type | Description |
|---|
days_since_last_activity | NUMBER | Days between snapshot_date and the query date. |
days_active_30d | NUMBER | Distinct days with activity in the rolling 30 days (0–30). |
days_active_lifetime | NUMBER | Distinct days the wallet has ever been active. |
lifetime_span_days | NUMBER | Days between the wallet’s first and last activity. 0 if both fall on the same day. |
tokens_used_count | NUMBER | Distinct stablecoin tokens ever transferred by the wallet (lifetime). |
chains_used_count | NUMBER | Distinct chains the wallet’s stablecoin activity was observed on, as computed within the source. In the per-chain tables this is 1; aggregate across rows (group by address) for a true multi-chain count. |
Engagement
engagement_score (0–100) measures how consistently active a wallet is. It is the sum of three sub-scores.
| Column Name | Data Type | Description |
|---|
engagement_score | NUMBER | recency_score + frequency_score + consistency_score (0–100). |
engagement_tier | VARCHAR | Bucketed engagement_score (see thresholds below). |
recency_score | NUMBER | 0–40, from how recently the wallet was active: 40 if active in the last 7 days; 30 if within 14 days; 20 if within 30 days; otherwise decays toward 0. |
frequency_score | NUMBER | 0–40, from days_active_30d: 40 at ≥25 active days, 35 at ≥20, 30 at ≥15, 25 at ≥10, 15 at ≥5, else days_active_30d × 2. |
consistency_score | NUMBER | 0–20, from the share of the wallet’s lifetime it has been active: min(20, (days_active_lifetime / lifetime_span_days) × 20). |
engagement_tier cutoffs:
| Tier | Engagement score |
|---|
highly_engaged | ≥ 80 |
engaged | ≥ 60 |
moderately_engaged | ≥ 40 |
low_engagement | ≥ 20 |
inactive | < 20 |
Risk
risk_score (0–100) flags balance volatility and anomalous swings. It is the sum of two sub-scores. It is a behavioral/volatility signal, not a sanctions or compliance screen.
| Column Name | Data Type | Description |
|---|
risk_score | NUMBER | volatility_risk_score + anomaly_risk_score (0–100). |
risk_flag | VARCHAR | high (≥ 70), medium (≥ 40), or low (< 40). |
volatility_risk_score | NUMBER | 0–50, from the 30-day balance coefficient of variation (stddev ÷ mean): 50 at CV ≥ 2.0, 40 at ≥ 1.0, 30 at ≥ 0.5, 20 at ≥ 0.3, else scaled down. |
anomaly_risk_score | NUMBER | 0–50, from the 30-day balance change: 50 at >500% change, 40 at >200%, 30 at >100%, 20 at >50%; also 40 when the balance is zero but 30-day volume exceeds $1,000 (drained wallet). |
Risk scores reflect stablecoin balance behavior only. A high score signals volatility or large swings worth a closer look, not wrongdoing.