From 006cc6d9122ded2c5b37d24354605ff46c3e349d Mon Sep 17 00:00:00 2001 From: Jkorf Date: Fri, 13 Mar 2026 16:31:24 +0100 Subject: [PATCH 01/10] wip --- BitMEX.Net.UnitTests/BitMEXRestClientTests.cs | 2 +- .../BitMEXRestIntegrationTests.cs | 2 +- .../BitMEXSocketIntegrationTests.cs | 2 +- BitMEX.Net.UnitTests/RestRequestTests.cs | 6 ++--- .../SocketSubscriptionTests.cs | 2 +- BitMEX.Net/BitMEX.Net.csproj | 4 ++- BitMEX.Net/BitMEXAuthenticationProvider.cs | 6 ++--- BitMEX.Net/BitMEXCredentials.cs | 26 +++++++++++++++++++ BitMEX.Net/BitMEXTrackerFactory.cs | 4 +-- BitMEX.Net/Clients/BitMEXRestClient.cs | 13 +--------- BitMEX.Net/Clients/BitMEXSocketClient.cs | 16 +----------- .../Clients/BitMEXUserClientProvider.cs | 10 +++---- .../BitMEXRestClientExchangeApi.cs | 4 +-- .../BitMEXSocketClientExchangeApi.cs | 6 ++--- .../IBitMEXRestClientExchangeApi.cs | 2 +- .../IBitMEXSocketClientExchangeApi.cs | 2 +- .../Interfaces/Clients/IBitMEXRestClient.cs | 13 +--------- .../Interfaces/Clients/IBitMEXSocketClient.cs | 15 +---------- .../Clients/IBitMEXUserClientProvider.cs | 6 ++--- .../Interfaces/IBitMEXTrackerFactory.cs | 4 +-- BitMEX.Net/Objects/Options/BitMEXOptions.cs | 2 +- .../Objects/Options/BitMEXRestOptions.cs | 9 +++---- .../Objects/Options/BitMEXSocketOptions.cs | 14 +++------- 23 files changed, 70 insertions(+), 100 deletions(-) create mode 100644 BitMEX.Net/BitMEXCredentials.cs diff --git a/BitMEX.Net.UnitTests/BitMEXRestClientTests.cs b/BitMEX.Net.UnitTests/BitMEXRestClientTests.cs index ac0be0b..9859fe5 100644 --- a/BitMEX.Net.UnitTests/BitMEXRestClientTests.cs +++ b/BitMEX.Net.UnitTests/BitMEXRestClientTests.cs @@ -14,7 +14,7 @@ public class BitMEXRestClientTests [Test] public void CheckSignatureExample1() { - var authProvider = new BitMEXAuthenticationProvider(new ApiCredentials("XXX", "XXX")); + var authProvider = new BitMEXAuthenticationProvider(new BitMEXCredentials("XXX", "XXX")); var client = (RestApiClient)new BitMEXRestClient().ExchangeApi; CryptoExchange.Net.Testing.TestHelpers.CheckSignature( diff --git a/BitMEX.Net.UnitTests/BitMEXRestIntegrationTests.cs b/BitMEX.Net.UnitTests/BitMEXRestIntegrationTests.cs index 6d04010..86fe144 100644 --- a/BitMEX.Net.UnitTests/BitMEXRestIntegrationTests.cs +++ b/BitMEX.Net.UnitTests/BitMEXRestIntegrationTests.cs @@ -26,7 +26,7 @@ public override BitMEXRestClient GetClient(ILoggerFactory loggerFactory) { AutoTimestamp = false, OutputOriginalData = true, - ApiCredentials = Authenticated ? new CryptoExchange.Net.Authentication.ApiCredentials(key, sec) : null + ApiCredentials = Authenticated ? new BitMEXCredentials(key, sec) : null })); } diff --git a/BitMEX.Net.UnitTests/BitMEXSocketIntegrationTests.cs b/BitMEX.Net.UnitTests/BitMEXSocketIntegrationTests.cs index aed857a..1afcd4f 100644 --- a/BitMEX.Net.UnitTests/BitMEXSocketIntegrationTests.cs +++ b/BitMEX.Net.UnitTests/BitMEXSocketIntegrationTests.cs @@ -28,7 +28,7 @@ public override BitMEXSocketClient GetClient(ILoggerFactory loggerFactory) return new BitMEXSocketClient(Options.Create(new BitMEXSocketOptions { OutputOriginalData = true, - ApiCredentials = Authenticated ? new CryptoExchange.Net.Authentication.ApiCredentials(key, sec) : null + ApiCredentials = Authenticated ? new BitMEXCredentials(key, sec) : null }), loggerFactory); } diff --git a/BitMEX.Net.UnitTests/RestRequestTests.cs b/BitMEX.Net.UnitTests/RestRequestTests.cs index 9cfec8d..c05aa97 100644 --- a/BitMEX.Net.UnitTests/RestRequestTests.cs +++ b/BitMEX.Net.UnitTests/RestRequestTests.cs @@ -18,7 +18,7 @@ public async Task ValidateAccountCalls() var client = new BitMEXRestClient(opts => { opts.AutoTimestamp = false; - opts.ApiCredentials = new CryptoExchange.Net.Authentication.ApiCredentials("123", "456"); + opts.ApiCredentials = new BitMEXCredentials("123", "456"); }); var tester = new RestRequestValidator(client, "Endpoints/Exchange/Account", "https://www.bitmex.com", IsAuthenticated); await tester.ValidateAsync(client => client.ExchangeApi.Account.GetUserEventsAsync(), "GetUserEvents", nestedJsonProperty: "userEvents"); @@ -33,7 +33,7 @@ public async Task ValidateExchangeDataCalls() var client = new BitMEXRestClient(opts => { opts.AutoTimestamp = false; - opts.ApiCredentials = new CryptoExchange.Net.Authentication.ApiCredentials("123", "456"); + opts.ApiCredentials = new BitMEXCredentials("123", "456"); }); var tester = new RestRequestValidator(client, "Endpoints/Exchange/ExchangeData", "https://www.bitmex.com", IsAuthenticated); await tester.ValidateAsync(client => client.ExchangeApi.ExchangeData.GetActiveSymbolsAsync(), "GetActiveSymbols", ignoreProperties: ["publishInterval", "fundingInterval", "rebalanceInterval"]); @@ -60,7 +60,7 @@ public async Task ValidateTradingCalls() var client = new BitMEXRestClient(opts => { opts.AutoTimestamp = false; - opts.ApiCredentials = new CryptoExchange.Net.Authentication.ApiCredentials("123", "456"); + opts.ApiCredentials = new BitMEXCredentials("123", "456"); }); var tester = new RestRequestValidator(client, "Endpoints/Exchange/Trading", "https://www.bitmex.com", IsAuthenticated); await tester.ValidateAsync(client => client.ExchangeApi.Trading.PlaceOrderAsync("ETHUSDT", Enums.OrderSide.Buy, Enums.OrderType.LimitIfTouched), "PlaceOrder", ignoreProperties: new List { "text" }); diff --git a/BitMEX.Net.UnitTests/SocketSubscriptionTests.cs b/BitMEX.Net.UnitTests/SocketSubscriptionTests.cs index 23ff566..8275306 100644 --- a/BitMEX.Net.UnitTests/SocketSubscriptionTests.cs +++ b/BitMEX.Net.UnitTests/SocketSubscriptionTests.cs @@ -42,7 +42,7 @@ public async Task ValidateSpotExchangeDataSubscriptions() var client = new BitMEXSocketClient(Options.Create(new BitMEXSocketOptions { - ApiCredentials = new CryptoExchange.Net.Authentication.ApiCredentials("123", "456", "789"), + ApiCredentials = new BitMEXCredentials("123", "456"), OutputOriginalData = true }), logger); var tester = new SocketSubscriptionValidator(client, "Subscriptions/Exchange", "wss://ws.bitmex.com/"); diff --git a/BitMEX.Net/BitMEX.Net.csproj b/BitMEX.Net/BitMEX.Net.csproj index 71164a1..f2d0675 100644 --- a/BitMEX.Net/BitMEX.Net.csproj +++ b/BitMEX.Net/BitMEX.Net.csproj @@ -52,10 +52,12 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - all runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/BitMEX.Net/BitMEXAuthenticationProvider.cs b/BitMEX.Net/BitMEXAuthenticationProvider.cs index b5877cc..685c0be 100644 --- a/BitMEX.Net/BitMEXAuthenticationProvider.cs +++ b/BitMEX.Net/BitMEXAuthenticationProvider.cs @@ -7,12 +7,12 @@ namespace BitMEX.Net { - internal class BitMEXAuthenticationProvider : AuthenticationProvider + internal class BitMEXAuthenticationProvider : AuthenticationProvider { private static readonly IMessageSerializer _serializer = new SystemTextJsonMessageSerializer(SerializerOptions.WithConverters(BitMEXExchange._serializerContext)); public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.Hmac]; - public BitMEXAuthenticationProvider(ApiCredentials credentials) : base(credentials) + public BitMEXAuthenticationProvider(BitMEXCredentials credentials) : base(credentials) { } @@ -26,7 +26,7 @@ public override void ProcessRequest(RestApiClient apiClient, RestRequestConfigur var expires = DateTimeConverter.ConvertToSeconds(timestamp.AddSeconds(5))!; request.Headers ??= new Dictionary(); request.Headers.Add("api-expires", expires.Value.ToString()); - request.Headers.Add("api-key", ApiKey); + request.Headers.Add("api-key", Credential.PublicKey); var body = (request.BodyParameters == null || request.BodyParameters.Count == 0) ? "" : GetSerializedBody(_serializer, request.BodyParameters); var queryParams = request.GetQueryString(true); diff --git a/BitMEX.Net/BitMEXCredentials.cs b/BitMEX.Net/BitMEXCredentials.cs new file mode 100644 index 0000000..cd002ac --- /dev/null +++ b/BitMEX.Net/BitMEXCredentials.cs @@ -0,0 +1,26 @@ +using CryptoExchange.Net.Authentication; + +namespace BitMEX.Net +{ + /// + /// BitMEX credentials + /// + public class BitMEXCredentials : ApiCredentials + { + /// + /// ctor + /// + /// The API key + /// The API secret + public BitMEXCredentials(string apiKey, string secret) : this(new HMACCredential(apiKey, secret)) { } + + /// + /// ctor + /// + /// The HMAC credentials + public BitMEXCredentials(HMACCredential credential) : base(credential) { } + + /// + public override ApiCredentials Copy() => new BitMEXCredentials(Hmac!); + } +} diff --git a/BitMEX.Net/BitMEXTrackerFactory.cs b/BitMEX.Net/BitMEXTrackerFactory.cs index 8045b32..56c971b 100644 --- a/BitMEX.Net/BitMEXTrackerFactory.cs +++ b/BitMEX.Net/BitMEXTrackerFactory.cs @@ -80,7 +80,7 @@ public IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig? } /// - public IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, ApiCredentials credentials, SpotUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null) + public IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, BitMEXCredentials credentials, SpotUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null) { var clientProvider = _serviceProvider?.GetRequiredService() ?? new BitMEXUserClientProvider(); var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment); @@ -109,7 +109,7 @@ public IUserFuturesDataTracker CreateUserFuturesDataTracker(FuturesUserDataTrack } /// - public IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, ApiCredentials credentials, FuturesUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null) + public IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, BitMEXCredentials credentials, FuturesUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null) { var clientProvider = _serviceProvider?.GetRequiredService() ?? new BitMEXUserClientProvider(); var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment); diff --git a/BitMEX.Net/Clients/BitMEXRestClient.cs b/BitMEX.Net/Clients/BitMEXRestClient.cs index 1bbb46b..88ec0ca 100644 --- a/BitMEX.Net/Clients/BitMEXRestClient.cs +++ b/BitMEX.Net/Clients/BitMEXRestClient.cs @@ -13,7 +13,7 @@ namespace BitMEX.Net.Clients { /// - public class BitMEXRestClient : BaseRestClient, IBitMEXRestClient + public class BitMEXRestClient : BaseRestClient, IBitMEXRestClient { #region Api clients @@ -50,12 +50,6 @@ public BitMEXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, I #endregion - /// - public void SetOptions(UpdateOptions options) - { - ExchangeApi.SetOptions(options); - } - /// /// Set the default options to be used when creating new clients /// @@ -65,10 +59,5 @@ public static void SetDefaultOptions(Action optionsDelegate) BitMEXRestOptions.Default = ApplyOptionsDelegate(optionsDelegate); } - /// - public void SetApiCredentials(ApiCredentials credentials) - { - ExchangeApi.SetApiCredentials(credentials); - } } } diff --git a/BitMEX.Net/Clients/BitMEXSocketClient.cs b/BitMEX.Net/Clients/BitMEXSocketClient.cs index 90e2edf..a03756f 100644 --- a/BitMEX.Net/Clients/BitMEXSocketClient.cs +++ b/BitMEX.Net/Clients/BitMEXSocketClient.cs @@ -12,7 +12,7 @@ namespace BitMEX.Net.Clients { /// - public class BitMEXSocketClient : BaseSocketClient, IBitMEXSocketClient + public class BitMEXSocketClient : BaseSocketClient, IBitMEXSocketClient { #region fields #endregion @@ -52,12 +52,6 @@ public BitMEXSocketClient(IOptions options, ILoggerFactory? } #endregion - /// - public void SetOptions(UpdateOptions options) - { - ExchangeApi.SetOptions(options); - } - /// /// Set the default options to be used when creating new clients /// @@ -66,13 +60,5 @@ public static void SetDefaultOptions(Action optionsDelegate { BitMEXSocketOptions.Default = ApplyOptionsDelegate(optionsDelegate); } - - /// - public void SetApiCredentials(ApiCredentials credentials) - { - - ExchangeApi.SetApiCredentials(credentials); - - } } } diff --git a/BitMEX.Net/Clients/BitMEXUserClientProvider.cs b/BitMEX.Net/Clients/BitMEXUserClientProvider.cs index 701bf8f..d5dec86 100644 --- a/BitMEX.Net/Clients/BitMEXUserClientProvider.cs +++ b/BitMEX.Net/Clients/BitMEXUserClientProvider.cs @@ -49,7 +49,7 @@ public BitMEXUserClientProvider( } /// - public void InitializeUserClient(string userIdentifier, ApiCredentials credentials, BitMEXEnvironment? environment = null) + public void InitializeUserClient(string userIdentifier, BitMEXCredentials credentials, BitMEXEnvironment? environment = null) { CreateRestClient(userIdentifier, credentials, environment); CreateSocketClient(userIdentifier, credentials, environment); @@ -63,7 +63,7 @@ public void ClearUserClients(string userIdentifier) } /// - public IBitMEXRestClient GetRestClient(string userIdentifier, ApiCredentials? credentials = null, BitMEXEnvironment? environment = null) + public IBitMEXRestClient GetRestClient(string userIdentifier, BitMEXCredentials? credentials = null, BitMEXEnvironment? environment = null) { if (!_restClients.TryGetValue(userIdentifier, out var client) || client.Disposed) client = CreateRestClient(userIdentifier, credentials, environment); @@ -72,7 +72,7 @@ public IBitMEXRestClient GetRestClient(string userIdentifier, ApiCredentials? cr } /// - public IBitMEXSocketClient GetSocketClient(string userIdentifier, ApiCredentials? credentials = null, BitMEXEnvironment? environment = null) + public IBitMEXSocketClient GetSocketClient(string userIdentifier, BitMEXCredentials? credentials = null, BitMEXEnvironment? environment = null) { if (!_socketClients.TryGetValue(userIdentifier, out var client) || client.Disposed) client = CreateSocketClient(userIdentifier, credentials, environment); @@ -80,7 +80,7 @@ public IBitMEXSocketClient GetSocketClient(string userIdentifier, ApiCredentials return client; } - private IBitMEXRestClient CreateRestClient(string userIdentifier, ApiCredentials? credentials, BitMEXEnvironment? environment) + private IBitMEXRestClient CreateRestClient(string userIdentifier, BitMEXCredentials? credentials, BitMEXEnvironment? environment) { var clientRestOptions = SetRestEnvironment(environment); var client = new BitMEXRestClient(_httpClient, _loggerFactory, clientRestOptions); @@ -92,7 +92,7 @@ private IBitMEXRestClient CreateRestClient(string userIdentifier, ApiCredentials return client; } - private IBitMEXSocketClient CreateSocketClient(string userIdentifier, ApiCredentials? credentials, BitMEXEnvironment? environment) + private IBitMEXSocketClient CreateSocketClient(string userIdentifier, BitMEXCredentials? credentials, BitMEXEnvironment? environment) { var clientSocketOptions = SetSocketEnvironment(environment); var client = new BitMEXSocketClient(clientSocketOptions!, _loggerFactory); diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApi.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApi.cs index d41b529..9c303a9 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApi.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApi.cs @@ -20,7 +20,7 @@ namespace BitMEX.Net.Clients.ExchangeApi { /// - internal partial class BitMEXRestClientExchangeApi : RestApiClient, IBitMEXRestClientExchangeApi + internal partial class BitMEXRestClientExchangeApi : RestApiClient, IBitMEXRestClientExchangeApi { #region fields public new BitMEXRestOptions ClientOptions => (BitMEXRestOptions)base.ClientOptions; @@ -57,7 +57,7 @@ internal BitMEXRestClientExchangeApi(ILogger logger, HttpClient? httpClient, Bit protected override IMessageSerializer CreateSerializer() => new SystemTextJsonMessageSerializer(SerializerOptions.WithConverters(BitMEXExchange._serializerContext)); /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) + protected override BitMEXAuthenticationProvider CreateAuthenticationProvider(BitMEXCredentials credentials) => new BitMEXAuthenticationProvider(credentials); internal Task SendAsync(RequestDefinition definition, ParameterCollection? parameters, CancellationToken cancellationToken, int? weight = null) diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApi.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApi.cs index fe3e5c2..d312420 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApi.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApi.cs @@ -33,7 +33,7 @@ namespace BitMEX.Net.Clients.ExchangeApi /// /// Client providing access to the BitMEX Exchange websocket Api /// - internal partial class BitMEXSocketClientExchangeApi : SocketApiClient, IBitMEXSocketClientExchangeApi + internal partial class BitMEXSocketClientExchangeApi : SocketApiClient, IBitMEXSocketClientExchangeApi { #region fields protected override ErrorMapping ErrorMapping => BitMEXErrors.SocketErrors; @@ -66,7 +66,7 @@ internal BitMEXSocketClientExchangeApi(ILogger logger, BitMEXSocketOptions optio public override ISocketMessageHandler CreateMessageConverter(WebSocketMessageType messageType) => new BitMexSocketExchangeMessageHandler(); /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) + protected override BitMEXAuthenticationProvider CreateAuthenticationProvider(BitMEXCredentials credentials) => new BitMEXAuthenticationProvider(credentials); /// @@ -544,7 +544,7 @@ public async Task> SubscribeToUserTradeUpdatesAsy var provider = (BitMEXAuthenticationProvider)AuthenticationProvider; var expires = DateTimeConverter.ConvertToSeconds(DateTime.UtcNow.AddSeconds(5)); - var queryParams = $"api-key={provider.ApiKey}&api-signature={provider.GetSignature("GET", "/realtime", expires.Value, "")}&api-expires={expires}"; + var queryParams = $"api-key={provider.PublicKey}&api-signature={provider.GetSignature("GET", "/realtime", expires.Value, "")}&api-expires={expires}"; return BaseAddress.AppendPath("realtime?" + queryParams); } diff --git a/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXRestClientExchangeApi.cs b/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXRestClientExchangeApi.cs index 2320476..0303b38 100644 --- a/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXRestClientExchangeApi.cs +++ b/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXRestClientExchangeApi.cs @@ -6,7 +6,7 @@ namespace BitMEX.Net.Interfaces.Clients.ExchangeApi /// /// BitMEX Exchange API endpoints /// - public interface IBitMEXRestClientExchangeApi : IRestApiClient, IDisposable + public interface IBitMEXRestClientExchangeApi : IRestApiClient, IDisposable { /// /// Endpoints related to account settings, info or actions diff --git a/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXSocketClientExchangeApi.cs b/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXSocketClientExchangeApi.cs index a8d0abc..f393881 100644 --- a/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXSocketClientExchangeApi.cs +++ b/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXSocketClientExchangeApi.cs @@ -13,7 +13,7 @@ namespace BitMEX.Net.Interfaces.Clients.ExchangeApi /// /// BitMEX Exchange streams /// - public interface IBitMEXSocketClientExchangeApi : ISocketApiClient, IDisposable + public interface IBitMEXSocketClientExchangeApi : ISocketApiClient, IDisposable { /// /// Subscribe to trade updates diff --git a/BitMEX.Net/Interfaces/Clients/IBitMEXRestClient.cs b/BitMEX.Net/Interfaces/Clients/IBitMEXRestClient.cs index 819ea08..abc4cc5 100644 --- a/BitMEX.Net/Interfaces/Clients/IBitMEXRestClient.cs +++ b/BitMEX.Net/Interfaces/Clients/IBitMEXRestClient.cs @@ -8,7 +8,7 @@ namespace BitMEX.Net.Interfaces.Clients /// /// Client for accessing the BitMEX Rest API. /// - public interface IBitMEXRestClient : IRestClient + public interface IBitMEXRestClient : IRestClient { /// @@ -17,16 +17,5 @@ public interface IBitMEXRestClient : IRestClient /// public IBitMEXRestClientExchangeApi ExchangeApi { get; } - /// - /// Update specific options - /// - /// Options to update. Only specific options are changeable after the client has been created - void SetOptions(UpdateOptions options); - - /// - /// Set the API credentials for this client. All Api clients in this client will use the new credentials, regardless of earlier set options. - /// - /// The credentials to set - void SetApiCredentials(ApiCredentials credentials); } } diff --git a/BitMEX.Net/Interfaces/Clients/IBitMEXSocketClient.cs b/BitMEX.Net/Interfaces/Clients/IBitMEXSocketClient.cs index 8081794..44416aa 100644 --- a/BitMEX.Net/Interfaces/Clients/IBitMEXSocketClient.cs +++ b/BitMEX.Net/Interfaces/Clients/IBitMEXSocketClient.cs @@ -8,25 +8,12 @@ namespace BitMEX.Net.Interfaces.Clients /// /// Client for accessing the BitMEX websocket API /// - public interface IBitMEXSocketClient : ISocketClient + public interface IBitMEXSocketClient : ISocketClient { - /// /// Exchange API endpoints /// /// public IBitMEXSocketClientExchangeApi ExchangeApi { get; } - - /// - /// Update specific options - /// - /// Options to update. Only specific options are changeable after the client has been created - void SetOptions(UpdateOptions options); - - /// - /// Set the API credentials for this client. All Api clients in this client will use the new credentials, regardless of earlier set options. - /// - /// The credentials to set - void SetApiCredentials(ApiCredentials credentials); } } diff --git a/BitMEX.Net/Interfaces/Clients/IBitMEXUserClientProvider.cs b/BitMEX.Net/Interfaces/Clients/IBitMEXUserClientProvider.cs index 2225049..12253a5 100644 --- a/BitMEX.Net/Interfaces/Clients/IBitMEXUserClientProvider.cs +++ b/BitMEX.Net/Interfaces/Clients/IBitMEXUserClientProvider.cs @@ -14,7 +14,7 @@ public interface IBitMEXUserClientProvider : IExchangeService /// The identifier for the user /// The credentials for the user /// The environment to use - void InitializeUserClient(string userIdentifier, ApiCredentials credentials, BitMEXEnvironment? environment = null); + void InitializeUserClient(string userIdentifier, BitMEXCredentials credentials, BitMEXEnvironment? environment = null); /// /// Reset the cached clients for a user. This can be useful when a user changes API credentials. @@ -27,7 +27,7 @@ public interface IBitMEXUserClientProvider : IExchangeService /// The identifier for user /// The credentials for the user. Required the first time a client is requested for this user unless has been called prior for this user. /// The environment to use - IBitMEXRestClient GetRestClient(string userIdentifier, ApiCredentials? credentials = null, BitMEXEnvironment? environment = null); + IBitMEXRestClient GetRestClient(string userIdentifier, BitMEXCredentials? credentials = null, BitMEXEnvironment? environment = null); /// /// Get the Socket client for a specific user. In case the client does not exist yet it will be created and the should be provided, unless has been called prior for this user. @@ -35,6 +35,6 @@ public interface IBitMEXUserClientProvider : IExchangeService /// The identifier for user /// The credentials for the user. Required the first time a client is requested for this user unless has been called prior for this user. /// The environment to use - IBitMEXSocketClient GetSocketClient(string userIdentifier, ApiCredentials? credentials = null, BitMEXEnvironment? environment = null); + IBitMEXSocketClient GetSocketClient(string userIdentifier, BitMEXCredentials? credentials = null, BitMEXEnvironment? environment = null); } } \ No newline at end of file diff --git a/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs b/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs index 0a15911..7bf8ed0 100644 --- a/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs +++ b/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs @@ -18,7 +18,7 @@ public interface IBitMEXTrackerFactory : ITrackerFactory /// Configuration /// Credentials /// Environment - IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, ApiCredentials credentials, SpotUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null); + IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, BitMEXCredentials credentials, SpotUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null); /// /// Create a new spot user data tracker /// @@ -32,7 +32,7 @@ public interface IBitMEXTrackerFactory : ITrackerFactory /// Configuration /// Credentials /// Environment - IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, ApiCredentials credentials, FuturesUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null); + IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, BitMEXCredentials credentials, FuturesUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null); /// /// Create a new futures user data tracker /// diff --git a/BitMEX.Net/Objects/Options/BitMEXOptions.cs b/BitMEX.Net/Objects/Options/BitMEXOptions.cs index 48b3bad..5cd7275 100644 --- a/BitMEX.Net/Objects/Options/BitMEXOptions.cs +++ b/BitMEX.Net/Objects/Options/BitMEXOptions.cs @@ -6,7 +6,7 @@ namespace BitMEX.Net.Objects.Options /// /// BitMEX options /// - public class BitMEXOptions : LibraryOptions + public class BitMEXOptions : LibraryOptions { } } diff --git a/BitMEX.Net/Objects/Options/BitMEXRestOptions.cs b/BitMEX.Net/Objects/Options/BitMEXRestOptions.cs index b17561c..c7e8b1d 100644 --- a/BitMEX.Net/Objects/Options/BitMEXRestOptions.cs +++ b/BitMEX.Net/Objects/Options/BitMEXRestOptions.cs @@ -5,7 +5,7 @@ namespace BitMEX.Net.Objects.Options /// /// Options for the BitMEXRestClient /// - public class BitMEXRestOptions : RestExchangeOptions + public class BitMEXRestOptions : RestExchangeOptions { /// /// Default options for new clients @@ -32,15 +32,12 @@ public BitMEXRestOptions() /// /// Exchange API options /// - public RestApiOptions ExchangeOptions { get; private set; } = new RestApiOptions(); - + public RestApiOptions ExchangeOptions { get; private set; } = new RestApiOptions(); internal BitMEXRestOptions Set(BitMEXRestOptions targetOptions) { - targetOptions = base.Set(targetOptions); - + targetOptions = base.Set(targetOptions); targetOptions.ExchangeOptions = ExchangeOptions.Set(targetOptions.ExchangeOptions); - return targetOptions; } } diff --git a/BitMEX.Net/Objects/Options/BitMEXSocketOptions.cs b/BitMEX.Net/Objects/Options/BitMEXSocketOptions.cs index 2e1f4ae..0928b25 100644 --- a/BitMEX.Net/Objects/Options/BitMEXSocketOptions.cs +++ b/BitMEX.Net/Objects/Options/BitMEXSocketOptions.cs @@ -5,7 +5,7 @@ namespace BitMEX.Net.Objects.Options /// /// Options for the BitMEXSocketClient /// - public class BitMEXSocketOptions : SocketExchangeOptions + public class BitMEXSocketOptions : SocketExchangeOptions { /// /// Default options for new clients @@ -16,7 +16,6 @@ public class BitMEXSocketOptions : SocketExchangeOptions SocketSubscriptionsCombineTarget = 10 }; - /// /// ctor /// @@ -24,21 +23,16 @@ public BitMEXSocketOptions() { Default?.Set(this); } - - - /// + /// /// Exchange API options /// - public SocketApiOptions ExchangeOptions { get; private set; } = new SocketApiOptions(); - + public SocketApiOptions ExchangeOptions { get; private set; } = new SocketApiOptions(); internal BitMEXSocketOptions Set(BitMEXSocketOptions targetOptions) { - targetOptions = base.Set(targetOptions); - + targetOptions = base.Set(targetOptions); targetOptions.ExchangeOptions = ExchangeOptions.Set(targetOptions.ExchangeOptions); - return targetOptions; } } From 46c65886a316922e72b86b12986fa1601560b22e Mon Sep 17 00:00:00 2001 From: JKorf Date: Sun, 15 Mar 2026 21:48:20 +0100 Subject: [PATCH 02/10] wip --- BitMEX.Net/BitMEXAuthenticationProvider.cs | 2 +- BitMEX.Net/BitMEXCredentials.cs | 16 ++++++++++++---- .../ExchangeApi/BitMEXSocketClientExchangeApi.cs | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/BitMEX.Net/BitMEXAuthenticationProvider.cs b/BitMEX.Net/BitMEXAuthenticationProvider.cs index 685c0be..a2123d5 100644 --- a/BitMEX.Net/BitMEXAuthenticationProvider.cs +++ b/BitMEX.Net/BitMEXAuthenticationProvider.cs @@ -26,7 +26,7 @@ public override void ProcessRequest(RestApiClient apiClient, RestRequestConfigur var expires = DateTimeConverter.ConvertToSeconds(timestamp.AddSeconds(5))!; request.Headers ??= new Dictionary(); request.Headers.Add("api-expires", expires.Value.ToString()); - request.Headers.Add("api-key", Credential.PublicKey); + request.Headers.Add("api-key", Credential.Key); var body = (request.BodyParameters == null || request.BodyParameters.Count == 0) ? "" : GetSerializedBody(_serializer, request.BodyParameters); var queryParams = request.GetQueryString(true); diff --git a/BitMEX.Net/BitMEXCredentials.cs b/BitMEX.Net/BitMEXCredentials.cs index cd002ac..54b140f 100644 --- a/BitMEX.Net/BitMEXCredentials.cs +++ b/BitMEX.Net/BitMEXCredentials.cs @@ -1,4 +1,5 @@ using CryptoExchange.Net.Authentication; +using System; namespace BitMEX.Net { @@ -8,19 +9,26 @@ namespace BitMEX.Net public class BitMEXCredentials : ApiCredentials { /// - /// ctor + /// + [Obsolete("Parameterless constructor is only for deserialization purposes and should not be used directly. Use parameterized constructor instead.")] + public BitMEXCredentials() { } + + /// + /// Create credentials using an HMAC key and secret /// /// The API key /// The API secret public BitMEXCredentials(string apiKey, string secret) : this(new HMACCredential(apiKey, secret)) { } - + /// - /// ctor + /// Create credentials using HMAC credentials /// /// The HMAC credentials public BitMEXCredentials(HMACCredential credential) : base(credential) { } /// - public override ApiCredentials Copy() => new BitMEXCredentials(Hmac!); +#pragma warning disable CS0618 // Type or member is obsolete + public override ApiCredentials Copy() => new BitMEXCredentials { CredentialPairs = CredentialPairs }; +#pragma warning restore CS0618 // Type or member is obsolete } } diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApi.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApi.cs index d312420..3316110 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApi.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApi.cs @@ -544,7 +544,7 @@ public async Task> SubscribeToUserTradeUpdatesAsy var provider = (BitMEXAuthenticationProvider)AuthenticationProvider; var expires = DateTimeConverter.ConvertToSeconds(DateTime.UtcNow.AddSeconds(5)); - var queryParams = $"api-key={provider.PublicKey}&api-signature={provider.GetSignature("GET", "/realtime", expires.Value, "")}&api-expires={expires}"; + var queryParams = $"api-key={provider.Key}&api-signature={provider.GetSignature("GET", "/realtime", expires.Value, "")}&api-expires={expires}"; return BaseAddress.AppendPath("realtime?" + queryParams); } From 107916a6f036a4638b8645c74cdb0c399e09bfad Mon Sep 17 00:00:00 2001 From: Jkorf Date: Mon, 16 Mar 2026 13:57:39 +0100 Subject: [PATCH 03/10] wip --- BitMEX.Net/BitMEX.Net.csproj | 1 + .../ServiceCollectionExtensions.cs | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/BitMEX.Net/BitMEX.Net.csproj b/BitMEX.Net/BitMEX.Net.csproj index f2d0675..2597b28 100644 --- a/BitMEX.Net/BitMEX.Net.csproj +++ b/BitMEX.Net/BitMEX.Net.csproj @@ -23,6 +23,7 @@ true true https://github.com/JKorf/BitMEX.Net?tab=readme-ov-file#release-notes + $(NoWarn);SYSLIB1100;SYSLIB1101 true diff --git a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 587a3bb..831ed15 100644 --- a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -37,11 +37,23 @@ public static IServiceCollection AddBitMEX( // Reset environment so we know if they're overridden options.Rest.Environment = null!; options.Socket.Environment = null!; - configuration.Bind(options); + + try + { + configuration.Bind(options); + } + catch (InvalidOperationException ex) + { + throw new InvalidOperationException("Invalid configuration provided", ex); + } if (options.Rest == null || options.Socket == null) throw new ArgumentException("Options null"); + LibraryHelpers.ValidateCredentials(options.ApiCredentials); + LibraryHelpers.ValidateCredentials(options.Rest.ApiCredentials); + LibraryHelpers.ValidateCredentials(options.Socket.ApiCredentials); + var restEnvName = options.Rest.Environment?.Name ?? options.Environment?.Name ?? BitMEXEnvironment.Live.Name; var socketEnvName = options.Socket.Environment?.Name ?? options.Environment?.Name ?? BitMEXEnvironment.Live.Name; options.Rest.Environment = BitMEXEnvironment.GetEnvironmentByName(restEnvName) ?? options.Rest.Environment!; From ceaa6adb25eb29d66fde57e3249e1bc95a4f7ac8 Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 16 Mar 2026 22:01:35 +0100 Subject: [PATCH 04/10] wip --- BitMEX.Net/BitMEXAuthenticationProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BitMEX.Net/BitMEXAuthenticationProvider.cs b/BitMEX.Net/BitMEXAuthenticationProvider.cs index a2123d5..8b8d85e 100644 --- a/BitMEX.Net/BitMEXAuthenticationProvider.cs +++ b/BitMEX.Net/BitMEXAuthenticationProvider.cs @@ -11,7 +11,7 @@ internal class BitMEXAuthenticationProvider : AuthenticationProvider [ApiCredentialsType.Hmac]; + public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.HMAC]; public BitMEXAuthenticationProvider(BitMEXCredentials credentials) : base(credentials) { } From 39d4134e878ec606a553ee40425158930cc62f03 Mon Sep 17 00:00:00 2001 From: Jkorf Date: Tue, 17 Mar 2026 09:57:47 +0100 Subject: [PATCH 05/10] wip --- .../BitMEXRestClientExchangeApiShared.cs | 26 +++++++++++++++---- .../BitMEXSocketClientExchangeApiShared.cs | 4 ++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs index 3254601..c22a684 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs @@ -194,7 +194,7 @@ async Task> IDepositRestClient.GetDepositsAsy x.Quantity.ToSharedAssetQuantity(x.Currency), x.TransactionStatus == TransactionStatus.Completed, x.TransactionTime, - x.TransactionStatus == TransactionStatus.Completed ? SharedTransferStatus.Completed : SharedTransferStatus.Failed) + ParseTransferStatus(x.TransactionStatus)) { Network = x.Network, TransactionId = x.Transaction, @@ -204,6 +204,17 @@ async Task> IDepositRestClient.GetDepositsAsy .ToArray(), nextPageRequest); } + private SharedTransferStatus ParseTransferStatus(TransactionStatus status) + { + if (status == TransactionStatus.Completed) + return SharedTransferStatus.Completed; + + if (status == TransactionStatus.Canceled) + return SharedTransferStatus.Failed; + + return SharedTransferStatus.Unknown; + } + #endregion #region Fee Client @@ -993,9 +1004,11 @@ async Task> ISpotOrderRestClient.CancelSpotOrderAsyn private SharedOrderStatus ParseOrderStatus(OrderStatus status) { - if (status == OrderStatus.New) return SharedOrderStatus.Open; - if (status == OrderStatus.Canceled || status == OrderStatus.Rejected) return SharedOrderStatus.Canceled; - return SharedOrderStatus.Filled; + if (status == OrderStatus.New || status == OrderStatus.PartiallyFilled) return SharedOrderStatus.Open; + if (status == OrderStatus.Rejected || status == OrderStatus.Canceled) return SharedOrderStatus.Canceled; + if (status == OrderStatus.Filled) return SharedOrderStatus.Filled; + + return SharedOrderStatus.Unknown; } private SharedOrderType ParseOrderType(OrderType type, ExecutionInstruction[]? executionInstruction) @@ -2016,7 +2029,10 @@ private SharedTriggerOrderStatus ParseTriggerOrderStatus(OrderStatus status) if (status == OrderStatus.Canceled || status == OrderStatus.Rejected) return SharedTriggerOrderStatus.CanceledOrRejected; - return SharedTriggerOrderStatus.Active; + if (status == OrderStatus.New || status == OrderStatus.PartiallyFilled) + return SharedTriggerOrderStatus.Active; + + return SharedTriggerOrderStatus.Unknown; } EndpointOptions ISpotTriggerOrderRestClient.CancelSpotTriggerOrderOptions { get; } = new EndpointOptions(true); diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApiShared.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApiShared.cs index 80b5406..b918439 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApiShared.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApiShared.cs @@ -87,7 +87,9 @@ private SharedOrderStatus ParseOrderStatus(OrderStatus status) { if (status == OrderStatus.New || status == OrderStatus.PartiallyFilled) return SharedOrderStatus.Open; if (status == OrderStatus.Rejected || status == OrderStatus.Canceled) return SharedOrderStatus.Canceled; - return SharedOrderStatus.Filled; + if (status == OrderStatus.Filled) return SharedOrderStatus.Filled; + + return SharedOrderStatus.Unknown; } private SharedOrderType ParseOrderType(OrderType orderType, ExecutionInstruction[]? executionInstruction) From 090354e994d0a26fc83f2e96a0d0534a01d5f07a Mon Sep 17 00:00:00 2001 From: Jkorf Date: Wed, 18 Mar 2026 16:16:07 +0100 Subject: [PATCH 06/10] wip --- .../BitMEXRestIntegrationTests.cs | 1 + .../BitMEXSocketIntegrationTests.cs | 1 + BitMEX.Net.UnitTests/RestRequestTests.cs | 1 + .../SocketSubscriptionTests.cs | 1 + BitMEX.Net/BitMEXAuthenticationProvider.cs | 5 ++- BitMEX.Net/BitMEXCredentials.cs | 31 +++++-------------- .../ServiceCollectionExtensions.cs | 3 +- .../IBitMEXRestClientExchangeApi.cs | 1 + .../IBitMEXSocketClientExchangeApi.cs | 1 + .../Objects/Options/BitMEXRestOptions.cs | 3 +- .../Objects/Options/BitMEXSocketOptions.cs | 3 +- 11 files changed, 22 insertions(+), 29 deletions(-) diff --git a/BitMEX.Net.UnitTests/BitMEXRestIntegrationTests.cs b/BitMEX.Net.UnitTests/BitMEXRestIntegrationTests.cs index 86fe144..d1525f7 100644 --- a/BitMEX.Net.UnitTests/BitMEXRestIntegrationTests.cs +++ b/BitMEX.Net.UnitTests/BitMEXRestIntegrationTests.cs @@ -8,6 +8,7 @@ using BitMEX.Net.Objects.Options; using System.Threading; using BitMEX.Net.SymbolOrderBooks; +using CryptoExchange.Net.Authentication; namespace BitMEX.Net.UnitTests { diff --git a/BitMEX.Net.UnitTests/BitMEXSocketIntegrationTests.cs b/BitMEX.Net.UnitTests/BitMEXSocketIntegrationTests.cs index 1afcd4f..23817ab 100644 --- a/BitMEX.Net.UnitTests/BitMEXSocketIntegrationTests.cs +++ b/BitMEX.Net.UnitTests/BitMEXSocketIntegrationTests.cs @@ -1,6 +1,7 @@ using BitMEX.Net.Clients; using BitMEX.Net.Objects.Models; using BitMEX.Net.Objects.Options; +using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Testing; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/BitMEX.Net.UnitTests/RestRequestTests.cs b/BitMEX.Net.UnitTests/RestRequestTests.cs index c05aa97..54bf1c8 100644 --- a/BitMEX.Net.UnitTests/RestRequestTests.cs +++ b/BitMEX.Net.UnitTests/RestRequestTests.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using BitMEX.Net.Clients; using System.Linq; +using CryptoExchange.Net.Authentication; namespace BitMEX.Net.UnitTests { diff --git a/BitMEX.Net.UnitTests/SocketSubscriptionTests.cs b/BitMEX.Net.UnitTests/SocketSubscriptionTests.cs index 8275306..363fd84 100644 --- a/BitMEX.Net.UnitTests/SocketSubscriptionTests.cs +++ b/BitMEX.Net.UnitTests/SocketSubscriptionTests.cs @@ -1,6 +1,7 @@ using BitMEX.Net.Clients; using BitMEX.Net.Objects.Models; using BitMEX.Net.Objects.Options; +using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Objects; using CryptoExchange.Net.Testing; using Microsoft.Extensions.Logging; diff --git a/BitMEX.Net/BitMEXAuthenticationProvider.cs b/BitMEX.Net/BitMEXAuthenticationProvider.cs index 8b8d85e..17d43a1 100644 --- a/BitMEX.Net/BitMEXAuthenticationProvider.cs +++ b/BitMEX.Net/BitMEXAuthenticationProvider.cs @@ -7,12 +7,11 @@ namespace BitMEX.Net { - internal class BitMEXAuthenticationProvider : AuthenticationProvider + internal class BitMEXAuthenticationProvider : AuthenticationProvider { private static readonly IMessageSerializer _serializer = new SystemTextJsonMessageSerializer(SerializerOptions.WithConverters(BitMEXExchange._serializerContext)); - public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.HMAC]; - public BitMEXAuthenticationProvider(BitMEXCredentials credentials) : base(credentials) + public BitMEXAuthenticationProvider(BitMEXCredentials credentials) : base(credentials, credentials) { } diff --git a/BitMEX.Net/BitMEXCredentials.cs b/BitMEX.Net/BitMEXCredentials.cs index 54b140f..37fe4fa 100644 --- a/BitMEX.Net/BitMEXCredentials.cs +++ b/BitMEX.Net/BitMEXCredentials.cs @@ -1,34 +1,19 @@ using CryptoExchange.Net.Authentication; -using System; namespace BitMEX.Net { /// - /// BitMEX credentials + /// BitMEX API credentials /// - public class BitMEXCredentials : ApiCredentials + public class BitMEXCredentials : HMACCredential { /// + /// Create new credentials providing only credentials in HMAC format /// - [Obsolete("Parameterless constructor is only for deserialization purposes and should not be used directly. Use parameterized constructor instead.")] - public BitMEXCredentials() { } - - /// - /// Create credentials using an HMAC key and secret - /// - /// The API key - /// The API secret - public BitMEXCredentials(string apiKey, string secret) : this(new HMACCredential(apiKey, secret)) { } - - /// - /// Create credentials using HMAC credentials - /// - /// The HMAC credentials - public BitMEXCredentials(HMACCredential credential) : base(credential) { } - - /// -#pragma warning disable CS0618 // Type or member is obsolete - public override ApiCredentials Copy() => new BitMEXCredentials { CredentialPairs = CredentialPairs }; -#pragma warning restore CS0618 // Type or member is obsolete + /// API key + /// API secret + public BitMEXCredentials(string key, string secret) : base(key, secret) + { + } } } diff --git a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 831ed15..6b7d949 100644 --- a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -24,7 +24,8 @@ public static class ServiceCollectionExtensions { /// - /// Add services such as the IBitMEXRestClient and IBitMEXSocketClient. Configures the services based on the provided configuration. + /// Add services such as the IBitMEXRestClient and IBitMEXSocketClient. Configures the services based on the provided configuration.
+ /// See for an example of how to set up the configuration. ///
/// The service collection /// The configuration(section) containing the options diff --git a/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXRestClientExchangeApi.cs b/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXRestClientExchangeApi.cs index 0303b38..0197a23 100644 --- a/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXRestClientExchangeApi.cs +++ b/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXRestClientExchangeApi.cs @@ -1,3 +1,4 @@ +using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Interfaces.Clients; using System; diff --git a/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXSocketClientExchangeApi.cs b/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXSocketClientExchangeApi.cs index f393881..9c8d3b0 100644 --- a/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXSocketClientExchangeApi.cs +++ b/BitMEX.Net/Interfaces/Clients/ExchangeApi/IBitMEXSocketClientExchangeApi.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using BitMEX.Net.Enums; using CryptoExchange.Net.Interfaces.Clients; +using CryptoExchange.Net.Authentication; namespace BitMEX.Net.Interfaces.Clients.ExchangeApi { diff --git a/BitMEX.Net/Objects/Options/BitMEXRestOptions.cs b/BitMEX.Net/Objects/Options/BitMEXRestOptions.cs index c7e8b1d..7f0d368 100644 --- a/BitMEX.Net/Objects/Options/BitMEXRestOptions.cs +++ b/BitMEX.Net/Objects/Options/BitMEXRestOptions.cs @@ -1,3 +1,4 @@ +using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Objects.Options; namespace BitMEX.Net.Objects.Options @@ -32,7 +33,7 @@ public BitMEXRestOptions() /// /// Exchange API options /// - public RestApiOptions ExchangeOptions { get; private set; } = new RestApiOptions(); + public RestApiOptions ExchangeOptions { get; private set; } = new RestApiOptions(); internal BitMEXRestOptions Set(BitMEXRestOptions targetOptions) { diff --git a/BitMEX.Net/Objects/Options/BitMEXSocketOptions.cs b/BitMEX.Net/Objects/Options/BitMEXSocketOptions.cs index 0928b25..9b6c23b 100644 --- a/BitMEX.Net/Objects/Options/BitMEXSocketOptions.cs +++ b/BitMEX.Net/Objects/Options/BitMEXSocketOptions.cs @@ -1,3 +1,4 @@ +using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Objects.Options; namespace BitMEX.Net.Objects.Options @@ -27,7 +28,7 @@ public BitMEXSocketOptions() /// /// Exchange API options /// - public SocketApiOptions ExchangeOptions { get; private set; } = new SocketApiOptions(); + public SocketApiOptions ExchangeOptions { get; private set; } = new SocketApiOptions(); internal BitMEXSocketOptions Set(BitMEXSocketOptions targetOptions) { From 6253754fc332d2c4c2e8e6397aa32d676f1188e9 Mon Sep 17 00:00:00 2001 From: Jkorf Date: Thu, 19 Mar 2026 16:35:16 +0100 Subject: [PATCH 07/10] wip --- BitMEX.Net/BitMEXCredentials.cs | 30 ++++++++++++++++++- .../ServiceCollectionExtensions.cs | 4 --- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/BitMEX.Net/BitMEXCredentials.cs b/BitMEX.Net/BitMEXCredentials.cs index 37fe4fa..802e7e9 100644 --- a/BitMEX.Net/BitMEXCredentials.cs +++ b/BitMEX.Net/BitMEXCredentials.cs @@ -1,4 +1,5 @@ using CryptoExchange.Net.Authentication; +using System; namespace BitMEX.Net { @@ -8,12 +9,39 @@ namespace BitMEX.Net public class BitMEXCredentials : HMACCredential { /// - /// Create new credentials providing only credentials in HMAC format + /// Create new credentials + /// + public BitMEXCredentials() { } + + /// + /// Create new credentials providing credentials in HMAC format /// /// API key /// API secret public BitMEXCredentials(string key, string secret) : base(key, secret) { } + + /// + /// Create new credentials providing HMAC credentials + /// + /// HMAC Credentials + public BitMEXCredentials(HMACCredential credential) : base(credential.Key, credential.Secret) + { + } + + /// + /// Specify the HMAC credentials + /// + /// API key + /// API secret + public BitMEXCredentials WithHMAC(string key, string secret) + { + if (!string.IsNullOrEmpty(Key)) throw new InvalidOperationException("Credentials already set"); + + Key = key; + Secret = secret; + return this; + } } } diff --git a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 6b7d949..e47f12f 100644 --- a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -51,10 +51,6 @@ public static IServiceCollection AddBitMEX( if (options.Rest == null || options.Socket == null) throw new ArgumentException("Options null"); - LibraryHelpers.ValidateCredentials(options.ApiCredentials); - LibraryHelpers.ValidateCredentials(options.Rest.ApiCredentials); - LibraryHelpers.ValidateCredentials(options.Socket.ApiCredentials); - var restEnvName = options.Rest.Environment?.Name ?? options.Environment?.Name ?? BitMEXEnvironment.Live.Name; var socketEnvName = options.Socket.Environment?.Name ?? options.Environment?.Name ?? BitMEXEnvironment.Live.Name; options.Rest.Environment = BitMEXEnvironment.GetEnvironmentByName(restEnvName) ?? options.Rest.Environment!; From 0829ab00937ab92648e18a55e752efa22a03294f Mon Sep 17 00:00:00 2001 From: Jkorf Date: Fri, 20 Mar 2026 13:57:07 +0100 Subject: [PATCH 08/10] wip --- .../ServiceCollectionExtensions.cs | 2 +- Examples/example-config.json | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 Examples/example-config.json diff --git a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs index e47f12f..30b5e7f 100644 --- a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -25,7 +25,7 @@ public static class ServiceCollectionExtensions /// /// Add services such as the IBitMEXRestClient and IBitMEXSocketClient. Configures the services based on the provided configuration.
- /// See for an example of how to set up the configuration. + /// See for an example of how to set up the configuration. ///
/// The service collection /// The configuration(section) containing the options diff --git a/Examples/example-config.json b/Examples/example-config.json new file mode 100644 index 0000000..23f7ce3 --- /dev/null +++ b/Examples/example-config.json @@ -0,0 +1,31 @@ +{ + // Options section, select this section during DI registration using Configuration.GetSection("BitMEX") + "BitMEX": { + // API credentials for both REST and Websocket client + "ApiCredentials": { + "Key": "APIKEY", + "Secret": "APISECRET" + }, + // Set the environment by name + "Environment": { + "name": "live" + }, + // REST client options + "Rest": { + "RequestTimeout": "00:00:20", + "CachingEnabled": true, + "OutputOriginalData": true, + "Proxy": { + "Host": "https://127.0.0.1", + "Port": 8080, + "Login": "User", + "Password": "Pass" + } + }, + // Socket client options + "Socket": { + "RequestTimeout": "00:00:05", + "SocketSubscriptionsCombineTarget": 15 + } + } +} \ No newline at end of file From f5e6166e845d08b3a2afb5f2f8f11097debe8e19 Mon Sep 17 00:00:00 2001 From: JKorf Date: Sun, 22 Mar 2026 22:03:53 +0100 Subject: [PATCH 09/10] wip --- .../CryptoClientExtensions.cs | 26 ------------------- .../ServiceCollectionExtensions.cs | 2 -- 2 files changed, 28 deletions(-) delete mode 100644 BitMEX.Net/ExtensionMethods/CryptoClientExtensions.cs diff --git a/BitMEX.Net/ExtensionMethods/CryptoClientExtensions.cs b/BitMEX.Net/ExtensionMethods/CryptoClientExtensions.cs deleted file mode 100644 index f79a2a2..0000000 --- a/BitMEX.Net/ExtensionMethods/CryptoClientExtensions.cs +++ /dev/null @@ -1,26 +0,0 @@ -using BitMEX.Net.Clients; -using BitMEX.Net.Interfaces.Clients; -using CryptoExchange.Net.Interfaces.Clients; - -namespace CryptoExchange.Net.Interfaces -{ - /// - /// Extensions for the ICryptoRestClient and ICryptoSocketClient interfaces - /// - public static class CryptoClientExtensions - { - /// - /// Get the BitMEX REST Api client - /// - /// - /// - public static IBitMEXRestClient BitMEX(this ICryptoRestClient baseClient) => baseClient.TryGet(() => new BitMEXRestClient()); - - /// - /// Get the BitMEX Websocket Api client - /// - /// - /// - public static IBitMEXSocketClient BitMEX(this ICryptoSocketClient baseClient) => baseClient.TryGet(() => new BitMEXSocketClient()); - } -} diff --git a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 30b5e7f..03ce97d 100644 --- a/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/BitMEX.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -109,8 +109,6 @@ private static IServiceCollection AddBitMEXCore( }).SetHandlerLifetime(Timeout.InfiniteTimeSpan); services.Add(new ServiceDescriptor(typeof(IBitMEXSocketClient), x => { return new BitMEXSocketClient(x.GetRequiredService>(), x.GetRequiredService()); }, socketClientLifeTime ?? ServiceLifetime.Singleton)); - services.AddTransient(); - services.AddSingleton(); services.AddTransient(); services.AddTransient(); services.AddTransient(); From 0efcfe7609a2fc56b116c044483559ba362d533e Mon Sep 17 00:00:00 2001 From: Jkorf Date: Mon, 23 Mar 2026 15:00:48 +0100 Subject: [PATCH 10/10] wip --- BitMEX.Net/BitMEX.Net.csproj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/BitMEX.Net/BitMEX.Net.csproj b/BitMEX.Net/BitMEX.Net.csproj index 2597b28..f61aebb 100644 --- a/BitMEX.Net/BitMEX.Net.csproj +++ b/BitMEX.Net/BitMEX.Net.csproj @@ -53,12 +53,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - \ No newline at end of file