diff --git a/README.md b/README.md index 81a2766..6466e58 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [](https://github.com/JKorf/CryptoExchange.Net/actions/workflows/dotnet.yml) [](https://www.nuget.org/packages/CryptoExchange.Net)  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. +Note that the CryptoExchange.Net package itself can not be used directly for accessing API's. Either install a client library from the list below or use [CryptoClients.Net](https://github.com/jkorf/CryptoClients.Net) which includes access to all exchange API's. For more information on what CryptoExchange.Net and it's client libraries offers see the [Documentation](https://jkorf.github.io/CryptoExchange.Net/). @@ -24,6 +25,8 @@ The following API's are directly supported. Note that there are 3rd party implem |Mexc|[JKorf/Mexc.Net](https://github.com/JKorf/Mexc.Net)|[](https://www.nuget.org/packages/JK.Mexc.Net)| |OKX|[JKorf/OKX.Net](https://github.com/JKorf/OKX.Net)|[](https://www.nuget.org/packages/JK.OKX.Net)| +Any of these can be installed independently or install [CryptoClients.Net](https://github.com/jkorf/CryptoClients.Net) which includes all exchange API's. + ## Discord [](https://discord.gg/MSpeEtSY8t) A Discord server is available [here](https://discord.gg/MSpeEtSY8t). Feel free to join for discussion and/or questions around the CryptoExchange.Net and implementation libraries. diff --git a/docs/index.html b/docs/index.html index 190d9f3..e21cd43 100644 --- a/docs/index.html +++ b/docs/index.html @@ -125,7 +125,7 @@
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.
-The following API's are directly supported. Note that there are 3rd party implementations going around, but only these are created and supported by me
OKX | JKorf/OKX.Net |
Alternatively, use CryptoClients.Net which combines these packages and allows easy access to all exchange API's.
+
The library is targeting both Add the package via dotnet, or add it via the package manager. Any number of libraries can be installed, just make sure you're always using the latest at that moment. Add the package via dotnet, or add it via the package manager. Any number of libraries can be installed, just make sure you're always using the latest at that moment. Instead of installing all libraries seperately the CryptoClients.Net library can be installed to include all the exchange package in one go.
- All client libraries support and encourage usage via the Dotnet dependency injection system. Add all necesary services by calling the CryptoExchange.Net exposes some common clients. These clients aim to make using the different API's easier. CryptoClients.Net exposes some common clients. These clients aim to make using the different API's easier. (I)CryptoRestClient (I)ExchangeRestClient
For example, having the Binance, Bybit and Kucoin packages installed allows you to use it like this:
- (I)CryptoSocketClient (I)ExchangeSocketClient Having the Bitget, Kraken and OKX packages installed would allow you to use it like this:
- For example accessing the Bitget, Kraken and OKX API's could be done like this:
+ ISpotClient Client side rate limiting is currently implemented for the following libraries: To be notified of when a rate limit is hit the static .NET Standard 2.0
and .NET Standard 2.1
for optimal compatibility
@@ -202,11 +204,14 @@
Installation
-
+ dotnet add package CryptoClients.Net
+
dotnet add package Binance.Net
Dependency Injection
Add[Library]();
extension method on the service collection. Options for the clients can be passed as parameters.
+ All client libraries support and encourage usage via the Dotnet dependency injection system. Add all necesary services per exchange by calling the Add[Library]();
extension method on the service collection, or use AddCryptoClients()
to add all exchange services in a single class. Options for the clients can be passed as parameters.
+ builder.Services.AddCryptoClients();
builder.Services.AddBinance();
+
+
+ Interface Description
+
+
+ IExchangeRestClient
The client for accessing all exchanges REST API's
+
+
+
+ IExchangeSocketClient
The client for accessing all exchanges Websocket API's
+
+
+
+ IExchangeOrderBookFactory
A factory class for accessing all exchanges SymbolOrderBook (locally synced order books) factory methods
+
+
+
+ I[Library]RestClient
All exchange specific REST clients, for example
+ IBinanceRestClient
and IMexcRestClient
+
+
+ I[Library]SocketClient
All exchange specific Websocket clients, for example
+ IBinanceSocketClient
and IMexcSocketClient
+
+
+ I[Library]OrderBookFactory
All exchange specific order book factories. The factory can be used for creating SymbolOrderBook (locally synced order books) instances for the exchange
+
+
+
+ ISpotClient
An implementation of the ISpotClient interface for Binance. The ISpotClient offers basic Spot API functionality in a combined interface
+
Interface Description
@@ -770,7 +822,10 @@
+ var client = new ExchangeRestClient();
+var tickersResult = await client.Binance.SpotApi.ExchangeData.GetTickersAsync();
+if (!tickersResult.Success)
+{
+ // Handle error, tickersResult.Error contains more information
+}
+else
+{
+ // Handle data, tickersResult.Data will contain the actual data
+}
var client = new BinanceRestClient();
var tickersResult = await client.SpotApi.ExchangeData.GetTickersAsync();
if (!tickersResult.Success)
@@ -1024,7 +1091,10 @@ else
+ var client = new ExchangeSocketClient();
+var subscribeResult = await client.Binance.SpotApi.ExchangeData.SubscribeToAllTickerUpdatesAsync(update => {
+ // Handle the data update, update.Data will contain the actual data
+});
+if (!subscribeResult.Success)
+{
+ // Handle error, subscribeResult.Error contains more information on why the subscription failed
+}
+// Subscribing was successfull, the data will now be streamed into the data handler
============================ -->
var client = new BinanceSocketClient();
var subscribeResult = await client.SpotApi.ExchangeData.SubscribeToAllTickerUpdatesAsync(update => {
@@ -1294,27 +1375,27 @@ await client.UnsubscribeAllAsync();
Common Clients
-
- The ICryptoRestClient
(or CryptoRestClient
when used directly) can be used to easily access REST clients for different API's through the different packages that have been installed. Each package adds it extension method to the interface, which allows the user to access the clients via it.
+
+ The ExchangeRestClient
(or ExchangeRestClient
when used directly) can be used to easily access REST clients for different API's.
+ var cryptoRestClient = new CryptoRestClient(); // Either construct it or inject the ICryptoRestClient into your service
-var binanceTicker = await cryptoRestClient.Binance().SpotApi.ExchangeData.GetTickersAsync();
-var bybitTicker = await cryptoRestClient.Bybit().V5Api.ExchangeData.GetTickers();
-var kucoinTicker = await cryptoRestClient.Kucoin().SpotApi.ExchangeData.GetTickers();
- var exchangeRestClient = new ExchangeRestClient(); // Either construct it or inject the IExchangeRestClient into your service
+var binanceTicker = await exchangeRestClient.Binance.SpotApi.ExchangeData.GetTickersAsync();
+var bybitTicker = await exchangeRestClient.Bybit.V5Api.ExchangeData.GetTickers();
+var kucoinTicker = await exchangeRestClient.Kucoin.SpotApi.ExchangeData.GetTickers();
- Similarly as the (I)CryptoRestClient this client allows you to access the different Websocket clients through a single access point.
+
+ Similarly as the (I)ExchangeRestClient this client allows you to access the different Websocket clients through a single access point.
+ var cryptoRestClient = new CryptoSocketClient(); // Either construct it or inject the ICryptoRestClient into your service
-var bitgetSub = await cryptoRestClient.Bitget().SpotApi.SubscribeToTickerUpdatesAsync("ETHUSDT", data => {});
-var krakenSub = await cryptoRestClient.Kraken().SpotApi.SubscribeToTickerUpdatesAsync("ETH/USD", data => {});
-var okxSub = await cryptoRestClient.OKX().UnifiedApi.ExchangeData.SubscribeToTickerUpdatesAsync("ETH-USDT", data => {});
var exchangeSocketClient = new ExchangeSocketClient(); // Either construct it or inject the ExchangeSocketClient into your service
+var bitgetSub = await exchangeSocketClient.Bitget.SpotApi.SubscribeToTickerUpdatesAsync("ETHUSDT", data => {});
+var krakenSub = await exchangeSocketClient.Kraken.SpotApi.SubscribeToTickerUpdatesAsync("ETH/USD", data => {});
+var okxSub = await exchangeSocketClient.OKX.UnifiedApi.ExchangeData.SubscribeToTickerUpdatesAsync("ETH-USDT", data => {});
@@ -1383,7 +1464,10 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
+ builder.Services.AddCryptoClients(globalOptions =>{
+ globalOptions.RequestTimeout = TimeSpan.FromSeconds(30);
+ });
builder.Services.AddBinance(
restOptions => {
restOptions.RequestTimeout = TimeSpan.FromSeconds(30);
@@ -1533,7 +1622,10 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
+ var exchangeRestClient = new ExchangeRestClient(opts =>
+{
+ opts.RequestTimeout = TimeSpan.FromSeconds(30);
+});
var binanceRestClient = new BinanceRestClient(opts =>
{
opts.RequestTimeout = TimeSpan.FromSeconds(30);
@@ -1796,7 +1894,7 @@ var client = new OKXRestClient();
ApiCredentials
- The credentials to use for private endpoints and streams. See Authorization for more info
+ The credentials to use for private endpoints and streams. See Authorization for more info. For CryptoClients this option allows the setting of ApiCredentials for all exchanges.
null
@@ -2282,6 +2380,9 @@ var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options
+ services.AddCryptoClients(x =>
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+});
Exchanges.RateLimiter
exposes an event which triggers when a rate limit is reached
+ BinanceExchange.RateLimiter.RateLimitTriggered += (rateLimitEvent) => Console.WriteLine("Limit triggered: " + rateLimitEvent);
+
+// Output: Limit triggered: RateLimitEvent { ApiLimit = Spot Socket, LimitDescription = Limit of 6000 per 00:01:00, RequestDefinition = GET 1, Host = wss://ws-api.binance.com, Current = 5752, RequestWeight = 250, Limit = 6000, TimePeriod = 00:01:00, DelayTime = 00:00:38.7784145, Behaviour = Wait }
+
services.AddBinance(x =>
x.RatelimiterEnabled = true;
@@ -2368,7 +2480,7 @@ var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options
+ // Name of the exchange can be whatever exchange library you have installed, for example Binance, Bybit, Kraken etc
-var spotClient = cryptoRestClient.SpotClient("[Name of the exchange]");
-await spotClient.GetSymbolsAsync();
// This example uses Binance, but can be any exchange support. For example Bybit, Kraken, Kucoin etc
+await exchangeRestClient.Binance.SpotApi.ExchangeData.GetExchangeInfoAsync();
@@ -2462,7 +2573,7 @@ await spotClient.GetSymbolsAsync();
await binanceClient.SpotApi.ExchangeData.GetExchangeInfoAsync();
+ // Name of the exchange can be whatever exchange library you have installed, for example Binance, Bybit, Kraken etc
-var spotClient = cryptoRestClient.SpotClient("[Name of the exchange]");
-await spotClient.GetTickerAsync(spotClient.GetSymbolName("BTC", "USDT"));
// This example uses Binance, but can be any exchange support. For example Bybit, Kraken, Kucoin etc
+await exchangeRestClient.Binance.SpotApi.ExchangeData.GetTickerAsync(spotClient.GetSymbolName("BTC", "USDT"));
@@ -2556,7 +2666,7 @@ await spotClient.GetTickerAsync(spotClient.GetSymbolName("BTC", "USDT"));
await binanceClient.SpotApi.ExchangeData.GetTickerAsync("BTCUSDT");
+ // Name of the exchange can be whatever exchange library you have installed, for example Binance, Bybit, Kraken etc
-var spotClient = cryptoRestClient.SpotClient("[Name of the exchange]");
-await spotClient.GetBalancesAsync();
// This example uses Binance, but can be any exchange support. For example Bybit, Kraken, Kucoin etc
+await exchangeRestClient.Binance.SpotApi.Account.GetBalancesAsync();
@@ -2654,7 +2763,7 @@ var result = await huobiClient.SpotApi.Account.GetBalancesAsync();
await binanceClient.SpotApi.Account.GetBalancesAsync();
+ // Name of the exchange can be whatever exchange library you have installed, for example Binance, Bybit, Kraken etc
-var spotClient = cryptoRestClient.SpotClient("[Name of the exchange]");
-await spotClient.PlaceOrderAsync(spotClient.GetSymbolName("BTC", "USDT"), CommonOrderSide.Buy, CommonOrderType.Limit, 0.1m, price: 50000);
// This example uses Binance, but can be any exchange support. For example Bybit, Kraken, Kucoin etc
+await exchangeRestClient.Binance.SpotApi.Trading.PlaceOrderAsync("BTCUSDT", OrderSide.Buy, SpotOrderType.Limit, 0.1m, price: 50000, timeInForce: TimeInForce.GoodTillCanceled);
@@ -2751,8 +2859,11 @@ var result = await huobiClient.SpotApi.Trading.PlaceOrderAsync(account.Id, "BTCU
await binanceClient.SpotApi.Trading.PlaceOrderAsync("BTCUSDT", OrderSide.Buy, SpotOrderType.Limit, 0.1m, price: 50000, timeInForce: TimeInForce.GoodTillCanceled);
+ // This example uses Binance, but can be any exchange support. For example Bybit, Kraken, Kucoin etc
+await exchangeSocketClient.Binance.SpotApi.ExchangeData.SubscribeToTickerUpdatesAsync("ETHUSDT", data => {
+ // Handle update
+});
@@ -2860,8 +2977,11 @@ var result = await huobiClient.SpotApi.Trading.PlaceOrderAsync(account.Id, "BTCU
await binanceSocketClient.SpotApi.ExchangeData.SubscribeToTickerUpdatesAsync("ETHUSDT", data => {
// Handle update
});
+ // This example uses Binance, but can be any exchange support. For example Bybit, Kraken, Kucoin etc
+
+// Retrieve the listen key
+var listenKey = await exchangeRestClient.Binance.SpotApi.Account.StartUserStreamAsync();
+
+// Subscribe using the key
+await exchangeSocketClient.Binance.SpotApi.Account.SubscribeToUserDataUpdatesAsync(listenKey.Data, data => {
+ // Handle update
+}, null, null, null);
+
+// The listen key will stay valid for 60 minutes, after this no updates will be send anymore
+// To extend the life time of the listen key it is recommended to call the KeepAliveUserStreamAsync method every 30 minutes
+_ = Task.Run(async () => {
+ while (true)
+ {
+ await Task.Delay(Timespan.FromMinutes(30));
+ await exchangeRestClient.Binance.SpotApi.Account.KeepAliveUserStreamAsync(listenKey.Data);
+ }
+});
// Retrieve the listen key
var listenKey = await binanceClient.SpotApi.Account.StartUserStreamAsync();
@@ -3018,17 +3159,17 @@ _ = Task.Run(async () => {
using CryptoExchange.Net.Interfaces;
+using CryptoClients.Net.Enums;
+using CryptoClients.Net.Interfaces;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
-builder.Services.AddBitfinex();
-builder.Services.AddBitget();
-builder.Services.AddKraken();
+builder.Services.AddCryptoClients();
var app = builder.Build();
-app.MapGet("Ticker/{exchange}/{baseAsset}/{quoteAsset}", async ([FromServices] ICryptoRestClient client, string exchange, string baseAsset, string quoteAsset) =>
+app.MapGet("Ticker/{exchange}/{baseAsset}/{quoteAsset}", async ([FromServices] IExchangeRestClient client, Exchange exchange, string baseAsset, string quoteAsset) =>
{
- var spotClient = client.SpotClient(exchange)!;
+ var spotClient = client.GetUnifiedSpotClient(exchange)!;
var result = await spotClient.GetTickerAsync(spotClient.GetSymbolName(baseAsset, quoteAsset));
return result.Data;
});