private FormUrlEncodedContent CreateHttpContent(IKrakenRequest requestData, long nonce, string uriPath) { var pathBytes = Encoding.UTF8.GetBytes($"/0/private/{uriPath}"); var props = "nonce=" + nonce + string.Join("", requestData.FormData.Select(x => $"&{x.Key}={x.Value}")); var np = nonce + Convert.ToChar(0) + props; var hash = Sha256(np); var z = new byte[pathBytes.Length + hash.Length]; pathBytes.CopyTo(z, 0); hash.CopyTo(z, pathBytes.Length); var signature = HmacSha512(Convert.FromBase64String(apiPrivateKey), z); var sigString = Convert.ToBase64String(signature); var data = new List <KeyValuePair <string, string> >(); data.Add(new KeyValuePair <string, string>("nonce", nonce.ToString())); data.AddRange(requestData.FormData); var content = new FormUrlEncodedContent(data); content.Headers.Add(ApiKeyHeader, new [] { apiKey }); content.Headers.Add(ApiSignHeader, new [] { sigString }); return(content); }
private async Task <T> MakePostRequestAsync <T>(string url, IKrakenRequest request, TranslatedSignalTableEntity translatedSignal, CancellationToken cancellationToken) { try { var now = DateTime.UtcNow; if ((now - lastRequestTime).TotalSeconds <= 2) { await Task.Delay(TimeSpan.FromSeconds(2), cancellationToken); } lastRequestTime = DateTime.UtcNow; var content = CreateHttpContent(request, nonceProvider.GetNonce(), url); var response = await apiClient.MakePostRequestAsync <ResponseBase <T> >($"{endpointUrl}/{url}", content, translatedSignal.RequestSent, translatedSignal.ResponseReceived, cancellationToken); if (response.Error.Any()) { if (response.Error.Any(x => x == "EOrder:Insufficient funds")) { throw new InsufficientFundsException(); } else { throw new ApiException(string.Join("; ", response.Error)); } } return(response.Result); } catch (Exception e) { translatedSignal?.Failure(e); throw; } }