Bitstamp 认证 API hmac
Bitstamp Authenticated API hmac
我希望你在这方面的运气比我好。
如标题所示,我正在尝试访问 bitstamp.net 上的私有 API 端点。 https://www.bitstamp.net/api/#api-authentication 尽我所能,我无法使签名有意义。我已经尽我所能地关注文档,我花了几个小时试图尽可能多地学习 python 并解密文档,因为没有 JavaScript 示例。
签名应该是 API 秘密的 sha256 hmac 和消息变量,它是一个反斜杠分隔的字符串,我再也找不到任何问题了。
我使用下面的 link 来查询服务器,apikey 和 secret 将在这一切正常时在生产中进行编码和解码。
http://localhost:3001/sha256/jorw1007/QGcJKrhenfqOML5cOpTsLOe9IbEPsJnN/bKXiqtYHawJ7DAUZIHviAPoRrp0zhfIv
const crypto = require('crypto');
app.get("/sha256/:id/:key/:secret", cors(), (request, response, next) => {
const APIkey = "BITSTAMP" + " " + request.params.key;
const APIsecret = request.params.secret;
const urlHost = "192.168.0.120:3001"; // where is querying the API from bitstamp? in this case its the server localhost:3001
const urlPath = "/api/v2/balance/";
const urlQuery = "";
const UTC = Date.now().toString();
const nonce = randomBytes(18).toString("hex").toLowerCase();
const nonce2 = "f93c979d-b00d-43a9-9b9c-fd4cd9547fa6"
const contentType = "application/x-www-form-urlencoded";
const version = "v2";
const payload = urlencoded({"offset": "1"})
let message = `${APIkey}\POST\${urlHost}\${urlPath}\${urlQuery}\${nonce}\${UTC}\${version}\`
// const encodedMsg = encodeURI(message) ///why are we encoding?
// const signature = createHmac("sha256", APIsecret ).update(JSON.stringify(encodedMsg) );
// const sigDigested = signature.digest('hex')
var signature = crypto.createHmac('sha256', APIsecret).update(encodeURI(message));
// to lowercase hexits
const digestedHash = signature.digest('hex');
console.log(message)
const headers = {
"X-Auth": APIkey,
"X-Auth-Signature": digestedHash,
"X-Auth-Nonce": nonce,
"X-Auth-Timestamp": UTC,
"X-Auth-Version": version,
};
fetch("https://www.bitstamp.net/api/v2/balance/", {
headers,
method: "POST",
data : payload
})
.then((res) => res.json())
.then((json) => response.send(json))
.catch((err) => console.error(err));
});
我不断收到错误 'API0005',这意味着签名无效。
有人能给我指出正确的方向吗?
谢谢
经过无数努力,我终于成功了。我将发布的代码是用 C# 编写的,但它与 JavaScript.
的代码非常相似
protected async Task<string> SendRequest(string @base, string endpoint, EndpointHttpMethod method, Dictionary<string, object> parameters = null, bool signed = true)
{
var resiliencyStrategy = ExchangeTools.DefineAndRetrieveResiliencyStrategy("Bitstamp");
parameters ??= new Dictionary<string, object>();
var payloadString = string.Empty;
var queryParameters = string.Empty;
var contentType = string.Empty;
if (method == EndpointHttpMethod.GET)
{
queryParameters = ExchangeTools.BuildQuery(parameters);
endpoint += !string.IsNullOrWhiteSpace(queryParameters) ? $"?{queryParameters}" : string.Empty;
}
else
{
payloadString = ExchangeTools.BuildQuery(parameters, true);
contentType = !string.IsNullOrWhiteSpace(payloadString) ? "application/x-www-form-urlencoded" : string.Empty;
}
using var client = new HttpClient();
using var httpRequestMessage = new HttpRequestMessage(new HttpMethod(method.ToString()), endpoint);
client.BaseAddress = new Uri(Endpoints.BasePrefix + @base);
if (signed)
{
var apiKey = $"BITSTAMP {publicKey}";
var version = "v2";
var nonce = Guid.NewGuid();
var timestamp = ExchangeTools.GetUnixTimestamp(1000);
var msg = $"{apiKey}{method}{@base}{endpoint}{queryParameters}{contentType}{nonce}{timestamp}{version}{payloadString}";
var signature = ExchangeTools.Sign(msg, privateKey, HashingAlgorithm.HMACSHA256, ByteEncoding.ASCII, SignatureEncoding.HexString);
httpRequestMessage.Headers.Add("X-Auth", apiKey);
httpRequestMessage.Headers.Add("X-Auth-Signature", signature);
httpRequestMessage.Headers.Add("X-Auth-Nonce", nonce.ToString()); ;
httpRequestMessage.Headers.Add("X-Auth-Timestamp", timestamp.ToString()); ;
httpRequestMessage.Headers.Add("X-Auth-Version", version);
if(parameters.Count > 0)
{
httpRequestMessage.Content = new FormUrlEncodedContent(parameters.ToDictionary(kv => kv.Key, kv => kv.Value.ToString()));
}
}
var response = await resiliencyStrategy.ExecuteAsync(() => client.SendAsync(httpRequestMessage));
var result = await response.Content.ReadAsStringAsync();
return result;
}
如果您需要进一步说明,请告诉我。我对你为什么不工作的最佳猜测归结为有条件地设置有效负载和查询参数,具体取决于你拥有的参数以及请求是 GET 还是 POST.
我希望你在这方面的运气比我好。
如标题所示,我正在尝试访问 bitstamp.net 上的私有 API 端点。 https://www.bitstamp.net/api/#api-authentication 尽我所能,我无法使签名有意义。我已经尽我所能地关注文档,我花了几个小时试图尽可能多地学习 python 并解密文档,因为没有 JavaScript 示例。
签名应该是 API 秘密的 sha256 hmac 和消息变量,它是一个反斜杠分隔的字符串,我再也找不到任何问题了。
我使用下面的 link 来查询服务器,apikey 和 secret 将在这一切正常时在生产中进行编码和解码。
http://localhost:3001/sha256/jorw1007/QGcJKrhenfqOML5cOpTsLOe9IbEPsJnN/bKXiqtYHawJ7DAUZIHviAPoRrp0zhfIv
const crypto = require('crypto');
app.get("/sha256/:id/:key/:secret", cors(), (request, response, next) => {
const APIkey = "BITSTAMP" + " " + request.params.key;
const APIsecret = request.params.secret;
const urlHost = "192.168.0.120:3001"; // where is querying the API from bitstamp? in this case its the server localhost:3001
const urlPath = "/api/v2/balance/";
const urlQuery = "";
const UTC = Date.now().toString();
const nonce = randomBytes(18).toString("hex").toLowerCase();
const nonce2 = "f93c979d-b00d-43a9-9b9c-fd4cd9547fa6"
const contentType = "application/x-www-form-urlencoded";
const version = "v2";
const payload = urlencoded({"offset": "1"})
let message = `${APIkey}\POST\${urlHost}\${urlPath}\${urlQuery}\${nonce}\${UTC}\${version}\`
// const encodedMsg = encodeURI(message) ///why are we encoding?
// const signature = createHmac("sha256", APIsecret ).update(JSON.stringify(encodedMsg) );
// const sigDigested = signature.digest('hex')
var signature = crypto.createHmac('sha256', APIsecret).update(encodeURI(message));
// to lowercase hexits
const digestedHash = signature.digest('hex');
console.log(message)
const headers = {
"X-Auth": APIkey,
"X-Auth-Signature": digestedHash,
"X-Auth-Nonce": nonce,
"X-Auth-Timestamp": UTC,
"X-Auth-Version": version,
};
fetch("https://www.bitstamp.net/api/v2/balance/", {
headers,
method: "POST",
data : payload
})
.then((res) => res.json())
.then((json) => response.send(json))
.catch((err) => console.error(err));
});
我不断收到错误 'API0005',这意味着签名无效。
有人能给我指出正确的方向吗?
谢谢
经过无数努力,我终于成功了。我将发布的代码是用 C# 编写的,但它与 JavaScript.
的代码非常相似protected async Task<string> SendRequest(string @base, string endpoint, EndpointHttpMethod method, Dictionary<string, object> parameters = null, bool signed = true)
{
var resiliencyStrategy = ExchangeTools.DefineAndRetrieveResiliencyStrategy("Bitstamp");
parameters ??= new Dictionary<string, object>();
var payloadString = string.Empty;
var queryParameters = string.Empty;
var contentType = string.Empty;
if (method == EndpointHttpMethod.GET)
{
queryParameters = ExchangeTools.BuildQuery(parameters);
endpoint += !string.IsNullOrWhiteSpace(queryParameters) ? $"?{queryParameters}" : string.Empty;
}
else
{
payloadString = ExchangeTools.BuildQuery(parameters, true);
contentType = !string.IsNullOrWhiteSpace(payloadString) ? "application/x-www-form-urlencoded" : string.Empty;
}
using var client = new HttpClient();
using var httpRequestMessage = new HttpRequestMessage(new HttpMethod(method.ToString()), endpoint);
client.BaseAddress = new Uri(Endpoints.BasePrefix + @base);
if (signed)
{
var apiKey = $"BITSTAMP {publicKey}";
var version = "v2";
var nonce = Guid.NewGuid();
var timestamp = ExchangeTools.GetUnixTimestamp(1000);
var msg = $"{apiKey}{method}{@base}{endpoint}{queryParameters}{contentType}{nonce}{timestamp}{version}{payloadString}";
var signature = ExchangeTools.Sign(msg, privateKey, HashingAlgorithm.HMACSHA256, ByteEncoding.ASCII, SignatureEncoding.HexString);
httpRequestMessage.Headers.Add("X-Auth", apiKey);
httpRequestMessage.Headers.Add("X-Auth-Signature", signature);
httpRequestMessage.Headers.Add("X-Auth-Nonce", nonce.ToString()); ;
httpRequestMessage.Headers.Add("X-Auth-Timestamp", timestamp.ToString()); ;
httpRequestMessage.Headers.Add("X-Auth-Version", version);
if(parameters.Count > 0)
{
httpRequestMessage.Content = new FormUrlEncodedContent(parameters.ToDictionary(kv => kv.Key, kv => kv.Value.ToString()));
}
}
var response = await resiliencyStrategy.ExecuteAsync(() => client.SendAsync(httpRequestMessage));
var result = await response.Content.ReadAsStringAsync();
return result;
}
如果您需要进一步说明,请告诉我。我对你为什么不工作的最佳猜测归结为有条件地设置有效负载和查询参数,具体取决于你拥有的参数以及请求是 GET 还是 POST.