Skip to content

Commit 9767b4e

Browse files
authored
CryptoExchange.Net 11.0.0 update (#292)
Updated CryptoExchange.Net to version 11.0.0 Updated class for supplying API credentials from ApiCredentials to BybitCredentials Updated Shared order status parsing to default to Unknown value if not parsable Added support for specifying non-HMAC credentials via Configuration Added json configuration example
1 parent c2a68bd commit 9767b4e

37 files changed

Lines changed: 347 additions & 176 deletions

ByBit.Net/Bybit.Net.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
2424
<EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
2525
<PackageReleaseNotes>https://github.com/JKorf/Bybit.Net?tab=readme-ov-file#release-notes</PackageReleaseNotes>
26+
<NoWarn>$(NoWarn);SYSLIB1100;SYSLIB1101</NoWarn>
2627
</PropertyGroup>
2728
<PropertyGroup Label="AOT" Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">
2829
<IsAotCompatible>true</IsAotCompatible>
@@ -52,7 +53,7 @@
5253
<PrivateAssets>all</PrivateAssets>
5354
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
5455
</PackageReference>
55-
<PackageReference Include="CryptoExchange.Net" Version="10.8.0" />
56+
<PackageReference Include="CryptoExchange.Net" Version="11.0.0" />
5657
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.101">
5758
<PrivateAssets>all</PrivateAssets>
5859
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

ByBit.Net/BybitAuthenticationProvider.cs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515

1616
namespace Bybit.Net
1717
{
18-
internal class BybitAuthenticationProvider : AuthenticationProvider
18+
internal class BybitAuthenticationProvider : AuthenticationProvider<BybitCredentials>
1919
{
2020
private static readonly IStringMessageSerializer _messageSerializer = new SystemTextJsonMessageSerializer(SerializerOptions.WithConverters(BybitExchange._serializerContext));
2121

22-
public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.Hmac, ApiCredentialsType.RsaPem, ApiCredentialsType.RsaXml];
22+
public override string Key => ApiCredentials.Credential.Key;
2323

24-
public BybitAuthenticationProvider(ApiCredentials credentials) : base(credentials)
24+
public BybitAuthenticationProvider(BybitCredentials credentials) : base(credentials)
2525
{
2626
}
2727

@@ -36,22 +36,28 @@ public override void ProcessRequest(RestApiClient apiClient, RestRequestConfigur
3636
if (request.ParameterPosition == HttpMethodParameterPosition.InUri)
3737
{
3838
var queryString = request.GetQueryString();
39-
payload = timestamp + _credentials.Key + recvWindow + queryString;
39+
payload = timestamp + ApiCredentials.Credential.Key + recvWindow + queryString;
4040
request.SetQueryString(queryString);
4141
}
4242
else
4343
{
4444
var requestBody = request.BodyFormat == RequestBodyFormat.FormData
4545
? (request.BodyParameters?.ToFormData() ?? string.Empty)
4646
: GetSerializedBody(_messageSerializer, request.BodyParameters ?? new Dictionary<string, object>());
47-
payload = timestamp + _credentials.Key + recvWindow + requestBody;
47+
payload = timestamp + ApiCredentials.Credential.Key + recvWindow + requestBody;
4848
request.SetBodyContent(requestBody);
4949
}
5050

51-
var signature = _credentials.CredentialType == ApiCredentialsType.Hmac ? SignHMACSHA256(payload) : SignRSASHA256(Encoding.UTF8.GetBytes(payload), SignOutputType.Base64);
51+
string signature;
52+
if (ApiCredentials.Credential is HMACCredential hmacCred)
53+
signature = SignHMACSHA256(hmacCred, payload);
54+
else if (ApiCredentials.Credential is RSACredential rsaCred)
55+
signature = SignRSASHA256(rsaCred, Encoding.UTF8.GetBytes(payload), SignOutputType.Base64);
56+
else
57+
throw new NotImplementedException();
5258

5359
request.Headers ??= new Dictionary<string, string>();
54-
request.Headers.Add("X-BAPI-API-KEY", _credentials.Key);
60+
request.Headers.Add("X-BAPI-API-KEY", ApiCredentials.Credential.Key);
5561
request.Headers.Add("X-BAPI-SIGN", signature);
5662
request.Headers.Add("X-BAPI-SIGN-TYPE", "2");
5763
request.Headers.Add("X-BAPI-TIMESTAMP", timestamp);
@@ -60,32 +66,36 @@ public override void ProcessRequest(RestApiClient apiClient, RestRequestConfigur
6066

6167
public override Query? GetAuthenticationQuery(SocketApiClient apiClient, SocketConnection connection, Dictionary<string, object?>? context = null)
6268
{
69+
var expireTime = DateTimeConverter.ConvertToMilliseconds(GetTimestamp(apiClient).AddSeconds(30))!;
70+
var key = ApiCredentials.Credential.Key;
71+
72+
string sign;
73+
if (ApiCredentials.Credential is HMACCredential hmacCred)
74+
sign = SignHMACSHA256(hmacCred, $"GET/realtime{expireTime}");
75+
else if (ApiCredentials.Credential is RSACredential rsaCred)
76+
sign = SignRSASHA256(rsaCred, Encoding.UTF8.GetBytes($"GET/realtime{expireTime}"), SignOutputType.Base64);
77+
else
78+
throw new NotImplementedException();
79+
6380
if (connection.ConnectionUri.AbsolutePath.EndsWith("private"))
6481
{
6582
// Auth subscription
66-
var expireTime = DateTimeConverter.ConvertToMilliseconds(GetTimestamp(apiClient).AddSeconds(30))!;
67-
var key = ApiKey;
68-
var sign = SignHMACSHA256($"GET/realtime{expireTime}");
69-
7083
return new BybitQuery(apiClient, "auth", new object[]
7184
{
72-
key,
73-
expireTime,
74-
sign
85+
key,
86+
expireTime,
87+
sign
7588
});
7689
}
7790
else
7891
{
7992
// Trading
80-
var expireTime = DateTimeConverter.ConvertToMilliseconds(GetTimestamp(apiClient).AddSeconds(30))!;
81-
var key = ApiKey;
82-
var sign = SignHMACSHA256($"GET/realtime{expireTime}");
8393

8494
return new BybitRequestQuery<object>(apiClient, "auth", null, new object[]
8595
{
86-
key,
87-
expireTime,
88-
sign
96+
key,
97+
expireTime,
98+
sign
8999
});
90100
}
91101
}

ByBit.Net/BybitCredentials.cs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
using CryptoExchange.Net.Authentication;
2+
using System;
3+
using System.Linq;
4+
5+
namespace Bybit.Net
6+
{
7+
/// <summary>
8+
/// Bybit credentials
9+
/// </summary>
10+
public class BybitCredentials : ApiCredentials
11+
{
12+
internal CredentialSet Credential { get; set; }
13+
14+
/// <summary>
15+
/// HMAC credentials
16+
/// </summary>
17+
public HMACCredential? HMAC
18+
{
19+
get => Credential as HMACCredential;
20+
set { if (value != null) Credential = value; }
21+
}
22+
23+
/// <summary>
24+
/// RSA credentials in XML format
25+
/// </summary>
26+
public RSAXmlCredential? RSAXml
27+
{
28+
get => Credential as RSAXmlCredential;
29+
set { if (value != null) Credential = value; }
30+
}
31+
32+
#if NETSTANDARD2_1_OR_GREATER || NET7_0_OR_GREATER
33+
/// <summary>
34+
/// RSA credentials in PEM/Base64 format
35+
/// </summary>
36+
public RSAPemCredential? RSAPem
37+
{
38+
get => Credential as RSAPemCredential;
39+
set { if (value != null) Credential = value; }
40+
}
41+
#endif
42+
43+
/// <summary>
44+
/// Create new credentials
45+
/// </summary>
46+
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
47+
public BybitCredentials() { }
48+
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
49+
50+
/// <summary>
51+
/// Create new credentials providing HMAC credentials
52+
/// </summary>
53+
/// <param name="key">API key</param>
54+
/// <param name="secret">API secret</param>
55+
public BybitCredentials(string key, string secret)
56+
{
57+
Credential = new HMACCredential(key, secret);
58+
}
59+
60+
/// <summary>
61+
/// Create new credentials providing HMAC credentials
62+
/// </summary>
63+
/// <param name="credential">HMAC Credentials</param>
64+
public BybitCredentials(HMACCredential credential)
65+
{
66+
Credential = credential;
67+
}
68+
69+
/// <summary>
70+
/// Create new credentials providing RSA credentials in XML format
71+
/// </summary>
72+
/// <param name="credential">RSA credentials in XML format</param>
73+
public BybitCredentials(RSAXmlCredential credential)
74+
{
75+
Credential = credential;
76+
}
77+
78+
#if NETSTANDARD2_1_OR_GREATER || NET7_0_OR_GREATER
79+
/// <summary>
80+
/// Create new credentials providing RSA credentials in PEM/Base64 format
81+
/// </summary>
82+
/// <param name="credential">RSA credentials in PEM/Base64 format</param>
83+
public BybitCredentials(RSAPemCredential credential)
84+
{
85+
Credential = credential;
86+
}
87+
#endif
88+
89+
/// <summary>
90+
/// Specify the HMAC credentials
91+
/// </summary>
92+
/// <param name="key">API key</param>
93+
/// <param name="secret">API secret</param>
94+
public BybitCredentials WithHMAC(string key, string secret)
95+
{
96+
if (Credential != null) throw new InvalidOperationException("Credentials already set");
97+
98+
Credential = new HMACCredential(key, secret);
99+
return this;
100+
}
101+
102+
/// <summary>
103+
/// Specify the RSA credentials in XML format
104+
/// </summary>
105+
/// <param name="key">API key</param>
106+
/// <param name="privateKey">Private key</param>
107+
public BybitCredentials WithRSAXml(string key, string privateKey)
108+
{
109+
if (Credential != null) throw new InvalidOperationException("Credentials already set");
110+
111+
Credential = new RSAXmlCredential(key, privateKey);
112+
return this;
113+
}
114+
115+
#if NETSTANDARD2_1_OR_GREATER || NET7_0_OR_GREATER
116+
/// <summary>
117+
/// Specify the RSA credentials in PEM/Base64 format
118+
/// </summary>
119+
/// <param name="key">API key</param>
120+
/// <param name="privateKey">Private key</param>
121+
public BybitCredentials WithRSAPem(string key, string privateKey)
122+
{
123+
if (Credential != null) throw new InvalidOperationException("Credentials already set");
124+
125+
Credential = new RSAPemCredential(key, privateKey);
126+
return this;
127+
}
128+
#endif
129+
130+
/// <inheritdoc />
131+
public override ApiCredentials Copy() => new BybitCredentials { Credential = Credential };
132+
133+
/// <inheritdoc />
134+
public override void Validate()
135+
{
136+
if (Credential == null)
137+
throw new ArgumentException($"No credentials provided on {GetType().Name}");
138+
139+
Credential.Validate();
140+
}
141+
}
142+
}

ByBit.Net/BybitTrackerFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig?
137137
}
138138

139139
/// <inheritdoc />
140-
public IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, ApiCredentials credentials, SpotUserDataTrackerConfig? config = null, BybitEnvironment? environment = null)
140+
public IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, BybitCredentials credentials, SpotUserDataTrackerConfig? config = null, BybitEnvironment? environment = null)
141141
{
142142
var clientProvider = _serviceProvider?.GetRequiredService<IBybitUserClientProvider>() ?? new BybitUserClientProvider();
143143
var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment);
@@ -166,7 +166,7 @@ public IUserFuturesDataTracker CreateUserFuturesDataTracker(FuturesUserDataTrack
166166
}
167167

168168
/// <inheritdoc />
169-
public IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, ApiCredentials credentials, FuturesUserDataTrackerConfig? config = null, BybitEnvironment? environment = null)
169+
public IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, BybitCredentials credentials, FuturesUserDataTrackerConfig? config = null, BybitEnvironment? environment = null)
170170
{
171171
var clientProvider = _serviceProvider?.GetRequiredService<IBybitUserClientProvider>() ?? new BybitUserClientProvider();
172172
var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment);

