Recipe — Portfolio page

A portfolio view answers three questions about a wallet's holdings: how risky is what they hold, is anything draining it, and which way have they been leaning lately. portfolio-overview answers all three in one request.

One call paints the page

POST /v1/portfolio-overview
{ "wallet": "0x…", "chain": "eth", "depth": 5 }   # depth = top-N holdings to assess
{
  "wallet": "0x…", "chain": "eth", "bundle": "portfolio-overview",
  "portfolioRisk": { "grade": "watch", "weightedRisk": 41, "concentration": "concentrated",
                     "riskyPositions": [{ "symbol": "…", "risk": "high" }],
                     "worstOffender": "…", "summary": "Moderate portfolio risk — a few holdings worth trimming." },
  "walletHealth":  { "health": "healthy", "healthScore": 88, "recommendedActions": [ … ] },
  "walletNetflow": { "posture": "accumulating", "buyShare": 0.71, "windowDays": 7 }
}

Each slot is the verbatim response of its single endpoint (/v1/portfolio-risk, /v1/wallet-health, /v1/wallet-netflow), composed server-side through the same handlers — call the singles individually when you only render one of them. Failures degrade per slot (partial: true + failed[]), never the whole response.

Fields worth rendering

  • Name
    portfolioRisk.grade
    Type
    'healthy' | 'watch' | 'exposed'
    Description

    The headline. no-holdings is a real answer too — the wallet is a pure trader or empty, and summary says so in a sentence you can render.

  • Name
    portfolioRisk.weightedRisk
    Type
    number 0–100
    Description

    Aggregate risk weighted by position size — good for a meter. Pair with concentration (diversified / concentrated / all-in).

  • Name
    portfolioRisk.riskyPositions
    Type
    array
    Description

    The holdings that earn the grade. Link each symbol to your Token page.

  • Name
    walletHealth.health
    Type
    'healthy' | … | 'exposed'
    Description

    Drain/approval exposure. recommendedActions[] is written to be shown to the user directly.

  • Name
    walletNetflow.posture
    Type
    'accumulating' | 'distributing' | …
    Description

    Which way the wallet has been leaning, with buyShare as the number behind it.

UX rules

  1. Render the summary sentences. portfolio-risk writes one per grade — they turn a meter into advice.
  2. no-holdings is not an error. Show the summary line, not an empty-state illustration; the wallet may be a trader whose story lives on the Trader page.
  3. Never invent USD. The API deliberately emits bands and percentages, not balances — your own wallet stack knows the balances; this layer adds the judgement.

Was this page helpful?