Wallet Graph Response Contract v1
GET /api/wallet?address=<0x-or-ens> returns a WalletGraph document for the read-only Ethereum wallet explorer. The contract is normalized by a shared normalization layer before the route sends JSON.
Request flow
The normalization layer sits between the route and the response: it strips internal-only metadata and sanitizes error messages and labels before anything reaches the client. See Serialization guardrails below for the full list of what must never appear in the response.Top-level fields
Required stable metadata:
Existing wallet metrics remain available for compatibility:
ens, ownedENSNames, totalValueUSD, totalValueEstimated, ethBalance, firstSeen, lastActive, txCount, overallRiskScore, dataConfidence, dataSource, transactions, and fingerprintScore.
Fingerprint score
fingerprintScore.total and every entry in fingerprintScore.breakdown are
nullable. Consumers must not assume a number.
Rules a consumer can rely on:
- A
partialresult is numeric. Itstotalis the ordinary sum of the same five component formulas — bounded coverage lowersconfidenceand is named incaveats, it never rescales a component. There is no renormalization onto a reduced denominator. - A subset is never summed. One to four measured dimensions is
insufficient_datawith anulltotal, not a partial score. A behavioural fingerprint cannot be assembled from part of itself. - Confirmed empty and unavailable are different facts. Both yield
insufficient_data, distinguished byreasonCodes:wallet_confirmed_emptymeans the history was read successfully and holds nothing measurable;wallet_evidence_unavailablemeans a source did not answer. A confirmed-empty wallet may still carry an observedriskManagementvalue. - A component of
0is a real measurement and must not be treated as absent. Onlynullmeans “not measured”. - Weights, ceilings, threshold anchors and label bands are unchanged. The eligibility gate decides whether a dimension is scored, never how.
evidence[axis].state is one of observed_complete,
observed_partial, confirmed_empty, unavailable or malformed. It is
derived from the canonical evidence-quality fields carried alongside it
(valueState, coverage, sampleStrength, invariantStatus), which remain the
source of truth.
History-leg dependencies
The two transaction-history legs settle independently, and each axis declares which it needs inevidence[axis].dependsOnLegs:
Combined axes join both legs pessimistically — the result is never stronger
than either input (
full+partial → partial, full+unknown → unknown),
and combined axes report nativeCoverage and tokenCoverage so the join is
auditable. A failed required leg withholds the axis rather than downgrading
it: a missing ERC-20 leg removes whole nodes, which makes the ratio unknown
rather than merely partial. A leg that succeeded and returned nothing is
confirmed-empty, not failed.
Coverage that is omitted by the caller is unknown, never full — silence
is not evidence of completeness. A producer that observed complete windows must
say so explicitly.
A malformed or legacy fingerprintScore is normalized to insufficient_data
rather than rejected, so a bad cached value degrades the score and never fails
the wallet response.
Data quality
dataQuality preserves legacy booleans and adds explicit flags:
Transaction sample
transactionSample describes loaded normal transactions, not global wallet totals:
Nodes
Each node is normalized to include:Optional node fields
Optional node fields
These fields may be present when derivable:
fullAddress, color, volumeEstimated, riskScore, balanceUSD, priceUSD, firstSeen, lastActive, protocolAttributionConfidence, timeline, topCounterparties, delta7d, anomalies, opportunities.Edges
Each edge is normalized to include:
Current edge relationships: wallet-to-token, token-to-protocol, and token-to-counterparty, derived from loaded Ethereum wallet activity.
Serialization guardrails
_observabilityMetais stripped before the response is sent and must not appear in the response body.- No provider API key or secret material may appear in any serialized field.
apiErrors[].messageis sanitized before the route returns.- Node
labelvalues are sanitized — phishing/spam symbols are redacted.
Non-goals
- No Solana holder analytics are claimed or implied.
- No new provider data is invented.
- No UI layout, loading screen, typography, or graph rendering behavior is part of this contract.
- Do not add new top-level fields to the wallet response without updating this document.
Related
Data Quality and Observability
The observability metadata, provider-selection logic, and trust model this contract’s
dataQuality fields build on.Wallet Evidence Model
The source-aware claims layer that extends this response with
walletEvidence.
