I want Get current user coin account remitano balances by python.
this is documents : https://developers.remitano.com/api-explorer/ and https://developers.remitano.com/docs/getting-started/access-key
This is my code:
import requests
import hashlib
import hmac
import base64
import time
ACCESS_KEY = "my_key"
SECRET_KEY = "my_SECRET"
# The API endpoint
API_ENDPOINT = "https://api.remitano.com/api/v1/users/coin_accounts"
def sign_request(method, url, body=""):
# Set the Content-Type header to "application/json"
headers = {
"Content-Type": "application/json",
}
# Hash the request body with MD5, base64 encode the hash, and set the Content-MD5 header
if body:
m = hashlib.md5()
m.update(body.encode())
headers["Content-MD5"] = base64.b64encode(m.digest()).decode()
# Set the "date" header to the current UTC time in the format "Wed, 21 Oct 2015 07:28:00 GMT"
headers["date"] = time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.gmtime())
# Construct the request string
request_string = f"{method},application/json,{headers.get('Content-MD5', '')},{url},{headers['date']}"
# Use the SECRET_KEY to create a hash of the request string using the HMAC-SHA1 algorithm, base64 encode the hash, and set the "Authorization" header
sig = hmac.new(SECRET_KEY.encode(), request_string.encode(), hashlib.sha1).digest()
headers["Authorization"] = f"APIAuth {ACCESS_KEY}:{base64.b64encode(sig).decode()}"
return headers
def make_request(method, url, body=""):
headers = sign_request(method, url, body)
return requests.request(method, url, headers=headers, data=body)
# Make a signed GET request
response = make_request("GET", API_ENDPOINT)
print(response.text) ```
I got the error: "{"error":"invalid signature"}" , how to fix this problem?
Thank you
CodePudding user response:
I see three problems.
The absolute URL (
https://api.remitano.com/api/v1/users/coin_accounts
) is used for the signature, but according to the documentation relative one should be used (/api/v1/users/coin_accounts
)While getting the time string the
%Z
parameter is used, but it returns the current time zone. Replace it withGMT
-time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime())
If there is no request body then code will put an empty string instead of
Content-MD5
, but in fact MD5 hash of an empty string isd41d8cd98f00b204e9800998ecf8427e
:import hashlib print(hashlib.md5("".encode()).hexdigest())
New code:
import requests
import hashlib
import hmac
import base64
import time
ACCESS_KEY = "my_key"
SECRET_KEY = "my_SECRET"
API_BASE_URL = "https://api.remitano.com"
# The API endpoint
API_ENDPOINT = "/api/v1/users/coin_accounts"
def sign_request(method, url, body=""):
# Set the Content-Type header to "application/json"
headers = {
"Content-Type": "application/json",
}
# Hash the request body with MD5, base64 encode the hash,
# and set the Content-MD5 header
if body:
m = hashlib.md5()
m.update(body.encode())
headers["Content-MD5"] = base64.b64encode(m.digest()).decode()
else:
# MD5 hash of an empty string - d41d8cd98f00b204e9800998ecf8427e
# base64 of this hash is 1B2M2Y8AsgTpgAmY7PhCfg==
headers["Content-MD5"] = "1B2M2Y8AsgTpgAmY7PhCfg=="
# Set the "date" header to the current UTC time in
# the format "Wed, 21 Oct 2015 07:28:00 GMT"
headers["date"] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime())
# Construct the request string
request_string = f"{method},application/json,{headers.get('Content-MD5')},{url},{headers['date']}"
# Use the SECRET_KEY to create a hash of the request string
# using the HMAC-SHA1 algorithm, base64 encode the hash,
# and set the "Authorization" header
sig = hmac.new(
SECRET_KEY.encode(),
request_string.encode(),
hashlib.sha1).digest()
headers["Authorization"] = f"APIAuth {ACCESS_KEY}:{base64.b64encode(sig).decode()}"
return headers
def make_request(method, base_url, api_endpoint, body=""):
headers = sign_request(method, api_endpoint, body)
return requests.request(
method,
base_url api_endpoint,
headers=headers,
data=body)
# Make a signed GET request
response = make_request("GET", API_BASE_URL, API_ENDPOINT)
print(response.text)
Unfortunately, I can not check by myself if the code works, because I don't have API credentials and it's not too easy to get them.