OK, I am having trouble getting ticker prices with the same Authorization error that I think many people seemed to suffer from. I have been through every thread here related to this (python and otherwise) and I can’t make my code work.
I have a couple of preliminary questions in case I am missing something basic:
- Do I have to authorize my development machine before the API will authorize me? (I have done this - at least I am logged on to coinbase.com from my dev machine and it is in my authorized devices)
- Do I need to use a REST API to somehow get a session or user id key before I can get messages from the websocket? (If yes, how? And then, how do I use it?)
- I have an API key I generated 6 months ago that I have been using for the v2 API, do I need to get a new one for Advanced Trade? (I have generated a new one to be safe, but it takes 48 hours before I can try it out)
Here is my code, having followed the websocket documentation:
def add_signature_ws(message:dict, secret:str):
nonce = int(time.time() * 1e6)
to_sign = f"{nonce}{message['channel']}{','.join(message['product_ids'])}"
signature = hmac.new(secret.encode('utf-8'), to_sign.encode('utf-8'), hashlib.sha256).hexdigest()
message['signature'] = signature
message['timestamp'] = str(nonce)
return message
def batch_ticker_price():
ticker_batch = {
"type": "subscribe",
"product_ids": [
"ETH-USD"
],
"channel": "ticker_batch",
'api_key' : SecretManager.get('COINBASE_API_KEY')
}
ws = websocket.create_connection("wss://advanced-trade-ws.coinbase.com")
msg = add_signature_ws(ticker_batch, SecretManager.get('COINBASE_API_SECRET'))
ws.send(json.dumps(msg))
data = json.loads(ws.recv())
what I sign looks like this:
1673924763477896ticker_batchETH-USD
the contents of the signed message look like this:
{'type': 'subscribe', 'product_ids': ['ETH-USD'], 'channel': 'ticker_batch', 'api_key': '---REDACTED---', 'signature': '3995240d5a6e8174df5e45734955b109ab1bfd77bff5f18d1922f1e3a44d0143', 'timestamp': '1673924763477896'}
what I get back is (always) this:
{'type': 'error', 'message': 'authentication failure'}
My SecretManager
is giving me the right values for my API key and Secret and the keys are appropriately scoped (wide open).
I have tried many, many variants of this, attempting to port code from Javascript, Java, R, C++, C#, but I just can’t get it to work. I have tried different encodings and digests of the signature, but no joy.
I am tearing my hair out and hoping it’s something really stupid.