4

I am pulling my hair out trying to query the CoinSpot API.

The endpoint for the Read Only API is: https://www.coinspot.com.au/api/ro

The documentation states:

All requests to the API will need to include the following security data.

Headers: key - Your API key generated from the settings page sign - The POST data is to be signed using your secret key according to HMAC-SHA512 method. Post Params: nonce - Any integer value which must always be greater than the previous requests nonce value.

I try to query the 'List My Balances' endpoint via: https://www.coinspot.com.au/api/ro/my/balances

However, the code I have formulated below always returns an error: "invalid/missing nonce".

I have tried so many different variations and approaches but it is always the same error.

require(httr)

key <- "68z...39k"
secret <- "71A...48i"

result <- POST("https://www.coinspot.com.au/api/ro/my/balances",
               body = list('nonce'=as.integer(as.POSIXct(Sys.time()))), add_headers("key"=key,"sign"=openssl::sha512("https://www.coinspot.com.au/api/ro/my/balances",key = secret)))

content(result)

Any help much appreciated.

timothyjgraham
  • 1,142
  • 1
  • 15
  • 28
  • 1
    did you find a fix for this? Im also having the same issue... – yush May 15 '21 at 10:51
  • 1
    Does `openssl::sha512` return a string? Looks like it needs to be a string of hex values. – Laurence Dougal Myers May 16 '21 at 03:40
  • 1
    @ayushlal - sadly I never found a solution for this problem. I ended up using Binance instead, as the REST API is well documented and easier to work with. There is an R package to interface with it, although it has some bugs as it is no longer maintained. DM me and I can help. – timothyjgraham May 17 '21 at 05:40
  • same issue at my end as well. Used postman to access but get the following error: {"status":"error","message":"invalid/missing nonce"} – raring sunny May 24 '21 at 15:56
  • Do they have any tech support that can help resolve this mystery? – raring sunny May 24 '21 at 15:57

3 Answers3

2

Ive struggled with this too- the coinspot API guide isn't very clear.

I figured out you are meant to encode the postdata in correct json format using sha512 and add that to the sign header. See example below querying account balances on v2 of the api.

require(httr)

api_key = "68z...39k"
api_secret = "71A...48i"
base_url = "https://www.coinspot.com.au/api/v2/ro"
request = "/my/balances"
nonce =  as.character(as.integer(Sys.time()))
postdata = paste0('{"nonce":"',nonce,'"}') # important to get the quotes correct
api_sign = digest::hmac(api_secret, postdata, algo="sha512",raw=F)

result = POST(paste0(base_url, request),
              body = list("nonce"=nonce), 
              add_headers(c("key"=api_key,
                            "sign"=api_sign)),
              encode="json"
)
cat(rawToChar(result$content))

You would change what is in postdata based on what you are doing with the API- this is a simple example to build on. If you want to see what postdata should look like prior to encryption in sign, use cat(rawToChar(result$request$options$postfields)) after making a request.

1

For me, I was missing the JSON string encoded postdata in the body, including the nonce. As soon as I added that, it started working.

ellioseven
  • 131
  • 6
0

Heres my code in c# using Restsharp and Newtonsoft

        //put the nonce at the beginning
        JObject joBody = JObject.Parse(@"{'nonce': '" + DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString() + "'}");
        joBody.Merge(originalBody);

        var client = new RestClient(_coinspotSettings.BaseURL);
        RestRequest request = new RestRequest(endpoint, Method.POST);
        request.AddJsonBody(JsonConvert.SerializeObject(joBody));
        request.AddHeader("key", coinspotAccount.APIKey);
        request.AddHeader("sign", SignData(coinspotAccount, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(joBody))).ToLower());
        request.AddHeader("Content-Type", "application/json");

    private string SignData(CoinspotAccount coinspotAccount, byte[] JSONData)
    {
        var HMAC = new HMACSHA512(Encoding.UTF8.GetBytes(coinspotAccount.APISecret));
        byte[] EncodedBytes = HMAC.ComputeHash(JSONData);

        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i <= EncodedBytes.Length - 1; i++)
            stringBuilder.Append(EncodedBytes[i].ToString("X2"));

        return stringBuilder.ToString();
    }