mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-08-11 16:32:57 +00:00
Feature/9.0.0 (#236)
* Added support for Native AOT compilation * Updated all IEnumerable response types to array response types * Added Pass support for ApiCredentials, removing the need for most implementations to add their own ApiCredentials type * Added KeepAliveTimeout setting setting ping frame timeouts for SocketApiClient * Added IBookTickerRestClient Shared interface for requesting book tickers * Added ISpotTriggerOrderRestClient Shared interface for managing spot trigger orders * Added ISpotOrderClientIdClient Shared interface for managing spot orders by client order id * Added IFuturesTriggerOrderRestClient Shared interface for managing futures trigger orders * Added IFuturesOrderClientIdClient Shared interface for managing futures orders by client order id * Added IFuturesTpSlRestClient Shared interface for setting TP/SL on open futures positions * Added GenerateClientOrderId to ISpotOrderRestClient and IFuturesOrderRestClient interface * Added OptionalExchangeParameters and Supported properties to EndpointOptions * Refactor Shared interfaces quantity parameters and properties to use SharedQuantity * Added SharedSymbol property to Shared interface models returning a symbol * Added TriggerPrice, IsTriggerOrder, TakeProfitPrice, StopLossPrice and IsCloseOrder to SharedFuturesOrder response model * Added MaxShortLeverage and MaxLongLeverage to SharedFuturesSymbol response model * Added StopLossPrice and TakeProfitPrice to SharedPosition response model * Added TriggerPrice and IsTriggerOrder to SharedSpotOrder response model * Added QuoteVolume property to SharedSpotTicker response model * Added AssetAlias configuration models * Added static ExchangeSymbolCache for tracking symbol information from exchanges * Added static CallResult.SuccessResult to be used instead of constructing success CallResult instance * Added static ApplyRules, RandomHexString and RandomLong helper methods to ExchangeHelpers class * Added AsErrorWithData To CallResult * Added OriginalData property to CallResult * Added support for adjusting the rate limit key per call, allowing for ratelimiting depending on request parameters * Added implementation for integration testing ISymbolOrderBook instances * Added implementation for integration testing socket subscriptions * Added implementation for testing socket queries * Updated request cancellation logging to Debug level * Updated logging SourceContext to include the client type * Updated some logging logic, errors no longer contain any data, exception are not logged as string but instead forwarded to structured logging * Fixed warning for Enum parsing throwing exception and output warnings for each object in a response to only once to prevent slowing down execution * Fixed memory leak in AsyncAutoRestEvent * Fixed logging for ping frame timeout * Fixed warning getting logged when user stops SymbolOrderBook instance * Fixed socket client `UnsubscribeAll` not unsubscribing dedicated connections * Fixed memory leak in Rest client cache * Fixed integers bigger than int16 not getting correctly parsed to enums * Fixed issue where the default options were overridden when using SetApiCredentials * Removed Newtonsoft.Json dependency * Removed legacy Rest client code * Removed legacy ISpotClient and IFuturesClient support
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.Objects
|
||||
{
|
||||
/// <summary>
|
||||
/// An alias used by the exchange for an asset commonly known by another name
|
||||
/// </summary>
|
||||
public class AssetAlias
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the asset on the exchange
|
||||
/// </summary>
|
||||
public string ExchangeAssetName { get; set; }
|
||||
/// <summary>
|
||||
/// The name of the asset as it's commonly known
|
||||
/// </summary>
|
||||
public string CommonAssetName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public AssetAlias(string exchangeName, string commonName)
|
||||
{
|
||||
ExchangeAssetName = exchangeName;
|
||||
CommonAssetName = commonName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.Objects
|
||||
{
|
||||
/// <summary>
|
||||
/// Exchange configuration for asset aliases
|
||||
/// </summary>
|
||||
public class AssetAliasConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Defined aliases
|
||||
/// </summary>
|
||||
public AssetAlias[] Aliases { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Auto convert asset names when using the Shared interfaces. Defaults to true
|
||||
/// </summary>
|
||||
public bool AutoConvertEnabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Map the common name to an exchange name for an asset. If there is no alias the input name is returned
|
||||
/// </summary>
|
||||
public string CommonToExchangeName(string commonName) => !AutoConvertEnabled ? commonName : Aliases.SingleOrDefault(x => x.CommonAssetName == commonName)?.ExchangeAssetName ?? commonName;
|
||||
|
||||
/// <summary>
|
||||
/// Map the exchange name to a common name for an asset. If there is no alias the input name is returned
|
||||
/// </summary>
|
||||
public string ExchangeToCommonName(string exchangeName) => !AutoConvertEnabled ? exchangeName : Aliases.SingleOrDefault(x => x.ExchangeAssetName == exchangeName)?.CommonAssetName ?? exchangeName;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,11 @@ namespace CryptoExchange.Net.Objects
|
||||
/// </summary>
|
||||
public class CallResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Static success result
|
||||
/// </summary>
|
||||
public static CallResult SuccessResult { get; } = new CallResult(null);
|
||||
|
||||
/// <summary>
|
||||
/// An error if the call didn't succeed, will always be filled if Success = false
|
||||
/// </summary>
|
||||
@@ -149,7 +154,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <returns></returns>
|
||||
public CallResult AsDataless()
|
||||
{
|
||||
return new CallResult(null);
|
||||
return SuccessResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -161,6 +166,18 @@ namespace CryptoExchange.Net.Objects
|
||||
return new CallResult(error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy the CallResult to a new data type
|
||||
/// </summary>
|
||||
/// <typeparam name="K">The new type</typeparam>
|
||||
/// <param name="data">The data</param>
|
||||
/// <param name="error">The error returned</param>
|
||||
/// <returns></returns>
|
||||
public CallResult<K> AsErrorWithData<K>(Error error, K data)
|
||||
{
|
||||
return new CallResult<K>(data, OriginalData, error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy the WebCallResult to a new data type
|
||||
/// </summary>
|
||||
@@ -192,7 +209,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// The headers sent with the request
|
||||
/// </summary>
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<string>>>? RequestHeaders { get; set; }
|
||||
public KeyValuePair<string, string[]>[]? RequestHeaders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The request id
|
||||
@@ -209,6 +226,11 @@ namespace CryptoExchange.Net.Objects
|
||||
/// </summary>
|
||||
public string? RequestBody { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The original data returned by the call, only available when `OutputOriginalData` is set to `true` in the client options
|
||||
/// </summary>
|
||||
public string? OriginalData { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The status code of the response. Note that a OK status does not always indicate success, check the Success parameter for this.
|
||||
/// </summary>
|
||||
@@ -217,7 +239,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// The response headers
|
||||
/// </summary>
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<string>>>? ResponseHeaders { get; set; }
|
||||
public KeyValuePair<string, string[]>[]? ResponseHeaders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time between sending the request and receiving the response
|
||||
@@ -227,30 +249,23 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="responseHeaders"></param>
|
||||
/// <param name="responseTime"></param>
|
||||
/// <param name="requestId"></param>
|
||||
/// <param name="requestUrl"></param>
|
||||
/// <param name="requestBody"></param>
|
||||
/// <param name="requestMethod"></param>
|
||||
/// <param name="requestHeaders"></param>
|
||||
/// <param name="error"></param>
|
||||
public WebCallResult(
|
||||
HttpStatusCode? code,
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<string>>>? responseHeaders,
|
||||
KeyValuePair<string, string[]>[]? responseHeaders,
|
||||
TimeSpan? responseTime,
|
||||
string? originalData,
|
||||
int? requestId,
|
||||
string? requestUrl,
|
||||
string? requestBody,
|
||||
HttpMethod? requestMethod,
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<string>>>? requestHeaders,
|
||||
KeyValuePair<string, string[]>[]? requestHeaders,
|
||||
Error? error) : base(error)
|
||||
{
|
||||
ResponseStatusCode = code;
|
||||
ResponseHeaders = responseHeaders;
|
||||
ResponseTime = responseTime;
|
||||
RequestId = requestId;
|
||||
OriginalData = originalData;
|
||||
|
||||
RequestUrl = requestUrl;
|
||||
RequestBody = requestBody;
|
||||
@@ -271,7 +286,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <returns></returns>
|
||||
public WebCallResult AsError(Error error)
|
||||
{
|
||||
return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, error);
|
||||
return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -343,7 +358,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// The headers sent with the request
|
||||
/// </summary>
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<string>>>? RequestHeaders { get; set; }
|
||||
public KeyValuePair<string, string[]>[]? RequestHeaders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The request id
|
||||
@@ -373,7 +388,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// The response headers
|
||||
/// </summary>
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<string>>>? ResponseHeaders { get; set; }
|
||||
public KeyValuePair<string, string[]>[]? ResponseHeaders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time between sending the request and receiving the response
|
||||
@@ -403,7 +418,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <param name="error"></param>
|
||||
public WebCallResult(
|
||||
HttpStatusCode? code,
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<string>>>? responseHeaders,
|
||||
KeyValuePair<string, string[]>[]? responseHeaders,
|
||||
TimeSpan? responseTime,
|
||||
long? responseLength,
|
||||
string? originalData,
|
||||
@@ -411,7 +426,7 @@ namespace CryptoExchange.Net.Objects
|
||||
string? requestUrl,
|
||||
string? requestBody,
|
||||
HttpMethod? requestMethod,
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<string>>>? requestHeaders,
|
||||
KeyValuePair<string, string[]>[]? requestHeaders,
|
||||
ResultDataSource dataSource,
|
||||
[AllowNull] T data,
|
||||
Error? error) : base(data, originalData, error)
|
||||
@@ -435,7 +450,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <returns></returns>
|
||||
public new WebCallResult AsDataless()
|
||||
{
|
||||
return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, Error);
|
||||
return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, Error);
|
||||
}
|
||||
/// <summary>
|
||||
/// Copy as a dataless result
|
||||
@@ -443,7 +458,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <returns></returns>
|
||||
public new WebCallResult AsDatalessError(Error error)
|
||||
{
|
||||
return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, error);
|
||||
return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -474,6 +489,18 @@ namespace CryptoExchange.Net.Objects
|
||||
return new WebCallResult<K>(ResponseStatusCode, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, default, error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy the WebCallResult to a new data type
|
||||
/// </summary>
|
||||
/// <typeparam name="K">The new type</typeparam>
|
||||
/// <param name="data">The data</param>
|
||||
/// <param name="error">The error returned</param>
|
||||
/// <returns></returns>
|
||||
public new WebCallResult<K> AsErrorWithData<K>(Error error, K data)
|
||||
{
|
||||
return new WebCallResult<K>(ResponseStatusCode, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, data, error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy the WebCallResult to an ExchangeWebResult of a new data type
|
||||
/// </summary>
|
||||
@@ -553,7 +580,7 @@ namespace CryptoExchange.Net.Objects
|
||||
if (ResponseLength != null)
|
||||
sb.Append($", {ResponseLength} bytes");
|
||||
if (ResponseTime != null)
|
||||
sb.Append($" received in {Math.Round(ResponseTime?.TotalMilliseconds ?? 0)}ms");
|
||||
sb.Append($", received in {Math.Round(ResponseTime?.TotalMilliseconds ?? 0)}ms");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
@@ -18,21 +18,18 @@ namespace CryptoExchange.Net.Objects
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The data which caused the error
|
||||
/// Underlying exception
|
||||
/// </summary>
|
||||
public object? Data { get; set; }
|
||||
public Exception? Exception { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected Error(int? code, string message, object? data)
|
||||
protected Error (int? code, string message, Exception? exception)
|
||||
{
|
||||
Code = code;
|
||||
Message = message;
|
||||
Data = data;
|
||||
Exception = exception;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -41,7 +38,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Code != null ? $"[{GetType().Name}] {Code}: {Message} {Data}" : $"[{GetType().Name}] {Message} {Data}";
|
||||
return Code != null ? $"[{GetType().Name}] {Code}: {Message}" : $"[{GetType().Name}] {Message}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,10 +55,12 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected CantConnectError(int? code, string message, object? data) : base(code, message, data) { }
|
||||
public CantConnectError(Exception? exception) : base(null, "Can't connect to the server", exception) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
protected CantConnectError(int? code, string message, Exception? exception) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -77,10 +76,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected NoApiCredentialsError(int? code, string message, object? data) : base(code, message, data) { }
|
||||
protected NoApiCredentialsError(int? code, string message, Exception? exception) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -91,25 +87,12 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public ServerError(string message, object? data = null) : base(null, message, data) { }
|
||||
public ServerError(string message) : base(null, message, null) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public ServerError(int code, string message, object? data = null) : base(code, message, data) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected ServerError(int? code, string message, object? data) : base(code, message, data) { }
|
||||
public ServerError(int? code, string message, Exception? exception = null) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -120,25 +103,12 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public WebError(string message, object? data = null) : base(null, message, data) { }
|
||||
public WebError(string message, Exception? exception = null) : base(null, message, exception) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public WebError(int code, string message, object? data = null) : base(code, message, data) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected WebError(int? code, string message, object? data): base(code, message, data) { }
|
||||
public WebError(int code, string message, Exception? exception = null) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -149,17 +119,12 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="message">The error message</param>
|
||||
/// <param name="data">The data which caused the error</param>
|
||||
public DeserializeError(string message, object? data) : base(null, message, data) { }
|
||||
public DeserializeError(string message, Exception? exception = null) : base(null, message, exception) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected DeserializeError(int? code, string message, object? data): base(code, message, data) { }
|
||||
protected DeserializeError(int? code, string message, Exception? exception = null) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -170,17 +135,12 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="message">Error message</param>
|
||||
/// <param name="data">Error data</param>
|
||||
public UnknownError(string message, object? data = null) : base(null, message, data) { }
|
||||
public UnknownError(string message, Exception? exception = null) : base(null, message, exception) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected UnknownError(int? code, string message, object? data): base(code, message, data) { }
|
||||
protected UnknownError(int? code, string message, Exception? exception = null): base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -191,16 +151,12 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
public ArgumentError(string message) : base(null, "Invalid parameter: " + message, null) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected ArgumentError(int? code, string message, object? data): base(code, message, data) { }
|
||||
protected ArgumentError(int? code, string message, Exception? exception = null) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -216,10 +172,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected BaseRateLimitError(int? code, string message, object? data) : base(code, message, data) { }
|
||||
protected BaseRateLimitError(int? code, string message, Exception? exception) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -236,10 +189,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected ClientRateLimitError(int? code, string message, object? data): base(code, message, data) { }
|
||||
protected ClientRateLimitError(int? code, string message, Exception? exception = null) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -250,16 +200,12 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
public ServerRateLimitError(string message) : base(null, "Server rate limit exceeded: " + message, null) { }
|
||||
public ServerRateLimitError(string? message = null, Exception? exception = null) : base(null, "Server rate limit exceeded" + (message?.Length > 0 ? " : " + message : null), exception) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected ServerRateLimitError(int? code, string message, object? data) : base(code, message, data) { }
|
||||
protected ServerRateLimitError(int? code, string message, Exception? exception = null) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -270,15 +216,12 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancellationRequestedError() : base(null, "Cancellation requested", null) { }
|
||||
public CancellationRequestedError(Exception? exception = null) : base(null, "Cancellation requested", exception) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public CancellationRequestedError(int? code, string message, object? data): base(code, message, data) { }
|
||||
public CancellationRequestedError(int? code, string message, Exception? exception = null) : base(code, message, exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -289,15 +232,11 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
public InvalidOperationError(string message) : base(null, message, null) { }
|
||||
public InvalidOperationError(string message, Exception? exception = null) : base(null, message, exception) { }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
protected InvalidOperationError(int? code, string message, object? data): base(code, message, data) { }
|
||||
protected InvalidOperationError(int? code, string message, Exception? exception = null) : base(code, message, exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace CryptoExchange.Net.Objects.Options
|
||||
/// </summary>
|
||||
public T Set<T>(T targetOptions) where T: LibraryOptions<TRestOptions, TSocketOptions, TApiCredentials, TEnvironment>
|
||||
{
|
||||
targetOptions.ApiCredentials = ApiCredentials;
|
||||
targetOptions.ApiCredentials = (TApiCredentials?)ApiCredentials?.Copy();
|
||||
targetOptions.Environment = Environment;
|
||||
targetOptions.SocketClientLifeTime = SocketClientLifeTime;
|
||||
targetOptions.Rest = Rest.Set(targetOptions.Rest);
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace CryptoExchange.Net.Objects.Options
|
||||
{
|
||||
/// <summary>
|
||||
/// Trade environment. Contains info about URL's to use to connect to the API. To swap environment select another environment for
|
||||
/// the exhange's environment list or create a custom environment using either `[Exchange]Environment.CreateCustom()` or `[Exchange]Environment.[Environment]`, for example `KucoinEnvironment.TestNet` or `BinanceEnvironment.Live`
|
||||
/// the exchange's environment list or create a custom environment using either `[Exchange]Environment.CreateCustom()` or `[Exchange]Environment.[Environment]`, for example `KucoinEnvironment.TestNet` or `BinanceEnvironment.Live`
|
||||
/// </summary>
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public TEnvironment Environment { get; set; }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using CryptoExchange.Net.Converters.SystemTextJson;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
@@ -173,11 +174,14 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// Add an enum value as the string value as mapped using the <see cref="MapAttribute" />
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
#if NET5_0_OR_GREATER
|
||||
public void AddEnum<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields)] T>(string key, T value)
|
||||
#else
|
||||
public void AddEnum<T>(string key, T value)
|
||||
#endif
|
||||
where T : struct, Enum
|
||||
{
|
||||
Add(key, EnumConverter.GetString(value)!);
|
||||
Add(key, EnumConverter<T>.GetString(value)!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -185,9 +189,14 @@ namespace CryptoExchange.Net.Objects
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
#if NET5_0_OR_GREATER
|
||||
public void AddEnumAsInt<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields)] T>(string key, T value)
|
||||
#else
|
||||
public void AddEnumAsInt<T>(string key, T value)
|
||||
#endif
|
||||
where T : struct, Enum
|
||||
{
|
||||
var stringVal = EnumConverter.GetString(value)!;
|
||||
var stringVal = EnumConverter<T>.GetString(value)!;
|
||||
Add(key, int.Parse(stringVal)!);
|
||||
}
|
||||
|
||||
@@ -196,22 +205,30 @@ namespace CryptoExchange.Net.Objects
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
#if NET5_0_OR_GREATER
|
||||
public void AddOptionalEnum<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields)] T>(string key, T? value)
|
||||
#else
|
||||
public void AddOptionalEnum<T>(string key, T? value)
|
||||
#endif
|
||||
where T : struct, Enum
|
||||
{
|
||||
if (value != null)
|
||||
Add(key, EnumConverter.GetString(value));
|
||||
Add(key, EnumConverter<T>.GetString(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an enum value as the string value as mapped using the <see cref="MapAttribute" />. Not added if value is null
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
#if NET5_0_OR_GREATER
|
||||
public void AddOptionalEnumAsInt<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields)] T>(string key, T? value)
|
||||
#else
|
||||
public void AddOptionalEnumAsInt<T>(string key, T? value)
|
||||
#endif
|
||||
where T : struct, Enum
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
var stringVal = EnumConverter.GetString(value);
|
||||
var stringVal = EnumConverter<T>.GetString(value);
|
||||
Add(key, int.Parse(stringVal));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,11 @@ namespace CryptoExchange.Net.Objects.Sockets
|
||||
/// </summary>
|
||||
public TimeSpan? KeepAliveInterval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timeout for keep alive response messages
|
||||
/// </summary>
|
||||
public TimeSpan? KeepAliveTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The rate limiter for the socket connection
|
||||
/// </summary>
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace CryptoExchange.Net.Objects
|
||||
if (!IsEnabled(logLevel))
|
||||
return;
|
||||
|
||||
var logMessage = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff} | {logLevel} | {(_categoryName == null ? "" : $"{_categoryName} | ")}{formatter(state, exception)}";
|
||||
var logMessage = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff} | {logLevel} | {(_categoryName == null ? "" : $"{_categoryName} | ")}{formatter(state, exception)}{(exception == null ? string.Empty : (", " + exception.ToLogString()))}";
|
||||
Trace.WriteLine(logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user