feat(market): auto-populate exchange pairs from CoinGecko (adds OurBit); DRGX dashboard

- Fetch /coins/dragonx-2/tickers once per session (App::refreshExchanges, reusing the
  price-fetch worker path) and build the exchange registry at runtime into
  state.market.exchanges; parseCoinGeckoTickers groups tickers by venue. The Market tab
  sources from this live list and falls back to the compiled-in registry (now including
  OurBit + Nonkyc.io) when offline. Fixes the missing OurBit pair and auto-tracks future
  listings.
- Fix stale selection defaults (TradeOgre / DRGX-BTC -> Nonkyc.io / DRGX/USDT) that never
  matched the registry, and make the attribution generic ("Price data from CoinGecko").
- Reframe the single-asset portfolio card as a DRGX holdings dashboard: relabel to
  "MY DRGX" and show the 24h change on the holdings value (colored by direction).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 15:25:22 -05:00
parent 57f52b7a6c
commit 1266b6e68e
8 changed files with 164 additions and 11 deletions

View File

@@ -30,9 +30,19 @@ struct ExchangeInfo {
};
/**
* @brief Returns the static registry of supported exchanges + pairs
* @brief Returns the static registry of supported exchanges + pairs.
* Used as the offline fallback / seed when the live CoinGecko list is unavailable.
*/
const std::vector<ExchangeInfo>& getExchangeRegistry();
/**
* @brief Parse a CoinGecko /coins/{id}/tickers JSON body into the exchange registry.
*
* Groups tickers by exchange (market.name), preserving first-seen order, into
* ExchangeInfo entries (each pair carries base/target/displayName/trade_url). Returns
* an empty vector on parse failure or when no usable tickers are present. Pure (no I/O).
*/
std::vector<ExchangeInfo> parseCoinGeckoTickers(const std::string& json);
} // namespace data
} // namespace dragonx