Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kraken private API with F# returns EGeneral: invalid arguments

I am trying to access the Kraken private API using F#. The code to access the public API runs perfectly fine, but when i try to access the private API i am always getting the error "EGeneral:Invalid arguments".

#r "FSharp.Data.dll"

open FSharp.Data
open System
open System.Text
open System.Security.Cryptography

let baseUri = "https://api.kraken.com"
let key = MY_KRAKEN_API_KEY
let secret = MY_KRAKEN_API_SECRET
let path = "/0/private/Balance"
let nonce = DateTime.UtcNow.Ticks
let bodyText = "nonce=" + nonce.ToString()

let hmac (key : byte []) (data : byte[]) =
    use hmac = new HMACSHA512(key)
    hmac.ComputeHash(data)

let sha256 (data : string) =
    use sha = SHA256Managed.Create()
    sha.ComputeHash(Encoding.UTF8.GetBytes(data))

let createSignature (nonce : int64) body (path : string) secret =
    let shaSum = nonce.ToString() + body |> sha256
    let data = Array.append (Encoding.UTF8.GetBytes path) shaSum
    let key = Convert.FromBase64String secret
    hmac key data |> Convert.ToBase64String

let signature = createSignature nonce bodyText path secret

let response = Http.RequestString (
    url = baseUri + path,
    httpMethod = "POST",
    headers = ([("API-Key", key); ("API-Sign", signature)] |> Seq.ofList),
    body = TextRequest bodyText
)

Does anybody see what i am doing wrong?

EDIT: The Kraken.com API documentation is awailable here: https://www.kraken.com/help/api

I suppose the header signature is incorrect. The docu requires the following two values to be submitted in the header:

API-Key = API key API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key

EDIT 2: The remaining parameters need to be transmitted with a POST method. In my case this is only the "nonce" value in the body part of the HTTP request.

like image 425
Philipp Gebhard Avatar asked Sep 08 '25 11:09

Philipp Gebhard


1 Answers

I had the same error while I was writing a C# library for Kraken and I found a solution of this problem:

This error does not appears if the API key or the sign are wrong or missing. The problem is that you do not add a mediatype to your request. I do not know how it works in F# but look at this example:

using (var client = new HttpClient())
{
    string address = String.Format("{0}/{1}/public/{2}", _url, _version, method);
    // Does not work with this:
    // var content = new StringContent(postData, Encoding.UTF8);
    var content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded");

    var response = await client.PostAsync(address, content);

    return await response.Content.ReadAsStringAsync();
}

The "application/x-www-form-urlencoded" is the critical path. If you do not send a request with that, you get the "EGeneral: invalid arguments"-error. With it, everything works fine. At least in my case.

like image 155
bittnerd Avatar answered Sep 11 '25 17:09

bittnerd