diff --git a/BTCPayServer.Rating/Providers/CoinAverageSettings.cs b/BTCPayServer.Rating/Providers/CoinAverageSettings.cs index ec255aab9..92769535a 100644 --- a/BTCPayServer.Rating/Providers/CoinAverageSettings.cs +++ b/BTCPayServer.Rating/Providers/CoinAverageSettings.cs @@ -70,61 +70,73 @@ namespace BTCPayServer.Services.Rates //} //b.AppendLine("}.ToArray()"); AvailableExchanges = new CoinAverageExchanges(); - foreach(var item in + foreach (var item in new[] { - (DisplayName: "BitBargain", Name: "bitbargain"), - (DisplayName: "Tidex", Name: "tidex"), - (DisplayName: "LocalBitcoins", Name: "localbitcoins"), - (DisplayName: "EtherDelta", Name: "etherdelta"), - (DisplayName: "Kraken", Name: "kraken"), - (DisplayName: "BitBay", Name: "bitbay"), - (DisplayName: "Independent Reserve", Name: "independentreserve"), - (DisplayName: "Exmoney", Name: "exmoney"), - (DisplayName: "Bitcoin.co.id", Name: "bitcoin_co_id"), - (DisplayName: "Huobi", Name: "huobi"), - (DisplayName: "GDAX", Name: "gdax"), - (DisplayName: "Coincheck", Name: "coincheck"), - (DisplayName: "Bittylicious", Name: "bittylicious"), - (DisplayName: "Gemini", Name: "gemini"), - (DisplayName: "Bit2C", Name: "bit2c"), - (DisplayName: "Luno", Name: "luno"), - (DisplayName: "Negocie Coins", Name: "negociecoins"), - (DisplayName: "FYB-SE", Name: "fybse"), - (DisplayName: "Hitbtc", Name: "hitbtc"), - (DisplayName: "Bitex.la", Name: "bitex"), - (DisplayName: "Korbit", Name: "korbit"), - (DisplayName: "itBit", Name: "itbit"), - (DisplayName: "Okex", Name: "okex"), - (DisplayName: "Bitsquare", Name: "bitsquare"), - (DisplayName: "Bitfinex", Name: "bitfinex"), - (DisplayName: "CoinMate", Name: "coinmate"), - (DisplayName: "Bitstamp", Name: "bitstamp"), - (DisplayName: "Cryptonit", Name: "cryptonit"), - (DisplayName: "Foxbit", Name: "foxbit"), - (DisplayName: "QuickBitcoin", Name: "quickbitcoin"), - (DisplayName: "Poloniex", Name: "poloniex"), - (DisplayName: "Bit-Z", Name: "bitz"), - (DisplayName: "Liqui", Name: "liqui"), - (DisplayName: "BitKonan", Name: "bitkonan"), - (DisplayName: "Kucoin", Name: "kucoin"), - (DisplayName: "Binance", Name: "binance"), - (DisplayName: "Rock Trading", Name: "rocktrading"), - (DisplayName: "Mercado Bitcoin", Name: "mercado"), - (DisplayName: "Coinsecure", Name: "coinsecure"), + (DisplayName: "Idex", Name: "idex"), (DisplayName: "Coinfloor", Name: "coinfloor"), - (DisplayName: "bitFlyer", Name: "bitflyer"), - (DisplayName: "BTCTurk", Name: "btcturk"), - (DisplayName: "Bittrex", Name: "bittrex"), - (DisplayName: "CampBX", Name: "campbx"), - (DisplayName: "Zaif", Name: "zaif"), - (DisplayName: "FYB-SG", Name: "fybsg"), - (DisplayName: "Quoine", Name: "quoine"), + (DisplayName: "Okex", Name: "okex"), + (DisplayName: "Bitfinex", Name: "bitfinex"), + (DisplayName: "Bittylicious", Name: "bittylicious"), (DisplayName: "BTC Markets", Name: "btcmarkets"), + (DisplayName: "Kucoin", Name: "kucoin"), + (DisplayName: "IDAX", Name: "idax"), + (DisplayName: "Kraken", Name: "kraken"), + (DisplayName: "Bit2C", Name: "bit2c"), + (DisplayName: "Mercado Bitcoin", Name: "mercado"), + (DisplayName: "CEX.IO", Name: "cex"), + (DisplayName: "Bitex.la", Name: "bitex"), + (DisplayName: "Quoine", Name: "quoine"), + (DisplayName: "Stex", Name: "stex"), + (DisplayName: "CoinTiger", Name: "cointiger"), + (DisplayName: "Poloniex", Name: "poloniex"), + (DisplayName: "Zaif", Name: "zaif"), + (DisplayName: "Huobi", Name: "huobi"), + (DisplayName: "QuickBitcoin", Name: "quickbitcoin"), + (DisplayName: "Tidex", Name: "tidex"), + (DisplayName: "Tokenomy", Name: "tokenomy"), + (DisplayName: "Bitcoin.co.id", Name: "bitcoin_co_id"), + (DisplayName: "Kryptono", Name: "kryptono"), (DisplayName: "Bitso", Name: "bitso"), + (DisplayName: "Korbit", Name: "korbit"), + (DisplayName: "Yobit", Name: "yobit"), + (DisplayName: "BitBargain", Name: "bitbargain"), + (DisplayName: "Livecoin", Name: "livecoin"), + (DisplayName: "Hotbit", Name: "hotbit"), + (DisplayName: "Coincheck", Name: "coincheck"), + (DisplayName: "Binance", Name: "binance"), + (DisplayName: "Bit-Z", Name: "bitz"), + (DisplayName: "Coinbase Pro", Name: "coinbasepro"), + (DisplayName: "Rock Trading", Name: "rocktrading"), + (DisplayName: "Bittrex", Name: "bittrex"), + (DisplayName: "BitBay", Name: "bitbay"), + (DisplayName: "Tokenize", Name: "tokenize"), + (DisplayName: "Hitbtc", Name: "hitbtc"), + (DisplayName: "Upbit", Name: "upbit"), + (DisplayName: "Bitstamp", Name: "bitstamp"), + (DisplayName: "Luno", Name: "luno"), + (DisplayName: "Trade.io", Name: "tradeio"), + (DisplayName: "LocalBitcoins", Name: "localbitcoins"), + (DisplayName: "Independent Reserve", Name: "independentreserve"), + (DisplayName: "Coinsquare", Name: "coinsquare"), + (DisplayName: "Exmoney", Name: "exmoney"), + (DisplayName: "Coinegg", Name: "coinegg"), + (DisplayName: "FYB-SG", Name: "fybsg"), + (DisplayName: "Cryptonit", Name: "cryptonit"), + (DisplayName: "BTCTurk", Name: "btcturk"), + (DisplayName: "bitFlyer", Name: "bitflyer"), + (DisplayName: "Negocie Coins", Name: "negociecoins"), + (DisplayName: "OasisDEX", Name: "oasisdex"), + (DisplayName: "CoinMate", Name: "coinmate"), + (DisplayName: "BitForex", Name: "bitforex"), + (DisplayName: "Bitsquare", Name: "bitsquare"), + (DisplayName: "FYB-SE", Name: "fybse"), + (DisplayName: "itBit", Name: "itbit"), }) { AvailableExchanges.TryAdd(item.Name, new CoinAverageExchange(item.Name, item.DisplayName, $"https://apiv2.bitcoinaverage.com/exchanges/{item.Name}")); } + // Keep back-compat + AvailableExchanges.Add(new CoinAverageExchange("gdax", string.Empty, $"https://apiv2.bitcoinaverage.com/exchanges/coinbasepro")); } public Task AddHeader(HttpRequestMessage message) diff --git a/BTCPayServer.Rating/Services/RateProviderFactory.cs b/BTCPayServer.Rating/Services/RateProviderFactory.cs index f23ed52ab..dd3449697 100644 --- a/BTCPayServer.Rating/Services/RateProviderFactory.cs +++ b/BTCPayServer.Rating/Services/RateProviderFactory.cs @@ -116,7 +116,6 @@ namespace BTCPayServer.Services.Rates Providers.Add("bitbank", new BitbankRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BITBANK"))); // Those exchanges make multiple requests when calling GetTickers so we remove them - //DirectProviders.Add("gdax", new ExchangeSharpRateProvider("gdax", new ExchangeGdaxAPI())); //DirectProviders.Add("gemini", new ExchangeSharpRateProvider("gemini", new ExchangeGeminiAPI())); //DirectProviders.Add("bitfinex", new ExchangeSharpRateProvider("bitfinex", new ExchangeBitfinexAPI())); //DirectProviders.Add("okex", new ExchangeSharpRateProvider("okex", new ExchangeOkexAPI())); diff --git a/BTCPayServer.Tests/RateRulesTest.cs b/BTCPayServer.Tests/RateRulesTest.cs index fe309cea4..8a508cede 100644 --- a/BTCPayServer.Tests/RateRulesTest.cs +++ b/BTCPayServer.Tests/RateRulesTest.cs @@ -34,7 +34,7 @@ namespace BTCPayServer.Tests builder.AppendLine("DOGE_X = DOGE_BTC * BTC_X * 1.1"); builder.AppendLine("DOGE_BTC = Bittrex(DOGE_BTC)"); builder.AppendLine("// Some other cool comments"); - builder.AppendLine("BTC_usd = GDax(BTC_USD)"); + builder.AppendLine("BTC_usd = kraken(BTC_USD)"); builder.AppendLine("BTC_X = Coinbase(BTC_X);"); builder.AppendLine("X_X = CoinAverage(X_X) * 1.02"); @@ -45,14 +45,14 @@ namespace BTCPayServer.Tests "DOGE_X = DOGE_BTC * BTC_X * 1.1;\n" + "DOGE_BTC = bittrex(DOGE_BTC);\n" + "// Some other cool comments\n" + - "BTC_USD = gdax(BTC_USD);\n" + + "BTC_USD = kraken(BTC_USD);\n" + "BTC_X = coinbase(BTC_X);\n" + "X_X = coinaverage(X_X) * 1.02;", rules.ToString()); var tests = new[] { - (Pair: "DOGE_USD", Expected: "bittrex(DOGE_BTC) * gdax(BTC_USD) * 1.1"), - (Pair: "BTC_USD", Expected: "gdax(BTC_USD)"), + (Pair: "DOGE_USD", Expected: "bittrex(DOGE_BTC) * kraken(BTC_USD) * 1.1"), + (Pair: "BTC_USD", Expected: "kraken(BTC_USD)"), (Pair: "BTC_CAD", Expected: "coinbase(BTC_CAD)"), (Pair: "DOGE_CAD", Expected: "bittrex(DOGE_BTC) * coinbase(BTC_CAD) * 1.1"), (Pair: "LTC_CAD", Expected: "coinaverage(LTC_CAD) * 1.02"), @@ -62,14 +62,14 @@ namespace BTCPayServer.Tests Assert.Equal(test.Expected, rules.GetRuleFor(CurrencyPair.Parse(test.Pair)).ToString()); } rules.Spread = 0.2m; - Assert.Equal("(bittrex(DOGE_BTC) * gdax(BTC_USD) * 1.1) * (0.8, 1.2)", rules.GetRuleFor(CurrencyPair.Parse("DOGE_USD")).ToString()); + Assert.Equal("(bittrex(DOGE_BTC) * kraken(BTC_USD) * 1.1) * (0.8, 1.2)", rules.GetRuleFor(CurrencyPair.Parse("DOGE_USD")).ToString()); //////////////// // Check errors conditions builder = new StringBuilder(); builder.AppendLine("DOGE_X = LTC_CAD * BTC_X * 1.1"); builder.AppendLine("DOGE_BTC = Bittrex(DOGE_BTC)"); - builder.AppendLine("BTC_usd = GDax(BTC_USD)"); + builder.AppendLine("BTC_usd = kraken(BTC_USD)"); builder.AppendLine("LTC_CHF = LTC_CHF * 1.01"); builder.AppendLine("BTC_X = Coinbase(BTC_X)"); Assert.True(RateRules.TryParse(builder.ToString(), out rules)); @@ -77,7 +77,7 @@ namespace BTCPayServer.Tests tests = new[] { (Pair: "LTC_CAD", Expected: "ERR_NO_RULE_MATCH(LTC_CAD)"), - (Pair: "DOGE_USD", Expected: "ERR_NO_RULE_MATCH(LTC_CAD) * gdax(BTC_USD) * 1.1"), + (Pair: "DOGE_USD", Expected: "ERR_NO_RULE_MATCH(LTC_CAD) * kraken(BTC_USD) * 1.1"), (Pair: "LTC_CHF", Expected: "ERR_TOO_MUCH_NESTED_CALLS(LTC_CHF) * 1.01"), }; foreach (var test in tests) @@ -90,15 +90,15 @@ namespace BTCPayServer.Tests builder = new StringBuilder(); builder.AppendLine("DOGE_X = DOGE_BTC * BTC_X * 1.1"); builder.AppendLine("DOGE_BTC = Bittrex(DOGE_BTC)"); - builder.AppendLine("BTC_usd = GDax(BTC_USD)"); + builder.AppendLine("BTC_usd = kraken(BTC_USD)"); builder.AppendLine("BTC_X = Coinbase(BTC_X)"); builder.AppendLine("X_X = CoinAverage(X_X) * 1.02"); Assert.True(RateRules.TryParse(builder.ToString(), out rules)); var tests2 = new[] { - (Pair: "DOGE_USD", Expected: "bittrex(DOGE_BTC) * gdax(BTC_USD) * 1.1", ExpectedExchangeRates: "bittrex(DOGE_BTC),gdax(BTC_USD)"), - (Pair: "BTC_USD", Expected: "gdax(BTC_USD)", ExpectedExchangeRates: "gdax(BTC_USD)"), + (Pair: "DOGE_USD", Expected: "bittrex(DOGE_BTC) * kraken(BTC_USD) * 1.1", ExpectedExchangeRates: "bittrex(DOGE_BTC),kraken(BTC_USD)"), + (Pair: "BTC_USD", Expected: "kraken(BTC_USD)", ExpectedExchangeRates: "kraken(BTC_USD)"), (Pair: "BTC_CAD", Expected: "coinbase(BTC_CAD)", ExpectedExchangeRates: "coinbase(BTC_CAD)"), (Pair: "DOGE_CAD", Expected: "bittrex(DOGE_BTC) * coinbase(BTC_CAD) * 1.1", ExpectedExchangeRates: "bittrex(DOGE_BTC),coinbase(BTC_CAD)"), (Pair: "LTC_CAD", Expected: "coinaverage(LTC_CAD) * 1.02", ExpectedExchangeRates: "coinaverage(LTC_CAD)"), diff --git a/BTCPayServer.Tests/UtilitiesTests.cs b/BTCPayServer.Tests/UtilitiesTests.cs index 1b1a25c2d..5862a6e59 100644 --- a/BTCPayServer.Tests/UtilitiesTests.cs +++ b/BTCPayServer.Tests/UtilitiesTests.cs @@ -9,6 +9,7 @@ using NBitcoin.DataEncoders; using Newtonsoft.Json.Linq; using Xunit; using System.IO; +using BTCPayServer.Services.Rates; namespace BTCPayServer.Tests { diff --git a/BTCPayServer/Controllers/StoresController.cs b/BTCPayServer/Controllers/StoresController.cs index 9c00e5d4e..63a2a7718 100644 --- a/BTCPayServer/Controllers/StoresController.cs +++ b/BTCPayServer/Controllers/StoresController.cs @@ -590,6 +590,7 @@ namespace BTCPayServer.Controllers private CoinAverageExchange[] GetSupportedExchanges() { return _RateFactory.RateProviderFactory.GetSupportedExchanges() + .Where(r => !string.IsNullOrWhiteSpace(r.Value.Display)) .Select(c => c.Value) .OrderBy(s => s.Name, StringComparer.OrdinalIgnoreCase) .ToArray(); diff --git a/BTCPayServer/Views/Stores/Rates.cshtml b/BTCPayServer/Views/Stores/Rates.cshtml index d98885402..5702dc8d7 100644 --- a/BTCPayServer/Views/Stores/Rates.cshtml +++ b/BTCPayServer/Views/Stores/Rates.cshtml @@ -58,25 +58,25 @@
The script language is composed of several rules composed of a currency pair and a mathematic expression.
- The example below will use gdax
for both LTC_USD
and BTC_USD
pairs.
+ The example below will use kraken
for both LTC_USD
and BTC_USD
pairs.
- LTC_USD = gdax(LTC_USD);
- BTC_USD = gdax(BTC_USD);
+ LTC_USD = kraken(LTC_USD);
+ BTC_USD = kraken(BTC_USD);
- However, explicitely setting specific pairs like this can be a bit difficult. Instead, you can define a rule X_X
which will match any currency pair. The following example will use gdax
for getting the rate of any currency pair.
However, explicitely setting specific pairs like this can be a bit difficult. Instead, you can define a rule X_X
which will match any currency pair. The following example will use kraken
for getting the rate of any currency pair.
- X_X = gdax(X_X);
+ X_X = kraken(X_X);
- However, gdax
does not support the BTC_CAD
pair. For this reason you can add a rule mapping all X_CAD
to quadrigacx
, a Canadian exchange.
However, kraken
does not support the BTC_CAD
pair. For this reason you can add a rule mapping all X_CAD
to quadrigacx
, a Canadian exchange.
X_CAD = quadrigacx(X_CAD);
- X_X = gdax(X_X);
+ X_X = kraken(X_X);
A given currency pair match the most specific rule. If two rules are matching and are as specific, the first rule will be chosen.
@@ -88,11 +88,11 @@
DOGE_X = bittrex(DOGE_BTC) * BTC_X
X_CAD = quadrigacx(X_CAD);
- X_X = gdax(X_X);
+ X_X = kraken(X_X);
- With DOGE_USD
will be expanded to bittrex(DOGE_BTC) * gdax(BTC_USD)
. And DOGE_CAD
will be expanded to bittrex(DOGE_BTC) * quadrigacx(BTC_CAD)
.
+ With DOGE_USD
will be expanded to bittrex(DOGE_BTC) * kraken(BTC_USD)
. And DOGE_CAD
will be expanded to bittrex(DOGE_BTC) * quadrigacx(BTC_CAD)
.
However, we advise you to write it that way to increase coverage so that DOGE_BTC
is also supported:
@@ -100,7 +100,7 @@ DOGE_X = DOGE_BTC * BTC_X DOGE_BTC = bittrex(DOGE_BTC) X_CAD = quadrigacx(X_CAD); - X_X = gdax(X_X); + X_X = kraken(X_X);