mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-08-31 12:42:00 +00:00
Merge branch 'master' into feature/code-analyzis
This commit is contained in:
commit
9ba29035b2
@ -6,9 +6,9 @@
|
||||
<PackageId>CryptoExchange.Net.Protobuf</PackageId>
|
||||
<Authors>JKorf</Authors>
|
||||
<Description>Protobuf support for CryptoExchange.Net</Description>
|
||||
<PackageVersion>9.5.0</PackageVersion>
|
||||
<AssemblyVersion>9.5.0</AssemblyVersion>
|
||||
<FileVersion>9.5.0</FileVersion>
|
||||
<PackageVersion>9.6.0</PackageVersion>
|
||||
<AssemblyVersion>9.6.0</AssemblyVersion>
|
||||
<FileVersion>9.6.0</FileVersion>
|
||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||
<PackageTags>CryptoExchange;CryptoExchange.Net</PackageTags>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
@ -41,7 +41,7 @@
|
||||
<DocumentationFile>CryptoExchange.Net.Protobuf.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CryptoExchange.Net" Version="9.5.0" />
|
||||
<PackageReference Include="CryptoExchange.Net" Version="9.6.0" />
|
||||
<PackageReference Include="protobuf-net" Version="3.2.56" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -5,6 +5,9 @@
|
||||
Protobuf support for CryptoExchange.Net.
|
||||
|
||||
## Release notes
|
||||
* Version 9.6.0 - 25 Aug 2025
|
||||
* Updated CryptoExchange.Net version to 9.6.0
|
||||
|
||||
* Version 9.5.0 - 19 Aug 2025
|
||||
* Updated CryptoExchange.Net version to 9.5.0
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations.Sockets
|
||||
return new CallResult(null);
|
||||
}
|
||||
|
||||
public override Query GetSubQuery(SocketConnection connection) => new TestQuery("sub", new object(), false, 1);
|
||||
public override Query GetUnsubQuery() => new TestQuery("unsub", new object(), false, 1);
|
||||
protected override Query GetSubQuery(SocketConnection connection) => new TestQuery("sub", new object(), false, 1);
|
||||
protected override Query GetUnsubQuery(SocketConnection connection) => new TestQuery("unsub", new object(), false, 1);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations.Sockets
|
||||
return new CallResult(null);
|
||||
}
|
||||
|
||||
public override Query GetSubQuery(SocketConnection connection) => new TestChannelQuery(_channel, "subscribe", false, 1);
|
||||
public override Query GetUnsubQuery() => new TestChannelQuery(_channel, "unsubscribe", false, 1);
|
||||
protected override Query GetSubQuery(SocketConnection connection) => new TestChannelQuery(_channel, "subscribe", false, 1);
|
||||
protected override Query GetUnsubQuery(SocketConnection connection) => new TestChannelQuery(_channel, "unsubscribe", false, 1);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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>9.5.0</PackageVersion>
|
||||
<AssemblyVersion>9.5.0</AssemblyVersion>
|
||||
<FileVersion>9.5.0</FileVersion>
|
||||
<PackageVersion>9.6.0</PackageVersion>
|
||||
<AssemblyVersion>9.6.0</AssemblyVersion>
|
||||
<FileVersion>9.6.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>
|
||||
|
@ -1,89 +1,95 @@
|
||||
using CryptoExchange.Net.RateLimiting.Interfaces;
|
||||
using CryptoExchange.Net.RateLimiting.Interfaces;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace CryptoExchange.Net.Objects;
|
||||
|
||||
/// <summary>
|
||||
/// The definition of a rest request
|
||||
/// </summary>
|
||||
public class RequestDefinition
|
||||
namespace CryptoExchange.Net.Objects
|
||||
{
|
||||
private string? _stringRep;
|
||||
|
||||
// Basics
|
||||
|
||||
/// <summary>
|
||||
/// Path of the request
|
||||
/// The definition of a rest request
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
/// <summary>
|
||||
/// Http method of the request
|
||||
/// </summary>
|
||||
public HttpMethod Method { get; set; }
|
||||
/// <summary>
|
||||
/// Is the request authenticated
|
||||
/// </summary>
|
||||
public bool Authenticated { get; set; }
|
||||
|
||||
// Formatting
|
||||
|
||||
/// <summary>
|
||||
/// The body format for this request
|
||||
/// </summary>
|
||||
public RequestBodyFormat? RequestBodyFormat { get; set; }
|
||||
/// <summary>
|
||||
/// The position of parameters for this request
|
||||
/// </summary>
|
||||
public HttpMethodParameterPosition? ParameterPosition { get; set; }
|
||||
/// <summary>
|
||||
/// The array serialization type for this request
|
||||
/// </summary>
|
||||
public ArrayParametersSerialization? ArraySerialization { get; set; }
|
||||
|
||||
// Rate limiting
|
||||
|
||||
/// <summary>
|
||||
/// Request weight
|
||||
/// </summary>
|
||||
public int Weight { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Rate limit gate to use
|
||||
/// </summary>
|
||||
public IRateLimitGate? RateLimitGate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Individual endpoint rate limit guard to use
|
||||
/// </summary>
|
||||
public IRateLimitGuard? LimitGuard { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this request should never be cached
|
||||
/// </summary>
|
||||
public bool PreventCaching { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Connection id
|
||||
/// </summary>
|
||||
public int? ConnectionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="method"></param>
|
||||
public RequestDefinition(string path, HttpMethod method)
|
||||
public class RequestDefinition
|
||||
{
|
||||
Path = path;
|
||||
Method = method;
|
||||
private string? _stringRep;
|
||||
|
||||
if (!Path.StartsWith("/"))
|
||||
Path = $"/{Path}";
|
||||
}
|
||||
// Basics
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return _stringRep ??= $"{Method} {Path}{(Authenticated ? " authenticated" : "")}";
|
||||
/// <summary>
|
||||
/// Path of the request
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
/// <summary>
|
||||
/// Http method of the request
|
||||
/// </summary>
|
||||
public HttpMethod Method { get; set; }
|
||||
/// <summary>
|
||||
/// Is the request authenticated
|
||||
/// </summary>
|
||||
public bool Authenticated { get; set; }
|
||||
|
||||
// Formatting
|
||||
|
||||
/// <summary>
|
||||
/// The body format for this request
|
||||
/// </summary>
|
||||
public RequestBodyFormat? RequestBodyFormat { get; set; }
|
||||
/// <summary>
|
||||
/// The position of parameters for this request
|
||||
/// </summary>
|
||||
public HttpMethodParameterPosition? ParameterPosition { get; set; }
|
||||
/// <summary>
|
||||
/// The array serialization type for this request
|
||||
/// </summary>
|
||||
public ArrayParametersSerialization? ArraySerialization { get; set; }
|
||||
|
||||
// Rate limiting
|
||||
|
||||
/// <summary>
|
||||
/// Request weight
|
||||
/// </summary>
|
||||
public int Weight { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Rate limit gate to use
|
||||
/// </summary>
|
||||
public IRateLimitGate? RateLimitGate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Individual endpoint rate limit guard to use
|
||||
/// </summary>
|
||||
public IRateLimitGuard? LimitGuard { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this request should never be cached
|
||||
/// </summary>
|
||||
public bool PreventCaching { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the response to this requests should attempted to be parsed even when the status indicates failure
|
||||
/// </summary>
|
||||
public bool TryParseOnNonSuccess { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Connection id
|
||||
/// </summary>
|
||||
public int? ConnectionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="method"></param>
|
||||
public RequestDefinition(string path, HttpMethod method)
|
||||
{
|
||||
Path = path;
|
||||
Method = method;
|
||||
|
||||
if (!Path.StartsWith("/"))
|
||||
Path = $"/{Path}";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return _stringRep ??= $"{Method} {Path}{(Authenticated ? " authenticated" : "")}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,110 +1,116 @@
|
||||
using CryptoExchange.Net.RateLimiting.Interfaces;
|
||||
using CryptoExchange.Net.RateLimiting.Interfaces;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace CryptoExchange.Net.Objects;
|
||||
|
||||
/// <summary>
|
||||
/// Request definitions cache
|
||||
/// </summary>
|
||||
public class RequestDefinitionCache
|
||||
namespace CryptoExchange.Net.Objects
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, RequestDefinition> _definitions = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get a definition if it is already in the cache or create a new definition and add it to the cache
|
||||
/// Request definitions cache
|
||||
/// </summary>
|
||||
/// <param name="method">The HttpMethod</param>
|
||||
/// <param name="path">Endpoint path</param>
|
||||
/// <param name="authenticated">Endpoint is authenticated</param>
|
||||
/// <returns></returns>
|
||||
public RequestDefinition GetOrCreate(HttpMethod method, string path, bool authenticated = false)
|
||||
=> GetOrCreate(method, path, null, 0, authenticated, null, null, null, null, null);
|
||||
|
||||
/// <summary>
|
||||
/// Get a definition if it is already in the cache or create a new definition and add it to the cache
|
||||
/// </summary>
|
||||
/// <param name="method">The HttpMethod</param>
|
||||
/// <param name="path">Endpoint path</param>
|
||||
/// <param name="rateLimitGate">The rate limit gate</param>
|
||||
/// <param name="weight">Request weight</param>
|
||||
/// <param name="authenticated">Endpoint is authenticated</param>
|
||||
/// <returns></returns>
|
||||
public RequestDefinition GetOrCreate(HttpMethod method, string path, IRateLimitGate rateLimitGate, int weight = 1, bool authenticated = false)
|
||||
=> GetOrCreate(method, path, rateLimitGate, weight, authenticated, null, null, null, null, null);
|
||||
|
||||
/// <summary>
|
||||
/// Get a definition if it is already in the cache or create a new definition and add it to the cache
|
||||
/// </summary>
|
||||
/// <param name="method">The HttpMethod</param>
|
||||
/// <param name="path">Endpoint path</param>
|
||||
/// <param name="rateLimitGate">The rate limit gate</param>
|
||||
/// <param name="limitGuard">The rate limit guard for this specific endpoint</param>
|
||||
/// <param name="weight">Request weight</param>
|
||||
/// <param name="authenticated">Endpoint is authenticated</param>
|
||||
/// <param name="requestBodyFormat">Request body format</param>
|
||||
/// <param name="parameterPosition">Parameter position</param>
|
||||
/// <param name="arraySerialization">Array serialization type</param>
|
||||
/// <param name="preventCaching">Prevent request caching</param>
|
||||
/// <returns></returns>
|
||||
public RequestDefinition GetOrCreate(
|
||||
HttpMethod method,
|
||||
string path,
|
||||
IRateLimitGate? rateLimitGate,
|
||||
int weight,
|
||||
bool authenticated,
|
||||
IRateLimitGuard? limitGuard = null,
|
||||
RequestBodyFormat? requestBodyFormat = null,
|
||||
HttpMethodParameterPosition? parameterPosition = null,
|
||||
ArrayParametersSerialization? arraySerialization = null,
|
||||
bool? preventCaching = null)
|
||||
=> GetOrCreate(method + path, method, path, rateLimitGate, weight, authenticated, limitGuard, requestBodyFormat, parameterPosition, arraySerialization, preventCaching);
|
||||
|
||||
/// <summary>
|
||||
/// Get a definition if it is already in the cache or create a new definition and add it to the cache
|
||||
/// </summary>
|
||||
/// <param name="identifier">Request identifier</param>
|
||||
/// <param name="method">The HttpMethod</param>
|
||||
/// <param name="path">Endpoint path</param>
|
||||
/// <param name="rateLimitGate">The rate limit gate</param>
|
||||
/// <param name="limitGuard">The rate limit guard for this specific endpoint</param>
|
||||
/// <param name="weight">Request weight</param>
|
||||
/// <param name="authenticated">Endpoint is authenticated</param>
|
||||
/// <param name="requestBodyFormat">Request body format</param>
|
||||
/// <param name="parameterPosition">Parameter position</param>
|
||||
/// <param name="arraySerialization">Array serialization type</param>
|
||||
/// <param name="preventCaching">Prevent request caching</param>
|
||||
/// <returns></returns>
|
||||
public RequestDefinition GetOrCreate(
|
||||
string identifier,
|
||||
HttpMethod method,
|
||||
string path,
|
||||
IRateLimitGate? rateLimitGate,
|
||||
int weight,
|
||||
bool authenticated,
|
||||
IRateLimitGuard? limitGuard = null,
|
||||
RequestBodyFormat? requestBodyFormat = null,
|
||||
HttpMethodParameterPosition? parameterPosition = null,
|
||||
ArrayParametersSerialization? arraySerialization = null,
|
||||
bool? preventCaching = null)
|
||||
public class RequestDefinitionCache
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, RequestDefinition> _definitions = new();
|
||||
|
||||
if (!_definitions.TryGetValue(identifier, out var def))
|
||||
/// <summary>
|
||||
/// Get a definition if it is already in the cache or create a new definition and add it to the cache
|
||||
/// </summary>
|
||||
/// <param name="method">The HttpMethod</param>
|
||||
/// <param name="path">Endpoint path</param>
|
||||
/// <param name="authenticated">Endpoint is authenticated</param>
|
||||
/// <returns></returns>
|
||||
public RequestDefinition GetOrCreate(HttpMethod method, string path, bool authenticated = false)
|
||||
=> GetOrCreate(method, path, null, 0, authenticated, null, null, null, null, null);
|
||||
|
||||
/// <summary>
|
||||
/// Get a definition if it is already in the cache or create a new definition and add it to the cache
|
||||
/// </summary>
|
||||
/// <param name="method">The HttpMethod</param>
|
||||
/// <param name="path">Endpoint path</param>
|
||||
/// <param name="rateLimitGate">The rate limit gate</param>
|
||||
/// <param name="weight">Request weight</param>
|
||||
/// <param name="authenticated">Endpoint is authenticated</param>
|
||||
/// <returns></returns>
|
||||
public RequestDefinition GetOrCreate(HttpMethod method, string path, IRateLimitGate rateLimitGate, int weight = 1, bool authenticated = false)
|
||||
=> GetOrCreate(method, path, rateLimitGate, weight, authenticated, null, null, null, null, null);
|
||||
|
||||
/// <summary>
|
||||
/// Get a definition if it is already in the cache or create a new definition and add it to the cache
|
||||
/// </summary>
|
||||
/// <param name="method">The HttpMethod</param>
|
||||
/// <param name="path">Endpoint path</param>
|
||||
/// <param name="rateLimitGate">The rate limit gate</param>
|
||||
/// <param name="limitGuard">The rate limit guard for this specific endpoint</param>
|
||||
/// <param name="weight">Request weight</param>
|
||||
/// <param name="authenticated">Endpoint is authenticated</param>
|
||||
/// <param name="requestBodyFormat">Request body format</param>
|
||||
/// <param name="parameterPosition">Parameter position</param>
|
||||
/// <param name="arraySerialization">Array serialization type</param>
|
||||
/// <param name="preventCaching">Prevent request caching</param>
|
||||
/// <param name="tryParseOnNonSuccess">Try parse the response even when status is not success</param>
|
||||
/// <returns></returns>
|
||||
public RequestDefinition GetOrCreate(
|
||||
HttpMethod method,
|
||||
string path,
|
||||
IRateLimitGate? rateLimitGate,
|
||||
int weight,
|
||||
bool authenticated,
|
||||
IRateLimitGuard? limitGuard = null,
|
||||
RequestBodyFormat? requestBodyFormat = null,
|
||||
HttpMethodParameterPosition? parameterPosition = null,
|
||||
ArrayParametersSerialization? arraySerialization = null,
|
||||
bool? preventCaching = null,
|
||||
bool? tryParseOnNonSuccess = null)
|
||||
=> GetOrCreate(method + path, method, path, rateLimitGate, weight, authenticated, limitGuard, requestBodyFormat, parameterPosition, arraySerialization, preventCaching, tryParseOnNonSuccess);
|
||||
|
||||
/// <summary>
|
||||
/// Get a definition if it is already in the cache or create a new definition and add it to the cache
|
||||
/// </summary>
|
||||
/// <param name="identifier">Request identifier</param>
|
||||
/// <param name="method">The HttpMethod</param>
|
||||
/// <param name="path">Endpoint path</param>
|
||||
/// <param name="rateLimitGate">The rate limit gate</param>
|
||||
/// <param name="limitGuard">The rate limit guard for this specific endpoint</param>
|
||||
/// <param name="weight">Request weight</param>
|
||||
/// <param name="authenticated">Endpoint is authenticated</param>
|
||||
/// <param name="requestBodyFormat">Request body format</param>
|
||||
/// <param name="parameterPosition">Parameter position</param>
|
||||
/// <param name="arraySerialization">Array serialization type</param>
|
||||
/// <param name="preventCaching">Prevent request caching</param>
|
||||
/// <param name="tryParseOnNonSuccess">Try parse the response even when status is not success</param>
|
||||
/// <returns></returns>
|
||||
public RequestDefinition GetOrCreate(
|
||||
string identifier,
|
||||
HttpMethod method,
|
||||
string path,
|
||||
IRateLimitGate? rateLimitGate,
|
||||
int weight,
|
||||
bool authenticated,
|
||||
IRateLimitGuard? limitGuard = null,
|
||||
RequestBodyFormat? requestBodyFormat = null,
|
||||
HttpMethodParameterPosition? parameterPosition = null,
|
||||
ArrayParametersSerialization? arraySerialization = null,
|
||||
bool? preventCaching = null,
|
||||
bool? tryParseOnNonSuccess = null)
|
||||
{
|
||||
def = new RequestDefinition(path, method)
|
||||
{
|
||||
Authenticated = authenticated,
|
||||
LimitGuard = limitGuard,
|
||||
RateLimitGate = rateLimitGate,
|
||||
Weight = weight,
|
||||
ArraySerialization = arraySerialization,
|
||||
RequestBodyFormat = requestBodyFormat,
|
||||
ParameterPosition = parameterPosition,
|
||||
PreventCaching = preventCaching ?? false
|
||||
};
|
||||
_definitions.TryAdd(identifier, def);
|
||||
}
|
||||
|
||||
return def;
|
||||
if (!_definitions.TryGetValue(identifier, out var def))
|
||||
{
|
||||
def = new RequestDefinition(path, method)
|
||||
{
|
||||
Authenticated = authenticated,
|
||||
LimitGuard = limitGuard,
|
||||
RateLimitGate = rateLimitGate,
|
||||
Weight = weight,
|
||||
ArraySerialization = arraySerialization,
|
||||
RequestBodyFormat = requestBodyFormat,
|
||||
ParameterPosition = parameterPosition,
|
||||
PreventCaching = preventCaching ?? false,
|
||||
TryParseOnNonSuccess = tryParseOnNonSuccess ?? false
|
||||
};
|
||||
_definitions.TryAdd(identifier, def);
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,12 @@ 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 9.6.0 - 25 Aug 2025
|
||||
* Added support for parsing REST response even though status indicates error
|
||||
* Added better support for subscriptions without subscribe confirmation
|
||||
* Added check in websocket for receiving 401 unauthorized http response status when 101 was expected
|
||||
* Removed obsolete attribute on Error.Code property, updated the description
|
||||
|
||||
* Version 9.5.0 - 19 Aug 2025
|
||||
* Added better error handling support
|
||||
* Added ErrorDescription, ErrorType and IsTransient to Error object
|
||||
|
Loading…
x
Reference in New Issue
Block a user