Skip to main content
The Discover Assets screen presents the complete set of listed instruments available to investors.
You render this screen by combining data from two sources: the Universe Configuration API for static metadata (names, descriptions, collections) and the Investment Products API for live trading data (prices, returns, trading status).

Data sources

Building a complete discover screen requires two data sources:

Prerequisites

  • Backend access to the M2M endpoints
  • Bearer token with read:users scope
  • Your tenant identifier for universe configuration

What to fetch

Use Get universe configuration to retrieve asset metadata and discovery content.Returns:
  • Asset names, descriptions, logos
  • Asset classes, sectors, geographies
  • Discovery collections (Big Tech, AI & Robotics, etc.)
  • Top movers, popular assets
  • Search terms for each asset
Use Investment products to retrieve all listed instruments with live pricing.
  • Query param — populateTicker: When true, the response includes currentTicker enriched with prices per currency and the user’s converted price.
Returns:
  • Listed status
  • Current prices and returns
  • Trading currency

Example: fetch and combine data

const CONFIG_BASE = 'https://{TENANT}-staging.wealthyhood.workers.dev';
const API_BASE = 'https://api.wealthyhood.com';

async function getDiscoverScreenData({ token, userId }) {
// Fetch both data sources in parallel
const [universeConfig, investmentProducts] = await Promise.all([
fetch(`${CONFIG_BASE}/b2b/app-config`)
.then(res => res.json()),
fetch(`${API_BASE}/investment-products?populateTicker=true`, {
headers: {
'Authorization': `Bearer ${token}`,
'x-user-id': userId,
'Accept': 'application/json'
}
}).then(res => res.json())
]);

// Create lookup for live data
const productMap = new Map(
investmentProducts.map(p => [p.commonId, p])
);

// Combine static + live data
const assets = Object.entries(universeConfig.investmentUniverse.assets)
.map(([key, config]) => {
const live = productMap.get(key);
return {
key,
isin: config.isin,
name: config.simpleName,
description: config.shortDescription,
logoUrl: config.logoUrl,
assetClass: config.assetClass,
sector: config.sector,
listed: live?.listed ?? false,
buyEnabled: live?.buyLine?.active ?? false,
currentPrice: live?.tradedPrice,
dailyReturn: live?.currentTicker?.dailyReturnPercentage
};
})
.filter(a => a.listed);

return { assets, discovery: universeConfig.discovery };
}

Building discovery sections

Use the discovery object from universe configuration to build curated sections:
function buildDiscoverySections(discovery, assetMap) {
  return {
    // Top movers section
    topMovers: {
      best: discovery.topMovers.best.map((m) => assetMap.get(m.asset)),
      worst: discovery.topMovers.worst.map((m) => assetMap.get(m.asset))
    },

    // Popular assets
    popular: discovery.popularAssetsSection.map((key) => assetMap.get(key)),

    // Collections (Big Tech, AI & Robotics, etc.)
    collections: Object.entries(discovery.collections)
      .map(([key, c]) => ({
        label: c.label,
        emoji: c.emoji,
        assets: c.assets.map((k) => assetMap.get(k))
      }))
      .filter((c) => c.assets.length > 0)
  };
}

See also