Build an Asset Dashboard (NAV, Supply, Balance, Holders)
In this section, you'll build an asset dashboard that will show live metrics for an asset (fungible marker or non-fungible scope), incl.:
- Latest NAV and NAV events
- Total supply (denom) and holders
- Balances (by address)
- Transfer activity (paged; great for tables/audit)
Replace in all snippets:
- {denom} → your token denom (e.g., ntesting)
- {address} → a Bech32 address (tp1… testnet / pb1… mainnet)
- {SCOPE_ID} → scope identifier (bech32 scope address or UUID)
Markers (Fungible)
List markers (optional overview)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/provenance/marker/v1/all"
Marker details (state, permissions, etc.)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/provenance/marker/v1/detail/\{denom\}"
Tip: For the convenience view you can also use: GET "$PROV_REST_BASE/marker/{denom}"
Total supply (by denom)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/cosmos/bank/v1beta1/supply/by_denom?denom=\{denom\}"
Holders (addresses)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/provenance/marker/v1/holding/\{denom\}"
(Alternate view via bank module)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/cosmos/bank/v1beta1/denom_owners/\{denom\}"
For large supplies, prefer Token Holders (Plus) with pagination.cursor for infinite-scroll tables.
Combining data for advanced metrics
To compute advanced metrics like "% of supply per address" or to identify restricted holders, you can combine data from multiple endpoints:
- Fetch Holders: Use the Query_Holding or Query_DenomOwners API to get a list of addresses holding the token. Example:
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/provenance/marker/v1/holding/\{denom\}"
2. Fetch Balances: Use the Query_AllBalances or Query_SpendableBalanceByDenom API to get the balance of each holder.
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/cosmos/bank/v1beta1/balances/\{address\}"
3. Combine data:
For each holder, calculate their percentage of the total supply: % of Supply = (Holder's Balance / Total Supply) * 100
Use the Query_SupplyOfQuery API to fetch the total supply:
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/cosmos/bank/v1beta1/supply/by_denom?denom=\{denom\}"
4. Identify restricted holders (if applicable):
If the marker enforces attributes, use the Query_Holding API to identify restricted holders based on their attributes.
Example workflow:
- Fetch all holders using Query_Holding.
- For each holder, fetch their balance using Query_AllBalances.
- Fetch the total supply using Query_SupplyOfQuery.
- Calculate the percentage of supply for each holder and flag restricted holders if necessary.
Token holders
Plus; cursor-paged with amounts
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_PLUS_BASE/v1/asset/holders/\{denom\}"
Denom metadata (name/symbol/units)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/cosmos/bank/v1beta1/denoms_metadata/\{denom\}"
NAV history (time-series for charts)
# Module view
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/provenance/marker/v1/netassetvalues/\{denom\}"
Tip: There's also a convenience path: GET "$PROV_REST_BASE/marker/{denom}/nav"
For the headline card use: GET /v1/asset/nav-events/latest?denom={denom}; for the chart use: GET /v1/asset/nav-events?denom={denom} with cursor pagination.
Plus view
Filterable, cursor-paged events:
# All NAV events for a denom (add ?startTime=...&endTime=... as needed)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_PLUS_BASE/v1/asset/nav-events?denom=\{denom\}"
# Latest NAV snapshot (e.g., for "headline" card)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_PLUS_BASE/v1/asset/nav-events/latest?denom=\{denom\}"
Scopes (Non-Fungible)
Scope details (base view)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/metadata/scope/\{SCOPE_ID\}"
Ownership & Value ownership (counts & lists)
# Scopes owned by an address (appears in owners list)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/provenance/metadata/v1/ownership/\{address\}"
# Scopes where address is the value_owner_address
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/provenance/metadata/v1/valueownership/\{address\}"
SPEC ADDRESS IS VALUE_OWNER_ADDRESS→
Scope NAV (time-series)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/provenance/metadata/v1/netassetvalues/\{SCOPE_ID\}"
Cross-asset widgets (Balances & Transfers)
Balances (for any address)
# All balances for an address
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/cosmos/bank/v1beta1/balances/\{address\}"
# Spendable balance for a denom
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_REST_BASE/cosmos/bank/v1beta1/spendable_balances/\{address\}/by_denom?denom=\{denom\}"
For balances: Consider also showing the Plus aggregate for balances when you want price/fiat fields and first/last touch metadata:
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_PLUS_BASE/v1/addresses/\{address\}/balance/details"
Transfer activity (paged; ideal for tables)
curl -s -H "Authorization: Bearer $PROV_API_TOKEN" \
"$PROV_PLUS_BASE/v1/asset/transfer-events?recipient=\{address\}&denom=\{denom\}"
# Add ?sender=..., ?before=..., ?after=..., ?limit=... as needed for pagination
Notes & tips
- Pick one base per widget: use the marker module view for supply/holders/state and the convenience /marker/{denom} or /marker/{denom}/nav when you need a single-object fetch. Keep your UI code consistent.
- Pagination & caching: transfer-events is cursor-paged; cache your last cursor and poll incrementally for live tables. Addresses for holder rows: combine holders + balances to compute % of supply per address and to flag restricted holders if your marker enforces attributes.
Common Error tips
- 0 holders returned? You may be querying bank owners for a restricted marker—use marker holding instead.
- NAV empty on module path? If you publish NAV via Plus only, read /v1/asset/nav-events / /latest.