// DragonX Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 #pragma once #include #include #include namespace dragonx { namespace data { /** * @brief A single trading pair on an exchange (e.g. DRGX/BTC) */ struct ExchangePair { std::string base; ///< e.g. "DRGX" std::string quote; ///< e.g. "BTC" std::string displayName; ///< e.g. "DRGX/BTC" std::string tradeUrl; ///< Link to the exchange pair page std::string identifier; ///< CoinGecko exchange id (e.g. "ourbit", "nonkyc_io") — keys the candle adapter double lastUsd = 0.0; ///< This venue's current price in USD (CoinGecko converted_last.usd); 0 if unknown double volumeUsd = 0.0; ///< This venue's 24h volume in USD (CoinGecko converted_volume.usd); 0 if unknown }; /** * @brief Metadata for a supported exchange */ struct ExchangeInfo { std::string name; ///< e.g. "TradeOgre" std::string baseUrl; ///< e.g. "https://tradeogre.com" std::vector 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& getExchangeRegistry(); /** * @brief Index of the selected exchange/pair in `reg`, resolved by saved NAME. * Matches the exchange name (any exchange when selEx is empty) THEN the pair display name, like the chart * fetch always has. Not found => (0,0), found=false (the registry's first pair - the app's default). * Single source of truth for the Market tab chips and App::refreshExchangeChart so they cannot diverge. */ struct ExchangeSelection { int exchangeIdx = 0; int pairIdx = 0; bool found = false; }; inline ExchangeSelection resolveExchangeSelection(const std::vector& reg, const std::string& selEx, const std::string& selPair) { for (std::size_t ei = 0; ei < reg.size(); ++ei) { if (!selEx.empty() && reg[ei].name != selEx) continue; for (std::size_t pi = 0; pi < reg[ei].pairs.size(); ++pi) if (reg[ei].pairs[pi].displayName == selPair) return {static_cast(ei), static_cast(pi), true}; } return {}; } /** * @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 parseCoinGeckoTickers(const std::string& json); } // namespace data } // namespace dragonx