diff --git a/CryptoExchange.Net/CryptoExchange.Net.csproj b/CryptoExchange.Net/CryptoExchange.Net.csproj index c22c03f..e5bb4b3 100644 --- a/CryptoExchange.Net/CryptoExchange.Net.csproj +++ b/CryptoExchange.Net/CryptoExchange.Net.csproj @@ -6,9 +6,9 @@ CryptoExchange.Net JKorf CryptoExchange.Net is a base library which is used to implement different cryptocurrency (exchange) API's. It provides a standardized way of implementing different API's, which results in a very similar experience for users of the API implementations. - 10.3.0 - 10.3.0 - 10.3.0 + 10.3.1 + 10.3.1 + 10.3.1 false OKX;OKX.Net;Mexc;Mexc.Net;Kucoin;Kucoin.Net;Kraken;Kraken.Net;Huobi;Huobi.Net;CoinEx;CoinEx.Net;Bybit;Bybit.Net;Bitget;Bitget.Net;Bitfinex;Bitfinex.Net;Binance;Binance.Net;CryptoCurrency;CryptoCurrency Exchange;CryptoExchange.Net git diff --git a/CryptoExchange.Net/ExchangeSymbolCache.cs b/CryptoExchange.Net/ExchangeSymbolCache.cs index 2b237d4..da00729 100644 --- a/CryptoExchange.Net/ExchangeSymbolCache.cs +++ b/CryptoExchange.Net/ExchangeSymbolCache.cs @@ -32,6 +32,66 @@ namespace CryptoExchange.Net _symbolInfos[topicId] = new ExchangeInfo(DateTime.UtcNow, updateData.ToDictionary(x => x.Name, x => x.SharedSymbol)); } + /// + /// Whether the specific topic has been cached + /// + /// Id + public static bool HasCached(string topicId) + { + if (!_symbolInfos.TryGetValue(topicId, out var exchangeInfo)) + return false; + + return exchangeInfo.Symbols.Count > 0; + } + + /// + /// Whether a specific exchange(topic) support the provided symbol + /// + /// Id for the provided data + /// The symbol name + public static bool SupportsSymbol(string topicId, string symbolName) + { + if (!_symbolInfos.TryGetValue(topicId, out var exchangeInfo)) + return false; + + if (!exchangeInfo.Symbols.TryGetValue(symbolName, out var symbolInfo)) + return false; + + return true; + } + + /// + /// Whether a specific exchange(topic) support the provided symbol + /// + /// Id for the provided data + /// The symbol info + public static bool SupportsSymbol(string topicId, SharedSymbol symbol) + { + if (!_symbolInfos.TryGetValue(topicId, out var exchangeInfo)) + return false; + + return exchangeInfo.Symbols.Any(x => + x.Value.TradingMode == symbol.TradingMode + && x.Value.BaseAsset == symbol.BaseAsset + && x.Value.QuoteAsset == symbol.QuoteAsset); + } + + /// + /// Get all symbols for a specific base asset + /// + /// Id for the provided data + /// Base asset name + public static SharedSymbol[] GetSymbolsForBaseAsset(string topicId, string baseAsset) + { + if (!_symbolInfos.TryGetValue(topicId, out var exchangeInfo)) + return []; + + return exchangeInfo.Symbols + .Where(x => x.Value.BaseAsset.Equals(baseAsset, StringComparison.InvariantCultureIgnoreCase)) + .Select(x => x.Value) + .ToArray(); + } + /// /// Parse a symbol name to a SharedSymbol /// diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesSymbolRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesSymbolRestClient.cs index 81b27db..fa7e977 100644 --- a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesSymbolRestClient.cs +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesSymbolRestClient.cs @@ -12,6 +12,25 @@ namespace CryptoExchange.Net.SharedApis /// Futures symbol request options /// EndpointOptions GetFuturesSymbolsOptions { get; } + + /// + /// Get all futures symbols for a specific base asset + /// + /// Asset, for example `ETH` + Task> GetFuturesSymbolsForBaseAssetAsync(string baseAsset); + + /// + /// Gets whether the client supports a futures symbol + /// + /// The symbol + Task> SupportsFuturesSymbolAsync(SharedSymbol symbol); + + /// + /// Gets whether the client supports a futures symbol + /// + /// The symbol name + Task> SupportsFuturesSymbolAsync(string symbolName); + /// /// Get info on all futures symbols supported on the exchange /// diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotSymbolRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotSymbolRestClient.cs index 78cb0f4..71f80a5 100644 --- a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotSymbolRestClient.cs +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotSymbolRestClient.cs @@ -1,4 +1,5 @@ -using System.Threading; +using CryptoExchange.Net.Objects; +using System.Threading; using System.Threading.Tasks; namespace CryptoExchange.Net.SharedApis @@ -13,6 +14,24 @@ namespace CryptoExchange.Net.SharedApis /// EndpointOptions GetSpotSymbolsOptions { get; } + /// + /// Get all spot symbols for a specific base asset + /// + /// Asset, for example `ETH` + Task> GetSpotSymbolsForBaseAssetAsync(string baseAsset); + + /// + /// Gets whether the client supports a spot symbol + /// + /// The symbol + Task> SupportsSpotSymbolAsync(SharedSymbol symbol); + + /// + /// Gets whether the client supports a spot symbol + /// + /// The symbol name + Task> SupportsSpotSymbolAsync(string symbolName); + /// /// Get info on all available spot symbols on the exchange /// diff --git a/CryptoExchange.Net/SharedApis/Models/ExchangeResult.cs b/CryptoExchange.Net/SharedApis/Models/ExchangeResult.cs index be09d54..8532966 100644 --- a/CryptoExchange.Net/SharedApis/Models/ExchangeResult.cs +++ b/CryptoExchange.Net/SharedApis/Models/ExchangeResult.cs @@ -38,6 +38,17 @@ namespace CryptoExchange.Net.SharedApis Exchange = exchange; } + /// + /// ctor + /// + public ExchangeResult( + string exchange, + T result) : + base(result, null, null) + { + Exchange = exchange; + } + /// public override string ToString() => $"{Exchange} - " + base.ToString(); } diff --git a/CryptoExchange.Net/Trackers/Klines/IKlineTracker.cs b/CryptoExchange.Net/Trackers/Klines/IKlineTracker.cs index c83b54a..f18526b 100644 --- a/CryptoExchange.Net/Trackers/Klines/IKlineTracker.cs +++ b/CryptoExchange.Net/Trackers/Klines/IKlineTracker.cs @@ -55,6 +55,11 @@ namespace CryptoExchange.Net.Trackers.Klines /// SharedKline? Last { get; } + /// + /// The kline interval + /// + public SharedKlineInterval Interval { get; } + /// /// Event for when a new kline is added /// diff --git a/CryptoExchange.Net/Trackers/Klines/KlineTracker.cs b/CryptoExchange.Net/Trackers/Klines/KlineTracker.cs index 3c475b5..5083474 100644 --- a/CryptoExchange.Net/Trackers/Klines/KlineTracker.cs +++ b/CryptoExchange.Net/Trackers/Klines/KlineTracker.cs @@ -45,10 +45,6 @@ namespace CryptoExchange.Net.Trackers.Klines /// protected bool _changed = false; /// - /// The kline interval - /// - protected readonly SharedKlineInterval _interval; - /// /// Whether the snapshot has been set /// protected bool _snapshotSet; @@ -66,6 +62,10 @@ namespace CryptoExchange.Net.Trackers.Klines /// protected DateTime? _firstTimestamp; + /// + /// The kline interval + /// + public SharedKlineInterval Interval { get; } /// public SyncStatus Status { @@ -165,7 +165,7 @@ namespace CryptoExchange.Net.Trackers.Klines Exchange = restClient.Exchange; Limit = limit; Period = period; - _interval = interval; + Interval = interval; _socketClient = socketClient; _restClient = restClient; } @@ -180,7 +180,7 @@ namespace CryptoExchange.Net.Trackers.Klines Status = SyncStatus.Syncing; _logger.KlineTrackerStarting(SymbolName); - var subResult = await _socketClient.SubscribeToKlineUpdatesAsync(new SubscribeKlineRequest(Symbol, _interval), + var subResult = await _socketClient.SubscribeToKlineUpdatesAsync(new SubscribeKlineRequest(Symbol, Interval), update => { AddOrUpdate(update.Data); @@ -237,7 +237,7 @@ namespace CryptoExchange.Net.Trackers.Klines var limit = Math.Min(_restClient.GetKlinesOptions.MaxLimit, Limit ?? 100); - var request = new GetKlinesRequest(Symbol, _interval, startTime, DateTime.UtcNow, limit: limit); + var request = new GetKlinesRequest(Symbol, Interval, startTime, DateTime.UtcNow, limit: limit); var data = new List(); await foreach (var result in ExchangeHelpers.ExecutePages(_restClient.GetKlinesAsync, request).ConfigureAwait(false)) { diff --git a/README.md b/README.md index fc67e45..4e1656a 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,9 @@ Make a one time donation in a crypto currency of your choice. If you prefer to d Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf). ## Release notes +* Version 10.3.1 - 27 Jan 2026 + * Fixed potential collection modified exception upon logging message not handled in websocket message handling + * Version 10.3.0 - 22 Jan 2026 * Added PlatformInfo class for specifying platform metadata * Added better handling for enabling AutoTimestamp in client options when not implemented in the API