Wallet Evidence Model
walletEvidence is a provenance-aware layer on the /api/wallet response. It normalizes
Etherscan transaction/transfer/balance data, Alchemy token balances, DeFiLlama contract
pricing, CoinGecko ETH pricing, and cache-only Dune DEX-trade enrichment into source-aware
claims: what is claimed, which source(s) back it, what its status is, what scope it
covers, what was excluded, what fallback was used, and how confident the UI should be.
Its central job is distinguishing zero data from unavailable or degraded data — for
example, a wallet that genuinely holds no ERC-20 tokens must never look identical to a
wallet whose token balances simply failed to load. See
Data Quality and Observability for the underlying
observability / dataQuality fields this model builds on, and the
Model Layer for the shared schema conventions it follows.
Wallet scan lifecycle
Every step below is read-only. There is no wallet connection, no signature request, and no transaction is ever executed on this path. The Wallet Evidence Model never calls a provider itself — it transforms data the route handler already fetched. If a provider is not configured or fails for this request, the affected claim reports a non-fresh status and an explicit caveat instead of silently
reading as “no data.”
Evidence schema
WALLET_EVIDENCE carries exactly five CLAIMs today — pricedPortfolioValue,
tokenHoldings, activity, protocolAffinity, and movements — plus one
SOURCE_HEALTH entry per provider (Etherscan, Alchemy, DeFiLlama, CoinGecko, Dune). A
CLAIM may name zero or more EXCLUSIONs (what it deliberately leaves out) and
FALLBACKs (what degraded path it used); every excluded or fallback reason also rolls
up into the top-level warnings list.
Status vocabulary
Every claim and everysourceHealth entry uses one shared status vocabulary, so
“throttled” or “fresh” means the same thing everywhere in the object:
| Status | Meaning |
|---|---|
fresh | The source answered normally for this request. |
partial | Some of the claim’s data loaded; part of it is sampled or incomplete. |
degraded | The source responded but produced no usable result for this wallet. |
throttled | The source rate-limited this request — a temporary gap, not a fact. |
unavailable | The source failed for this request. |
not_configured | No API key/credential is configured for this source. |
not_used | The source was not needed for this claim (not a failure). |
Claims
| Claim | Answers |
|---|---|
pricedPortfolioValue | What is the wallet’s priced USD value, and which legs (ETH, tokens) contributed? |
tokenHoldings | Which ERC-20 holdings were priced, and what was excluded (unpriced, invalid, or beyond the top-25 cap)? |
activity | How many observed transactions and token transfers, and is the sample complete? |
protocolAffinity | Which known routers/contracts does observed activity touch — not full protocol exposure. |
movements | The largest priced-movement candidates, and how each was priced (transfer-time vs. current rate). |
Not built for the mock/demo provider — synthetic data has no real provenance to
report, so
walletEvidence is simply absent there. Every consumer treats it as
optional and falls back to the legacy fields it extends.Evidence layer, at a glance
Related
Data Quality and Observability
The underlying observability and data-quality fields this model builds on.
Model Layer
The shared schema layer for source provenance and quality metadata across features.
Wallet Graph Contract
The full
/api/wallet response contract that walletEvidence extends.
