For private endpoints of Crypto.com, I am getting the error:
{ id: xx,
method: 'private/get-order-detail',
code: 10007,
message: 'INVALID_NONCE' }
for the following code:
function getOrderStatus() {
var nonce = Math.floor(new Date().setSeconds(new Date().getSeconds() - 10) / 1000);
nonce += 1; // Increment nonce for each request, is this the increase?
var payload = {
"id": orderId,
"method": "private/get-order-detail",
"params": {
"order_id": orderId
},
"nonce": nonce
};
var payloadString = JSON.stringify(payload);
var signature = Utilities.computeHmacSha256Signature(payloadString, secretKey);
var signatureHex = Utilities.base64Encode(signature).toString();
var headers = {
"Content-Type": "application/json",
"API-Key": apiKey,
"Signature": signatureHex,
"Timestamp": nonce
};
var options = {
"method": "post",
"headers": headers,
"payload": payloadString,
"muteHttpExceptions": true
};
var response = UrlFetchApp.fetch("https://api.crypto.com/v2/private/get-order-detail", options);
var data = JSON.parse(response.getContentText());
console.log(data)
return data;
}
From my understanding, the nonce value needs to be increasing on every request?
When I saw the official document of Crypto.com Spot Exchange V2.1 API for Exchange reference documentation,
nonce long Y Current timestamp (milliseconds since the Unix epoch)
It seems that the sample value of nonce
is 1587846358253
.
When I saw your script using new Date('2020-04-26T05:25:58.253Z')
, 1587878748
is returned as nonce
. And, the document says about code: 10007,
as 10007 400 INVALID_NONCE Nonce value differs by more than 30 seconds from server
.
If my understanding is correct, I thought that this might be the reason for your current issue. If my understanding is correct, how about the following modification?
var nonce = Math.floor(new Date().setSeconds(new Date().getSeconds() - 10) / 1000);
var nonce = new Date().setSeconds(new Date().getSeconds() - 10);
or
var nonce = new Date().getTime();
or
var nonce = new Date().getTime().toString();
nonce
correctly works for using the API you want to use. Please be careful about this.From your following reply,
with the change it gives a permission error code: 10002, message: 'UNAUTHORIZED' }. I know the API keys are correct.
I could confirm that your issue of nonce
in your question was resolved. And also, I confirmed that your other part script except for nonce
was not correct, and, this is your new issue. In this case, I think that it is required to modify your request. I think that your issue of nonce
of this question can be resolved by my answer. So, how about modifying your request as follows?
The function signRequest
is from https://exchange-docs.crypto.com/spot/index.html#request-format.
function myFunction() {
// Please set your valid values.
const nonce = new Date().getTime();
const id = "###"; // Please set your ID.
const orderId = "###"; // Please set your order ID.
const apiKey = "###"; // Please set your API key.
const apiSecret = "###"; // Please set your secret.
const signRequest = (request_body, api_key, secret) => {
const { id, method, params, nonce } = request_body;
function isObject(obj) { return obj !== undefined && obj !== null && obj.constructor == Object; }
function isArray(obj) { return obj !== undefined && obj !== null && obj.constructor == Array; }
function arrayToString(obj) { return obj.reduce((a, b) => { return a + (isObject(b) ? objectToString(b) : (isArray(b) ? arrayToString(b) : b)); }, ""); }
function objectToString(obj) { return (obj == null ? "" : Object.keys(obj).sort().reduce((a, b) => { return a + b + (isArray(obj[b]) ? arrayToString(obj[b]) : (isObject(obj[b]) ? objectToString(obj[b]) : obj[b])); }, "")); }
const paramsString = objectToString(params);
console.log(paramsString);
const sigPayload = method + id + api_key + paramsString + nonce;
request_body.sig = Utilities.computeHmacSha256Signature(sigPayload, secret).map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
return request_body;
};
let request = {
id: id,
method: "private/get-order-detail",
api_key: apiKey,
params: { order_id: orderId },
nonce: nonce,
};
const requestBody = JSON.stringify(signRequest(request, apiKey, apiSecret));
const options = {
method: "post",
contentType: "application/json",
payload: requestBody,
}
var response = UrlFetchApp.fetch("https://api.crypto.com/v2/private/get-order-detail", options);
var data = JSON.parse(response.getContentText());
console.log(data)
return data;
}