diff --git a/BTCPayServer.Rating/BTCPayServer.Rating.csproj b/BTCPayServer.Rating/BTCPayServer.Rating.csproj index ecd6c8e8e..1a5e55b1a 100644 --- a/BTCPayServer.Rating/BTCPayServer.Rating.csproj +++ b/BTCPayServer.Rating/BTCPayServer.Rating.csproj @@ -8,11 +8,11 @@ - + - + diff --git a/BTCPayServer.Rating/Providers/ExchangeSharpRateProvider.cs b/BTCPayServer.Rating/Providers/ExchangeSharpRateProvider.cs index fe96643fb..336a6c4d8 100644 --- a/BTCPayServer.Rating/Providers/ExchangeSharpRateProvider.cs +++ b/BTCPayServer.Rating/Providers/ExchangeSharpRateProvider.cs @@ -36,27 +36,27 @@ namespace BTCPayServer.Services.Rates { await new SynchronizationContextRemover(); var rates = await _ExchangeAPI.GetTickersAsync(); - lock (notFoundSymbols) - { - var exchangeRates = - rates + + var exchangeRateTasks = rates .Where(t => t.Value.Ask != 0m && t.Value.Bid != 0m) - .Select(t => CreateExchangeRate(t)) - .Where(t => t != null) - .ToArray(); - return new ExchangeRates(exchangeRates); - } + .Select(t => CreateExchangeRate(t)); + + var exchangeRates = await Task.WhenAll(exchangeRateTasks); + + return new ExchangeRates(exchangeRates + .Where(t => t != null) + .ToArray()); } // ExchangeSymbolToGlobalSymbol throws exception which would kill perf ConcurrentDictionary notFoundSymbols = new ConcurrentDictionary(); - private ExchangeRate CreateExchangeRate(KeyValuePair ticker) + private async Task CreateExchangeRate(KeyValuePair ticker) { - if (notFoundSymbols.ContainsKey(ticker.Key)) + if (notFoundSymbols.TryGetValue(ticker.Key, out _)) return null; try { - var tickerName = _ExchangeAPI.ExchangeSymbolToGlobalSymbol(ticker.Key); + var tickerName = await _ExchangeAPI.ExchangeMarketSymbolToGlobalMarketSymbolAsync(ticker.Key); if (!CurrencyPair.TryParse(tickerName, out var pair)) { notFoundSymbols.TryAdd(ticker.Key, ticker.Key); diff --git a/BTCPayServer.Rating/Providers/KrakenExchangeRateProvider.cs b/BTCPayServer.Rating/Providers/KrakenExchangeRateProvider.cs index c17a22d5f..5ccdbab7d 100644 --- a/BTCPayServer.Rating/Providers/KrakenExchangeRateProvider.cs +++ b/BTCPayServer.Rating/Providers/KrakenExchangeRateProvider.cs @@ -91,7 +91,7 @@ namespace BTCPayServer.Services.Rates { var result = new ExchangeRates(); var symbols = await GetSymbolsAsync(cancellationToken); - var normalizedPairsList = symbols.Where(s => !notFoundSymbols.ContainsKey(s)).Select(s => _Helper.NormalizeSymbol(s)).ToList(); + var normalizedPairsList = symbols.Where(s => !notFoundSymbols.ContainsKey(s)).Select(s => _Helper.NormalizeMarketSymbol(s)).ToList(); var csvPairsList = string.Join(",", normalizedPairsList); JToken apiTickers = await MakeJsonRequestAsync("/0/public/Ticker", null, new Dictionary { { "pair", csvPairsList } }, cancellationToken: cancellationToken); var tickers = new List>(); @@ -114,7 +114,7 @@ namespace BTCPayServer.Services.Rates } else { - global = _Helper.ExchangeSymbolToGlobalSymbol(symbol); + global = await _Helper.ExchangeMarketSymbolToGlobalMarketSymbolAsync(symbol); } if (CurrencyPair.TryParse(global, out var pair)) result.Add(new ExchangeRate("kraken", pair.Inverse(), new BidAsk(ticker.Bid, ticker.Ask))); @@ -142,10 +142,10 @@ namespace BTCPayServer.Services.Rates Last = last, Volume = new ExchangeVolume { - BaseVolume = ticker["v"][1].ConvertInvariant(), - BaseSymbol = symbol, - ConvertedVolume = ticker["v"][1].ConvertInvariant() * last, - ConvertedSymbol = symbol, + BaseCurrencyVolume = ticker["v"][1].ConvertInvariant(), + BaseCurrency = symbol, + QuoteCurrencyVolume = ticker["v"][1].ConvertInvariant() * last, + QuoteCurrency = symbol, Timestamp = DateTime.UtcNow } }; diff --git a/BTCPayServer.Rating/Providers/NdaxRateProvider.cs b/BTCPayServer.Rating/Providers/NdaxRateProvider.cs deleted file mode 100644 index 1b8e27a62..000000000 --- a/BTCPayServer.Rating/Providers/NdaxRateProvider.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using BTCPayServer.Rating; -using Newtonsoft.Json.Linq; - -namespace BTCPayServer.Services.Rates -{ - public class NdaxRateProvider : IRateProvider, IHasExchangeName - { - private readonly HttpClient _httpClient; - - public NdaxRateProvider(HttpClient httpClient) - { - _httpClient = httpClient ?? new HttpClient(); - } - - public string ExchangeName => "ndax"; - - public async Task GetRatesAsync(CancellationToken cancellationToken) - { - var response = await _httpClient.GetAsync("https://ndax.io/api/returnTicker", cancellationToken); - var jobj = await response.Content.ReadAsAsync>(cancellationToken); - return new ExchangeRates(jobj.Select(pair => new ExchangeRate(ExchangeName, CurrencyPair.Parse(pair.Key), - new BidAsk(GetValue(pair.Value["highestBid"]), GetValue(pair.Value["lowestAsk"]))))); - } - - private static decimal GetValue(JToken jobj) - { - return string.IsNullOrEmpty(jobj.ToString()) ? 0 : jobj.Value(); - } - - } -} diff --git a/BTCPayServer.Rating/Services/RateProviderFactory.cs b/BTCPayServer.Rating/Services/RateProviderFactory.cs index 1f2ff9a8f..a6d9fc616 100644 --- a/BTCPayServer.Rating/Services/RateProviderFactory.cs +++ b/BTCPayServer.Rating/Services/RateProviderFactory.cs @@ -9,6 +9,7 @@ using ExchangeSharp; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using MemoryCache = Microsoft.Extensions.Caching.Memory.MemoryCache; namespace BTCPayServer.Services.Rates { @@ -103,7 +104,8 @@ namespace BTCPayServer.Services.Rates Providers.Add("binance", new ExchangeSharpRateProvider("binance", new ExchangeBinanceAPI(), true)); Providers.Add("bittrex", new ExchangeSharpRateProvider("bittrex", new ExchangeBittrexAPI(), true)); Providers.Add("poloniex", new ExchangeSharpRateProvider("poloniex", new ExchangePoloniexAPI(), true)); - Providers.Add("hitbtc", new ExchangeSharpRateProvider("hitbtc", new ExchangeHitbtcAPI(), false)); + Providers.Add("hitbtc", new ExchangeSharpRateProvider("hitbtc", new ExchangeHitBTCAPI(), false)); + Providers.Add("ndax", new ExchangeSharpRateProvider("ndax", new ExchangeNDAXAPI(), false)); // Cryptopia is often not available // Disabled because of https://twitter.com/Cryptopia_NZ/status/1085084168852291586 @@ -115,7 +117,6 @@ namespace BTCPayServer.Services.Rates Providers.Add("bylls", new ByllsRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BYLLS"))); Providers.Add("bitbank", new BitbankRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BITBANK"))); Providers.Add("bitpay", new BitpayRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BITPAY"))); - Providers.Add("ndax", new NdaxRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_NDAX"))); // Those exchanges make multiple requests when calling GetTickers so we remove them //DirectProviders.Add("gemini", new ExchangeSharpRateProvider("gemini", new ExchangeGeminiAPI())); @@ -172,7 +173,7 @@ namespace BTCPayServer.Services.Rates // Add other exchanges supported here exchanges.Add(new CoinAverageExchange(CoinAverageRateProvider.CoinAverageName, "Coin Average", $"https://apiv2.bitcoinaverage.com/indices/global/ticker/short")); exchanges.Add(new CoinAverageExchange("bylls", "Bylls", "https://bylls.com/api/price?from_currency=BTC&to_currency=CAD")); - //exchanges.Add(new CoinAverageExchange("ndax", "NDAX", "https://ndax.io/api/returnTicker")); Buggy + exchanges.Add(new CoinAverageExchange("ndax", "NDAX", "https://ndax.io/api/returnTicker")); exchanges.Add(new CoinAverageExchange("bitbank", "Bitbank", "https://public.bitbank.cc/prices")); return exchanges;