diff --git a/BTCPayServer.Rating/Providers/CryptoMarketExchangeRateProvider.cs b/BTCPayServer.Rating/Providers/CryptoMarketExchangeRateProvider.cs new file mode 100644 index 000000000..c5e864a49 --- /dev/null +++ b/BTCPayServer.Rating/Providers/CryptoMarketExchangeRateProvider.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using System.Globalization; +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 CryptoMarketExchangeRateProvider : IRateProvider + { + private readonly HttpClient _httpClient; + public CryptoMarketExchangeRateProvider(HttpClient httpClient) + { + _httpClient = httpClient ?? new HttpClient(); + } + + + readonly List SupportedPairs = new List() + { + "BTCARS", + "BTCCLP", + "BTCBRL" + }; + + public async Task GetRatesAsync(CancellationToken cancellationToken) + { + var response = await _httpClient.GetAsync("https://api.exchange.cryptomkt.com/api/3/public/ticker/", cancellationToken); + var jobj = await response.Content.ReadAsAsync(cancellationToken); + + return ((jobj as JObject) ?? new JObject()) + .Properties() + .Where(p => SupportedPairs.Contains(p.Name)) + .Select(p => new PairRate(CurrencyPair.Parse(p.Name), CreateBidAsk(p))) + .ToArray(); + } + private static BidAsk CreateBidAsk(JProperty p) + { + var bid = decimal.Parse(p.Value["bid"].Value(), System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture); + var ask = decimal.Parse(p.Value["ask"].Value(), System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture); + if (bid > ask) + return null; + return new BidAsk(bid, ask); + } + } +} diff --git a/BTCPayServer.Rating/Services/RateProviderFactory.cs b/BTCPayServer.Rating/Services/RateProviderFactory.cs index f7b4d7d38..4ea7124da 100644 --- a/BTCPayServer.Rating/Services/RateProviderFactory.cs +++ b/BTCPayServer.Rating/Services/RateProviderFactory.cs @@ -76,6 +76,7 @@ namespace BTCPayServer.Services.Rates yield return new AvailableRateProvider("bitflyer", "Bitflyer", "https://api.bitflyer.com/v1/ticker"); yield return new AvailableRateProvider("bitpay", "Bitpay", "https://bitpay.com/rates"); yield return new AvailableRateProvider("ripio", "Ripio", "https://api.exchange.ripio.com/api/v1/rate/all/"); + yield return new AvailableRateProvider("cryptomarket", "CryptoMarket", "https://api.exchange.cryptomkt.com/api/3/public/ticker/"); yield return new AvailableRateProvider("polispay", "PolisPay", "https://obol.polispay.com/complex/btc/polis"); @@ -101,6 +102,7 @@ namespace BTCPayServer.Services.Rates Providers.Add("bitbank", new BitbankRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BITBANK"))); Providers.Add("bitpay", new BitpayRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BITPAY"))); Providers.Add("ripio", new RipioExchangeProvider(_httpClientFactory?.CreateClient("EXCHANGE_RIPIO"))); + Providers.Add("cryptomarket", new CryptoMarketExchangeRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_CRYPTOMARKET"))); Providers.Add("bitflyer", new BitflyerRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BITFLYER"))); Providers.Add("polispay", new PolisRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_POLIS"))); // Providers.Add("argoneum", new ArgoneumRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_ARGONEUM"))); diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index 892c05589..c3d18b459 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -3313,6 +3313,12 @@ namespace BTCPayServer.Tests && e.BidAsk.Bid > 1.0m)); // 1BTC will always be more than 1USD } } + else if (result.ExpectedName == "cryptomarket") + { + Assert.Contains(exchangeRates.ByExchange[result.ExpectedName], + e => e.CurrencyPair == new CurrencyPair("BTC", "CLP") && + e.BidAsk.Bid > 1.0m); // 1 BTC will always be more than 1 CLP + } else { // This check if the currency pair is using right currency pair