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

@@ -285,6 +285,9 @@ public:
void refreshMiningInfo();
void refreshPeerInfo();
void refreshMarketData();
// Fetch the live exchange/pair list from CoinGecko once per session (venues are
// near-static); populates state.market.exchanges. Safe to call every frame.
void refreshExchanges();
/// @brief Per-category refresh intervals, adjusted by active tab
using RefreshIntervals = services::NetworkRefreshService::Intervals;
@@ -516,6 +519,7 @@ private:
long long last_balance_eval_ms_ = 0; // steady-clock ms of the last refresh kick
bool balance_refresh_pending_ = false; // UI asked for an immediate refresh
bool balance_snapshot_seen_ = false; // the current in-flight snapshot was applied
bool exchanges_fetch_started_ = false; // once-per-session CoinGecko tickers fetch
util::AsyncTaskManager async_tasks_;
bool pending_antivirus_dialog_ = false; // Show Windows Defender help dialog