mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 09:54:30 +01:00
Fix Kraken API
This commit is contained in:
parent
a8fdc4798d
commit
02663a149e
@ -8,6 +8,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Rating;
|
using BTCPayServer.Rating;
|
||||||
using ExchangeSharp;
|
using ExchangeSharp;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ namespace BTCPayServer.Services.Rates
|
|||||||
// Make sure that only one request is sent to kraken in general
|
// Make sure that only one request is sent to kraken in general
|
||||||
public class KrakenExchangeRateProvider : IRateProvider
|
public class KrakenExchangeRateProvider : IRateProvider
|
||||||
{
|
{
|
||||||
public RateSourceInfo RateSourceInfo => new("kraken", "Kraken", "https://api.kraken.com/0/public/Ticker?pair=ATOMETH,ATOMEUR,ATOMUSD,ATOMXBT,BATETH,BATEUR,BATUSD,BATXBT,BCHEUR,BCHUSD,BCHXBT,DAIEUR,DAIUSD,DAIUSDT,DASHEUR,DASHUSD,DASHXBT,EOSETH,EOSXBT,ETHCHF,ETHDAI,ETHUSDC,ETHUSDT,GNOETH,GNOXBT,ICXETH,ICXEUR,ICXUSD,ICXXBT,LINKETH,LINKEUR,LINKUSD,LINKXBT,LSKETH,LSKEUR,LSKUSD,LSKXBT,NANOETH,NANOEUR,NANOUSD,NANOXBT,OMGETH,OMGEUR,OMGUSD,OMGXBT,PAXGETH,PAXGEUR,PAXGUSD,PAXGXBT,SCETH,SCEUR,SCUSD,SCXBT,USDCEUR,USDCUSD,USDCUSDT,USDTCAD,USDTEUR,USDTGBP,USDTZUSD,WAVESETH,WAVESEUR,WAVESUSD,WAVESXBT,XBTCHF,XBTDAI,XBTUSDC,XBTUSDT,XDGEUR,XDGUSD,XETCXETH,XETCXXBT,XETCZEUR,XETCZUSD,XETHXXBT,XETHZCAD,XETHZEUR,XETHZGBP,XETHZJPY,XETHZUSD,XLTCXXBT,XLTCZEUR,XLTCZUSD,XMLNXETH,XMLNXXBT,XMLNZEUR,XMLNZUSD,XREPXETH,XREPXXBT,XREPZEUR,XXBTZCAD,XXBTZEUR,XXBTZGBP,XXBTZJPY,XXBTZUSD,XXDGXXBT,XXLMXXBT,XXMRXXBT,XXMRZEUR,XXMRZUSD,XXRPXXBT,XXRPZEUR,XXRPZUSD,XZECXXBT,XZECZEUR,XZECZUSD");
|
public RateSourceInfo RateSourceInfo => new("kraken", "Kraken", "https://api.kraken.com/0/public/Ticker");
|
||||||
public HttpClient HttpClient
|
public HttpClient HttpClient
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -31,39 +32,6 @@ namespace BTCPayServer.Services.Rates
|
|||||||
|
|
||||||
HttpClient _LocalClient;
|
HttpClient _LocalClient;
|
||||||
static readonly HttpClient _Client = new HttpClient();
|
static readonly HttpClient _Client = new HttpClient();
|
||||||
|
|
||||||
// ExchangeSymbolToGlobalSymbol throws exception which would kill perf
|
|
||||||
readonly ConcurrentDictionary<string, string> notFoundSymbols = new ConcurrentDictionary<string, string>(new Dictionary<string, string>()
|
|
||||||
{
|
|
||||||
{"ADAXBT","ADAXBT"},
|
|
||||||
{ "BSVUSD","BSVUSD"},
|
|
||||||
{ "QTUMEUR","QTUMEUR"},
|
|
||||||
{ "QTUMXBT","QTUMXBT"},
|
|
||||||
{ "EOSUSD","EOSUSD"},
|
|
||||||
{ "XTZUSD","XTZUSD"},
|
|
||||||
{ "XREPZUSD","XREPZUSD"},
|
|
||||||
{ "ADAEUR","ADAEUR"},
|
|
||||||
{ "ADAUSD","ADAUSD"},
|
|
||||||
{ "GNOEUR","GNOEUR"},
|
|
||||||
{ "XTZETH","XTZETH"},
|
|
||||||
{ "XXRPZJPY","XXRPZJPY"},
|
|
||||||
{ "XXRPZCAD","XXRPZCAD"},
|
|
||||||
{ "XTZEUR","XTZEUR"},
|
|
||||||
{ "QTUMETH","QTUMETH"},
|
|
||||||
{ "XXLMZUSD","XXLMZUSD"},
|
|
||||||
{ "QTUMCAD","QTUMCAD"},
|
|
||||||
{ "QTUMUSD","QTUMUSD"},
|
|
||||||
{ "XTZXBT","XTZXBT"},
|
|
||||||
{ "GNOUSD","GNOUSD"},
|
|
||||||
{ "ADAETH","ADAETH"},
|
|
||||||
{ "ADACAD","ADACAD"},
|
|
||||||
{ "XTZCAD","XTZCAD"},
|
|
||||||
{ "BSVEUR","BSVEUR"},
|
|
||||||
{ "XZECZJPY","XZECZJPY"},
|
|
||||||
{ "XXLMZEUR","XXLMZEUR"},
|
|
||||||
{"EOSEUR","EOSEUR"},
|
|
||||||
{"BSVXBT","BSVXBT"}
|
|
||||||
});
|
|
||||||
string[] _Symbols = Array.Empty<string>();
|
string[] _Symbols = Array.Empty<string>();
|
||||||
DateTimeOffset? _LastSymbolUpdate = null;
|
DateTimeOffset? _LastSymbolUpdate = null;
|
||||||
readonly Dictionary<string, string> _TickerMapping = new Dictionary<string, string>()
|
readonly Dictionary<string, string> _TickerMapping = new Dictionary<string, string>()
|
||||||
@ -76,47 +44,54 @@ namespace BTCPayServer.Services.Rates
|
|||||||
{ "ZEUR", "EUR" },
|
{ "ZEUR", "EUR" },
|
||||||
{ "ZJPY", "JPY" },
|
{ "ZJPY", "JPY" },
|
||||||
{ "ZCAD", "CAD" },
|
{ "ZCAD", "CAD" },
|
||||||
{ "ZGBP", "GBP" }
|
{ "ZGBP", "GBP" },
|
||||||
|
{ "XXMR", "XMR" },
|
||||||
|
{ "XETH", "ETH" },
|
||||||
|
{ "USDC", "USDC" }, // On A=A purpose
|
||||||
};
|
};
|
||||||
|
|
||||||
|
string Normalize(string ticker)
|
||||||
|
{
|
||||||
|
_TickerMapping.TryGetValue(ticker, out var normalized);
|
||||||
|
return normalized ?? ticker;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly ConcurrentDictionary<string, CurrencyPair> CachedCurrencyPairs = new ConcurrentDictionary<string, CurrencyPair>();
|
||||||
|
private CurrencyPair GetCurrencyPair(string symbol)
|
||||||
|
{
|
||||||
|
if (CachedCurrencyPairs.TryGetValue(symbol, out var pair))
|
||||||
|
return pair;
|
||||||
|
var found = _TickerMapping.Where(t => symbol.StartsWith(t.Key, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.Select(t => new { KrakenTicker = t.Key, PayTicker = t.Value }).FirstOrDefault();
|
||||||
|
if (found is not null)
|
||||||
|
{
|
||||||
|
pair = new CurrencyPair(found.PayTicker, Normalize(symbol.Substring(found.KrakenTicker.Length)));
|
||||||
|
}
|
||||||
|
if (pair is null)
|
||||||
|
{
|
||||||
|
found = _TickerMapping.Where(t => symbol.EndsWith(t.Key, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.Select(t => new { KrakenTicker = t.Key, PayTicker = t.Value }).FirstOrDefault();
|
||||||
|
if (found is not null)
|
||||||
|
pair = new CurrencyPair(Normalize(symbol.Substring(0, symbol.Length - found.KrakenTicker.Length)), found.PayTicker);
|
||||||
|
}
|
||||||
|
if (pair is null)
|
||||||
|
CurrencyPair.TryParse(symbol, out pair);
|
||||||
|
CachedCurrencyPairs.TryAdd(symbol, pair);
|
||||||
|
return pair;
|
||||||
|
}
|
||||||
public async Task<PairRate[]> GetRatesAsync(CancellationToken cancellationToken)
|
public async Task<PairRate[]> GetRatesAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = new List<PairRate>();
|
var result = new List<PairRate>();
|
||||||
var symbols = await GetSymbolsAsync(cancellationToken);
|
var symbols = await GetSymbolsAsync(cancellationToken);
|
||||||
var helper = (ExchangeKrakenAPI)await ExchangeAPI.GetExchangeAPIAsync<ExchangeKrakenAPI>();
|
JToken apiTickers = await MakeJsonRequestAsync<JToken>("/0/public/Ticker", null, null, cancellationToken: cancellationToken);
|
||||||
var normalizedPairsList = symbols.Where(s => !notFoundSymbols.ContainsKey(s)).Select(s => helper.NormalizeMarketSymbol(s)).ToList();
|
|
||||||
var csvPairsList = string.Join(",", normalizedPairsList);
|
|
||||||
JToken apiTickers = await MakeJsonRequestAsync<JToken>("/0/public/Ticker", null, new Dictionary<string, object> { { "pair", csvPairsList } }, cancellationToken: cancellationToken);
|
|
||||||
foreach (string symbol in symbols)
|
foreach (string symbol in symbols)
|
||||||
{
|
{
|
||||||
var ticker = ConvertToExchangeTicker(symbol, apiTickers[symbol]);
|
var ticker = ConvertToExchangeTicker(symbol, apiTickers[symbol]);
|
||||||
if (ticker != null)
|
if (ticker != null)
|
||||||
{
|
{
|
||||||
try
|
var pair = GetCurrencyPair(symbol);
|
||||||
{
|
if (pair is not null)
|
||||||
string global = null;
|
result.Add(new PairRate(pair, new BidAsk(ticker.Bid, ticker.Ask)));
|
||||||
var mapped1 = _TickerMapping.Where(t => symbol.StartsWith(t.Key, StringComparison.OrdinalIgnoreCase))
|
|
||||||
.Select(t => new { KrakenTicker = t.Key, PayTicker = t.Value }).SingleOrDefault();
|
|
||||||
if (mapped1 != null)
|
|
||||||
{
|
|
||||||
var p2 = symbol.Substring(mapped1.KrakenTicker.Length);
|
|
||||||
if (_TickerMapping.TryGetValue(p2, out var mapped2))
|
|
||||||
p2 = mapped2;
|
|
||||||
global = $"{mapped1.PayTicker}_{p2}";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
global = await helper.ExchangeMarketSymbolToGlobalMarketSymbolAsync(symbol);
|
|
||||||
}
|
|
||||||
if (CurrencyPair.TryParse(global, out var pair))
|
|
||||||
result.Add(new PairRate(pair, new BidAsk(ticker.Bid, ticker.Ask)));
|
|
||||||
else
|
|
||||||
notFoundSymbols.TryAdd(symbol, symbol);
|
|
||||||
}
|
|
||||||
catch (ArgumentException)
|
|
||||||
{
|
|
||||||
notFoundSymbols.TryAdd(symbol, symbol);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result.ToArray();
|
return result.ToArray();
|
||||||
|
Loading…
Reference in New Issue
Block a user