ByBit.Net/Clients/BybitRestClient.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace Bybit.Net.Clients
1212
{
1313
/// <inheritdoc cref="IBybitRestClient" />
14-
public class BybitRestClient : BaseRestClient, IBybitRestClient
14+
public class BybitRestClient : BaseRestClient<BybitEnvironment, BybitCredentials>, IBybitRestClient
1515
{
1616
/// <inheritdoc />
1717
public Interfaces.Clients.V5.IBybitRestClientApi V5Api { get; }
@@ -42,12 +42,6 @@ public BybitRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, IO
4242

4343
#endregion
4444

45-
/// <inheritdoc />
46-
public void SetOptions(UpdateOptions options)
47-
{
48-
V5Api.SetOptions(options);
49-
}
50-
5145
/// <summary>
5246
/// Set the default options to be used when creating new clients
5347
/// </summary>
@@ -56,11 +50,5 @@ public static void SetDefaultOptions(Action<BybitRestOptions> optionsDelegate)
5650
{
5751
BybitRestOptions.Default = ApplyOptionsDelegate(optionsDelegate);
5852
}
59-
60-
/// <inheritdoc />
61-
public void SetApiCredentials(ApiCredentials credentials)
62-
{
63-
V5Api.SetApiCredentials(credentials);
64-
}
6553
}
6654
}

