diff --git a/OKX.Net.UnitTests/OKXRestIntegrationTests.cs b/OKX.Net.UnitTests/OKXRestIntegrationTests.cs index 86e3373..8da16d0 100644 --- a/OKX.Net.UnitTests/OKXRestIntegrationTests.cs +++ b/OKX.Net.UnitTests/OKXRestIntegrationTests.cs @@ -9,6 +9,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using OKX.Net.Objects.Options; namespace OKX.Net.UnitTests { @@ -28,11 +30,11 @@ public override OKXRestClient GetClient(ILoggerFactory loggerFactory) var pass = Environment.GetEnvironmentVariable("APIPASS"); Authenticated = key != null && sec != null; - return new OKXRestClient(null, loggerFactory, opts => + return new OKXRestClient(null, loggerFactory, Options.Create(new OKXRestOptions { - opts.OutputOriginalData = true; - opts.ApiCredentials = Authenticated ? new OKXApiCredentials(key, sec, pass) : null; - }); + OutputOriginalData = true, + ApiCredentials = Authenticated ? new OKXApiCredentials(key, sec, pass) : null + })); } [Test] diff --git a/OKX.Net.UnitTests/OXKRestClientTests.cs b/OKX.Net.UnitTests/OXKRestClientTests.cs index ab68930..79ed4a1 100644 --- a/OKX.Net.UnitTests/OXKRestClientTests.cs +++ b/OKX.Net.UnitTests/OXKRestClientTests.cs @@ -5,6 +5,10 @@ using CryptoExchange.Net.Clients; using OKX.Net.Objects; using System.Text.Json; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using CryptoExchange.Net.Objects; +using OKX.Net.Interfaces.Clients; namespace OKX.Net.UnitTests { @@ -101,5 +105,107 @@ public void CheckInterfaces() CryptoExchange.Net.Testing.TestHelpers.CheckForMissingRestInterfaces(); CryptoExchange.Net.Testing.TestHelpers.CheckForMissingSocketInterfaces(); } + + + [Test] + [TestCase(TradeEnvironmentNames.Live, "https://www.okx.com")] + [TestCase(TradeEnvironmentNames.Testnet, "https://www.okx.com")] + [TestCase("", "https://www.okx.com")] + public void TestConstructorEnvironments(string environmentName, string expected) + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + { "OKX:Environment:Name", environmentName }, + }).Build(); + + var collection = new ServiceCollection(); + collection.AddOKX(configuration.GetSection("OKX")); + var provider = collection.BuildServiceProvider(); + + var client = provider.GetRequiredService(); + + var address = client.UnifiedApi.BaseAddress; + + Assert.That(address, Is.EqualTo(expected)); + } + + [Test] + public void TestConstructorNullEnvironment() + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + { "OKX", null }, + }).Build(); + + var collection = new ServiceCollection(); + collection.AddOKX(configuration.GetSection("OKX")); + var provider = collection.BuildServiceProvider(); + + var client = provider.GetRequiredService(); + + var address = client.UnifiedApi.BaseAddress; + + Assert.That(address, Is.EqualTo("https://www.okx.com")); + } + + [Test] + public void TestConstructorApiOverwriteEnvironment() + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + { "OKX:Environment:Name", "test" }, + { "OKX:Rest:Environment:Name", "live" }, + }).Build(); + + var collection = new ServiceCollection(); + collection.AddOKX(configuration.GetSection("OKX")); + var provider = collection.BuildServiceProvider(); + + var client = provider.GetRequiredService(); + + var address = client.UnifiedApi.BaseAddress; + + Assert.That(address, Is.EqualTo("https://www.okx.com")); + } + + [Test] + public void TestConstructorConfiguration() + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + { "ApiCredentials:Key", "123" }, + { "ApiCredentials:Secret", "456" }, + { "ApiCredentials:PassPhrase", "222" }, + { "Socket:ApiCredentials:Key", "456" }, + { "Socket:ApiCredentials:Secret", "789" }, + { "Socket:ApiCredentials:PassPhrase", "111" }, + { "Rest:OutputOriginalData", "true" }, + { "Socket:OutputOriginalData", "false" }, + { "Rest:Proxy:Host", "host" }, + { "Rest:Proxy:Port", "80" }, + { "Socket:Proxy:Host", "host2" }, + { "Socket:Proxy:Port", "81" }, + }).Build(); + + var collection = new ServiceCollection(); + collection.AddOKX(configuration); + var provider = collection.BuildServiceProvider(); + + var restClient = provider.GetRequiredService(); + var socketClient = provider.GetRequiredService(); + + Assert.That(((BaseApiClient)restClient.UnifiedApi).OutputOriginalData, Is.True); + Assert.That(((BaseApiClient)socketClient.UnifiedApi).OutputOriginalData, Is.False); + Assert.That(((BaseApiClient)restClient.UnifiedApi).AuthenticationProvider.ApiKey, Is.EqualTo("123")); + Assert.That(((BaseApiClient)socketClient.UnifiedApi).AuthenticationProvider.ApiKey, Is.EqualTo("456")); + Assert.That(((BaseApiClient)restClient.UnifiedApi).ClientOptions.Proxy.Host, Is.EqualTo("host")); + Assert.That(((BaseApiClient)restClient.UnifiedApi).ClientOptions.Proxy.Port, Is.EqualTo(80)); + Assert.That(((BaseApiClient)socketClient.UnifiedApi).ClientOptions.Proxy.Host, Is.EqualTo("host2")); + Assert.That(((BaseApiClient)socketClient.UnifiedApi).ClientOptions.Proxy.Port, Is.EqualTo(81)); + } } } diff --git a/OKX.Net/Clients/OKXRestClient.cs b/OKX.Net/Clients/OKXRestClient.cs index b7bcb70..85c16d6 100644 --- a/OKX.Net/Clients/OKXRestClient.cs +++ b/OKX.Net/Clients/OKXRestClient.cs @@ -1,4 +1,5 @@ using CryptoExchange.Net.Clients; +using Microsoft.Extensions.Options; using OKX.Net.Clients.UnifiedApi; using OKX.Net.Interfaces.Clients; using OKX.Net.Interfaces.Clients.UnifiedApi; @@ -22,25 +23,23 @@ public class OKXRestClient : BaseRestClient, IOKXRestClient /// Create a new instance of the OKXRestClient using provided options /// /// Option configuration delegate - public OKXRestClient(Action? optionsDelegate = null) : this(null, null, optionsDelegate) + public OKXRestClient(Action? optionsDelegate = null) + : this(null, null, Options.Create(ApplyOptionsDelegate(optionsDelegate))) { } /// /// Create a new instance of the OKXRestClient /// - /// Option configuration delegate + /// Option configuration /// The logger factory /// Http client for this client - public OKXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, Action? optionsDelegate = null) + public OKXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, IOptions options) : base(loggerFactory, "OKX") { - var options = OKXRestOptions.Default.Copy(); - if (optionsDelegate != null) - optionsDelegate(options); - Initialize(options); + Initialize(options.Value); - UnifiedApi = AddApiClient(new OKXRestClientUnifiedApi(_logger, httpClient, options)); + UnifiedApi = AddApiClient(new OKXRestClientUnifiedApi(_logger, httpClient, options.Value)); } #endregion @@ -51,9 +50,7 @@ public OKXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, Acti /// Callback for setting the options public static void SetDefaultOptions(Action optionsDelegate) { - var options = OKXRestOptions.Default.Copy(); - optionsDelegate(options); - OKXRestOptions.Default = options; + OKXRestOptions.Default = ApplyOptionsDelegate(optionsDelegate); } /// diff --git a/OKX.Net/Clients/OKXSocketClient.cs b/OKX.Net/Clients/OKXSocketClient.cs index b7366ea..c1b37cf 100644 --- a/OKX.Net/Clients/OKXSocketClient.cs +++ b/OKX.Net/Clients/OKXSocketClient.cs @@ -1,4 +1,5 @@ using CryptoExchange.Net.Clients; +using Microsoft.Extensions.Options; using OKX.Net.Clients.UnifiedApi; using OKX.Net.Interfaces.Clients; using OKX.Net.Interfaces.Clients.UnifiedApi; @@ -16,19 +17,13 @@ public class OKXSocketClient : BaseSocketClient, IOKXSocketClient public IOKXSocketClientUnifiedApi UnifiedApi { get; } #region ctor - /// - /// Create a new instance of the OKXSocketClient - /// - /// The logger - public OKXSocketClient(ILoggerFactory? loggerFactory = null) : this((x) => { }, loggerFactory) - { - } /// /// Create a new instance of the OKXSocketClient /// /// Option configuration delegate - public OKXSocketClient(Action optionsDelegate) : this(optionsDelegate, null) + public OKXSocketClient(Action? optionsDelegate = null) + : this(Options.Create(ApplyOptionsDelegate(optionsDelegate)), null) { } @@ -36,14 +31,12 @@ public OKXSocketClient(Action optionsDelegate) : this(optionsD /// Create a new instance of the OKXSocketClient /// /// The logger - /// Option configuration delegate - public OKXSocketClient(Action optionsDelegate, ILoggerFactory? loggerFactory = null) : base(loggerFactory, "OKX") + /// Option configuration delegate + public OKXSocketClient(IOptions options, ILoggerFactory? loggerFactory = null) : base(loggerFactory, "OKX") { - var options = OKXSocketOptions.Default.Copy(); - optionsDelegate(options); - Initialize(options); + Initialize(options.Value); - UnifiedApi = AddApiClient(new OKXSocketClientUnifiedApi(_logger, options)); + UnifiedApi = AddApiClient(new OKXSocketClientUnifiedApi(_logger, options.Value)); } #endregion @@ -54,9 +47,7 @@ public OKXSocketClient(Action optionsDelegate, ILoggerFactory? /// public static void SetDefaultOptions(Action optionsDelegate) { - var options = OKXSocketOptions.Default.Copy(); - optionsDelegate(options); - OKXSocketOptions.Default = options; + OKXSocketOptions.Default = ApplyOptionsDelegate(optionsDelegate); } /// diff --git a/OKX.Net/Clients/UnifiedApi/OKXRestClientUnifiedApi.cs b/OKX.Net/Clients/UnifiedApi/OKXRestClientUnifiedApi.cs index 25312fd..e453459 100644 --- a/OKX.Net/Clients/UnifiedApi/OKXRestClientUnifiedApi.cs +++ b/OKX.Net/Clients/UnifiedApi/OKXRestClientUnifiedApi.cs @@ -40,7 +40,7 @@ internal OKXRestClientUnifiedApi(ILogger logger, HttpClient? httpClient, OKXRest _ref = !string.IsNullOrEmpty(options.BrokerId) ? options.BrokerId! : "1425d83a94fbBCDE"; - if (options.Environment.EnvironmentName == TradeEnvironmentNames.Testnet) + if (options.Environment.Name == TradeEnvironmentNames.Testnet) { StandardRequestHeaders = new Dictionary { diff --git a/OKX.Net/Clients/UnifiedApi/OKXSocketClientUnifiedApi.cs b/OKX.Net/Clients/UnifiedApi/OKXSocketClientUnifiedApi.cs index b8bf8da..12b7f58 100644 --- a/OKX.Net/Clients/UnifiedApi/OKXSocketClientUnifiedApi.cs +++ b/OKX.Net/Clients/UnifiedApi/OKXSocketClientUnifiedApi.cs @@ -45,7 +45,7 @@ internal OKXSocketClientUnifiedApi(ILogger logger, OKXSocketOptions options) : _ref = !string.IsNullOrEmpty(options.BrokerId) ? options.BrokerId! : "078ee129065aBCDE"; - _demoTrading = options.Environment.EnvironmentName == TradeEnvironmentNames.Testnet; + _demoTrading = options.Environment.Name == TradeEnvironmentNames.Testnet; RegisterPeriodicQuery("Ping", TimeSpan.FromSeconds(20), x => new OKXPingQuery(), null); diff --git a/OKX.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/OKX.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 6925669..7872f5e 100644 --- a/OKX.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/OKX.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -1,4 +1,6 @@ using CryptoExchange.Net.Clients; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; using OKX.Net; using OKX.Net.Clients; using OKX.Net.Interfaces; @@ -14,47 +16,115 @@ namespace Microsoft.Extensions.DependencyInjection /// public static class ServiceCollectionExtensions { + /// - /// Add the IOKXRestClient and IOKXSocketClient to the sevice collection so they can be injected + /// Add services such as the IOKXRestClient and IOKXSocketClient. Configures the services based on the provided configuration. /// /// The service collection - /// Set default options for the rest client - /// Set default options for the socket client - /// The lifetime of the IOKXSocketClient for the service collection. Defaults to Singleton. + /// The configuration(section) containing the options /// public static IServiceCollection AddOKX( this IServiceCollection services, - Action? defaultRestOptionsDelegate = null, - Action? defaultSocketOptionsDelegate = null, - ServiceLifetime? socketClientLifeTime = null) + IConfiguration configuration) { - var restOptions = OKXRestOptions.Default.Copy(); + var options = new OKXOptions(); + // Reset environment so we know if theyre overriden + options.Rest.Environment = null!; + options.Socket.Environment = null!; + configuration.Bind(options); - if (defaultRestOptionsDelegate != null) - { - defaultRestOptionsDelegate(restOptions); - OKXRestClient.SetDefaultOptions(defaultRestOptionsDelegate); - } + if (options.Rest == null || options.Socket == null) + throw new ArgumentException("Options null"); - if (defaultSocketOptionsDelegate != null) - OKXSocketClient.SetDefaultOptions(defaultSocketOptionsDelegate); + var restEnvName = options.Rest.Environment?.Name ?? options.Environment?.Name ?? OKXEnvironment.Live.Name; + var socketEnvName = options.Socket.Environment?.Name ?? options.Environment?.Name ?? OKXEnvironment.Live.Name; + options.Rest.Environment = OKXEnvironment.GetEnvironmentByName(restEnvName) ?? options.Rest.Environment!; + options.Rest.ApiCredentials = options.Rest.ApiCredentials ?? options.ApiCredentials; + options.Socket.Environment = OKXEnvironment.GetEnvironmentByName(socketEnvName) ?? options.Socket.Environment!; + options.Socket.ApiCredentials = options.Socket.ApiCredentials ?? options.ApiCredentials; - services.AddHttpClient(options => - { - options.Timeout = restOptions.RequestTimeout; - }).ConfigurePrimaryHttpMessageHandler(() => + + services.AddSingleton(x => Options.Options.Create(options.Rest)); + services.AddSingleton(x => Options.Options.Create(options.Socket)); + + return AddOKXCore(services, options.SocketClientLifeTime); + } + + /// + /// Add services such as the IOKXRestClient and IOKXSocketClient. Services will be configured based on the provided options. + /// + /// The service collection + /// Set options for the OKX services + /// + public static IServiceCollection AddOKX( + this IServiceCollection services, + Action? optionsDelegate = null) + { + var options = new OKXOptions(); + // Reset environment so we know if theyre overriden + options.Rest.Environment = null!; + options.Socket.Environment = null!; + optionsDelegate?.Invoke(options); + if (options.Rest == null || options.Socket == null) + throw new ArgumentException("Options null"); + + options.Rest.Environment = options.Rest.Environment ?? options.Environment ?? OKXEnvironment.Live; + options.Rest.ApiCredentials = options.Rest.ApiCredentials ?? options.ApiCredentials; + options.Socket.Environment = options.Socket.Environment ?? options.Environment ?? OKXEnvironment.Live; + options.Socket.ApiCredentials = options.Socket.ApiCredentials ?? options.ApiCredentials; + + services.AddSingleton(x => Options.Options.Create(options.Rest)); + services.AddSingleton(x => Options.Options.Create(options.Socket)); + + return AddOKXCore(services, options.SocketClientLifeTime); + } + + /// + /// DEPRECATED; use instead + /// + public static IServiceCollection AddOKX( + this IServiceCollection services, + Action restDelegate, + Action? socketDelegate = null, + ServiceLifetime? socketClientLifeTime = null) + { + services.Configure((x) => { restDelegate?.Invoke(x); }); + services.Configure((x) => { socketDelegate?.Invoke(x); }); + + return AddOKXCore(services, socketClientLifeTime); + } + + private static IServiceCollection AddOKXCore( + this IServiceCollection services, + ServiceLifetime? socketClientLifeTime = null) + { + services.AddHttpClient((client, serviceProvider) => { + var options = serviceProvider.GetRequiredService>().Value; + client.Timeout = options.RequestTimeout; + return new OKXRestClient(client, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService>()); + }).ConfigurePrimaryHttpMessageHandler((serviceProvider) => { var handler = new HttpClientHandler(); - if (restOptions.Proxy != null) + try + { + handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; + } + catch (PlatformNotSupportedException) + { } + + var options = serviceProvider.GetRequiredService>().Value; + if (options.Proxy != null) { handler.Proxy = new WebProxy { - Address = new Uri($"{restOptions.Proxy.Host}:{restOptions.Proxy.Port}"), - Credentials = restOptions.Proxy.Password == null ? null : new NetworkCredential(restOptions.Proxy.Login, restOptions.Proxy.Password) + Address = new Uri($"{options.Proxy.Host}:{options.Proxy.Port}"), + Credentials = options.Proxy.Password == null ? null : new NetworkCredential(options.Proxy.Login, options.Proxy.Password) }; } return handler; }); + services.Add(new ServiceDescriptor(typeof(IOKXSocketClient), x => { return new OKXSocketClient(x.GetRequiredService>(), x.GetRequiredService()); }, socketClientLifeTime ?? ServiceLifetime.Singleton)); + services.AddTransient(); services.AddTransient(); @@ -65,10 +135,6 @@ public static IServiceCollection AddOKX( services.RegisterSharedRestInterfaces(x => x.GetRequiredService().UnifiedApi.SharedClient); services.RegisterSharedSocketInterfaces(x => x.GetRequiredService().UnifiedApi.SharedClient); - if (socketClientLifeTime == null) - services.AddSingleton(); - else - services.Add(new ServiceDescriptor(typeof(IOKXSocketClient), typeof(OKXSocketClient), socketClientLifeTime.Value)); return services; } } diff --git a/OKX.Net/OKX.Net.csproj b/OKX.Net/OKX.Net.csproj index 61268ca..1b6c7c9 100644 --- a/OKX.Net/OKX.Net.csproj +++ b/OKX.Net/OKX.Net.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;netstandard2.1 latest @@ -49,7 +49,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/OKX.Net/OKX.Net.xml b/OKX.Net/OKX.Net.xml index 8600e07..48207b3 100644 --- a/OKX.Net/OKX.Net.xml +++ b/OKX.Net/OKX.Net.xml @@ -18,11 +18,11 @@ Option configuration delegate - + Create a new instance of the OKXRestClient - Option configuration delegate + Option configuration The logger factory Http client for this client @@ -46,24 +46,18 @@ Unified API endpoints - - - Create a new instance of the OKXSocketClient - - The logger - Create a new instance of the OKXSocketClient Option configuration delegate - + Create a new instance of the OKXSocketClient The logger - Option configuration delegate + Option configuration delegate @@ -6218,9 +6212,9 @@ ctor - - - + The API key + The API secret + The API passphrase @@ -6228,6 +6222,36 @@ + + + OKX options + + + + + Rest client options + + + + + Socket client options + + + + + Trade environment. Contains info about URL's to use to connect to the API. Use `OKXEnvironment` to swap environment, for example `Environment = OKXEnvironment.Live` + + + + + The api credentials used for signing requests. + + + + + The DI service lifetime for the IOKXSocketClient + + Order book options @@ -6258,6 +6282,11 @@ Default options for new OKXRestClients + + + ctor + + Whether or not to sign public requests @@ -6283,6 +6312,11 @@ Default options for new OKXRestClients + + + ctor + + Broker ID for earning rebates @@ -9125,6 +9159,16 @@ Socket API base address + + + ctor for DI, use for creating a custom environment + + + + + Get the OKX environment by name + + Live environment @@ -9154,6 +9198,16 @@ Exchange name + + + Exchange name + + + + + Url to exchange image + + Url to the main website @@ -9286,15 +9340,26 @@ Extensions for DI - + + + Add services such as the IOKXRestClient and IOKXSocketClient. Configures the services based on the provided configuration. + + The service collection + The configuration(section) containing the options + + + - Add the IOKXRestClient and IOKXSocketClient to the sevice collection so they can be injected + Add services such as the IOKXRestClient and IOKXSocketClient. Services will be configured based on the provided options. The service collection - Set default options for the rest client - Set default options for the socket client - The lifetime of the IOKXSocketClient for the service collection. Defaults to Singleton. + Set options for the OKX services + + + DEPRECATED; use instead + + diff --git a/OKX.Net/OKXEnvironment.cs b/OKX.Net/OKXEnvironment.cs index 48e48fc..59eedb0 100644 --- a/OKX.Net/OKXEnvironment.cs +++ b/OKX.Net/OKXEnvironment.cs @@ -23,6 +23,27 @@ internal OKXEnvironment(string name, SocketAddress = socketAddress; } + /// + /// ctor for DI, use for creating a custom environment + /// +#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. + public OKXEnvironment() : base(TradeEnvironmentNames.Live) +#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. + { } + + /// + /// Get the OKX environment by name + /// + public static OKXEnvironment? GetEnvironmentByName(string? name) + => name switch + { + TradeEnvironmentNames.Live => Live, + TradeEnvironmentNames.Testnet => Demo, + "" => Live, + null => Live, + _ => default + }; + /// /// Live environment /// diff --git a/OKX.Net/OKXExchange.cs b/OKX.Net/OKXExchange.cs index b95ce8e..350c40c 100644 --- a/OKX.Net/OKXExchange.cs +++ b/OKX.Net/OKXExchange.cs @@ -14,6 +14,16 @@ public static class OKXExchange /// public static string ExchangeName => "OKX"; + /// + /// Exchange name + /// + public static string DisplayName => "OKX"; + + /// + /// Url to exchange image + /// + public static string ImageUrl { get; } = "https://raw.githubusercontent.com/JKorf/OKX.Net/master/OKX.Net/Icon/icon.png"; + /// /// Url to the main website /// diff --git a/OKX.Net/Objects/OKXApiCredentials.cs b/OKX.Net/Objects/OKXApiCredentials.cs index c65c79c..d342771 100644 --- a/OKX.Net/Objects/OKXApiCredentials.cs +++ b/OKX.Net/Objects/OKXApiCredentials.cs @@ -6,17 +6,17 @@ public class OKXApiCredentials : ApiCredentials /// /// Passphrase /// - public string PassPhrase { get; } + public string PassPhrase { get; set; } /// /// ctor /// - /// - /// - /// - public OKXApiCredentials(string apiKey, string apiSecret, string apiPassPhrase) : base(apiKey, apiSecret) + /// The API key + /// The API secret + /// The API passphrase + public OKXApiCredentials(string key, string secret, string passPhrase) : base(key, secret) { - PassPhrase = apiPassPhrase; + PassPhrase = passPhrase; } /// diff --git a/OKX.Net/Objects/Options/OKXOptions.cs b/OKX.Net/Objects/Options/OKXOptions.cs new file mode 100644 index 0000000..5cb6ea9 --- /dev/null +++ b/OKX.Net/Objects/Options/OKXOptions.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Text; + +namespace OKX.Net.Objects.Options; +/// +/// OKX options +/// +public class OKXOptions +{ + /// + /// Rest client options + /// + public OKXRestOptions Rest { get; set; } = new OKXRestOptions(); + + /// + /// Socket client options + /// + public OKXSocketOptions Socket { get; set; } = new OKXSocketOptions(); + + /// + /// Trade environment. Contains info about URL's to use to connect to the API. Use `OKXEnvironment` to swap environment, for example `Environment = OKXEnvironment.Live` + /// + public OKXEnvironment? Environment { get; set; } + + /// + /// The api credentials used for signing requests. + /// + public OKXApiCredentials? ApiCredentials { get; set; } + + /// + /// The DI service lifetime for the IOKXSocketClient + /// + public ServiceLifetime? SocketClientLifeTime { get; set; } +} diff --git a/OKX.Net/Objects/Options/OKXRestOptions.cs b/OKX.Net/Objects/Options/OKXRestOptions.cs index b962159..01e56a4 100644 --- a/OKX.Net/Objects/Options/OKXRestOptions.cs +++ b/OKX.Net/Objects/Options/OKXRestOptions.cs @@ -10,11 +10,19 @@ public class OKXRestOptions : RestExchangeOptions /// Default options for new OKXRestClients /// - public static OKXRestOptions Default { get; set; } = new OKXRestOptions() + internal static OKXRestOptions Default { get; set; } = new OKXRestOptions() { Environment = OKXEnvironment.Live }; + /// + /// ctor + /// + public OKXRestOptions() + { + Default?.Set(this); + } + /// /// Whether or not to sign public requests /// @@ -30,12 +38,12 @@ public class OKXRestOptions : RestExchangeOptions public RestApiOptions UnifiedOptions { get; private set; } = new RestApiOptions(); - internal OKXRestOptions Copy() + internal OKXRestOptions Set(OKXRestOptions targetOptions) { - var options = Copy(); - options.SignPublicRequests = SignPublicRequests; - options.BrokerId = BrokerId; - options.UnifiedOptions = UnifiedOptions.Copy(); - return options; + targetOptions = base.Set(targetOptions); + targetOptions.SignPublicRequests = SignPublicRequests; + targetOptions.BrokerId = BrokerId; + targetOptions.UnifiedOptions = UnifiedOptions.Set(targetOptions.UnifiedOptions); + return targetOptions; } } diff --git a/OKX.Net/Objects/Options/OKXSocketOptions.cs b/OKX.Net/Objects/Options/OKXSocketOptions.cs index 8687ee9..c709c56 100644 --- a/OKX.Net/Objects/Options/OKXSocketOptions.cs +++ b/OKX.Net/Objects/Options/OKXSocketOptions.cs @@ -10,12 +10,20 @@ public class OKXSocketOptions : SocketExchangeOptions /// Default options for new OKXRestClients /// - public static OKXSocketOptions Default { get; set; } = new OKXSocketOptions() + internal static OKXSocketOptions Default { get; set; } = new OKXSocketOptions() { SocketSubscriptionsCombineTarget = 10, Environment = OKXEnvironment.Live }; + /// + /// ctor + /// + public OKXSocketOptions() + { + Default?.Set(this); + } + /// /// Broker ID for earning rebates /// @@ -26,11 +34,11 @@ public class OKXSocketOptions : SocketExchangeOptions public SocketApiOptions UnifiedOptions { get; private set; } = new SocketApiOptions(); - internal OKXSocketOptions Copy() + internal OKXSocketOptions Set(OKXSocketOptions targetOptions) { - var options = Copy(); - options.BrokerId = BrokerId; - options.UnifiedOptions = UnifiedOptions.Copy(); - return options; + targetOptions = base.Set(targetOptions); + targetOptions.BrokerId = BrokerId; + targetOptions.UnifiedOptions = UnifiedOptions.Set(targetOptions.UnifiedOptions); + return targetOptions; } } diff --git a/docs/index.html b/docs/index.html index f3e0652..0d0aa91 100644 --- a/docs/index.html +++ b/docs/index.html @@ -190,16 +190,22 @@

API Access

OKX.Net can be configured using Dotnet dependency injection, after which the clients can be injected into your services. It also correctly configures logging and HttpClient usage.

-
builder.Services.AddOKX(options => {
-  // Options can be configured here, for example:
-  options.ApiCredentials = new ApiCredentials("APIKEY", "APISECRET");
+		  
// Configure options from config file
+// see https://github.com/JKorf/CryptoExchange.Net/tree/master/Examples/example-config.json for an example
+builder.Services.AddOKX(builder.Configuration.GetSection("OKX"));
+		  
+// OR
+		  
+ builder.Services.AddOKX(options => {
+  // Configure options in code
+  options.ApiCredentials = new OKXApiCredentials("APIKEY", "APISECRET", "APIPASS");
 });

The IOKXRestClient and IOKXSocketClient can then be injected.

Alternatively the rest and socket client can be constructed directly

var restClient = new OKXRestClient(options => {
   // Options can be configured here, for example:
-  options.ApiCredentials = new ApiCredentials("APIKEY", "APISECRET");
+  options.ApiCredentials = new OKXApiCredentials("APIKEY", "APISECRET", "APIPASS");
 });
 var socketClient = new OKXSocketClient();