Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
JKorf committed Jan 14, 2025
1 parent 236b57f commit ecbdcd1
Show file tree
Hide file tree
Showing 15 changed files with 441 additions and 58 deletions.
11 changes: 11 additions & 0 deletions HyperLiquid.Net/Clients/Api/HyperLiquidRestClientApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.SharedApis;
using CryptoExchange.Net.Converters.MessageParsing;
using HyperLiquid.Net.Objects.Models;

namespace HyperLiquid.Net.Clients.Api
{
Expand Down Expand Up @@ -80,6 +81,16 @@ internal async Task<WebCallResult<T>> SendToAddressAsync<T>(string baseAddress,
return result;
}

internal async Task<WebCallResult<T>> SendAuthAsync<T>(RequestDefinition definition, ParameterCollection? parameters, CancellationToken cancellationToken, int? weight = null)
{
var result = await SendToAddressAsync<HyperLiquidAuthResponse<T>>(BaseAddress, definition, parameters, cancellationToken, weight).ConfigureAwait(false);
if (!result)
return result.As<T>(default);

return result.As<T>(result.Data.Data);
}


protected override Error? TryParseError(IEnumerable<KeyValuePair<string, IEnumerable<string>>> responseHeaders, IMessageAccessor accessor)
{
var status = accessor.GetValue<string?>(MessagePath.Get().Property("status"));
Expand Down
98 changes: 94 additions & 4 deletions HyperLiquid.Net/Clients/Api/HyperLiquidRestClientApiTrading.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Threading.Tasks;
using System.Threading;
using System;
using HyperLiquid.Net.Utils;
using HyperLiquid.Net.Enums;

namespace HyperLiquid.Net.Clients.Api
{
Expand Down Expand Up @@ -140,12 +142,94 @@ public async Task<WebCallResult<IEnumerable<HyperLiquidOrderStatus>>> GetClosedO

#endregion

#region Place Multiple Orders

/// <inheritdoc />
public async Task<WebCallResult<IEnumerable<CallResult<HyperLiquidOrderResult>>>> PlaceMultipleOrdersAsync(
IEnumerable<HyperLiquidOrderRequest> orders,
CancellationToken ct = default)
{
var orderRequests = new List<ParameterCollection>();
foreach(var order in orders)
{
var symbolId = await HyperLiquidUtils.GetSymbolIdFromName(order.SymbolType, order.Symbol).ConfigureAwait(false);
if (!symbolId)
return new WebCallResult<IEnumerable<CallResult<HyperLiquidOrderResult>>>(symbolId.Error);

var orderParameters = new ParameterCollection();
orderParameters.Add("a", symbolId.Data);
orderParameters.AddString("s", order.Quantity);

var orderTypeParameters = new ParameterCollection();
if (order.OrderType == OrderType.Limit)
{
var limitParameters = new ParameterCollection();
limitParameters.AddEnum("tif", order.TimeInForce);
orderTypeParameters.Add("limit", limitParameters);
}
else if(order.OrderType == OrderType.StopMarket || order.OrderType == OrderType.StopLimit)
{
var triggerParameters = new ParameterCollection();
triggerParameters.Add("isMarket", order.TimeInForce);
triggerParameters.Add("triggerPx", order.TriggerPrice);
triggerParameters.AddEnum("tpsl", order.TpSlType);
orderTypeParameters.Add("trigger", triggerParameters);
}

orderParameters.Add("t", orderTypeParameters);

orderParameters.AddOptional("b", order.Side == OrderSide.Buy);
orderParameters.AddOptionalString("p", order.Price);
orderParameters.AddOptional("r", order.ReduceOnly);
orderParameters.AddOptional("c", order.ClientOrderId);
#warning TODO builder

Check warning on line 185 in HyperLiquid.Net/Clients/Api/HyperLiquidRestClientApiTrading.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'TODO builder'
if (order.TpSlGrouping != null)
orderParameters.AddEnum("grouping", order.TpSlGrouping);
else
orderParameters.Add("grouping", "na");

orderRequests.Add(orderParameters);
}

var parameters = new ParameterCollection()
{
{
"action", new ParameterCollection
{
{ "type", "order" },
{ "orders", orderRequests }
}
}
};

var request = _definitions.GetOrCreate(HttpMethod.Post, "exchange", HyperLiquidExchange.RateLimiter.HyperLiquid, 1, true);
var intResult = await _baseClient.SendAuthAsync<IEnumerable<HyperLiquidOrderResultInt>>(request, parameters, ct).ConfigureAwait(false);
if(!intResult)
return intResult.As<IEnumerable<CallResult<HyperLiquidOrderResult>>>(default);

var result = new List<CallResult<HyperLiquidOrderResult>>();
foreach (var order in intResult.Data)
{
if (order.Error != null)
result.Add(new CallResult<HyperLiquidOrderResult>(new ServerError(order.Error)));
else
result.Add(new CallResult<HyperLiquidOrderResult>(order.ResultResting ?? order.ResultFilled!));
}

return intResult.As<IEnumerable<CallResult<HyperLiquidOrderResult>>>(result);
}

#endregion

#region Cancel Order

/// <inheritdoc />
public async Task<WebCallResult<IEnumerable<HyperLiquidOrderStatus>>> CancelOrderAsync(string symbol, long orderId, CancellationToken ct = default)
public async Task<WebCallResult> CancelOrderAsync(SymbolType symbolType, string symbol, long orderId, CancellationToken ct = default)
{
var symbolId = 1; // TODO
var symbolId = await HyperLiquidUtils.GetSymbolIdFromName(symbolType, symbol).ConfigureAwait(false);
if (!symbolId)
return new WebCallResult(symbolId.Error!);

var parameters = new ParameterCollection()
{
{
Expand All @@ -157,7 +241,7 @@ public async Task<WebCallResult<IEnumerable<HyperLiquidOrderStatus>>> CancelOrde
{
new ParameterCollection
{
{ "a", symbolId },
{ "a", symbolId.Data },
{ "o", orderId }
}
}
Expand All @@ -167,7 +251,13 @@ public async Task<WebCallResult<IEnumerable<HyperLiquidOrderStatus>>> CancelOrde
};

var request = _definitions.GetOrCreate(HttpMethod.Post, "exchange", HyperLiquidExchange.RateLimiter.HyperLiquid, 1, true);
return await _baseClient.SendAsync<IEnumerable<HyperLiquidOrderStatus>>(request, parameters, ct).ConfigureAwait(false);
var result = await _baseClient.SendAuthAsync<HyperLiquidOrderStatusResult>(request, parameters, ct).ConfigureAwait(false);
if (!result)
return result.AsDatalessError(result.Error!);

#warning check responses

Check warning on line 258 in HyperLiquid.Net/Clients/Api/HyperLiquidRestClientApiTrading.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'check responses'

return result.AsDataless();
}

#endregion
Expand Down
12 changes: 12 additions & 0 deletions HyperLiquid.Net/Enums/SymbolType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace HyperLiquid.Net.Enums
{
public enum SymbolType
{
Spot,
Futures
}
}
29 changes: 29 additions & 0 deletions HyperLiquid.Net/Enums/TimeInForce.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using CryptoExchange.Net.Attributes;
using System;
using System.Collections.Generic;
using System.Text;

namespace HyperLiquid.Net.Enums
{
/// <summary>
/// Time in force
/// </summary>
public enum TimeInForce
{
/// <summary>
/// Post only
/// </summary>
[Map("Alo")]
PostOnly,
/// <summary>
/// Immediate or cancel
/// </summary>
[Map("Ioc")]
ImmediateOrCancel,
/// <summary>
/// Good till canceled
/// </summary>
[Map("Gtc")]
GoodTillCanceled
}
}
21 changes: 21 additions & 0 deletions HyperLiquid.Net/Enums/TpSlGrouping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace HyperLiquid.Net.Enums
{
/// <summary>
/// TakeProfit/StopLoss grouping
/// </summary>
public enum TpSlGrouping
{
/// <summary>
/// Normal TakeProfit/StopLoss
/// </summary>
NormalTpSl,
/// <summary>
/// Position TakeProfit/StopLoss
/// </summary>
PositionTpSl
}
}
12 changes: 12 additions & 0 deletions HyperLiquid.Net/Enums/TpSlType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace HyperLiquid.Net.Enums
{
public enum TpSlType
{
TakeProfit,
StopLoss
}
}
70 changes: 54 additions & 16 deletions HyperLiquid.Net/HyperLiquid.Net.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions HyperLiquid.Net/HyperLiquidAuthenticationProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Nethereum.Util;
using Nethereum.Signer;
using Nethereum.ABI.EIP712;
using HyperLiquid.Net.Utils;

namespace HyperLiquid.Net
{
Expand Down Expand Up @@ -75,15 +76,14 @@ public override void AuthenticateRequest(
bodyParameters!.Add("nonce", nonce);
var action = bodyParameters["action"];

var hash = this.actionHash(action, nonce);
var hash = GenerateActionHash(action, nonce);
var phantomAgent = new Dictionary<string, object>()
{
{ "source", "a" },
{ "connectionId", hash },
};

var msg = ethEncodeStructuredData(_domain, _messageTypes, phantomAgent);

var msg = EncodeEip721(_domain, _messageTypes, phantomAgent);
var keccakSigned = BytesToHexString(SignKeccak(msg));
var signature = SignRequest(keccakSigned, ApiKey);

Expand All @@ -100,11 +100,11 @@ public static Dictionary<string, object> SignRequest(string request, string secr
{
{ "r", "0x" + BytesToHexString(sign.R).ToLowerInvariant() },
{ "s", "0x" + BytesToHexString(sign.S).ToLowerInvariant() },
{ "v", ((int)sign.V[0]) - 27 },
{ "v", ((int)sign.V[0]) - 27 }
};
}

public byte[] ethEncodeStructuredData(
public byte[] EncodeEip721(
Dictionary<string, object> domain,
Dictionary<string, object> messageTypes,
Dictionary<string, object> messageData)
Expand Down Expand Up @@ -186,7 +186,7 @@ public byte[] ethEncodeStructuredData(
return Eip712TypedDataSigner.Current.EncodeTypedDataRaw(typeRaw);
}

private byte[] actionHash(object action, long nonce)
private byte[] GenerateActionHash(object action, long nonce)
{
var packer = new PackConverter();
var dataHex = BytesToHexString(packer.Pack(action));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using CryptoExchange.Net.Objects;
using HyperLiquid.Net.Objects.Models;
using System;
using HyperLiquid.Net.Enums;

namespace HyperLiquid.Net.Interfaces.Clients.Api
{
Expand All @@ -27,6 +28,10 @@ Task<WebCallResult<IEnumerable<HyperLiquidUserTrade>>> GetUserTradesByTimeAsync(

Task<WebCallResult<IEnumerable<HyperLiquidOrderStatus>>> GetClosedOrdersAsync(string address, CancellationToken ct = default);

Task<WebCallResult<IEnumerable<HyperLiquidOrderStatus>>> CancelOrderAsync(string symbol, long orderId, CancellationToken ct = default);
Task<WebCallResult> CancelOrderAsync(SymbolType symbolType, string symbol, long orderId, CancellationToken ct = default);

Task<WebCallResult<IEnumerable<CallResult<HyperLiquidOrderResult>>>> PlaceMultipleOrdersAsync(
IEnumerable<HyperLiquidOrderRequest> orders,
CancellationToken ct = default);
}
}
Loading

0 comments on commit ecbdcd1

Please sign in to comment.