diff --git a/Huobi.Net.UnitTests/Huobi.Net.UnitTests.csproj b/Huobi.Net.UnitTests/Huobi.Net.UnitTests.csproj index f0b860fd..e919484b 100644 --- a/Huobi.Net.UnitTests/Huobi.Net.UnitTests.csproj +++ b/Huobi.Net.UnitTests/Huobi.Net.UnitTests.csproj @@ -6,10 +6,10 @@ - - - - + + + + diff --git a/Huobi.Net.UnitTests/HuobiClientTests.cs b/Huobi.Net.UnitTests/HuobiClientTests.cs index 545185f1..12fc2454 100644 --- a/Huobi.Net.UnitTests/HuobiClientTests.cs +++ b/Huobi.Net.UnitTests/HuobiClientTests.cs @@ -11,6 +11,7 @@ using Huobi.Net.Clients.SpotApi; using Huobi.Net.ExtensionMethods; using CryptoExchange.Net.Objects.Sockets; +using NUnit.Framework.Legacy; namespace Huobi.Net.UnitTests { @@ -27,9 +28,9 @@ public async Task ReceivingErrorResponse_Should_FailCall() var result = await client.SpotApi.ExchangeData.GetAssetsAsync(); // assert - Assert.IsFalse(result.Success); - Assert.IsTrue(result.Error.ToString().Contains("Error!")); - Assert.IsTrue(result.Error.ToString().Contains("ErrorMessage")); + ClassicAssert.IsFalse(result.Success); + Assert.That(result.Error.ToString().Contains("Error!")); + Assert.That(result.Error.ToString().Contains("ErrorMessage")); } [TestCase] @@ -42,8 +43,8 @@ public async Task ReceivingHttpErrorResponse_Should_FailCall() var result = await client.SpotApi.ExchangeData.GetAssetsAsync(); // assert - Assert.IsFalse(result.Success); - Assert.IsTrue(result.Error.ToString().Contains("Error message")); + ClassicAssert.IsFalse(result.Success); + Assert.That(result.Error.ToString().Contains("Error message")); } @@ -84,7 +85,7 @@ public void CheckRestInterfaces() foreach (var method in implementation.GetMethods().Where(m => m.ReturnType.IsAssignableTo(typeof(Task)))) { var interfaceMethod = clientInterface.GetMethod(method.Name, method.GetParameters().Select(p => p.ParameterType).ToArray()); - Assert.NotNull(interfaceMethod, $"Missing interface for method {method.Name} in {implementation.Name} implementing interface {clientInterface.Name}"); + ClassicAssert.NotNull(interfaceMethod, $"Missing interface for method {method.Name} in {implementation.Name} implementing interface {clientInterface.Name}"); methods++; } Debug.WriteLine($"{clientInterface.Name} {methods} methods validated"); @@ -104,7 +105,7 @@ public void CheckSocketInterfaces() foreach (var method in implementation.GetMethods().Where(m => m.ReturnType.IsAssignableTo(typeof(Task>)))) { var interfaceMethod = clientInterface.GetMethod(method.Name, method.GetParameters().Select(p => p.ParameterType).ToArray()); - Assert.NotNull(interfaceMethod, $"Missing interface for method {method.Name} in {implementation.Name} implementing interface {clientInterface.Name}"); + ClassicAssert.NotNull(interfaceMethod, $"Missing interface for method {method.Name} in {implementation.Name} implementing interface {clientInterface.Name}"); methods++; } Debug.WriteLine($"{clientInterface.Name} {methods} methods validated"); diff --git a/Huobi.Net.UnitTests/HuobiSocketClientTests.cs b/Huobi.Net.UnitTests/HuobiSocketClientTests.cs index ad9d20db..2067be84 100644 --- a/Huobi.Net.UnitTests/HuobiSocketClientTests.cs +++ b/Huobi.Net.UnitTests/HuobiSocketClientTests.cs @@ -12,6 +12,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NUnit.Framework; +using NUnit.Framework.Legacy; namespace Huobi.Net.UnitTests { @@ -19,7 +20,7 @@ namespace Huobi.Net.UnitTests public class HuobiSocketClientTests { [Test] - public async Task SubscribeV1_Should_SucceedIfSubbedResponse() + public void SubscribeV1_Should_SucceedIfSubbedResponse() { // arrange var socket = new TestSocket(); @@ -29,11 +30,11 @@ public async Task SubscribeV1_Should_SucceedIfSubbedResponse() // act var subTask = client.SpotApi.SubscribeToPartialOrderBookUpdates1SecondAsync("ETHBTC", 1, test => { }); var id = JToken.Parse(socket.LastSendMessage)["id"]; - await socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\":\"{id}\", \"status\": \"ok\"}}"); + socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\":\"{id}\", \"status\": \"ok\"}}"); var subResult = subTask.Result; // assert - Assert.IsTrue(subResult.Success); + Assert.That(subResult.Success); } [Test] @@ -51,11 +52,11 @@ public async Task SubscribeV1_Should_FailIfNoResponse() var subResult = await client.SpotApi.SubscribeToPartialOrderBookUpdates1SecondAsync("ETHBTC", 1, test => { }); // assert - Assert.IsFalse(subResult.Success); + ClassicAssert.IsFalse(subResult.Success); } [Test] - public async Task SubscribeV1_Should_FailIfErrorResponse() + public void SubscribeV1_Should_FailIfErrorResponse() { // arrange var socket = new TestSocket(); @@ -65,15 +66,15 @@ public async Task SubscribeV1_Should_FailIfErrorResponse() // act var subTask = client.SpotApi.SubscribeToPartialOrderBookUpdates1SecondAsync("ETHBTC", 1, test => { }); var id = JToken.Parse(socket.LastSendMessage)["id"]; - await socket.InvokeMessage($"{{\"status\": \"error\", \"id\": \"{id}\", \"err-code\": \"Fail\", \"err-msg\": \"failed\"}}"); + socket.InvokeMessage($"{{\"status\": \"error\", \"id\": \"{id}\", \"err-code\": \"Fail\", \"err-msg\": \"failed\"}}"); var subResult = subTask.Result; // assert - Assert.IsFalse(subResult.Success); + ClassicAssert.IsFalse(subResult.Success); } [Test] - public async Task SubscribeToDepthUpdates_Should_TriggerWithDepthUpdate() + public void SubscribeToDepthUpdates_Should_TriggerWithDepthUpdate() { // arrange var socket = new TestSocket(); @@ -83,7 +84,7 @@ public async Task SubscribeToDepthUpdates_Should_TriggerWithDepthUpdate() HuobiOrderBook result = null; var subTask = client.SpotApi.SubscribeToPartialOrderBookUpdates1SecondAsync("ETHBTC", 1, test => result = test.Data); var id = JToken.Parse(socket.LastSendMessage)["id"]; - await socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"status\": \"ok\", \"id\": \"{id}\"}}"); + socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"status\": \"ok\", \"id\": \"{id}\"}}"); var subResult = subTask.Result; var expected = new HuobiOrderBook() @@ -99,16 +100,16 @@ public async Task SubscribeToDepthUpdates_Should_TriggerWithDepthUpdate() }; // act - await socket.InvokeMessage(SerializeExpected("market.ethbtc.depth.step1", expected)); + socket.InvokeMessage(SerializeExpected("market.ethbtc.depth.step1", expected)); // assert - Assert.IsTrue(subResult.Success); - Assert.IsTrue(TestHelpers.AreEqual(expected.Asks.ToList()[0], result.Asks.ToList()[0])); - Assert.IsTrue(TestHelpers.AreEqual(expected.Bids.ToList()[0], result.Bids.ToList()[0])); + Assert.That(subResult.Success); + Assert.That(TestHelpers.AreEqual(expected.Asks.ToList()[0], result.Asks.ToList()[0])); + Assert.That(TestHelpers.AreEqual(expected.Bids.ToList()[0], result.Bids.ToList()[0])); } [Test] - public async Task SubscribeToDetailUpdates_Should_TriggerWithDetailUpdate() + public void SubscribeToDetailUpdates_Should_TriggerWithDetailUpdate() { // arrange var socket = new TestSocket(); @@ -118,7 +119,7 @@ public async Task SubscribeToDetailUpdates_Should_TriggerWithDetailUpdate() HuobiSymbolDetails result = null; var subTask = client.SpotApi.SubscribeToSymbolDetailUpdatesAsync("ETHBTC", test => result = test.Data); var id = JToken.Parse(socket.LastSendMessage)["id"]; - await socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"id\": \"{id}\", \"status\": \"ok\"}}"); + socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"id\": \"{id}\", \"status\": \"ok\"}}"); var subResult = subTask.Result; var expected = new HuobiSymbolData() @@ -133,15 +134,15 @@ public async Task SubscribeToDetailUpdates_Should_TriggerWithDetailUpdate() }; // act - await socket.InvokeMessage(SerializeExpected("market.ethbtc.detail", expected)); + socket.InvokeMessage(SerializeExpected("market.ethbtc.detail", expected)); // assert - Assert.IsTrue(subResult.Success); - Assert.IsTrue(TestHelpers.AreEqual(expected, result)); + Assert.That(subResult.Success); + Assert.That(TestHelpers.AreEqual(expected, result)); } [Test] - public async Task SubscribeToKlineUpdates_Should_TriggerWithKlineUpdate() + public void SubscribeToKlineUpdates_Should_TriggerWithKlineUpdate() { // arrange var socket = new TestSocket(); @@ -151,7 +152,7 @@ public async Task SubscribeToKlineUpdates_Should_TriggerWithKlineUpdate() HuobiSymbolData result = null; var subTask = client.SpotApi.SubscribeToKlineUpdatesAsync("ETHBTC", KlineInterval.FiveMinutes, test => result = test.Data); var id = JToken.Parse(socket.LastSendMessage)["id"]; - await socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"id\": \"{id}\", \"status\": \"ok\"}}"); + socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"id\": \"{id}\", \"status\": \"ok\"}}"); var subResult = subTask.Result; var expected = new HuobiSymbolData() @@ -166,15 +167,15 @@ public async Task SubscribeToKlineUpdates_Should_TriggerWithKlineUpdate() }; // act - await socket.InvokeMessage(SerializeExpected("market.ethbtc.kline.5min", expected)); + socket.InvokeMessage(SerializeExpected("market.ethbtc.kline.5min", expected)); // assert - Assert.IsTrue(subResult.Success); - Assert.IsTrue(TestHelpers.AreEqual(expected, result)); + Assert.That(subResult.Success); + Assert.That(TestHelpers.AreEqual(expected, result)); } [Test] - public async Task SubscribeToTickerUpdates_Should_TriggerWithTickerUpdate() + public void SubscribeToTickerUpdates_Should_TriggerWithTickerUpdate() { // arrange var socket = new TestSocket(); @@ -184,7 +185,7 @@ public async Task SubscribeToTickerUpdates_Should_TriggerWithTickerUpdate() IEnumerable result = null; var subTask = client.SpotApi.SubscribeToTickerUpdatesAsync((test => result = test.Data)); var id = JToken.Parse(socket.LastSendMessage)["id"]; - await socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\": \"{id}\", \"status\": \"ok\"}}"); + socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\": \"{id}\", \"status\": \"ok\"}}"); var subResult = subTask.Result; var expected = new List @@ -202,15 +203,15 @@ public async Task SubscribeToTickerUpdates_Should_TriggerWithTickerUpdate() }; // act - await socket.InvokeMessage(SerializeExpected("market.tickers", expected)); + socket.InvokeMessage(SerializeExpected("market.tickers", expected)); // assert - Assert.IsTrue(subResult.Success); - Assert.IsTrue(TestHelpers.AreEqual(expected[0], result.First())); + Assert.That(subResult.Success); + Assert.That(TestHelpers.AreEqual(expected[0], result.First())); } [Test] - public async Task SubscribeToTradeUpdates_Should_TriggerWithTradeUpdate() + public void SubscribeToTradeUpdates_Should_TriggerWithTradeUpdate() { // arrange var socket = new TestSocket(); @@ -220,7 +221,7 @@ public async Task SubscribeToTradeUpdates_Should_TriggerWithTradeUpdate() HuobiSymbolTrade result = null; var subTask = client.SpotApi.SubscribeToTradeUpdatesAsync("ethusdt", test => result = test.Data); var id = JToken.Parse(socket.LastSendMessage)["id"]; - await socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\": \"{id}\", \"status\": \"ok\"}}"); + socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\": \"{id}\", \"status\": \"ok\"}}"); var subResult = subTask.Result; var expected = @@ -242,16 +243,16 @@ public async Task SubscribeToTradeUpdates_Should_TriggerWithTradeUpdate() }; // act - await socket.InvokeMessage(SerializeExpected("market.ethusdt.trade.detail", expected)); + socket.InvokeMessage(SerializeExpected("market.ethusdt.trade.detail", expected)); // assert - Assert.IsTrue(subResult.Success); - Assert.IsTrue(TestHelpers.AreEqual(expected, result, "Details")); - Assert.IsTrue(TestHelpers.AreEqual(expected.Details.ToList()[0], result.Details.ToList()[0])); + Assert.That(subResult.Success); + Assert.That(TestHelpers.AreEqual(expected, result, "Details")); + Assert.That(TestHelpers.AreEqual(expected.Details.ToList()[0], result.Details.ToList()[0])); } [Test] - public async Task SubscribeToAccountUpdates_Should_TriggerWithAccountUpdate() + public void SubscribeToAccountUpdates_Should_TriggerWithAccountUpdate() { // arrange var socket = new TestSocket(); @@ -260,9 +261,9 @@ public async Task SubscribeToAccountUpdates_Should_TriggerWithAccountUpdate() HuobiAccountUpdate result = null; var subTask = client.SpotApi.SubscribeToAccountUpdatesAsync(test => result = test.Data); - await socket.InvokeMessage("{\"ch\": \"auth\", \"code\": 200, \"action\": \"req\"}"); + socket.InvokeMessage("{\"ch\": \"auth\", \"code\": 200, \"action\": \"req\"}"); Thread.Sleep(100); - await socket.InvokeMessage($"{{\"action\": \"sub\", \"code\": 200, \"ch\": \"accounts.update#1\"}}"); + socket.InvokeMessage($"{{\"action\": \"sub\", \"code\": 200, \"ch\": \"accounts.update#1\"}}"); var subResult = subTask.Result; var expected = new HuobiAccountUpdate() @@ -277,15 +278,15 @@ public async Task SubscribeToAccountUpdates_Should_TriggerWithAccountUpdate() }; // act - await socket.InvokeMessage(SerializeExpectedAuth("accounts.update#1", expected)); + socket.InvokeMessage(SerializeExpectedAuth("accounts.update#1", expected)); // assert - Assert.IsTrue(subResult.Success); - Assert.IsTrue(TestHelpers.AreEqual(expected, result)); + Assert.That(subResult.Success); + Assert.That(TestHelpers.AreEqual(expected, result)); } [Test] - public async Task SubscribeV2_Should_SucceedIfSubbedResponse() + public void SubscribeV2_Should_SucceedIfSubbedResponse() { // arrange var socket = new TestSocket(); @@ -294,17 +295,17 @@ public async Task SubscribeV2_Should_SucceedIfSubbedResponse() // act var subTask = client.SpotApi.SubscribeToAccountUpdatesAsync(test => { }); - await socket.InvokeMessage("{\"action\": \"req\", \"code\": 200, \"ch\": \"auth\"}"); + socket.InvokeMessage("{\"action\": \"req\", \"code\": 200, \"ch\": \"auth\"}"); Thread.Sleep(10); - await socket.InvokeMessage("{\"action\": \"sub\", \"code\": 200, \"ch\": \"accounts.update#1\"}"); + socket.InvokeMessage("{\"action\": \"sub\", \"code\": 200, \"ch\": \"accounts.update#1\"}"); var subResult = subTask.Result; // assert - Assert.IsTrue(subResult.Success); + Assert.That(subResult.Success); } [Test] - public async Task SubscribeV2_Should_FailIfAuthErrorResponse() + public void SubscribeV2_Should_FailIfAuthErrorResponse() { // arrange var socket = new TestSocket(); @@ -313,11 +314,11 @@ public async Task SubscribeV2_Should_FailIfAuthErrorResponse() // act var subTask = client.SpotApi.SubscribeToAccountUpdatesAsync(test => { }); - await socket.InvokeMessage("{ \"action\": \"req\", \"ch\": \"auth\", \"code\": 400}"); + socket.InvokeMessage("{ \"action\": \"req\", \"ch\": \"auth\", \"code\": 400}"); var subResult = subTask.Result; // assert - Assert.IsFalse(subResult.Success); + ClassicAssert.IsFalse(subResult.Success); } //[Test] @@ -330,14 +331,14 @@ public async Task SubscribeV2_Should_FailIfAuthErrorResponse() // // act // var subTask = client.SpotApi.SubscribeToAccountUpdatesAsync(test => { }); - // await socket.InvokeMessage("{\"op\": \"auth\"}"); + // socket.InvokeMessage("{\"op\": \"auth\"}"); // Thread.Sleep(10); // var id = JToken.Parse(socket.LastSendMessage)["id"]; - // await socket.InvokeMessage($"{{\"op\": \"sub\", \"cid\": \"{id}\", \"status\": \"error\", \"err-code\": 1, \"err-msg\": \"failed\"}}"); + // socket.InvokeMessage($"{{\"op\": \"sub\", \"cid\": \"{id}\", \"status\": \"error\", \"err-code\": 1, \"err-msg\": \"failed\"}}"); // var subResult = subTask.Result; // // assert - // Assert.IsFalse(subResult.Success); + // ClassicAssert.IsFalse(subResult.Success); //} [Test] @@ -356,7 +357,7 @@ public void SubscribeV2_Should_FailIfNoResponse() var subResult = subTask.Result; // assert - Assert.IsFalse(subResult.Success); + ClassicAssert.IsFalse(subResult.Success); } public string SerializeExpected(string channel, T data) diff --git a/Huobi.Net.UnitTests/JsonToObjectComparer.cs b/Huobi.Net.UnitTests/JsonToObjectComparer.cs index 5e2cd2b7..5f747ca7 100644 --- a/Huobi.Net.UnitTests/JsonToObjectComparer.cs +++ b/Huobi.Net.UnitTests/JsonToObjectComparer.cs @@ -1,9 +1,11 @@ using CryptoExchange.Net.Converters; +using CryptoExchange.Net.Converters.JsonNet; using CryptoExchange.Net.Objects; using Huobi.Net.UnitTests.TestImplementations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NUnit.Framework; +using NUnit.Framework.Legacy; using System; using System.Collections; using System.Collections.Generic; @@ -85,7 +87,7 @@ public async Task ProcessSubject( var result = (CallResult)await TestHelpers.InvokeAsync(method, getSubject(client), input.ToArray()); // asset - Assert.Null(result.Error, method.Name); + ClassicAssert.Null(result.Error, method.Name); var resultProp = result.GetType().GetProperty("Data", BindingFlags.Public | BindingFlags.Instance); if (resultProp == null) @@ -235,10 +237,8 @@ private static void CheckObject(string method, JProperty prop, object obj, Dicti // Property has a value var property = resultProperties.SingleOrDefault(p => p.Item2?.PropertyName == prop.Name).p; - if (property is null) - property = resultProperties.SingleOrDefault(p => p.p.Name == prop.Name).p; - if (property is null) - property = resultProperties.SingleOrDefault(p => p.p.Name.ToUpperInvariant() == prop.Name.ToUpperInvariant()).p; + property ??= resultProperties.SingleOrDefault(p => p.p.Name == prop.Name).p; + property ??= resultProperties.SingleOrDefault(p => p.p.Name.ToUpperInvariant() == prop.Name.ToUpperInvariant()).p; if (property is null) { @@ -352,7 +352,9 @@ private static void CheckPropertyValue(string method, JToken propValue, object p if (info.GetCustomAttribute(true) == null && info.GetCustomAttribute(true) == null && info.GetCustomAttribute(true)?.ItemConverterType == null) + { CheckValues(method, propertyName, (JValue)propValue, propertyValue); + } } } } @@ -391,7 +393,9 @@ private static void CheckValues(string method, string property, JValue jsonValue // timestamp, hard to check.. } else if (jsonValue.Value.ToString().ToLowerInvariant() != objectValue.ToString().ToLowerInvariant()) + { throw new Exception($"{method}: {property} not equal: {jsonValue.Value()} vs {objectValue.ToString()}"); + } } else if (jsonValue.Type == JTokenType.Integer) { diff --git a/Huobi.Net.UnitTests/TestImplementations/TestSocket.cs b/Huobi.Net.UnitTests/TestImplementations/TestSocket.cs index cab7b5a0..f3eefded 100644 --- a/Huobi.Net.UnitTests/TestImplementations/TestSocket.cs +++ b/Huobi.Net.UnitTests/TestImplementations/TestSocket.cs @@ -21,7 +21,7 @@ public class TestSocket: IWebsocket public event Func OnReconnecting; #pragma warning restore 0067 public event Func OnRequestSent; - public event Func OnStreamMessage; + public event Action> OnStreamMessage; public event Func OnError; public event Func OnOpen; @@ -93,16 +93,14 @@ public void InvokeOpen() OnOpen?.Invoke(); } - public async Task InvokeMessage(string data) + public void InvokeMessage(string data) { - var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)); - await OnStreamMessage?.Invoke(WebSocketMessageType.Text, stream); + OnStreamMessage?.Invoke(WebSocketMessageType.Text, new ReadOnlyMemory(Encoding.UTF8.GetBytes(data))); } - public async Task InvokeMessage(T data) + public void InvokeMessage(T data) { - var stream = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data))); - await OnStreamMessage?.Invoke(WebSocketMessageType.Text, stream); + OnStreamMessage?.Invoke(WebSocketMessageType.Text, new ReadOnlyMemory(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data)))); } public void InvokeError(Exception error) diff --git a/Huobi.Net/Clients/HuobiRestClient.cs b/Huobi.Net/Clients/HuobiRestClient.cs index e192e679..3e7c6c6b 100644 --- a/Huobi.Net/Clients/HuobiRestClient.cs +++ b/Huobi.Net/Clients/HuobiRestClient.cs @@ -1,5 +1,4 @@ -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Authentication; using Huobi.Net.Clients.FuturesApi; using Huobi.Net.Clients.SpotApi; using Huobi.Net.Interfaces.Clients; @@ -9,6 +8,7 @@ using System.Net.Http; using System; using Huobi.Net.Objects.Options; +using CryptoExchange.Net.Clients; namespace Huobi.Net.Clients { diff --git a/Huobi.Net/Clients/HuobiSocketClient.cs b/Huobi.Net/Clients/HuobiSocketClient.cs index d113fb80..61b62b1f 100644 --- a/Huobi.Net/Clients/HuobiSocketClient.cs +++ b/Huobi.Net/Clients/HuobiSocketClient.cs @@ -1,5 +1,5 @@ -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Clients; using Huobi.Net.Clients.SpotApi; using Huobi.Net.Interfaces.Clients; using Huobi.Net.Interfaces.Clients.SpotApi; diff --git a/Huobi.Net/Clients/SpotApi/HuobiRestClientSpotApi.cs b/Huobi.Net/Clients/SpotApi/HuobiRestClientSpotApi.cs index 6f2f1a33..f21dbbdf 100644 --- a/Huobi.Net/Clients/SpotApi/HuobiRestClientSpotApi.cs +++ b/Huobi.Net/Clients/SpotApi/HuobiRestClientSpotApi.cs @@ -5,9 +5,10 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using CryptoExchange.Net; using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Clients; using CryptoExchange.Net.CommonObjects; +using CryptoExchange.Net.Converters.MessageParsing; using CryptoExchange.Net.Interfaces.CommonClients; using CryptoExchange.Net.Objects; using Huobi.Net.Enums; @@ -60,8 +61,6 @@ internal HuobiRestClientSpotApi(ILogger logger, HttpClient? httpClient, HuobiRes ExchangeData = new HuobiRestClientSpotApiExchangeData(this); Trading = new HuobiRestClientSpotApiTrading(this); - manualParseError = true; - _brokerId = !string.IsNullOrEmpty(options.BrokerId) ? options.BrokerId! : "AA1ef14811"; } #endregion @@ -109,33 +108,19 @@ internal async Task> SendHuobiRequest(Uri uri, HttpMethod me } /// - protected override Task TryParseErrorAsync(JToken data) + protected override Error ParseErrorResponse(int httpStatusCode, IEnumerable>> responseHeaders, IMessageAccessor accessor) { - if (data["code"] != null && data["code"]?.Value() != 200) - { - if (data["err-code"] != null) - return Task.FromResult(new ServerError($"{(string)data["err-code"]!}, {(string)data["err-msg"]!}")); - - return Task.FromResult(new ServerError($"{(string)data["code"]!}, {(string)data["message"]!}")); - } + if (!accessor.IsJson) + return new ServerError(accessor.GetOriginalString()); - if (data["err-code"] == null && data["err-msg"] == null) - return Task.FromResult(null); + var code = accessor.GetValue(MessagePath.Get().Property("err-code")); + var msg = accessor.GetValue(MessagePath.Get().Property("err-msg")); - return Task.FromResult(new ServerError($"{(string)data["err-code"]!}, {(string)data["err-msg"]!}")); - } - - /// - protected override Error ParseErrorResponse(int httpStatusCode, IEnumerable>> responseHeaders, string data) - { - var errorData = ValidateJson(data); - if (!errorData) - return new ServerError(data); + if (code == null || msg == null) + return new ServerError(accessor.GetOriginalString()); - if (errorData.Data["err-code"] == null || errorData.Data["err-msg"] == null) - return new ServerError(errorData.Data.ToString()); - return new ServerError($"{(string)errorData.Data["err-code"]!}, {(string)errorData.Data["err-msg"]!}"); + return new ServerError($"{code}, {msg}"); } /// diff --git a/Huobi.Net/Clients/SpotApi/HuobiSocketClientSpotApi.cs b/Huobi.Net/Clients/SpotApi/HuobiSocketClientSpotApi.cs index ba8934c0..16fc8d60 100644 --- a/Huobi.Net/Clients/SpotApi/HuobiSocketClientSpotApi.cs +++ b/Huobi.Net/Clients/SpotApi/HuobiSocketClientSpotApi.cs @@ -5,13 +5,12 @@ using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; -using CryptoExchange.Net; using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Clients; +using CryptoExchange.Net.Converters.MessageParsing; using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Sockets; -using CryptoExchange.Net.Sockets.MessageParsing; -using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Huobi.Net.Converters; using Huobi.Net.Enums; using Huobi.Net.ExtensionMethods; @@ -75,16 +74,16 @@ internal HuobiSocketClientSpotApi(ILogger logger, HuobiSocketOptions options) } /// - public override Stream PreprocessStreamMessage(WebSocketMessageType type, Stream stream) + public override ReadOnlyMemory PreprocessStreamMessage(WebSocketMessageType type, ReadOnlyMemory data) { if (type != WebSocketMessageType.Binary) - return stream; + return data; var decompressedStream = new MemoryStream(); - using var deflateStream = new GZipStream(stream, CompressionMode.Decompress); + using var deflateStream = new GZipStream(new MemoryStream(data.ToArray()), CompressionMode.Decompress); deflateStream.CopyTo(decompressedStream); decompressedStream.Position = 0; - return decompressedStream; + return new ReadOnlyMemory(decompressedStream.ToArray()); } /// diff --git a/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiClientUsdtMarginSwapApi.cs b/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiClientUsdtMarginSwapApi.cs index 1821521e..822ad52d 100644 --- a/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiClientUsdtMarginSwapApi.cs +++ b/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiClientUsdtMarginSwapApi.cs @@ -1,6 +1,7 @@ -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Clients; using CryptoExchange.Net.CommonObjects; +using CryptoExchange.Net.Converters.MessageParsing; using CryptoExchange.Net.Objects; using Huobi.Net.Clients.UsdtMarginSwapApi; using Huobi.Net.Interfaces.Clients.UsdtMarginSwapApi; @@ -57,8 +58,6 @@ internal HuobiClientUsdtMarginSwapApi(ILogger log, HttpClient? httpClient, Huobi ExchangeData = new HuobiClientUsdtMarginSwapApiExchangeData(this); Trading = new HuobiClientUsdtMarginSwapApiTrading(this); - manualParseError = true; - _brokerId = !string.IsNullOrEmpty(options.BrokerId) ? options.BrokerId! : "AA1ef14811"; } #endregion @@ -103,33 +102,19 @@ internal async Task> SendHuobiRequest(Uri uri, HttpMethod me } /// - protected override Task TryParseErrorAsync(JToken data) + protected override Error ParseErrorResponse(int httpStatusCode, IEnumerable>> responseHeaders, IMessageAccessor accessor) { - if (data["code"] != null && data["code"]?.Value() != 200) - { - if (data["err-code"] != null) - return Task.FromResult(new ServerError($"{(string)data["err-code"]!}, {(string)data["err-msg"]!}")); - - return Task.FromResult(new ServerError($"{(string)data["code"]!}, {(string)data["message"]!}")); - } - - if (data["err-code"] == null && data["err-msg"] == null) - return Task.FromResult(null); + if (!accessor.IsJson) + return new ServerError(accessor.GetOriginalString()); - return Task.FromResult(new ServerError($"{(string)data["err-code"]!}, {(string)data["err-msg"]!}")); - } + var code = accessor.GetValue(MessagePath.Get().Property("err-code")); + var msg = accessor.GetValue(MessagePath.Get().Property("err-msg")); - /// - protected override Error ParseErrorResponse(int httpStatusCode, IEnumerable>> responseHeaders, string data) - { - var errorData = ValidateJson(data); - if (!errorData) - return new ServerError(data); + if (code == null || msg == null) + return new ServerError(accessor.GetOriginalString()); - if (errorData.Data["err-code"] == null || errorData.Data["err-msg"] == null) - return new ServerError(errorData.Data.ToString()); - return new ServerError($"{(string)errorData.Data["err-code"]!}, {(string)errorData.Data["err-msg"]!}"); + return new ServerError($"{code}, {msg}"); } internal void InvokeOrderPlaced(OrderId id) diff --git a/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiSocketClientUsdtMarginSwapApi.cs b/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiSocketClientUsdtMarginSwapApi.cs index 48815754..be6d8e76 100644 --- a/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiSocketClientUsdtMarginSwapApi.cs +++ b/Huobi.Net/Clients/UsdtMarginSwapApi/HuobiSocketClientUsdtMarginSwapApi.cs @@ -4,12 +4,11 @@ using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; -using CryptoExchange.Net; using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Clients; +using CryptoExchange.Net.Converters.MessageParsing; using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Sockets; -using CryptoExchange.Net.Sockets.MessageParsing; -using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Huobi.Net.Converters; using Huobi.Net.Enums; using Huobi.Net.Interfaces.Clients.UsdtMarginSwapApi; @@ -42,16 +41,16 @@ internal HuobiSocketClientUsdtMarginSwapApi(ILogger logger, HuobiSocketOptions o #endregion /// - public override Stream PreprocessStreamMessage(WebSocketMessageType type, Stream stream) + public override ReadOnlyMemory PreprocessStreamMessage(WebSocketMessageType type, ReadOnlyMemory data) { if (type != WebSocketMessageType.Binary) - return stream; + return data; var decompressedStream = new MemoryStream(); - using var deflateStream = new GZipStream(stream, CompressionMode.Decompress); + using var deflateStream = new GZipStream(new MemoryStream(data.ToArray()), CompressionMode.Decompress); deflateStream.CopyTo(decompressedStream); decompressedStream.Position = 0; - return decompressedStream; + return new ReadOnlyMemory(decompressedStream.ToArray()); } /// diff --git a/Huobi.Net/Huobi.Net.csproj b/Huobi.Net/Huobi.Net.csproj index b5338ec4..4a9873c7 100644 --- a/Huobi.Net/Huobi.Net.csproj +++ b/Huobi.Net/Huobi.Net.csproj @@ -2,14 +2,14 @@ netstandard2.0;netstandard2.1 enable - 8.0 + 10.0 Huobi.Net JKorf - 5.1.0 - 5.1.0 - 5.1.0 + 5.2.0 + 5.2.0 + 5.2.0 Huobi.Net is a client library for accessing the Huobi REST and Websocket API. All data is mapped to readable models and enum values. Additional features include an implementation for maintaining a client side order book, easy integration with other exchange client libraries and more. false Huobi;Huobi.Net;Huobi Client;Huobi API;CryptoCurrency;CryptoCurrency Exchange @@ -44,14 +44,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - all runtime; build; native; contentfiles; analyzers; buildtransitive + \ No newline at end of file diff --git a/Huobi.Net/Huobi.Net.xml b/Huobi.Net/Huobi.Net.xml index c1599c23..b2b7e535 100644 --- a/Huobi.Net/Huobi.Net.xml +++ b/Huobi.Net/Huobi.Net.xml @@ -104,10 +104,7 @@ - - - - + @@ -334,10 +331,10 @@ - + - + @@ -400,10 +397,10 @@ - + - + @@ -481,10 +478,7 @@ - - - - + diff --git a/Huobi.Net/HuobiAuthenticationProvider.cs b/Huobi.Net/HuobiAuthenticationProvider.cs index fbfb7c16..dd9f4785 100644 --- a/Huobi.Net/HuobiAuthenticationProvider.cs +++ b/Huobi.Net/HuobiAuthenticationProvider.cs @@ -1,5 +1,5 @@ -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Clients; using CryptoExchange.Net.Objects; using Huobi.Net.Objects.Internal; using Huobi.Net.Objects.Sockets; @@ -33,6 +33,7 @@ public override void AuthenticateRequest(RestApiClient apiClient, bool auth, ArrayParametersSerialization arraySerialization, HttpMethodParameterPosition parameterPosition, + RequestBodyFormat bodyFormat, out SortedDictionary uriParameters, out SortedDictionary bodyParameters, out Dictionary headers) diff --git a/Huobi.Net/Objects/Sockets/Queries/HuobiAuthQuery.cs b/Huobi.Net/Objects/Sockets/Queries/HuobiAuthQuery.cs index 022c10fb..e1f4a08a 100644 --- a/Huobi.Net/Objects/Sockets/Queries/HuobiAuthQuery.cs +++ b/Huobi.Net/Objects/Sockets/Queries/HuobiAuthQuery.cs @@ -18,12 +18,12 @@ public HuobiAuthQuery(HuobiAuthRequest request) : base(request, true, 1) ListenerIdentifiers = new HashSet { request.Action + request.Channel }; } - public override Task> HandleMessageAsync(SocketConnection connection, DataEvent message) + public override CallResult HandleMessage(SocketConnection connection, DataEvent message) { if (message.Data.Code != 200) - return Task.FromResult(new CallResult(new ServerError(message.Data.Code, message.Data.Message!))); + return new CallResult(new ServerError(message.Data.Code, message.Data.Message!)); - return base.HandleMessageAsync(connection, message); + return base.HandleMessage(connection, message); } } } diff --git a/Huobi.Net/Objects/Sockets/Queries/HuobiQuery.cs b/Huobi.Net/Objects/Sockets/Queries/HuobiQuery.cs index 6a4b3b96..91e9f3b8 100644 --- a/Huobi.Net/Objects/Sockets/Queries/HuobiQuery.cs +++ b/Huobi.Net/Objects/Sockets/Queries/HuobiQuery.cs @@ -17,12 +17,12 @@ public HuobiQuery(string topic, bool authenticated, int weight = 1) : base(new H ListenerIdentifiers = new HashSet { ((HuobiSocketRequest)Request).Id }; } - public override Task>> HandleMessageAsync(SocketConnection connection, DataEvent> message) + public override CallResult> HandleMessage(SocketConnection connection, DataEvent> message) { if (message.Data.IsSuccessful) - return Task.FromResult(new CallResult>(message.Data, message.OriginalData, null)); + return new CallResult>(message.Data, message.OriginalData, null); - return Task.FromResult(new CallResult>(new ServerError(message.Data.ErrorCode!, message.Data.ErrorMessage))); + return new CallResult>(new ServerError(message.Data.ErrorCode!, message.Data.ErrorMessage)); } } } diff --git a/Huobi.Net/Objects/Sockets/Queries/HuobiSubscribeQuery.cs b/Huobi.Net/Objects/Sockets/Queries/HuobiSubscribeQuery.cs index cc89e3ce..82ffa526 100644 --- a/Huobi.Net/Objects/Sockets/Queries/HuobiSubscribeQuery.cs +++ b/Huobi.Net/Objects/Sockets/Queries/HuobiSubscribeQuery.cs @@ -16,12 +16,12 @@ public HuobiSubscribeQuery(string topic, bool authenticated, int weight = 1) : b ListenerIdentifiers = new HashSet { ((HuobiSubscribeRequest)Request).Id }; } - public override Task> HandleMessageAsync(SocketConnection connection, DataEvent message) + public override CallResult HandleMessage(SocketConnection connection, DataEvent message) { if (message.Data.Status != "ok") - return Task.FromResult(new CallResult(new ServerError(message.Data.ErrorMessage!))); + return new CallResult(new ServerError(message.Data.ErrorMessage!)); - return Task.FromResult(new CallResult(message.Data, message.OriginalData, null)); + return new CallResult(message.Data, message.OriginalData, null); } } } diff --git a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiAccountSubscription.cs b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiAccountSubscription.cs index b766507e..67494828 100644 --- a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiAccountSubscription.cs +++ b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiAccountSubscription.cs @@ -1,7 +1,6 @@ using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Sockets; -using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Huobi.Net.Objects.Internal; using Huobi.Net.Objects.Models.Socket; using Huobi.Net.Objects.Sockets.Queries; @@ -34,11 +33,11 @@ public HuobiAccountSubscription(ILogger logger, string topic, Action DoHandleMessageAsync(SocketConnection connection, DataEvent message) + public override CallResult DoHandleMessage(SocketConnection connection, DataEvent message) { var update = (HuobiDataEvent)message.Data; _handler.Invoke(message.As(update.Data, update.Channel)); - return Task.FromResult(new CallResult(null)); + return new CallResult(null); } public override Type? GetMessageType(IMessageAccessor message) => typeof(HuobiDataEvent); diff --git a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiAuthPingSubscription.cs b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiAuthPingSubscription.cs index 7378cb4b..37216dd4 100644 --- a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiAuthPingSubscription.cs +++ b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiAuthPingSubscription.cs @@ -16,10 +16,10 @@ public HuobiAuthPingSubscription(ILogger logger) : base(logger, false) { } - public override Task HandleMessageAsync(SocketConnection connection, DataEvent message) + public override CallResult HandleMessage(SocketConnection connection, DataEvent message) { connection.Send(ExchangeHelpers.NextId(), new HuobiAuthPongMessage() { Action = "pong", Data = new HuobiAuthPongMessageTimestamp { Pong = message.Data.Data.Ping } }, 1); - return Task.FromResult(new CallResult(null)); + return new CallResult(null); } } } diff --git a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiOrderDetailsSubscription.cs b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiOrderDetailsSubscription.cs index 85d8ef47..1f68aa8a 100644 --- a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiOrderDetailsSubscription.cs +++ b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiOrderDetailsSubscription.cs @@ -1,8 +1,7 @@ -using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Converters.MessageParsing; +using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Sockets; -using CryptoExchange.Net.Sockets.MessageParsing; -using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Huobi.Net.Objects.Internal; using Huobi.Net.Objects.Models.Socket; using Huobi.Net.Objects.Sockets.Queries; @@ -41,14 +40,14 @@ public HuobiOrderDetailsSubscription( { return new HuobiAuthQuery("unsub", _topic, Authenticated); } - public override Task DoHandleMessageAsync(SocketConnection connection, DataEvent message) + public override CallResult DoHandleMessage(SocketConnection connection, DataEvent message) { var data = message.Data; if (data is HuobiDataEvent tradeEvent) _onOrderMatch?.Invoke(message.As(tradeEvent.Data, tradeEvent.Channel)); if (data is HuobiDataEvent cancelEvent) _onOrderCancel?.Invoke(message.As(cancelEvent.Data, cancelEvent.Channel)); - return Task.FromResult(new CallResult(null)); + return new CallResult(null); } public override Type? GetMessageType(IMessageAccessor message) diff --git a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiOrderSubscription.cs b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiOrderSubscription.cs index 9595a4af..4a2fe96b 100644 --- a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiOrderSubscription.cs +++ b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiOrderSubscription.cs @@ -1,8 +1,7 @@ -using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Converters.MessageParsing; +using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Sockets; -using CryptoExchange.Net.Sockets.MessageParsing; -using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Huobi.Net.Objects.Internal; using Huobi.Net.Objects.Models.Socket; using Huobi.Net.Objects.Sockets.Queries; @@ -50,7 +49,7 @@ public HuobiOrderSubscription( { return new HuobiAuthQuery("unsub", _topic, Authenticated); } - public override Task DoHandleMessageAsync(SocketConnection connection, DataEvent message) + public override CallResult DoHandleMessage(SocketConnection connection, DataEvent message) { var data = message.Data; if (data is HuobiDataEvent triggerFailEvent) @@ -63,7 +62,7 @@ public override Task DoHandleMessageAsync(SocketConnection connectio _onOrderMatched?.Invoke(message.As(matchOrderEvent.Data, matchOrderEvent.Channel)); if (data is HuobiDataEvent cancelOrderEvent) _onOrderCancelation?.Invoke(message.As(cancelOrderEvent.Data, cancelOrderEvent.Channel)); - return Task.FromResult(new CallResult(null)); + return new CallResult(null); } public override Type? GetMessageType(IMessageAccessor message) diff --git a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiPingSubscription.cs b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiPingSubscription.cs index 2ad59fe3..a94274cc 100644 --- a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiPingSubscription.cs +++ b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiPingSubscription.cs @@ -16,10 +16,10 @@ public HuobiPingSubscription(ILogger logger) : base(logger, false) { } - public override Task HandleMessageAsync(SocketConnection connection, DataEvent message) + public override CallResult HandleMessage(SocketConnection connection, DataEvent message) { connection.Send(ExchangeHelpers.NextId(), new HuobiPongMessage() { Pong = message.Data.Ping }, 1); - return Task.FromResult(new CallResult(null)); + return new CallResult(null); } } } diff --git a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiSpotPingSubscription.cs b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiSpotPingSubscription.cs index ba8efe80..57b3f61d 100644 --- a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiSpotPingSubscription.cs +++ b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiSpotPingSubscription.cs @@ -16,10 +16,10 @@ public HuobiSpotPingSubscription(ILogger logger) : base(logger, false) { } - public override Task HandleMessageAsync(SocketConnection connection, DataEvent message) + public override CallResult HandleMessage(SocketConnection connection, DataEvent message) { connection.Send(ExchangeHelpers.NextId(), new HuobiSpotPongMessage() { Pong = new HuobiSpotPingMessage { Ping = message.Data.Data.Ping } }, 1); - return Task.FromResult(new CallResult(null)); + return new CallResult(null); } } } diff --git a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiSubscription.cs b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiSubscription.cs index 1a5b3f7e..0ca87b11 100644 --- a/Huobi.Net/Objects/Sockets/Subscriptions/HuobiSubscription.cs +++ b/Huobi.Net/Objects/Sockets/Subscriptions/HuobiSubscription.cs @@ -1,7 +1,6 @@ using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Sockets; -using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Huobi.Net.Objects.Internal; using Huobi.Net.Objects.Sockets.Queries; using Microsoft.Extensions.Logging; @@ -36,11 +35,11 @@ public HuobiSubscription(ILogger logger, string topic, Action> hand public override Type? GetMessageType(IMessageAccessor message) => typeof(HuobiDataEvent); - public override Task DoHandleMessageAsync(SocketConnection connection, DataEvent message) + public override CallResult DoHandleMessage(SocketConnection connection, DataEvent message) { var huobiEvent = (HuobiDataEvent)message.Data; _handler.Invoke(message.As(huobiEvent.Data, huobiEvent.Channel)); - return Task.FromResult(new CallResult(null)); + return new CallResult(null); } } } diff --git a/Huobi.Net/Usings.cs b/Huobi.Net/Usings.cs new file mode 100644 index 00000000..d7109a0c --- /dev/null +++ b/Huobi.Net/Usings.cs @@ -0,0 +1,17 @@ +global using CryptoExchange.Net; +global using CryptoExchange.Net.Authentication; +global using CryptoExchange.Net.Converters.JsonNet; +global using CryptoExchange.Net.Interfaces; +global using CryptoExchange.Net.Objects; +global using Microsoft.Extensions.Logging; +global using Newtonsoft.Json; +global using Newtonsoft.Json.Linq; +global using Newtonsoft.Json.Serialization; +global using System; +global using System.Collections.Generic; +global using System.Globalization; +global using System.Linq; +global using System.Net.Http; +global using System.Security; +global using System.Threading; +global using System.Threading.Tasks; \ No newline at end of file diff --git a/README.md b/README.md index 38bc9ac1..aca9ff3c 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,10 @@ Make a one time donation in a crypto currency of your choice. If you prefer to d Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf). ## Release notes +* Version 5.2.0 - 16 Mar 2024 + * Updated CryptoExchange.Net to 7.1.0, see https://github.com/JKorf/CryptoExchange.Net?tab=readme-ov-file#release-notes for release notes + * Updated unit test package dependencies and updated tests accordingly + * Version 5.1.0 - 25 Feb 2024 * Updated CryptoExchange.Net and implemented reworked websocket message handling. For release notes for the CryptoExchange.Net base library see: https://github.com/JKorf/CryptoExchange.Net?tab=readme-ov-file#release-notes * Fixed issue in DI registration causing http client to not be correctly injected