Closed Tallthunder closed 4 years ago
@justin-ngin @martin-nginio I have gone through the entire issues folder, but not able to find a good answer. I have base64 decoded my key, base64 encoded the HMAC signature, made sure the headers are in the right order, time stamp is in the correct format. My only guess is either
Thanks again!
Hi @Tallthunder ,
I couldn't replicate the issue with your above code, because the interpreter didn't like it. Once I tweaked it to the below, account balance is working correctly for me. Please let me know if you are able to use this as well.
import base64, hashlib, hmac, time, urllib2, urllib2, json
from collections import OrderedDict
base_url = 'https://api.btcmarkets.net'
def request(action, key, signature, timestamp, path, data):
header = {
'Accept': 'application/json',
'Accept-Charset': 'UTF-8',
'Content-Type': 'application/json',
'apikey': key,
'timestamp': timestamp,
'signature': signature,
}
http_request = urllib2.Request(base_url + path, data, header)
if action == 'post':
response = urllib2.urlopen(http_request, data)
else:
response = urllib2.urlopen(http_request)
return json.loads(response.read())
def get_request(key, secret, path):
nowInMilisecond = str(int(time.time() * 1000))
stringToSign = path + "\n" + nowInMilisecond + "\n"
presignature = base64.b64encode(hmac.new(secret, stringToSign.encode('utf-8'), digestmod=hashlib.sha512).digest())
signature = presignature.decode('utf8')
return request('get', key, signature, nowInMilisecond, path, None)
def post_request(key, secret, path, postData):
nowInMilisecond = str(int(time.time() * 1000))
stringToSign = path + "\n" + nowInMilisecond + "\n" + postData
signature = base64.b64encode(hmac.new(secret, stringToSign.encode('utf-8'), digestmod=hashlib.sha512).digest())
return request('post', key, signature, nowInMilisecond, path, postData)
class BTCMarkets:
def __init__(self, key, secret):
self.key = key
self.secret = base64.b64decode(secret)
def account_balance(self):
return get_request(self.key, self.secret, '/account/balance')
api_key = 'xxxx'
private_key = 'yyyy'
client = BTCMarkets (api_key, private_key)
print (client.account_balance())
Cheers, Justin
Hi @justin-ngin , Thanks for getting back to me. I tried the above code in jupyter notebook with python 3 after converting urllib2-> urllib.request as I had it on the first post and I am still getting the same error. This makes me think it is either something to do with python 3's urllib.request module or just the interpreter that I am using(since you seem to have issues with yours).
Which interpreter are you using?
I will try the above code with python 2 and get back to you.
Kind regards,
Jim
Just switched to python2 and used the native python interpreter. Literally copied and pasted what you posted and still getting the same error-
{u'errorCode': 1, u'errorMessage': u'Authentication failed.', u'success': False}
I wonder, what it could be...
I'm using Python 2.7 as my interpreter for the code I provided.
If you're using the code above, and you're sure that your keys are correct, the other most likely thing is your timestamp variance is too high. Please check that your machine is connected to a time server, and if you have the option, force it to sync, and try again.
I will whip out my jupyter notebook and try running it through that as well.
Hey @justin-ngin
I have checked my keys multiple times and I am pretty sure it is accurate .
I checked via command prompt and seems like my PC is synced to the NTP server .
Is there an alternate way to get an appropriate timestamp ? I have used the timestamp from the ticker for other exchanges succesfully but not sure if it would work for BTCmarkets.
Hi @Tallthunder ,
I have just tested this inside jupyter notebook, and the account balance call is working for me. After further investigation, I don't think the sole cause would be your timestamp, as the API actually returns an error message specifically for timestamps that are out of range. If you haven't already, can you please clone or download this project: BTC-Markets Python and use your API keys in main.py and try using the account balance call?
Cheers, Justin
Hey @justin-ngin ,
Just tried that and am still getting the same error code. The only thing that works for me is get_market_tick.
At this point I have ruled out timestamp, syntax, keys, use of the Request module, python 3, base 64 decoding/ encoding, signature matching (using the sample keys and timestamp provided on btcmarkets api page) and order of headers.
Would it be worth it to try a different operating system?? Btcmarkets is the only exchange I am having trouble with. I used ccxt library for the other exchanges.
Hi @Tallthunder ,
You can replicate the example signatures in the wiki using those timestamps and keys? What operating system are you running, and would you be able to try with a different language?
Regards, Justin
Hey @justin-ngin Yes, I am able to replicate the signatures using the sample timestamp and private key. I am running a windows 7 home premium 64 bit OS. I tried Java but ended up bashing my head in since I had to learn the language from scratch. Ended up crashing my PC and had to reboot. So that is on hold for now.
I have come across a python wrapper searching through the issues tab. I might give that a go.
Hey @justin-ngin
Just tried with a Java wrapper for python and Im getting the same error code- 1, authentication failure. The only possible solution would be an incorrect public and private API key. None of the other variables can possibly be causing the issue. If the issue is my key, how would I go about fixing this?
Hi, I have the same problem with PHP - Laravel
This is my function:
private function RequestApi($path, $public, $private){
$timestamp = time()*1000;
$message = $path . "\n" . $timestamp . "\n";
$signature = base64_encode(hash_hmac('sha512', $message, base64_decode($private), true));
// Create a stream
$opts = [
"http" => [
"method" => "GET",
"header" => "apikey: $public\r\n". "timestamp: $timestamp\r\n"."signature: $signature\r\n"
]
];
$this->context = stream_context_create($opts);
try{
// Open the file using the HTTP headers set above
$request = file_get_contents('https://api.btcmarkets.net'.$path, false, $this->context);
dd($request);
}catch(Exception $e){
dd($e->getMessage());
}
return json_decode($request);
}
This is the response:
"{"success":false,"errorCode":1,"errorMessage":"Authentication failed."}"
Any suggestions?
Regards, Juan
Hi @Tallthunder
A sample client API code (mainly authentication) for Python 3 has been added here: https://github.com/BTCMarkets/api-client-python3
The code has been tested with Python 3.7 (on Ubuntu) but it should be the same on other operating systems.
Thanks for your feedback.
Hi @JuanNavasJN
Please feel free to take a look at the following PHP authentication sample code: https://github.com/BTCMarkets/api-client-php
The code has been tested with PHP 7.1.23 but it should work with higher versions as well.
Thanks for your feedback.
Thanks @martin-nginio
I already resolved it. Apparently I had problems with my keys.
closing the issue.
Keep getting the above code. Not sure why. I would appreciate any help.
Here is the code I am using ( Its not my public/private API keys as I have checked them multiple times ):
import base64, hashlib, hmac, time, urllib, urllib.request, json from collections import OrderedDict
base_url = 'https://api.btcmarkets.net'
def request(action, key, signature, timestamp, path, data):
def get_request(key, secret, path):
def post_request(key, secret, path, postData):
class BTCMarkets:
api_key = 'xxxxxx' private_key = 'xxxxx'
client = BTCMarkets (api_key, private_key)
print (client.get_market_tick('ETH','AUD'))
print (client.account_balance())