socketClient.SpotApi.SubscribeToUserTradeUpdatesAsync requires webSocketToken
Closed this issue · 2 comments
Describe the bug
The webSocketToken could nowhere be found and also the corresponding function GetWebSocketsToken not.
var tickerSubscriptionResult = await _socketClient.SpotApi.SubscribeToUserTradeUpdatesAsync(webSocketToken, (data) =>
{
//TODO: Something
}, CancellationToken.None);
To Reproduce
SpotApi.SubscribeToUserTradeUpdatesAsync
Expected behavior
Please add possibility to get the token or remove it from the signature and do it internally.
Kraken provides example code how to obtain the WebSocketsToken:
https://support.kraken.com/hc/en-us/articles/4407678695316-Example-code-for-C-REST-and-WebSocket-API
private static readonly string[] separator = ["\"token\":\"", "\"}}"];
string webSocketRestResponseJSON = await QueryPrivateEndpoint("GetWebSocketsToken", "", _configuration["KrakenApiKey"], _configuration["KrakenSecret"]);
var splits = webSocketRestResponseJSON.Split(separator, StringSplitOptions.None);
string webSocketToken = splits[1];
#region Private REST API Endpoints
private static async Task<string> QueryPrivateEndpoint(string endpointName,
string inputParameters,
string apiPublicKey,
string apiPrivateKey)
{
string baseDomain = "https://api.kraken.com";
string privatePath = "/0/private/";
string apiEndpointFullURL = baseDomain + privatePath + endpointName;
string nonce = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
if (string.IsNullOrWhiteSpace(inputParameters) == false)
{
inputParameters = "&" + inputParameters;
}
string apiPostBodyData = "nonce=" + nonce + inputParameters;
string signature = CreateAuthenticationSignature(apiPrivateKey,
privatePath,
endpointName,
nonce,
inputParameters);
string jsonData;
using (HttpClient client = new())
{
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("API-Key", apiPublicKey);
client.DefaultRequestHeaders.Add("API-Sign", signature);
client.DefaultRequestHeaders.Add("User-Agent", "KrakenDotNet Client");
StringContent data = new(apiPostBodyData, Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage response = await client.PostAsync(apiEndpointFullURL, data);
jsonData = response.Content.ReadAsStringAsync().Result;
}
return jsonData;
}
#endregion
#region Authentication Algorithm
public static string CreateAuthenticationSignature(string apiPrivateKey,
string apiPath,
string endpointName,
string nonce,
string inputParams)
{
byte[] sha256Hash = ComputeSha256Hash(nonce, inputParams);
byte[] sha512Hash = ComputeSha512Hash(apiPrivateKey, sha256Hash, apiPath, endpointName);
string signatureString = Convert.ToBase64String(sha512Hash);
return signatureString;
}
private static byte[] ComputeSha256Hash(string nonce, string inputParams)
{
byte[] sha256Hash;
string sha256HashData = nonce.ToString() + "nonce=" + nonce.ToString() + inputParams;
sha256Hash = SHA256.HashData(Encoding.UTF8.GetBytes(sha256HashData));
return sha256Hash;
}
private static byte[] ComputeSha512Hash(string apiPrivateKey,
byte[] sha256Hash,
string apiPath,
string endpointName)
{
string apiEndpointPath = apiPath + endpointName;
byte[] apiEndpointPathBytes = Encoding.UTF8.GetBytes(apiEndpointPath);
byte[] sha512HashData = [.. apiEndpointPathBytes, .. sha256Hash];
HMACSHA512 encryptor = new(Convert.FromBase64String(apiPrivateKey));
byte[] sha512Hash = encryptor.ComputeHash(sha512HashData);
return sha512Hash;
}
#endregion
You can request the token using the rest client and then provide it using the socket client.
// Retrieve the token
var tokenResult = await krakenClient.SpotApi.Account.GetWebsocketTokenAsync();
// Subscribe using the token
await krakenSocketClient.SpotApi.SubscribeToUserTradeUpdatesAsync(tokenResult.Data.Token, data => {
// Handle update
});
Great that works perfectly well. Many thanks for your fast help!
The Issue can be closed. 👍