Kraken private API 与 F# returns EGeneral:无效参数
Kraken private API with F# returns EGeneral: invalid arguments
我正在尝试使用 F# 访问 Kraken private API。访问 public API 的代码运行得很好,但是当我尝试访问私有 API 时,我总是收到错误 "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
)
有没有人body看出我做错了什么?
编辑:
Kraken.com API 文档可在此处获取:https://www.kraken.com/help/api
我想 header 签名不正确。该文档要求在 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
编辑 2:
剩下的参数需要用POST的方式传递。在我的例子中,这只是 HTTP 请求的 body 部分中的 "nonce" 值。
我在为 Kraken 编写 C# 库时遇到了同样的错误,我找到了这个问题的解决方案:
如果 API 键或符号错误或丢失,则不会出现此错误。问题是您没有在请求中添加媒体类型。我不知道它在 F# 中是如何工作的,但看看这个例子:
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();
}
"application/x-www-form-urlencoded"是关键路径。如果您不发送请求,您将收到 "EGeneral: invalid arguments"-错误。有了它,一切正常。至少在我的情况下。
我正在尝试使用 F# 访问 Kraken private API。访问 public API 的代码运行得很好,但是当我尝试访问私有 API 时,我总是收到错误 "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
)
有没有人body看出我做错了什么?
编辑: Kraken.com API 文档可在此处获取:https://www.kraken.com/help/api
我想 header 签名不正确。该文档要求在 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
编辑 2: 剩下的参数需要用POST的方式传递。在我的例子中,这只是 HTTP 请求的 body 部分中的 "nonce" 值。
我在为 Kraken 编写 C# 库时遇到了同样的错误,我找到了这个问题的解决方案:
如果 API 键或符号错误或丢失,则不会出现此错误。问题是您没有在请求中添加媒体类型。我不知道它在 F# 中是如何工作的,但看看这个例子:
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();
}
"application/x-www-form-urlencoded"是关键路径。如果您不发送请求,您将收到 "EGeneral: invalid arguments"-错误。有了它,一切正常。至少在我的情况下。