Reputation: 515
I promise I tried my best but I just couldn't get this to work.
Here's the exact python code from the API Website: https://exchange-docs.crypto.com/spot/index.html?python#digital-signature
import hmac
import hashlib
import json
import requests
import time
API_KEY = "API_KEY"
SECRET_KEY = "SECRET_KEY"
req = {
"id": 11,
"method": "private/get-order-detail",
"api_key": API_KEY,
"params": {
"order_id": "337843775021233500",
},
"nonce": int(time.time() * 1000)
};
# First ensure the params are alphabetically sorted by key
paramString = ""
if "params" in req:
for key in sorted(req['params']):
paramString += key
paramString += str(req['params'][key])
sigPayload = req['method'] + str(req['id']) + req['api_key'] + paramString + str(req['nonce'])
req['sig'] = hmac.new(
bytes(str(SECRET_KEY), 'utf-8'),
msg=bytes(sigPayload, 'utf-8'),
digestmod=hashlib.sha256
).hexdigest()
I'm not sure if I got anywhere close, but here's what I got but isn't working -- unfortunately I can't for the life of me tell WHAT I'm getting wrong as I just get a generic error message. For example, maybe I'm not formatting my UNIX time the way they want it.. Any ideas, please help!
library(httr)
library(digest)
API_KEY <- "FOO"
SECRET_KEY <- "BAR"
base <- "https://api.crypto.com/v2/"
API.Balance <- function() {
method <- "private/get-account-summary"
hash<-paste0(method,11,API_KEY,"",ceiling(as.numeric(Sys.time())))
print(hash)
hash<-hmac(SECRET_KEY,hash,algo="sha256")
print(hash)
call1 <- paste0(base,method,"?api_key=",API_KEY,"&sig=",hash)
print(call1)
get.req <- GET(call1)
get.req.txt <- content(get.req, "text",encoding = "UTF-8")
return(fromJSON(get.req.txt, flatten = TRUE))
}
API.Balance()
This returns:
[1] "private/get-account-summary11FOO5"
[1] "ed19ac611d5342f2cbd93a52c70ce884bbcdb9a4062572b013a494fd2c50fd03"
[1] "https://api.crypto.com/v2/private/get-account-summary?api_key=FOO&sig=ed19ac611d5342f2cbd93a52c70ce884bbcdb9a4062572b013a494fd2c50fd03"
$code
[1] "100001"
$msg
[1] "SYS_ERROR"
So I gave it a few hours but I'm just scratching my head. I know it's something simple I'm missing. Could someone please help me translate the Python approach to R? Thank you.
Upvotes: 1
Views: 788
Reputation: 515
Ok I figured it out and for the good of humanity I think I'll post my solution! Complete with sorting params.
I was using a GET instead of a POST and I totally forgot to reinject the hash into the "req" object after it was calculated (and other minor things). Anyway, several hours of tearing out my hair, so you don't have to, you get this:
API.Balance <- function() {
endpoint <- "private/get-account-summary"
req <- list(
id=11, #This doesn't matter, you define it
method=endpoint,
api_key=API_KEY,
params=list(
currency="USDT" #leave blank if no params
),
nonce=floor(as.numeric(Sys.time())*1000)
)
req$params <- req$params[order(names(req$params))]
params<-""
for(i in 1:length(req$params)) {
params=paste0(params,names(req$params)[i])
params=paste0(params,req$params[[i]])
}
hash<-paste0(req$method,
req$id,
req$api_key,
params,
req$nonce)
hash<-hmac(SECRET_KEY,
hash,
algo="sha256")
req<-c(req,sig=hash)
response <- POST(url=paste0(base,endpoint),
body=req,
encode="json")
response.txt <- content(response, "text",encoding = "UTF-8")
return(fromJSON(response.txt, flatten = TRUE))
}
API.Balance()
Upvotes: 3