diff --git a/src/api/common/CMakeLists.txt b/src/api/common/CMakeLists.txt index db65ea32..1b3d9b30 100644 --- a/src/api/common/CMakeLists.txt +++ b/src/api/common/CMakeLists.txt @@ -19,7 +19,7 @@ function(add_common_test name) add_unit_test( ${name} ${MY_UNPARSED_ARGUMENTS} - src/cryptowatchapi.cpp + src/commonapi.cpp LIBRARIES coincenter_api-objects coincenter_http-request @@ -28,8 +28,8 @@ function(add_common_test name) endfunction() add_common_test( - cryptowatchapi_test - test/cryptowatchapi_test.cpp + commonapi_test + test/commonapi_test.cpp ) add_common_test( diff --git a/src/api/common/include/commonapi.hpp b/src/api/common/include/commonapi.hpp new file mode 100644 index 00000000..f46cdee5 --- /dev/null +++ b/src/api/common/include/commonapi.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include +#include + +#include "cachedresult.hpp" +#include "cct_flatset.hpp" +#include "cct_json.hpp" +#include "curlhandle.hpp" +#include "exchangebase.hpp" +#include "market.hpp" +#include "timedef.hpp" + +namespace cct { +class CoincenterInfo; +namespace api { +/// Public API connected to different exchanges, providing fast methods to retrieve huge amount of data. +class CommonAPI : public ExchangeBase { + public: + using Fiats = FlatSet; + + CommonAPI(const CoincenterInfo &config, Duration fiatsUpdateFrequency = std::chrono::hours(96), + bool loadFromFileCacheAtInit = true); + + /// Returns a new set of fiat currencies. + Fiats queryFiats() { + std::lock_guard guard(_fiatsMutex); + return _fiatsCache.get(); + } + + /// Tells whether given currency code is a fiat currency or not. + /// Fiat currencies are traditional currencies, such as EUR, USD, GBP, KRW, etc. + /// Information here: https://en.wikipedia.org/wiki/Fiat_money + bool queryIsCurrencyCodeFiat(CurrencyCode currencyCode) { + std::lock_guard guard(_fiatsMutex); + return _fiatsCache.get().contains(currencyCode); + } + + void updateCacheFile() const override; + + private: + struct FiatsFunc { + FiatsFunc(); + + Fiats operator()(); + + CurlHandle _curlHandle; + }; + + CachedResultVault _cachedResultVault; + const CoincenterInfo &_coincenterInfo; + std::mutex _fiatsMutex; + CachedResult _fiatsCache; +}; +} // namespace api +} // namespace cct \ No newline at end of file diff --git a/src/api/common/include/cryptowatchapi.hpp b/src/api/common/include/cryptowatchapi.hpp deleted file mode 100644 index 3b20b5b1..00000000 --- a/src/api/common/include/cryptowatchapi.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "cachedresult.hpp" -#include "cct_flatset.hpp" -#include "cct_json.hpp" -#include "curlhandle.hpp" -#include "exchangebase.hpp" -#include "market.hpp" -#include "runmodes.hpp" -#include "timedef.hpp" - -namespace cct { -class CoincenterInfo; -namespace api { -/// Public API connected to different exchanges, providing fast methods to retrieve huge amount of data. -class CryptowatchAPI : public ExchangeBase { - public: - using Fiats = FlatSet; - - CryptowatchAPI(const CoincenterInfo &config, settings::RunMode runMode, - Duration fiatsUpdateFrequency = std::chrono::hours(96), bool loadFromFileCacheAtInit = true); - - /// Tells whether given exchange is supported by Cryptowatch. - bool queryIsExchangeSupported(std::string_view exchangeName) { - std::lock_guard guard(_exchangesMutex); - return _supportedExchanges.get().contains(exchangeName); - } - - /// Query the approximate price of market 'mk' for exchange name 'exchangeName'. - /// Data may not be up to date, but should respond quickly. - std::optional queryPrice(std::string_view exchangeName, Market mk); - - /// Returns a new set of fiat currencies. - Fiats queryFiats() { - std::lock_guard guard(_fiatsMutex); - return _fiatsCache.get(); - } - - /// Tells whether given currency code is a fiat currency or not. - /// Fiat currencies are traditional currencies, such as EUR, USD, GBP, KRW, etc. - /// Information here: https://en.wikipedia.org/wiki/Fiat_money - bool queryIsCurrencyCodeFiat(CurrencyCode currencyCode) { - std::lock_guard guard(_fiatsMutex); - return _fiatsCache.get().contains(currencyCode); - } - - void updateCacheFile() const override; - - private: - using SupportedExchanges = FlatSet>; - /// Cryptowatch markets are represented by one unique string pair, it's not trivial to split the two currencies - /// acronyms. A second match will be needed to transform it to a final 'Market' - using PricesPerMarketMap = std::unordered_map; - - struct SupportedExchangesFunc { -#ifndef CCT_AGGR_INIT_CXX20 - explicit SupportedExchangesFunc(CurlHandle &curlHandle) : _curlHandle(curlHandle) {} -#endif - - SupportedExchanges operator()(); - - CurlHandle &_curlHandle; - }; - - struct AllPricesFunc { -#ifndef CCT_AGGR_INIT_CXX20 - explicit AllPricesFunc(CurlHandle &curlHandle) : _curlHandle(curlHandle) {} -#endif - - json operator()(); - - CurlHandle &_curlHandle; - }; - - struct FiatsFunc { -#ifndef CCT_AGGR_INIT_CXX20 - explicit FiatsFunc(CurlHandle &curlHandle) : _curlHandle(curlHandle) {} -#endif - - Fiats operator()(); - - CurlHandle &_curlHandle; - }; - - CachedResultVault _cachedResultVault; - const CoincenterInfo &_coincenterInfo; - CurlHandle _curlHandle; - std::mutex _pricesMutex, _fiatsMutex, _exchangesMutex; - CachedResult _fiatsCache; - CachedResult _supportedExchanges; - CachedResult _allPricesCache; -}; -} // namespace api -} // namespace cct \ No newline at end of file diff --git a/src/api/common/include/exchangepublicapi.hpp b/src/api/common/include/exchangepublicapi.hpp index 73100b60..f1fcfc3f 100644 --- a/src/api/common/include/exchangepublicapi.hpp +++ b/src/api/common/include/exchangepublicapi.hpp @@ -4,7 +4,7 @@ #include #include "cct_string.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "currencycode.hpp" #include "currencyexchangeflatset.hpp" #include "exchangebase.hpp" @@ -28,7 +28,7 @@ class ExchangePublic : public ExchangeBase { static constexpr int kDefaultDepth = MarketOrderBook::kDefaultDepth; static constexpr int kNbLastTradesDefault = 100; - using Fiats = CryptowatchAPI::Fiats; + using Fiats = CommonAPI::Fiats; virtual ~ExchangePublic() = default; @@ -57,7 +57,7 @@ class ExchangePublic : public ExchangeBase { Fiats fiats = queryFiats(); MarketSet markets; MarketsPath conversionPath = findMarketsPath(a.currencyCode(), toCurrency, markets, fiats, true); - return convert(a, toCurrency, conversionPath, fiats, marketOrderBookMap, true, priceOptions); + return convert(a, toCurrency, conversionPath, fiats, marketOrderBookMap, priceOptions); } /// Attempts to convert amount into a target currency. @@ -65,7 +65,7 @@ class ExchangePublic : public ExchangeBase { /// No external calls is made with this version, it has all what it needs std::optional convert(MonetaryAmount a, CurrencyCode toCurrency, const MarketsPath &conversionPath, const Fiats &fiats, MarketOrderBookMap &marketOrderBookMap, - bool canUseCryptowatchAPI, const PriceOptions &priceOptions = PriceOptions()); + const PriceOptions &priceOptions = PriceOptions()); /// Retrieve the fixed withdrawal fees per currency. /// Depending on the exchange, this could be retrieved dynamically, @@ -97,7 +97,7 @@ class ExchangePublic : public ExchangeBase { /// Retrieve the last price of given market. virtual MonetaryAmount queryLastPrice(Market mk) = 0; - Fiats queryFiats() { return _cryptowatchApi.queryFiats(); } + Fiats queryFiats() { return _commonApi.queryFiats(); } /// Get the name of the exchange in lower case. std::string_view name() const { return _name; } @@ -160,18 +160,18 @@ class ExchangePublic : public ExchangeBase { const ExchangeInfo &exchangeInfo() const { return _exchangeInfo; } - CryptowatchAPI &cryptowatchAPI() { return _cryptowatchApi; } + CommonAPI &commonAPI() { return _commonApi; } protected: friend class ExchangePrivate; - ExchangePublic(std::string_view name, FiatConverter &fiatConverter, CryptowatchAPI &cryptowatchApi, + ExchangePublic(std::string_view name, FiatConverter &fiatConverter, CommonAPI &commonApi, const CoincenterInfo &coincenterInfo); string _name; CachedResultVault _cachedResultVault; FiatConverter &_fiatConverter; - CryptowatchAPI &_cryptowatchApi; + CommonAPI &_commonApi; const CoincenterInfo &_coincenterInfo; const ExchangeInfo &_exchangeInfo; }; diff --git a/src/api/common/include/exchangepublicapi_mock.hpp b/src/api/common/include/exchangepublicapi_mock.hpp index 2123ddd3..d313f364 100644 --- a/src/api/common/include/exchangepublicapi_mock.hpp +++ b/src/api/common/include/exchangepublicapi_mock.hpp @@ -2,7 +2,7 @@ #include -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "exchangepublicapi.hpp" #include "exchangepublicapitypes.hpp" #include "fiatconverter.hpp" @@ -10,9 +10,9 @@ namespace cct::api { class MockExchangePublic : public ExchangePublic { public: - MockExchangePublic(std::string_view name, FiatConverter &fiatConverter, CryptowatchAPI &cryptowatchApi, + MockExchangePublic(std::string_view name, FiatConverter &fiatConverter, CommonAPI &commonApi, const CoincenterInfo &config) - : ExchangePublic(name, fiatConverter, cryptowatchApi, config) {} + : ExchangePublic(name, fiatConverter, commonApi, config) {} MOCK_METHOD(bool, healthCheck, (), (override)); MOCK_METHOD(CurrencyExchangeFlatSet, queryTradableCurrencies, (), (override)); diff --git a/src/api/common/src/commonapi.cpp b/src/api/common/src/commonapi.cpp new file mode 100644 index 00000000..9d3eb510 --- /dev/null +++ b/src/api/common/src/commonapi.cpp @@ -0,0 +1,91 @@ +#include "commonapi.hpp" + +#include +#include + +#include "cct_exception.hpp" +#include "cct_json.hpp" +#include "cct_log.hpp" +#include "coincenterinfo.hpp" +#include "curloptions.hpp" +#include "file.hpp" +#include "permanentcurloptions.hpp" +#include "timedef.hpp" +#include "toupperlower.hpp" + +namespace cct::api { +namespace { + +File GetFiatCacheFile(std::string_view dataDir) { + return {dataDir, File::Type::kCache, "fiatcache.json", File::IfError::kNoThrow}; +} + +} // namespace + +CommonAPI::CommonAPI(const CoincenterInfo& config, Duration fiatsUpdateFrequency, bool loadFromFileCacheAtInit) + : _coincenterInfo(config), _fiatsCache(CachedResultOptions(fiatsUpdateFrequency, _cachedResultVault)) { + if (loadFromFileCacheAtInit) { + json data = GetFiatCacheFile(_coincenterInfo.dataDir()).readAllJson(); + if (!data.empty()) { + int64_t timeEpoch = data["timeepoch"].get(); + auto& fiatsFile = data["fiats"]; + Fiats fiats; + fiats.reserve(static_cast(fiatsFile.size())); + for (json& val : fiatsFile) { + log::trace("Reading fiat {} from cache file", val.get()); + fiats.emplace_hint(fiats.end(), std::move(val.get_ref())); + } + log::debug("Loaded {} fiats from cache file", fiats.size()); + _fiatsCache.set(std::move(fiats), TimePoint(std::chrono::seconds(timeEpoch))); + } + } +} + +namespace { +constexpr std::string_view kFiatsUrl = "https://datahub.io/core/currency-codes/r/codes-all.json"; +} + +CommonAPI::FiatsFunc::FiatsFunc() + : _curlHandle(kFiatsUrl, nullptr, PermanentCurlOptions::Builder().setFollowLocation().build()) {} + +CommonAPI::Fiats CommonAPI::FiatsFunc::operator()() { + json dataCSV = json::parse(_curlHandle.query("", CurlOptions(HttpRequestType::kGet))); + Fiats fiats; + for (const json& fiatData : dataCSV) { + auto codeIt = fiatData.find("AlphabeticCode"); + auto withdrawalDateIt = fiatData.find("WithdrawalDate"); + if (codeIt != fiatData.end() && !codeIt->is_null() && withdrawalDateIt != fiatData.end() && + withdrawalDateIt->is_null()) { + fiats.insert(CurrencyCode(codeIt->get())); + log::debug("Stored {} fiat", codeIt->get()); + } + } + if (fiats.empty()) { + throw exception("Error parsing currency codes, no fiats found in {}", dataCSV.dump()); + } + + log::info("Stored {} fiats", fiats.size()); + return fiats; +} + +void CommonAPI::updateCacheFile() const { + File fiatsCacheFile = GetFiatCacheFile(_coincenterInfo.dataDir()); + json data = fiatsCacheFile.readAllJson(); + auto fiatsPtrLastUpdatedTimePair = _fiatsCache.retrieve(); + auto timeEpochIt = data.find("timeepoch"); + if (timeEpochIt != data.end()) { + int64_t lastTimeFileUpdated = timeEpochIt->get(); + if (TimePoint(std::chrono::seconds(lastTimeFileUpdated)) >= fiatsPtrLastUpdatedTimePair.second) { + return; // No update + } + } + data.clear(); + if (fiatsPtrLastUpdatedTimePair.first != nullptr) { + for (CurrencyCode fiatCode : *fiatsPtrLastUpdatedTimePair.first) { + data["fiats"].emplace_back(fiatCode.str()); + } + data["timeepoch"] = TimestampToS(fiatsPtrLastUpdatedTimePair.second); + fiatsCacheFile.write(data); + } +} +} // namespace cct::api diff --git a/src/api/common/src/cryptowatchapi.cpp b/src/api/common/src/cryptowatchapi.cpp deleted file mode 100644 index 39be40be..00000000 --- a/src/api/common/src/cryptowatchapi.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "cryptowatchapi.hpp" - -#include - -#include "cct_exception.hpp" -#include "cct_json.hpp" -#include "cct_log.hpp" -#include "coincenterinfo.hpp" -#include "curloptions.hpp" -#include "file.hpp" -#include "timedef.hpp" -#include "toupperlower.hpp" - -namespace cct::api { -namespace { -std::string_view Query(CurlHandle& curlHandle, std::string_view endpoint, CurlPostData&& postData = CurlPostData()) { - return curlHandle.query(endpoint, CurlOptions(HttpRequestType::kGet, std::move(postData))); -} - -const json& CollectResults(const json& dataJson) { - auto errIt = dataJson.find("error"); - if (errIt != dataJson.end() && !errIt->empty()) { - throw exception("Cryptowatch::query error: {}", errIt->front().get()); - } - return dataJson["result"]; -} - -File GetFiatCacheFile(std::string_view dataDir) { - return {dataDir, File::Type::kCache, "fiatcache.json", File::IfError::kNoThrow}; -} - -constexpr std::string_view kCryptowatchBaseUrl = "https://api.cryptowat.ch"; -} // namespace - -CryptowatchAPI::CryptowatchAPI(const CoincenterInfo& config, settings::RunMode runMode, Duration fiatsUpdateFrequency, - bool loadFromFileCacheAtInit) - : _coincenterInfo(config), - _curlHandle(kCryptowatchBaseUrl, config.metricGatewayPtr(), PermanentCurlOptions(), runMode), - _fiatsCache(CachedResultOptions(fiatsUpdateFrequency, _cachedResultVault), _curlHandle), - _supportedExchanges(CachedResultOptions(std::chrono::hours(96), _cachedResultVault), _curlHandle), - _allPricesCache(CachedResultOptions(std::chrono::seconds(30), _cachedResultVault), _curlHandle) { - if (loadFromFileCacheAtInit) { - json data = GetFiatCacheFile(_coincenterInfo.dataDir()).readAllJson(); - if (!data.empty()) { - int64_t timeEpoch = data["timeepoch"].get(); - auto& fiatsFile = data["fiats"]; - Fiats fiats; - fiats.reserve(static_cast(fiatsFile.size())); - for (json& val : fiatsFile) { - log::trace("Reading fiat {} from cache file", val.get()); - fiats.emplace_hint(fiats.end(), std::move(val.get_ref())); - } - log::debug("Loaded {} fiats from cache file", fiats.size()); - _fiatsCache.set(std::move(fiats), TimePoint(std::chrono::seconds(timeEpoch))); - } - } -} - -std::optional CryptowatchAPI::queryPrice(std::string_view exchangeName, Market mk) { - string marketPrefix("market:"); - marketPrefix.append(exchangeName); - marketPrefix.push_back(':'); - - std::lock_guard guard(_pricesMutex); - - for (int marketPos = 0; marketPos < 2; ++marketPos) { - string mStr = marketPrefix; - mStr.append(mk.assetsPairStrLower()); - - const json& result = _allPricesCache.get(); - auto foundIt = result.find(mStr); - if (foundIt != result.end()) { - const double price = static_cast(*foundIt); - return marketPos == 0 ? price : (1 / price); - } - mk = mk.reverse(); // Second try with reversed market - } - return std::nullopt; -} - -CryptowatchAPI::Fiats CryptowatchAPI::FiatsFunc::operator()() { - json dataJson = json::parse(Query(_curlHandle, "/assets")); - const json& result = CollectResults(dataJson); - Fiats fiats; - for (const json& assetDetails : result) { - auto foundIt = assetDetails.find("fiat"); - if (foundIt != assetDetails.end() && foundIt->get()) { - CurrencyCode fiatCode(assetDetails["symbol"].get()); - log::debug("Storing fiat {}", fiatCode); - fiats.insert(std::move(fiatCode)); - } - } - log::info("Stored {} fiats", fiats.size()); - return fiats; -} - -CryptowatchAPI::SupportedExchanges CryptowatchAPI::SupportedExchangesFunc::operator()() { - SupportedExchanges ret; - json dataJson = json::parse(Query(_curlHandle, "/exchanges")); - const json& result = CollectResults(dataJson); - for (const json& exchange : result) { - std::string_view exchangeNameLowerCase = exchange["symbol"].get(); - log::debug("{} is supported by Cryptowatch", exchangeNameLowerCase); - ret.emplace(exchangeNameLowerCase); - } - log::info("{} exchanges supported by Cryptowatch", ret.size()); - return ret; -} - -json CryptowatchAPI::AllPricesFunc::operator()() { - json dataJson = json::parse(Query(_curlHandle, "/markets/prices")); - return CollectResults(dataJson); -} - -void CryptowatchAPI::updateCacheFile() const { - File fiatsCacheFile = GetFiatCacheFile(_coincenterInfo.dataDir()); - json data = fiatsCacheFile.readAllJson(); - auto fiatsPtrLastUpdatedTimePair = _fiatsCache.retrieve(); - auto timeEpochIt = data.find("timeepoch"); - if (timeEpochIt != data.end()) { - int64_t lastTimeFileUpdated = timeEpochIt->get(); - if (TimePoint(std::chrono::seconds(lastTimeFileUpdated)) >= fiatsPtrLastUpdatedTimePair.second) { - return; // No update - } - } - data.clear(); - if (fiatsPtrLastUpdatedTimePair.first != nullptr) { - for (CurrencyCode fiatCode : *fiatsPtrLastUpdatedTimePair.first) { - data["fiats"].emplace_back(fiatCode.str()); - } - data["timeepoch"] = TimestampToS(fiatsPtrLastUpdatedTimePair.second); - fiatsCacheFile.write(data); - } -} -} // namespace cct::api diff --git a/src/api/common/src/exchangepublicapi.cpp b/src/api/common/src/exchangepublicapi.cpp index 97585f5a..19fec950 100644 --- a/src/api/common/src/exchangepublicapi.cpp +++ b/src/api/common/src/exchangepublicapi.cpp @@ -9,17 +9,17 @@ #include "unreachable.hpp" namespace cct::api { -ExchangePublic::ExchangePublic(std::string_view name, FiatConverter &fiatConverter, CryptowatchAPI &cryptowatchApi, +ExchangePublic::ExchangePublic(std::string_view name, FiatConverter &fiatConverter, CommonAPI &commonApi, const CoincenterInfo &coincenterInfo) : _name(name), _fiatConverter(fiatConverter), - _cryptowatchApi(cryptowatchApi), + _commonApi(commonApi), _coincenterInfo(coincenterInfo), _exchangeInfo(coincenterInfo.exchangeInfo(name)) {} std::optional ExchangePublic::convert(MonetaryAmount amount, CurrencyCode toCurrency, const MarketsPath &conversionPath, const Fiats &fiats, - MarketOrderBookMap &marketOrderBookMap, bool canUseCryptowatchAPI, + MarketOrderBookMap &marketOrderBookMap, const PriceOptions &priceOptions) { if (amount.currencyCode() == toCurrency) { return amount; @@ -29,8 +29,6 @@ std::optional ExchangePublic::convert(MonetaryAmount amount, Cur } const ExchangeInfo::FeeType feeType = priceOptions.isTakerStrategy() ? ExchangeInfo::FeeType::kTaker : ExchangeInfo::FeeType::kMaker; - bool canUseCryptoWatch = - canUseCryptowatchAPI && priceOptions.isAveragePrice() && _cryptowatchApi.queryIsExchangeSupported(_name); for (Market mk : conversionPath) { CurrencyCode mFromCurrencyCode = amount.currencyCode(); assert(mk.canTrade(mFromCurrencyCode)); @@ -44,13 +42,6 @@ std::optional ExchangePublic::convert(MonetaryAmount amount, Cur if (isFromFiatLike && isToFiatLike) { amount = _fiatConverter.convert(MonetaryAmount(amount, fiatFromLikeCurCode), fiatToLikeCurCode); } else { - if (canUseCryptoWatch) { - std::optional rate = _cryptowatchApi.queryPrice(_name, Market(mFromCurrencyCode, mToCurrencyCode)); - if (rate) { - amount = amount.toNeutral() * MonetaryAmount(*rate, mToCurrencyCode); - continue; - } - } if (marketOrderBookMap.empty()) { marketOrderBookMap = queryAllApproximatedOrderBooks(1); } @@ -86,7 +77,7 @@ using CurrencyDirPath = SmallVector; class CurrencyDirFastestPathComparator { public: - explicit CurrencyDirFastestPathComparator(CryptowatchAPI &cryptowatchApi) : _cryptowatchApi(cryptowatchApi) {} + explicit CurrencyDirFastestPathComparator(CommonAPI &commonApi) : _commonApi(commonApi) {} bool operator()(const CurrencyDirPath &lhs, const CurrencyDirPath &rhs) { // First, favor the shortest path @@ -96,12 +87,12 @@ class CurrencyDirFastestPathComparator { // For equal path sizes, favor non-fiat currencies. Two reasons for this: // - In some countries, tax are automatically collected when any conversion to a fiat on an exchange is made // - It may have the highest volume, as fiats are only present on some regions - auto isFiat = [this](CurrencyDir curDir) { return _cryptowatchApi.queryIsCurrencyCodeFiat(curDir.cur); }; + auto isFiat = [this](CurrencyDir curDir) { return _commonApi.queryIsCurrencyCodeFiat(curDir.cur); }; return std::ranges::count_if(lhs, isFiat) > std::ranges::count_if(rhs, isFiat); } private: - CryptowatchAPI &_cryptowatchApi; + CommonAPI &_commonApi; }; } // namespace @@ -116,7 +107,7 @@ MarketsPath ExchangePublic::findMarketsPath(CurrencyCode fromCurrency, CurrencyC considerStableCoinsAsFiats ? _coincenterInfo.fiatCurrencyIfStableCoin(toCurrency) : std::nullopt; const bool isToFiatLike = optFiatFromStableCoin.has_value() || fiats.contains(toCurrency); - CurrencyDirFastestPathComparator comp(_cryptowatchApi); + CurrencyDirFastestPathComparator comp(_commonApi); vector searchPaths(1, CurrencyDirPath(1, CurrencyDir(fromCurrency, false))); using VisitedCurrenciesSet = std::unordered_set; diff --git a/src/api/common/test/commonapi_test.cpp b/src/api/common/test/commonapi_test.cpp new file mode 100644 index 00000000..cbdd4302 --- /dev/null +++ b/src/api/common/test/commonapi_test.cpp @@ -0,0 +1,24 @@ + +#include "commonapi.hpp" + +#include + +#include "coincenterinfo.hpp" + +namespace cct::api { + +class CommonAPITest : public ::testing::Test { + protected: + settings::RunMode runMode = settings::RunMode::kTestKeys; + CoincenterInfo config{runMode}; + CommonAPI commonAPI{config}; +}; + +TEST_F(CommonAPITest, IsFiatService) { + EXPECT_TRUE(commonAPI.queryIsCurrencyCodeFiat("EUR")); + EXPECT_TRUE(commonAPI.queryIsCurrencyCodeFiat("KRW")); + EXPECT_TRUE(commonAPI.queryIsCurrencyCodeFiat("USD")); + EXPECT_FALSE(commonAPI.queryIsCurrencyCodeFiat("BTC")); + EXPECT_FALSE(commonAPI.queryIsCurrencyCodeFiat("XRP")); +} +} // namespace cct::api \ No newline at end of file diff --git a/src/api/common/test/cryptowatchapi_test.cpp b/src/api/common/test/cryptowatchapi_test.cpp deleted file mode 100644 index 624b1575..00000000 --- a/src/api/common/test/cryptowatchapi_test.cpp +++ /dev/null @@ -1,29 +0,0 @@ - -#include "cryptowatchapi.hpp" - -#include - -#include "coincenterinfo.hpp" - -namespace cct::api { - -class CryptowatchAPITest : public ::testing::Test { - protected: - settings::RunMode runMode = settings::RunMode::kTestKeys; - CoincenterInfo config{runMode}; - CryptowatchAPI cryptowatchAPI{config, runMode}; -}; - -TEST_F(CryptowatchAPITest, Prices) { - EXPECT_NE(cryptowatchAPI.queryPrice("kraken", Market("BTC", "EUR")), std::nullopt); - EXPECT_NE(cryptowatchAPI.queryPrice("bithumb", Market("KRW", "ETH")), std::nullopt); -} - -TEST_F(CryptowatchAPITest, IsFiatService) { - EXPECT_TRUE(cryptowatchAPI.queryIsCurrencyCodeFiat("EUR")); - EXPECT_TRUE(cryptowatchAPI.queryIsCurrencyCodeFiat("KRW")); - EXPECT_TRUE(cryptowatchAPI.queryIsCurrencyCodeFiat("USD")); - EXPECT_FALSE(cryptowatchAPI.queryIsCurrencyCodeFiat("BTC")); - EXPECT_FALSE(cryptowatchAPI.queryIsCurrencyCodeFiat("XRP")); -} -} // namespace cct::api \ No newline at end of file diff --git a/src/api/common/test/exchangeprivateapi_test.cpp b/src/api/common/test/exchangeprivateapi_test.cpp index e49e614d..9151bc23 100644 --- a/src/api/common/test/exchangeprivateapi_test.cpp +++ b/src/api/common/test/exchangeprivateapi_test.cpp @@ -49,10 +49,10 @@ class ExchangePrivateTest : public ::testing::Test { LoadConfiguration loadConfiguration{kDefaultDataDir, LoadConfiguration::ExchangeConfigFileType::kTest}; CoincenterInfo coincenterInfo{settings::RunMode::kTestKeys, loadConfiguration}; - CryptowatchAPI cryptowatchAPI{coincenterInfo, settings::RunMode::kTestKeys, Duration::max(), true}; + CommonAPI commonAPI{coincenterInfo, Duration::max(), true}; FiatConverter fiatConverter{coincenterInfo, Duration::max()}; // max to avoid real Fiat converter queries - MockExchangePublic exchangePublic{kSupportedExchanges[0], fiatConverter, cryptowatchAPI, coincenterInfo}; + MockExchangePublic exchangePublic{kSupportedExchanges[0], fiatConverter, commonAPI, coincenterInfo}; APIKey key{"test", "testUser", "", "", ""}; MockExchangePrivate exchangePrivate{exchangePublic, coincenterInfo, key}; @@ -422,7 +422,7 @@ class ExchangePrivateWithdrawTest : public ExchangePrivateTest { MonetaryAmount grossAmount{"2.5ETH"}; CurrencyCode cur{grossAmount.currencyCode()}; - MockExchangePublic destinationExchangePublic{"kraken", fiatConverter, cryptowatchAPI, coincenterInfo}; + MockExchangePublic destinationExchangePublic{"kraken", fiatConverter, commonAPI, coincenterInfo}; MockExchangePrivate destinationExchangePrivate{destinationExchangePublic, coincenterInfo, key}; Wallet receivingWallet{ destinationExchangePrivate.exchangeName(), cur, "TestAddress", "TestTag", WalletCheck(), AccountOwner()}; @@ -490,7 +490,7 @@ TEST_F(ExchangePrivateWithdrawTest, WithdrawSynchronousReceivedBeforeSent) { TEST_F(ExchangePrivateTest, WithdrawAsynchronous) { MonetaryAmount grossAmount("2.5ETH"); CurrencyCode cur = grossAmount.currencyCode(); - MockExchangePublic destinationExchangePublic("bithumb", fiatConverter, cryptowatchAPI, coincenterInfo); + MockExchangePublic destinationExchangePublic("bithumb", fiatConverter, commonAPI, coincenterInfo); MockExchangePrivate destinationExchangePrivate(destinationExchangePublic, coincenterInfo, key); Wallet receivingWallet(destinationExchangePrivate.exchangeName(), cur, "TestAddress", "TestTag", WalletCheck(), AccountOwner("SmithJohn", "스미스존")); diff --git a/src/api/common/test/exchangepublicapi_test.cpp b/src/api/common/test/exchangepublicapi_test.cpp index 2ebaec6c..1b394466 100644 --- a/src/api/common/test/exchangepublicapi_test.cpp +++ b/src/api/common/test/exchangepublicapi_test.cpp @@ -6,7 +6,7 @@ #include "cct_const.hpp" #include "cct_exception.hpp" #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "exchangeinfo.hpp" #include "exchangepublicapi_mock.hpp" #include "fiatconverter.hpp" @@ -17,9 +17,9 @@ class ExchangePublicTest : public ::testing::Test { settings::RunMode runMode = settings::RunMode::kTestKeys; LoadConfiguration loadConfiguration{kDefaultDataDir, LoadConfiguration::ExchangeConfigFileType::kTest}; CoincenterInfo coincenterInfo{runMode, loadConfiguration}; - CryptowatchAPI cryptowatchAPI{coincenterInfo, runMode}; + CommonAPI commonAPI{coincenterInfo}; FiatConverter fiatConverter{coincenterInfo, Duration::max()}; // max to avoid real Fiat converter queries - MockExchangePublic exchangePublic{kSupportedExchanges[0], fiatConverter, cryptowatchAPI, coincenterInfo}; + MockExchangePublic exchangePublic{kSupportedExchanges[0], fiatConverter, commonAPI, coincenterInfo}; }; namespace { @@ -82,17 +82,16 @@ class ExchangePublicConvertTest : public ExchangePublicTest { {Market("XRP", "BTC"), marketOrderBook2}, {Market("SOL", "EUR"), marketOrderBook3}}; - bool canUseCryptowatchAPI = false; PriceOptions priceOptions; }; TEST_F(ExchangePublicConvertTest, ConvertImpossible) { MonetaryAmount from{50000, "XLM"}; CurrencyCode toCurrency{"BTC"}; - MarketsPath conversionPath{}; + MarketsPath conversionPath; - std::optional ret = exchangePublic.convert(from, toCurrency, conversionPath, fiats, - marketOrderBookMap, canUseCryptowatchAPI, priceOptions); + std::optional ret = + exchangePublic.convert(from, toCurrency, conversionPath, fiats, marketOrderBookMap, priceOptions); ASSERT_FALSE(ret.has_value()); } @@ -101,8 +100,8 @@ TEST_F(ExchangePublicConvertTest, ConvertSimple) { CurrencyCode toCurrency{"BTC"}; MarketsPath conversionPath{{"XLM", "BTC"}}; - std::optional ret = exchangePublic.convert(from, toCurrency, conversionPath, fiats, - marketOrderBookMap, canUseCryptowatchAPI, priceOptions); + std::optional ret = + exchangePublic.convert(from, toCurrency, conversionPath, fiats, marketOrderBookMap, priceOptions); ASSERT_TRUE(ret.has_value()); MonetaryAmount res = exchangePublic.exchangeInfo().applyFee(*marketOrderBook1.convert(from, priceOptions), ExchangeInfo::FeeType::kMaker); @@ -113,8 +112,8 @@ TEST_F(ExchangePublicConvertTest, ConvertDouble) { MonetaryAmount from{50000, "XLM"}; CurrencyCode toCurrency{"XRP"}; MarketsPath conversionPath{{"XLM", "BTC"}, {"XRP", "BTC"}}; - std::optional ret = exchangePublic.convert(from, toCurrency, conversionPath, fiats, - marketOrderBookMap, canUseCryptowatchAPI, priceOptions); + std::optional ret = + exchangePublic.convert(from, toCurrency, conversionPath, fiats, marketOrderBookMap, priceOptions); ASSERT_TRUE(ret.has_value()); MonetaryAmount res = exchangePublic.exchangeInfo().applyFee(*marketOrderBook1.convert(from, priceOptions), ExchangeInfo::FeeType::kMaker); diff --git a/src/api/exchanges/include/binancepublicapi.hpp b/src/api/exchanges/include/binancepublicapi.hpp index 5b8cb09b..87c0ea57 100644 --- a/src/api/exchanges/include/binancepublicapi.hpp +++ b/src/api/exchanges/include/binancepublicapi.hpp @@ -19,15 +19,14 @@ class ExchangeInfo; class FiatConverter; namespace api { -class CryptowatchAPI; +class CommonAPI; class BinancePublic : public ExchangePublic { public: static constexpr std::string_view kURLBases[] = {"https://api.binance.com", "https://api1.binance.com", "https://api2.binance.com", "https://api3.binance.com"}; - BinancePublic(const CoincenterInfo& coincenterInfo, FiatConverter& fiatConverter, - api::CryptowatchAPI& cryptowatchAPI); + BinancePublic(const CoincenterInfo& coincenterInfo, FiatConverter& fiatConverter, api::CommonAPI& commonAPI); bool healthCheck() override; diff --git a/src/api/exchanges/include/bithumbpublicapi.hpp b/src/api/exchanges/include/bithumbpublicapi.hpp index 7313356b..7d16741b 100644 --- a/src/api/exchanges/include/bithumbpublicapi.hpp +++ b/src/api/exchanges/include/bithumbpublicapi.hpp @@ -13,13 +13,13 @@ class ExchangeInfo; class FiatConverter; namespace api { -class CryptowatchAPI; +class CommonAPI; class BithumbPublic : public ExchangePublic { public: static constexpr std::string_view kStatusOKStr = "0000"; - BithumbPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CryptowatchAPI& cryptowatchAPI); + BithumbPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CommonAPI& commonAPI); bool healthCheck() override; @@ -60,14 +60,14 @@ class BithumbPublic : public ExchangePublic { struct TradableCurrenciesFunc { #ifndef CCT_AGGR_INIT_CXX20 - TradableCurrenciesFunc(const CoincenterInfo& config, CryptowatchAPI& cryptowatchAPI, CurlHandle& curlHandle) - : _coincenterInfo(config), _cryptowatchAPI(cryptowatchAPI), _curlHandle(curlHandle) {} + TradableCurrenciesFunc(const CoincenterInfo& config, CommonAPI& commonAPI, CurlHandle& curlHandle) + : _coincenterInfo(config), _commonAPI(commonAPI), _curlHandle(curlHandle) {} #endif CurrencyExchangeFlatSet operator()(); const CoincenterInfo& _coincenterInfo; - CryptowatchAPI& _cryptowatchAPI; + CommonAPI& _commonAPI; CurlHandle& _curlHandle; }; diff --git a/src/api/exchanges/include/huobipublicapi.hpp b/src/api/exchanges/include/huobipublicapi.hpp index a35fd879..9f2367c6 100644 --- a/src/api/exchanges/include/huobipublicapi.hpp +++ b/src/api/exchanges/include/huobipublicapi.hpp @@ -20,7 +20,7 @@ class ExchangeInfo; class FiatConverter; namespace api { -class CryptowatchAPI; +class CommonAPI; class HuobiPublic : public ExchangePublic { public: @@ -28,7 +28,7 @@ class HuobiPublic : public ExchangePublic { static constexpr int kHuobiStandardOrderBookDefaultDepth = 150; - HuobiPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, api::CryptowatchAPI& cryptowatchAPI); + HuobiPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, api::CommonAPI& commonAPI); bool healthCheck() override; diff --git a/src/api/exchanges/include/krakenpublicapi.hpp b/src/api/exchanges/include/krakenpublicapi.hpp index f705a026..4520c219 100644 --- a/src/api/exchanges/include/krakenpublicapi.hpp +++ b/src/api/exchanges/include/krakenpublicapi.hpp @@ -15,11 +15,11 @@ class CoincenterInfo; class ExchangeInfo; namespace api { -class CryptowatchAPI; +class CommonAPI; class KrakenPublic : public ExchangePublic { public: - KrakenPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CryptowatchAPI& cryptowatchAPI); + KrakenPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CommonAPI& commonAPI); bool healthCheck() override; @@ -66,18 +66,15 @@ class KrakenPublic : public ExchangePublic { struct TradableCurrenciesFunc { #ifndef CCT_AGGR_INIT_CXX20 - TradableCurrenciesFunc(const CoincenterInfo& config, CryptowatchAPI& cryptowatchApi, CurlHandle& curlHandle, + TradableCurrenciesFunc(const CoincenterInfo& config, CommonAPI& commonApi, CurlHandle& curlHandle, const ExchangeInfo& exchangeInfo) - : _coincenterInfo(config), - _cryptowatchApi(cryptowatchApi), - _curlHandle(curlHandle), - _exchangeInfo(exchangeInfo) {} + : _coincenterInfo(config), _commonApi(commonApi), _curlHandle(curlHandle), _exchangeInfo(exchangeInfo) {} #endif CurrencyExchangeFlatSet operator()(); const CoincenterInfo& _coincenterInfo; - CryptowatchAPI& _cryptowatchApi; + CommonAPI& _commonApi; CurlHandle& _curlHandle; const ExchangeInfo& _exchangeInfo; }; diff --git a/src/api/exchanges/include/kucoinpublicapi.hpp b/src/api/exchanges/include/kucoinpublicapi.hpp index f5622117..4cc16aab 100644 --- a/src/api/exchanges/include/kucoinpublicapi.hpp +++ b/src/api/exchanges/include/kucoinpublicapi.hpp @@ -22,7 +22,7 @@ class ExchangeInfo; class FiatConverter; namespace api { -class CryptowatchAPI; +class CommonAPI; class KucoinPublic : public ExchangePublic { public: @@ -30,7 +30,7 @@ class KucoinPublic : public ExchangePublic { static constexpr int kKucoinStandardOrderBookDefaultDepth = 20; - KucoinPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, api::CryptowatchAPI& cryptowatchAPI); + KucoinPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, api::CommonAPI& commonAPI); bool healthCheck() override; @@ -73,8 +73,8 @@ class KucoinPublic : public ExchangePublic { struct TradableCurrenciesFunc { #ifndef CCT_AGGR_INIT_CXX20 - TradableCurrenciesFunc(CurlHandle& curlHandle, const CoincenterInfo& coincenterInfo, CryptowatchAPI& cryptowatchApi) - : _curlHandle(curlHandle), _coincenterInfo(coincenterInfo), _cryptowatchApi(cryptowatchApi) {} + TradableCurrenciesFunc(CurlHandle& curlHandle, const CoincenterInfo& coincenterInfo, CommonAPI& commonApi) + : _curlHandle(curlHandle), _coincenterInfo(coincenterInfo), _commonApi(commonApi) {} #endif struct CurrencyInfo { @@ -98,7 +98,7 @@ class KucoinPublic : public ExchangePublic { CurlHandle& _curlHandle; const CoincenterInfo& _coincenterInfo; - CryptowatchAPI& _cryptowatchApi; + CommonAPI& _commonApi; }; struct MarketsFunc { diff --git a/src/api/exchanges/include/upbitprivateapi.hpp b/src/api/exchanges/include/upbitprivateapi.hpp index 871273cb..ae825406 100644 --- a/src/api/exchanges/include/upbitprivateapi.hpp +++ b/src/api/exchanges/include/upbitprivateapi.hpp @@ -59,8 +59,8 @@ class UpbitPrivate : public ExchangePrivate { struct TradableCurrenciesFunc { #ifndef CCT_AGGR_INIT_CXX20 TradableCurrenciesFunc(CurlHandle& curlHandle, const APIKey& apiKey, const ExchangeInfo& exchangeInfo, - CryptowatchAPI& cryptowatchApi) - : _curlHandle(curlHandle), _apiKey(apiKey), _exchangeInfo(exchangeInfo), _cryptowatchApi(cryptowatchApi) {} + CommonAPI& commonApi) + : _curlHandle(curlHandle), _apiKey(apiKey), _exchangeInfo(exchangeInfo), _commonApi(commonApi) {} #endif CurrencyExchangeFlatSet operator()(); @@ -68,7 +68,7 @@ class UpbitPrivate : public ExchangePrivate { CurlHandle& _curlHandle; const APIKey& _apiKey; const ExchangeInfo& _exchangeInfo; - CryptowatchAPI& _cryptowatchApi; + CommonAPI& _commonApi; }; struct DepositWalletFunc { diff --git a/src/api/exchanges/include/upbitpublicapi.hpp b/src/api/exchanges/include/upbitpublicapi.hpp index af8cc1d6..9157bf6c 100644 --- a/src/api/exchanges/include/upbitpublicapi.hpp +++ b/src/api/exchanges/include/upbitpublicapi.hpp @@ -15,11 +15,11 @@ class ExchangeInfo; class FiatConverter; namespace api { -class CryptowatchAPI; +class CommonAPI; class UpbitPublic : public ExchangePublic { public: - UpbitPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CryptowatchAPI& cryptowatchAPI); + UpbitPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CommonAPI& commonAPI); bool healthCheck() override; diff --git a/src/api/exchanges/src/binancepublicapi.cpp b/src/api/exchanges/src/binancepublicapi.cpp index d1e04b39..f7acff81 100644 --- a/src/api/exchanges/src/binancepublicapi.cpp +++ b/src/api/exchanges/src/binancepublicapi.cpp @@ -13,7 +13,7 @@ #include "cct_log.hpp" #include "codec.hpp" #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "curloptions.hpp" #include "fiatconverter.hpp" #include "monetaryamount.hpp" @@ -58,8 +58,8 @@ VolAndPriNbDecimals QueryVolAndPriNbDecimals(const ExchangeInfoDataByMarket& exc } // namespace BinancePublic::BinancePublic(const CoincenterInfo& coincenterInfo, FiatConverter& fiatConverter, - api::CryptowatchAPI& cryptowatchAPI) - : ExchangePublic("binance", fiatConverter, cryptowatchAPI, coincenterInfo), + api::CommonAPI& commonAPI) + : ExchangePublic("binance", fiatConverter, commonAPI, coincenterInfo), _commonInfo(coincenterInfo, exchangeInfo(), coincenterInfo.getRunMode()), _exchangeInfoCache(CachedResultOptions(exchangeInfo().getAPICallUpdateFrequency(kCurrencies), _cachedResultVault), _commonInfo), diff --git a/src/api/exchanges/src/bithumbpublicapi.cpp b/src/api/exchanges/src/bithumbpublicapi.cpp index 54751231..8c777387 100644 --- a/src/api/exchanges/src/bithumbpublicapi.cpp +++ b/src/api/exchanges/src/bithumbpublicapi.cpp @@ -10,7 +10,7 @@ #include "cct_json.hpp" #include "cct_log.hpp" #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "curloptions.hpp" #include "fiatconverter.hpp" #include "monetaryamount.hpp" @@ -50,8 +50,8 @@ json PublicQuery(CurlHandle& curlHandle, std::string_view endpoint, CurrencyCode } // namespace -BithumbPublic::BithumbPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CryptowatchAPI& cryptowatchAPI) - : ExchangePublic("bithumb", fiatConverter, cryptowatchAPI, config), +BithumbPublic::BithumbPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CommonAPI& commonAPI) + : ExchangePublic("bithumb", fiatConverter, commonAPI, config), _curlHandle(kUrlBase, config.metricGatewayPtr(), PermanentCurlOptions::Builder() .setMinDurationBetweenQueries(exchangeInfo().publicAPIRate()) @@ -60,7 +60,7 @@ BithumbPublic::BithumbPublic(const CoincenterInfo& config, FiatConverter& fiatCo config.getRunMode()), _tradableCurrenciesCache( CachedResultOptions(exchangeInfo().getAPICallUpdateFrequency(kCurrencies), _cachedResultVault), config, - cryptowatchAPI, _curlHandle), + commonAPI, _curlHandle), _withdrawalFeesCache( CachedResultOptions(exchangeInfo().getAPICallUpdateFrequency(kWithdrawalFees), _cachedResultVault), config.metricGatewayPtr(), @@ -179,9 +179,8 @@ CurrencyExchangeFlatSet BithumbPublic::TradableCurrenciesFunc::operator()() { : CurrencyExchange::Deposit::kUnavailable, withdrawalDeposit["withdrawal_status"] == 1 ? CurrencyExchange::Withdraw::kAvailable : CurrencyExchange::Withdraw::kUnavailable, - _cryptowatchAPI.queryIsCurrencyCodeFiat(currencyCode) - ? CurrencyExchange::Type::kFiat - : CurrencyExchange::Type::kCrypto); + _commonAPI.queryIsCurrencyCodeFiat(currencyCode) ? CurrencyExchange::Type::kFiat + : CurrencyExchange::Type::kCrypto); log::debug("Retrieved Bithumb Currency {}", newCurrency.str()); currencies.push_back(std::move(newCurrency)); diff --git a/src/api/exchanges/src/huobipublicapi.cpp b/src/api/exchanges/src/huobipublicapi.cpp index 8a3f0e45..229c7283 100644 --- a/src/api/exchanges/src/huobipublicapi.cpp +++ b/src/api/exchanges/src/huobipublicapi.cpp @@ -8,7 +8,7 @@ #include "cct_exception.hpp" #include "cct_log.hpp" #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "curloptions.hpp" #include "fiatconverter.hpp" #include "monetaryamount.hpp" @@ -35,9 +35,8 @@ json PublicQuery(CurlHandle& curlHandle, std::string_view endpoint, const CurlPo } // namespace -HuobiPublic::HuobiPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, - api::CryptowatchAPI& cryptowatchAPI) - : ExchangePublic("huobi", fiatConverter, cryptowatchAPI, config), +HuobiPublic::HuobiPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, api::CommonAPI& commonAPI) + : ExchangePublic("huobi", fiatConverter, commonAPI, config), _exchangeInfo(config.exchangeInfo(_name)), _curlHandle(kURLBases, config.metricGatewayPtr(), PermanentCurlOptions::Builder() @@ -136,8 +135,8 @@ CurrencyExchangeFlatSet HuobiPublic::queryTradableCurrencies() { : CurrencyExchange::Deposit::kUnavailable; auto withdrawAllowed = withdrawAllowedStr == "allowed" ? CurrencyExchange::Withdraw::kAvailable : CurrencyExchange::Withdraw::kUnavailable; - auto curExchangeType = _cryptowatchApi.queryIsCurrencyCodeFiat(cur) ? CurrencyExchange::Type::kFiat - : CurrencyExchange::Type::kCrypto; + auto curExchangeType = + _commonApi.queryIsCurrencyCodeFiat(cur) ? CurrencyExchange::Type::kFiat : CurrencyExchange::Type::kCrypto; CurrencyExchange newCurrency(cur, curStr, curStr, depositAllowed, withdrawAllowed, curExchangeType); diff --git a/src/api/exchanges/src/krakenpublicapi.cpp b/src/api/exchanges/src/krakenpublicapi.cpp index b3a23a55..a3687a64 100644 --- a/src/api/exchanges/src/krakenpublicapi.cpp +++ b/src/api/exchanges/src/krakenpublicapi.cpp @@ -9,7 +9,7 @@ #include "cct_json.hpp" #include "cct_log.hpp" #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "curloptions.hpp" #include "file.hpp" #include "timedef.hpp" @@ -71,8 +71,8 @@ constexpr std::string_view kExchangeName = "kraken"; } // namespace -KrakenPublic::KrakenPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CryptowatchAPI& cryptowatchAPI) - : ExchangePublic(kExchangeName, fiatConverter, cryptowatchAPI, config), +KrakenPublic::KrakenPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CommonAPI& commonAPI) + : ExchangePublic(kExchangeName, fiatConverter, commonAPI, config), _curlHandle(kUrlBase, config.metricGatewayPtr(), PermanentCurlOptions::Builder() .setMinDurationBetweenQueries(exchangeInfo().publicAPIRate()) @@ -81,7 +81,7 @@ KrakenPublic::KrakenPublic(const CoincenterInfo& config, FiatConverter& fiatConv config.getRunMode()), _tradableCurrenciesCache( CachedResultOptions(exchangeInfo().getAPICallUpdateFrequency(kCurrencies), _cachedResultVault), config, - cryptowatchAPI, _curlHandle, exchangeInfo()), + commonAPI, _curlHandle, exchangeInfo()), _withdrawalFeesCache( CachedResultOptions(exchangeInfo().getAPICallUpdateFrequency(kWithdrawalFees), _cachedResultVault), config, exchangeInfo().publicAPIRate()), @@ -336,9 +336,8 @@ CurrencyExchangeFlatSet KrakenPublic::TradableCurrenciesFunc::operator()() { CurrencyCode standardCode(_coincenterInfo.standardizeCurrencyCode(altCodeStr)); CurrencyExchange newCurrency(standardCode, CurrencyCode(krakenAssetName), CurrencyCode(altCodeStr), CurrencyExchange::Deposit::kAvailable, CurrencyExchange::Withdraw::kAvailable, - _cryptowatchApi.queryIsCurrencyCodeFiat(standardCode) - ? CurrencyExchange::Type::kFiat - : CurrencyExchange::Type::kCrypto); + _commonApi.queryIsCurrencyCodeFiat(standardCode) ? CurrencyExchange::Type::kFiat + : CurrencyExchange::Type::kCrypto); log::debug("Retrieved Kraken Currency {}", newCurrency.str()); currencies.push_back(std::move(newCurrency)); diff --git a/src/api/exchanges/src/kucoinpublicapi.cpp b/src/api/exchanges/src/kucoinpublicapi.cpp index 0f7f7fb6..f39db12a 100644 --- a/src/api/exchanges/src/kucoinpublicapi.cpp +++ b/src/api/exchanges/src/kucoinpublicapi.cpp @@ -8,7 +8,7 @@ #include "cct_exception.hpp" #include "cct_log.hpp" #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "curloptions.hpp" #include "fiatconverter.hpp" #include "monetaryamount.hpp" @@ -35,9 +35,8 @@ json PublicQuery(CurlHandle& curlHandle, std::string_view endpoint, const CurlPo } // namespace -KucoinPublic::KucoinPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, - api::CryptowatchAPI& cryptowatchAPI) - : ExchangePublic("kucoin", fiatConverter, cryptowatchAPI, config), +KucoinPublic::KucoinPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, api::CommonAPI& commonAPI) + : ExchangePublic("kucoin", fiatConverter, commonAPI, config), _curlHandle(kUrlBase, config.metricGatewayPtr(), PermanentCurlOptions::Builder() .setMinDurationBetweenQueries(exchangeInfo().publicAPIRate()) @@ -46,7 +45,7 @@ KucoinPublic::KucoinPublic(const CoincenterInfo& config, FiatConverter& fiatConv config.getRunMode()), _tradableCurrenciesCache( CachedResultOptions(exchangeInfo().getAPICallUpdateFrequency(kCurrencies), _cachedResultVault), _curlHandle, - _coincenterInfo, cryptowatchAPI), + _coincenterInfo, commonAPI), _marketsCache(CachedResultOptions(exchangeInfo().getAPICallUpdateFrequency(kMarkets), _cachedResultVault), _curlHandle, exchangeInfo()), _allOrderBooksCache( @@ -90,7 +89,7 @@ KucoinPublic::TradableCurrenciesFunc::CurrencyInfoSet KucoinPublic::TradableCurr : CurrencyExchange::Deposit::kUnavailable, curDetail["isWithdrawEnabled"].get() ? CurrencyExchange::Withdraw::kAvailable : CurrencyExchange::Withdraw::kUnavailable, - _cryptowatchApi.queryIsCurrencyCodeFiat(cur) ? CurrencyExchange::Type::kFiat : CurrencyExchange::Type::kCrypto); + _commonApi.queryIsCurrencyCodeFiat(cur) ? CurrencyExchange::Type::kFiat : CurrencyExchange::Type::kCrypto); log::debug("Retrieved Kucoin Currency {}", currencyExchange.str()); diff --git a/src/api/exchanges/src/upbitprivateapi.cpp b/src/api/exchanges/src/upbitprivateapi.cpp index e1a9db12..b89e52f3 100644 --- a/src/api/exchanges/src/upbitprivateapi.cpp +++ b/src/api/exchanges/src/upbitprivateapi.cpp @@ -14,7 +14,7 @@ #include "cct_log.hpp" #include "codec.hpp" #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "curloptions.hpp" #include "monetaryamount.hpp" #include "ssl_sha.hpp" @@ -77,7 +77,7 @@ UpbitPrivate::UpbitPrivate(const CoincenterInfo& config, UpbitPublic& upbitPubli config.getRunMode()), _tradableCurrenciesCache( CachedResultOptions(exchangeInfo().getAPICallUpdateFrequency(kCurrencies), _cachedResultVault), _curlHandle, - _apiKey, exchangeInfo(), upbitPublic._cryptowatchApi), + _apiKey, exchangeInfo(), upbitPublic._commonApi), _depositWalletsCache( CachedResultOptions(exchangeInfo().getAPICallUpdateFrequency(kDepositWallet), _cachedResultVault), _curlHandle, _apiKey, upbitPublic), @@ -117,9 +117,9 @@ CurrencyExchangeFlatSet UpbitPrivate::TradableCurrenciesFunc::operator()() { if (depositStatus == CurrencyExchange::Deposit::kUnavailable) { log::debug("{} cannot be deposited to Upbit", cur); } - currencies.emplace_back(cur, cur, cur, depositStatus, withdrawStatus, - _cryptowatchApi.queryIsCurrencyCodeFiat(cur) ? CurrencyExchange::Type::kFiat - : CurrencyExchange::Type::kCrypto); + currencies.emplace_back( + cur, cur, cur, depositStatus, withdrawStatus, + _commonApi.queryIsCurrencyCodeFiat(cur) ? CurrencyExchange::Type::kFiat : CurrencyExchange::Type::kCrypto); } } CurrencyExchangeFlatSet ret(std::move(currencies)); diff --git a/src/api/exchanges/src/upbitpublicapi.cpp b/src/api/exchanges/src/upbitpublicapi.cpp index 2cb41707..f370428a 100644 --- a/src/api/exchanges/src/upbitpublicapi.cpp +++ b/src/api/exchanges/src/upbitpublicapi.cpp @@ -32,8 +32,8 @@ json PublicQuery(CurlHandle& curlHandle, std::string_view endpoint, CurlPostData } // namespace -UpbitPublic::UpbitPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CryptowatchAPI& cryptowatchAPI) - : ExchangePublic("upbit", fiatConverter, cryptowatchAPI, config), +UpbitPublic::UpbitPublic(const CoincenterInfo& config, FiatConverter& fiatConverter, CommonAPI& commonAPI) + : ExchangePublic("upbit", fiatConverter, commonAPI, config), _curlHandle(kUrlBase, config.metricGatewayPtr(), PermanentCurlOptions::Builder() .setMinDurationBetweenQueries(exchangeInfo().publicAPIRate()) diff --git a/src/api/exchanges/test/bithumb_place_order_test.cpp b/src/api/exchanges/test/bithumb_place_order_test.cpp index 3bb20abb..ed97a8b6 100644 --- a/src/api/exchanges/test/bithumb_place_order_test.cpp +++ b/src/api/exchanges/test/bithumb_place_order_test.cpp @@ -26,8 +26,8 @@ class BithumbPrivateAPIPlaceOrderTest : public ::testing::Test { LoadConfiguration loadConfig{kDefaultDataDir, LoadConfiguration::ExchangeConfigFileType::kTest}; CoincenterInfo coincenterInfo{runMode, loadConfig}; FiatConverter fiatConverter{coincenterInfo, Duration::max()}; // max to avoid real Fiat converter queries - CryptowatchAPI cryptowatchAPI{coincenterInfo, runMode}; - BithumbPublic exchangePublic{coincenterInfo, fiatConverter, cryptowatchAPI}; + CommonAPI commonAPI{coincenterInfo}; + BithumbPublic exchangePublic{coincenterInfo, fiatConverter, commonAPI}; APIKeysProvider apiKeysProvider{coincenterInfo.dataDir(), coincenterInfo.getRunMode()}; ExchangeName exchangeName{exchangePublic.name(), apiKeysProvider.getKeyNames(exchangePublic.name()).front()}; const APIKey& testKey = apiKeysProvider.get(exchangeName); diff --git a/src/api/exchanges/test/commonapi_test.hpp b/src/api/exchanges/test/commonapi_test.hpp index 17cd8058..89e40489 100644 --- a/src/api/exchanges/test/commonapi_test.hpp +++ b/src/api/exchanges/test/commonapi_test.hpp @@ -8,7 +8,7 @@ #include "apikeysprovider.hpp" #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "exchangeprivateapi.hpp" #include "exchangepublicapi.hpp" #include "exchangepublicapitypes.hpp" @@ -53,8 +53,8 @@ class TestAPI { CoincenterInfo coincenterInfo{runMode, loadConfig}; APIKeysProvider apiKeysProvider{coincenterInfo.dataDir(), coincenterInfo.getRunMode()}; FiatConverter fiatConverter{coincenterInfo, Duration::max()}; // max to avoid real Fiat converter queries - CryptowatchAPI cryptowatchAPI{coincenterInfo, runMode}; - PublicExchangeT exchangePublic{coincenterInfo, fiatConverter, cryptowatchAPI}; + CommonAPI commonAPI{coincenterInfo}; + PublicExchangeT exchangePublic{coincenterInfo, fiatConverter, commonAPI}; std::optional exchangePrivateOpt; CurrencyExchangeFlatSet currencies; diff --git a/src/api/interface/include/exchangepool.hpp b/src/api/interface/include/exchangepool.hpp index 9f15bf3a..925624c9 100644 --- a/src/api/interface/include/exchangepool.hpp +++ b/src/api/interface/include/exchangepool.hpp @@ -28,13 +28,13 @@ class KrakenPrivate; class KucoinPrivate; class UpbitPrivate; -class CryptowatchAPI; +class CommonAPI; class APIKeysProvider; } // namespace api class ExchangePool { public: - ExchangePool(const CoincenterInfo& coincenterInfo, FiatConverter& fiatConverter, api::CryptowatchAPI& cryptowatchAPI, + ExchangePool(const CoincenterInfo& coincenterInfo, FiatConverter& fiatConverter, api::CommonAPI& commonAPI, const api::APIKeysProvider& apiKeyProvider); ExchangePool(const ExchangePool&) = delete; @@ -52,7 +52,7 @@ class ExchangePool { const CoincenterInfo& _coincenterInfo; FiatConverter& _fiatConverter; - api::CryptowatchAPI& _cryptowatchAPI; + api::CommonAPI& _commonAPI; const api::APIKeysProvider& _apiKeyProvider; // Public exchanges diff --git a/src/api/interface/src/exchangepool.cpp b/src/api/interface/src/exchangepool.cpp index dc2d2a7e..7deb55ce 100644 --- a/src/api/interface/src/exchangepool.cpp +++ b/src/api/interface/src/exchangepool.cpp @@ -15,17 +15,17 @@ namespace cct { ExchangePool::ExchangePool(const CoincenterInfo& coincenterInfo, FiatConverter& fiatConverter, - api::CryptowatchAPI& cryptowatchAPI, const api::APIKeysProvider& apiKeyProvider) + api::CommonAPI& commonAPI, const api::APIKeysProvider& apiKeyProvider) : _coincenterInfo(coincenterInfo), _fiatConverter(fiatConverter), - _cryptowatchAPI(cryptowatchAPI), + _commonAPI(commonAPI), _apiKeyProvider(apiKeyProvider), - _binancePublic(_coincenterInfo, _fiatConverter, _cryptowatchAPI), - _bithumbPublic(_coincenterInfo, _fiatConverter, _cryptowatchAPI), - _huobiPublic(_coincenterInfo, _fiatConverter, _cryptowatchAPI), - _krakenPublic(_coincenterInfo, _fiatConverter, _cryptowatchAPI), - _kucoinPublic(_coincenterInfo, _fiatConverter, _cryptowatchAPI), - _upbitPublic(_coincenterInfo, _fiatConverter, _cryptowatchAPI) { + _binancePublic(_coincenterInfo, _fiatConverter, _commonAPI), + _bithumbPublic(_coincenterInfo, _fiatConverter, _commonAPI), + _huobiPublic(_coincenterInfo, _fiatConverter, _commonAPI), + _krakenPublic(_coincenterInfo, _fiatConverter, _commonAPI), + _kucoinPublic(_coincenterInfo, _fiatConverter, _commonAPI), + _upbitPublic(_coincenterInfo, _fiatConverter, _commonAPI) { for (std::string_view exchangeStr : kSupportedExchanges) { api::ExchangePublic* exchangePublic; if (exchangeStr == "binance") { diff --git a/src/engine/include/coincenter.hpp b/src/engine/include/coincenter.hpp index 00a211db..6f1aa4bd 100644 --- a/src/engine/include/coincenter.hpp +++ b/src/engine/include/coincenter.hpp @@ -6,7 +6,7 @@ #include "apikeysprovider.hpp" #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "exchange.hpp" #include "exchangename.hpp" #include "exchangepool.hpp" @@ -125,8 +125,8 @@ class Coincenter { const CoincenterInfo &coincenterInfo() const { return _coincenterInfo; } - api::CryptowatchAPI &cryptowatchAPI() { return _cryptowatchAPI; } - const api::CryptowatchAPI &cryptowatchAPI() const { return _cryptowatchAPI; } + api::CommonAPI &commonAPI() { return _commonAPI; } + const api::CommonAPI &commonAPI() const { return _commonAPI; } FiatConverter &fiatConverter() { return _fiatConverter; } const FiatConverter &fiatConverter() const { return _fiatConverter; } @@ -135,7 +135,7 @@ class Coincenter { void processCommand(const CoincenterCommand &cmd); const CoincenterInfo &_coincenterInfo; - api::CryptowatchAPI _cryptowatchAPI; + api::CommonAPI _commonAPI; FiatConverter _fiatConverter; api::APIKeysProvider _apiKeyProvider; diff --git a/src/engine/src/coincenter.cpp b/src/engine/src/coincenter.cpp index b1108a8f..cabb7327 100644 --- a/src/engine/src/coincenter.cpp +++ b/src/engine/src/coincenter.cpp @@ -17,11 +17,11 @@ using UniquePublicSelectedExchanges = ExchangeRetriever::UniquePublicSelectedExc Coincenter::Coincenter(const CoincenterInfo &coincenterInfo, const ExchangeSecretsInfo &exchangeSecretsInfo) : _coincenterInfo(coincenterInfo), - _cryptowatchAPI(coincenterInfo, coincenterInfo.getRunMode()), + _commonAPI(coincenterInfo), _fiatConverter(coincenterInfo, coincenterInfo.fiatConversionQueryRate()), _apiKeyProvider(coincenterInfo.dataDir(), exchangeSecretsInfo, coincenterInfo.getRunMode()), _metricsExporter(coincenterInfo.metricGatewayPtr()), - _exchangePool(coincenterInfo, _fiatConverter, _cryptowatchAPI, _apiKeyProvider), + _exchangePool(coincenterInfo, _fiatConverter, _commonAPI, _apiKeyProvider), _exchangesOrchestrator(coincenterInfo.requestsConfig(), _exchangePool.exchanges()), _queryResultPrinter(coincenterInfo.apiOutputType(), _coincenterInfo.loggingInfo()) {} @@ -315,7 +315,7 @@ MonetaryAmountPerExchange Coincenter::getLastPricePerExchange(Market mk, Exchang void Coincenter::updateFileCaches() const { log::debug("Store all cache files"); - _cryptowatchAPI.updateCacheFile(); + _commonAPI.updateCacheFile(); _fiatConverter.updateCacheFile(); auto exchanges = _exchangePool.exchanges(); std::for_each(exchanges.begin(), exchanges.end(), [](const Exchange &exchange) { exchange.updateCacheFile(); }); diff --git a/src/engine/src/exchangesorchestrator.cpp b/src/engine/src/exchangesorchestrator.cpp index 0f44d1aa..9d878a0f 100644 --- a/src/engine/src/exchangesorchestrator.cpp +++ b/src/engine/src/exchangesorchestrator.cpp @@ -312,8 +312,8 @@ UniquePublicSelectedExchanges ExchangesOrchestrator::getExchangesTradingMarket(M namespace { using MarketSetsPerPublicExchange = FixedCapacityVector; -api::CryptowatchAPI::Fiats QueryFiats(const ExchangeRetriever::PublicExchangesVec &publicExchanges) { - api::CryptowatchAPI::Fiats fiats; +api::CommonAPI::Fiats QueryFiats(const ExchangeRetriever::PublicExchangesVec &publicExchanges) { + api::CommonAPI::Fiats fiats; if (!publicExchanges.empty()) { fiats = publicExchanges.front()->queryFiats(); } @@ -342,7 +342,7 @@ using KeepExchangeBoolArray = std::array; ExchangeAmountMarketsPathVector FilterConversionPaths(const ExchangeAmountPairVector &exchangeAmountPairVector, CurrencyCode fromCurrency, CurrencyCode toCurrency, MarketSetsPerPublicExchange &marketsPerPublicExchange, - const api::CryptowatchAPI::Fiats &fiats, + const api::CommonAPI::Fiats &fiats, const TradeOptions &tradeOptions) { ExchangeAmountMarketsPathVector ret; @@ -426,7 +426,7 @@ ExchangeAmountMarketsPathVector CreateExchangeAmountMarketsPathVector(ExchangeRe MarketSetsPerPublicExchange marketsPerPublicExchange(publicExchanges.size()); - api::CryptowatchAPI::Fiats fiats = QueryFiats(publicExchanges); + api::CommonAPI::Fiats fiats = QueryFiats(publicExchanges); return FilterConversionPaths(exchangeAmountPairVector, fromCurrency, toCurrency, marketsPerPublicExchange, fiats, tradeOptions); @@ -508,11 +508,10 @@ TradedAmountsPerExchange ExchangesOrchestrator::smartBuy(MonetaryAmount endAmoun FixedCapacityVector marketOrderbooksPerPublicExchange( publicExchanges.size()); - api::CryptowatchAPI::Fiats fiats = QueryFiats(publicExchanges); + api::CommonAPI::Fiats fiats = QueryFiats(publicExchanges); ExchangeAmountToCurrencyToAmountVector trades; MonetaryAmount remEndAmount = endAmount; - constexpr bool canUseCryptowatchAPI = false; constexpr bool considerStableCoinsAsFiats = false; for (int nbSteps = 1;; ++nbSteps) { bool continuingHigherStepsPossible = false; @@ -555,9 +554,8 @@ TradedAmountsPerExchange ExchangesOrchestrator::smartBuy(MonetaryAmount endAmoun continuingHigherStepsPossible = true; } else if (nbConversions == nbSteps) { MonetaryAmount startAmount = avAmount; - std::optional optEndAmount = - exchangePublic.convert(startAmount, toCurrency, conversionPath, fiats, marketOrderBookMap, - canUseCryptowatchAPI, tradeOptions.priceOptions()); + std::optional optEndAmount = exchangePublic.convert( + startAmount, toCurrency, conversionPath, fiats, marketOrderBookMap, tradeOptions.priceOptions()); if (optEndAmount) { trades.emplace_back(pExchange, startAmount, toCurrency, std::move(conversionPath), *optEndAmount); } @@ -623,7 +621,7 @@ TradedAmountsPerExchange ExchangesOrchestrator::smartSell(MonetaryAmount startAm MarketSetsPtrPerExchange marketSetsPtrPerExchange = MapMarketSetsPtrInExchangesOrder(exchangeAmountPairVector, publicExchanges, marketsPerPublicExchange); - api::CryptowatchAPI::Fiats fiats = QueryFiats(publicExchanges); + api::CommonAPI::Fiats fiats = QueryFiats(publicExchanges); if (isPercentageTrade) { MonetaryAmount totalAvailableAmount = std::accumulate( diff --git a/src/engine/test/exchangedata_test.hpp b/src/engine/test/exchangedata_test.hpp index 65886b6e..d8a712de 100644 --- a/src/engine/test/exchangedata_test.hpp +++ b/src/engine/test/exchangedata_test.hpp @@ -3,7 +3,7 @@ #include #include "coincenterinfo.hpp" -#include "cryptowatchapi.hpp" +#include "commonapi.hpp" #include "exchange.hpp" #include "exchangeprivateapi_mock.hpp" #include "exchangepublicapi_mock.hpp" @@ -23,11 +23,11 @@ class ExchangesBaseTest : public ::testing::Test { LoadConfiguration loadConfiguration{kDefaultDataDir, LoadConfiguration::ExchangeConfigFileType::kTest}; settings::RunMode runMode = settings::RunMode::kTestKeys; CoincenterInfo coincenterInfo{runMode, loadConfiguration}; - api::CryptowatchAPI cryptowatchAPI{coincenterInfo, runMode, Duration::max(), true}; + api::CommonAPI commonAPI{coincenterInfo, Duration::max(), true}; FiatConverter fiatConverter{coincenterInfo, Duration::max()}; // max to avoid real Fiat converter queries - api::MockExchangePublic exchangePublic1{kSupportedExchanges[0], fiatConverter, cryptowatchAPI, coincenterInfo}; - api::MockExchangePublic exchangePublic2{kSupportedExchanges[1], fiatConverter, cryptowatchAPI, coincenterInfo}; - api::MockExchangePublic exchangePublic3{kSupportedExchanges[2], fiatConverter, cryptowatchAPI, coincenterInfo}; + api::MockExchangePublic exchangePublic1{kSupportedExchanges[0], fiatConverter, commonAPI, coincenterInfo}; + api::MockExchangePublic exchangePublic2{kSupportedExchanges[1], fiatConverter, commonAPI, coincenterInfo}; + api::MockExchangePublic exchangePublic3{kSupportedExchanges[2], fiatConverter, commonAPI, coincenterInfo}; api::APIKey key1{"test1", "testuser1", "", "", ""}; api::APIKey key2{"test2", "testuser2", "", "", ""}; api::APIKey key3{"test3", "testuser3", "", "", ""}; diff --git a/src/http-request/CMakeLists.txt b/src/http-request/CMakeLists.txt index ee2b2f02..d80b2c67 100644 --- a/src/http-request/CMakeLists.txt +++ b/src/http-request/CMakeLists.txt @@ -29,3 +29,11 @@ add_unit_test( LIBRARIES coincenter_http-request ) + + +add_unit_test( + permanentcurloptions_test + test/permanentcurloptions_test.cpp + LIBRARIES + coincenter_tech +) diff --git a/src/http-request/include/permanentcurloptions.hpp b/src/http-request/include/permanentcurloptions.hpp index 1fd1c9ae..7715aff5 100644 --- a/src/http-request/include/permanentcurloptions.hpp +++ b/src/http-request/include/permanentcurloptions.hpp @@ -17,45 +17,75 @@ class PermanentCurlOptions { Duration minDurationBetweenQueries() const { return _minDurationBetweenQueries; } + bool followLocation() const { return _followLocation; } + class Builder { public: Builder() noexcept = default; + Builder &setUserAgent(string userAgent) { + _userAgent = std::move(userAgent); + return *this; + } + Builder &setUserAgent(std::string_view userAgent) { _userAgent = string(userAgent); return *this; } + Builder &setUserAgent(const char *userAgent) { + _userAgent = string(userAgent); + return *this; + } + + Builder &setAcceptedEncoding(string acceptedEncoding) { + _acceptedEncoding = std::move(acceptedEncoding); + return *this; + } + Builder &setAcceptedEncoding(std::string_view acceptedEncoding) { _acceptedEncoding = string(acceptedEncoding); return *this; } + Builder &setAcceptedEncoding(const char *acceptedEncoding) { + _acceptedEncoding = string(acceptedEncoding); + return *this; + } + Builder &setMinDurationBetweenQueries(Duration minDurationBetweenQueries) { _minDurationBetweenQueries = minDurationBetweenQueries; return *this; } - PermanentCurlOptions build() const { - return PermanentCurlOptions(_userAgent, _acceptedEncoding, _minDurationBetweenQueries); + Builder &setFollowLocation() { + _followLocation = true; + return *this; + } + + PermanentCurlOptions build() { + return {std::move(_userAgent), std::move(_acceptedEncoding), _minDurationBetweenQueries, _followLocation}; } private: string _userAgent; string _acceptedEncoding; Duration _minDurationBetweenQueries{}; + bool _followLocation = false; }; private: - PermanentCurlOptions(std::string_view userAgent, std::string_view acceptedEncoding, - Duration minDurationBetweenQueries) - : _userAgent(userAgent), - _acceptedEncoding(acceptedEncoding), - _minDurationBetweenQueries(minDurationBetweenQueries) {} + PermanentCurlOptions(string userAgent, string acceptedEncoding, Duration minDurationBetweenQueries, + bool followLocation) + : _userAgent(std::move(userAgent)), + _acceptedEncoding(std::move(acceptedEncoding)), + _minDurationBetweenQueries(minDurationBetweenQueries), + _followLocation(followLocation) {} string _userAgent; string _acceptedEncoding; - Duration _minDurationBetweenQueries{}; + Duration _minDurationBetweenQueries; + bool _followLocation; }; } // namespace cct \ No newline at end of file diff --git a/src/http-request/src/curlhandle.cpp b/src/http-request/src/curlhandle.cpp index ee787558..dbcba8f6 100644 --- a/src/http-request/src/curlhandle.cpp +++ b/src/http-request/src/curlhandle.cpp @@ -94,6 +94,8 @@ CurlHandle::CurlHandle(const BestURLPicker &bestURLPicker, AbstractMetricGateway CurlSetLogIfError(curl, CURLOPT_ACCEPT_ENCODING, acceptedEncoding.data()); } + CurlSetLogIfError(curl, CURLOPT_FOLLOWLOCATION, permanentCurlOptions.followLocation() ? 1L : 0L); + #ifdef CCT_MSVC // https://stackoverflow.com/questions/37551409/configure-curl-to-use-default-system-cert-store-on-windows CurlSetLogIfError(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); diff --git a/src/http-request/test/permanentcurloptions_test.cpp b/src/http-request/test/permanentcurloptions_test.cpp new file mode 100644 index 00000000..c07dcacd --- /dev/null +++ b/src/http-request/test/permanentcurloptions_test.cpp @@ -0,0 +1,10 @@ +#include "permanentcurloptions.hpp" + +#include + +namespace cct { +TEST(PermanentCurlOptions, Builder) { + auto permanentCurlOptions = PermanentCurlOptions::Builder().setAcceptedEncoding("SomeEncoding").build(); + EXPECT_EQ(permanentCurlOptions.getAcceptedEncoding(), string("SomeEncoding")); +} +} // namespace cct \ No newline at end of file