1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-10-17 08:30:53 +00:00

Compare commits

...

4 Commits

7 changed files with 228 additions and 7 deletions
+3 -3
View File
@@ -6,9 +6,9 @@
<PackageId>CryptoExchange.Net</PackageId>
<Authors>JKorf</Authors>
<Description>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.</Description>
<PackageVersion>13.0.0</PackageVersion>
<AssemblyVersion>13.0.0</AssemblyVersion>
<FileVersion>13.0.0</FileVersion>
<PackageVersion>13.1.0</PackageVersion>
<AssemblyVersion>13.1.0</AssemblyVersion>
<FileVersion>13.1.0</FileVersion>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageTags>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</PackageTags>
<RepositoryType>git</RepositoryType>
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CryptoExchange.Net.SharedApis
{
@@ -104,6 +105,11 @@ namespace CryptoExchange.Net.SharedApis
SharedCapabilityResolution<T>? GetCapability<T>(SharedCapabilityReference<T> capability, TradingMode tradingMode)
where T : ISharedApiCapability;
/// <summary>
/// Unsubscribes all subscriptions created by the underlying socket API
/// client and closes its subscription connections.
/// </summary>
Task UnsubscribeAllAsync();
}
/// <summary>
@@ -209,6 +215,15 @@ namespace CryptoExchange.Net.SharedApis
return GetCapabilities<T>(tradingMode);
}
/// <inheritdoc />
public Task UnsubscribeAllAsync()
{
return Task.WhenAll(
_sharedApis
.OfType<ISharedSubscription>()
.Select(x => x.UnsubscribeAllAsync()));
}
object? ISharedApiClientResolver.GetCapability(Type capabilityType)
{
return _sharedApis
@@ -1,10 +1,12 @@
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Objects.Sockets;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace CryptoExchange.Net.SharedApis
{
@@ -624,5 +626,198 @@ namespace CryptoExchange.Net.SharedApis
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to trade updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeTradesSocket>> capabilities,
SubscribeTradeRequest request,
Action<DataEvent<SharedTrade[]>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToTradeUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to balance updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeBalancesSocket>> capabilities,
SubscribeBalancesRequest request,
Action<DataEvent<SharedBalance[]>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToBalanceUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to index price updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeIndexPriceSocket>> capabilities,
SubscribeIndexPriceRequest request,
Action<DataEvent<SharedIndexPrice>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToIndexPriceUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to kline updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeKlinesSocket>> capabilities,
SubscribeKlineRequest request,
Action<DataEvent<SharedKline>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToKlineUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to mark price updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeMarkPriceSocket>> capabilities,
SubscribeMarkPriceRequest request,
Action<DataEvent<SharedMarkPrice>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToMarkPriceUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to order book updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeOrderBookSocket>> capabilities,
SubscribeOrderBookRequest request,
Action<DataEvent<SharedOrderBook>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToOrderBookUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to incremental order book updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeIncrementalOrderBookSocket>> capabilities,
SubscribeOrderBookRequest request,
Action<DataEvent<SharedOrderBook>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToOrderBookUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to futures order updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeFuturesOrdersSocket>> capabilities,
SubscribeFuturesOrderRequest request,
Action<DataEvent<SharedFuturesOrderUpdate[]>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToFuturesOrderUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to spot order updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeSpotOrdersSocket>> capabilities,
SubscribeSpotOrderRequest request,
Action<DataEvent<SharedSpotOrderUpdate[]>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToSpotOrderUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to position updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribePositionsSocket>> capabilities,
SubscribePositionRequest request,
Action<DataEvent<SharedPosition[]>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToPositionUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to ticker updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeTickerSocket>> capabilities,
SubscribeTickerRequest request,
Action<DataEvent<SharedTicker>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToTickerUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to all ticker updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeAllTickersSocket>> capabilities,
SubscribeAllTickersRequest request,
Action<DataEvent<SharedTicker[]>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToAllTickersUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Subscribe to user trade updates for all capabilities in parallel and return results as they arrive
/// </summary>
public static IAsyncEnumerable<WebSocketResult<UpdateSubscription>> SubscribeAllAsync(
this IEnumerable<SharedCapabilityResolution<ISubscribeUserTradesSocket>> capabilities,
SubscribeUserTradeRequest request,
Action<DataEvent<SharedUserTrade[]>> onData,
CancellationToken ct = default)
{
return capabilities
.Select(x => x.Capability.SubscribeToUserTradeUpdatesAsync(request, onData, ct))
.ParallelEnumerateAsync();
}
/// <summary>
/// Wait for all results from an IAsyncEnumerable and return them as an array
/// </summary>
public static async Task<T[]> WaitAllAsync<T>(this IAsyncEnumerable<T> enumerable)
{
var result = new List<T>();
await foreach (var itemResult in enumerable.ConfigureAwait(false))
result.Add(itemResult);
return result.ToArray();
}
}
}
@@ -1,13 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Shared WebSocket API subscription capabitlity
/// Shared WebSocket API subscription capability
/// </summary>
public interface ISharedSubscription : ISharedSocket
{
/// <summary>
/// Unsubscribes all subscriptions created by the underlying socket API
/// client and closes its subscription connections.
/// </summary>
Task UnsubscribeAllAsync();
}
}
+5
View File
@@ -127,6 +127,11 @@ Various:
* PlatformInfo now required support environment names in the constructor
## Release notes
* Version 13.1.0 - 28 Sep 2026
* Added UnsubscribeAllAsync method to Shared APIs ISharedSubscription and ISharedApiClientBase
* Added WaitAllAsync extension method for waiting on an IAsyncEnumerable to finish
* Added SubscribeAllAsync extension methods for Shared API resolved capabilities
* Version 13.0.0 - 23 Sep 2026
* Shared APIs
* Added Shared API V2 with fine-grained capability interfaces for individual REST requests, WebSocket requests and subscriptions
+2 -2
View File
@@ -1,8 +1,8 @@
# CryptoExchange.Net — full AI context
Library: CryptoExchange.Net
Library version: 13.0.0
CryptoExchange.Net package version: 13.0.0
Library version: 13.1.0
CryptoExchange.Net package version: 13.1.0
Language: C#/.NET
Targets: netstandard2.0, netstandard2.1, net8.0, net9.0, net10.0
+1 -1
View File
@@ -2,7 +2,7 @@
> Base C#/.NET library used by 28+ cryptocurrency exchange clients. It standardizes REST, WebSocket, authentication, rate limiting, results, and exchange-agnostic Shared APIs.
CryptoExchange.Net is not an exchange client by itself. Install exchange-specific packages such as Binance.Net, Bybit.Net, JK.OKX.Net, Kraken.Net, or Coinbase.Net, or install `CryptoClients.Net` for the bundle. Current release: 13.0.0. Targets netstandard2.0, netstandard2.1, net8.0, net9.0, and net10.0; Native AOT is supported.
CryptoExchange.Net is not an exchange client by itself. Install exchange-specific packages such as Binance.Net, Bybit.Net, JK.OKX.Net, Kraken.Net, or Coinbase.Net, or install `CryptoClients.Net` for the bundle. Current release: 13.1.0. Targets netstandard2.0, netstandard2.1, net8.0, net9.0, and net10.0; Native AOT is supported.
## Shared API V2