ByBit.Net/Clients/BybitSocketClient.cs

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace Bybit.Net.Clients
1313
{
1414
/// <inheritdoc cref="IBybitSocketClient" />
15-
public class BybitSocketClient : BaseSocketClient, IBybitSocketClient
15+
public class BybitSocketClient : BaseSocketClient<BybitEnvironment, BybitCredentials>, IBybitSocketClient
1616
{
1717
/// <inheritdoc />
1818
public IBybitSocketClientSpotApi V5SpotApi { get; }
@@ -53,17 +53,6 @@ public BybitSocketClient(IOptions<BybitSocketOptions> options, ILoggerFactory? l
5353
V5PrivateApi = AddApiClient(new BybitSocketClientPrivateApi(_logger, options.Value));
5454
}
5555

56-
/// <inheritdoc />
57-
public void SetOptions(UpdateOptions options)
58-
{
59-
V5SpotApi.SetOptions(options);
60-
V5InverseApi.SetOptions(options);
61-
V5LinearApi.SetOptions(options);
62-
V5OptionsApi.SetOptions(options);
63-
V5SpreadApi.SetOptions(options);
64-
V5PrivateApi.SetOptions(options);
65-
}
66-
6756
/// <summary>
6857
/// Set the default options to be used when creating new clients
6958
/// </summary>
@@ -72,16 +61,5 @@ public static void SetDefaultOptions(Action<BybitSocketOptions> optionsDelegate)
7261
{
7362
BybitSocketOptions.Default = ApplyOptionsDelegate(optionsDelegate);
7463
}
75-
76-
/// <inheritdoc />
77-
public void SetApiCredentials(ApiCredentials credentials)
78-
{
79-
V5LinearApi.SetApiCredentials(credentials);
80-
V5OptionsApi.SetApiCredentials(credentials);
81-
V5InverseApi.SetApiCredentials(credentials);
82-
V5PrivateApi.SetApiCredentials(credentials);
83-
V5SpreadApi.SetApiCredentials(credentials);
84-
V5SpotApi.SetApiCredentials(credentials);
85-
}
8664
}
8765
}

0 commit comments

Comments
 (0)