Hi
I try to send a subscribe message to Coinbase websocket but still get this error (advanced trade API):
{‘type’: ‘error’, ‘message’: ‘authentication failure’}
this is part of my code regarding websocket:
url_websocket = 'wss://advanced-trade-ws.coinbase.com'
now = int(time.time()) # line just added here for reference as it is at the beginning of the code
channel_name = 'level2'
product_ids = 'ETH-USDT', 'ETH-EUR'
str_to_sign_websocket = str(now) + channel_name + ','.join(product_ids)
print(str_to_sign_websocket)
signature_websocket = hmac.new(str_to_sign_websocket.encode('utf-8'), api_secret.encode('utf-8'), hashlib.sha256).hexdigest()
print(signature_websocket)
message = {
"type": "subscribe",
"channel": channel_name,
"api_key": api_key,
"product_ids": product_ids,
"signature": signature_websocket,
"timestamp": str(now)
}
async def main():
ws = await websockets.connect(url_websocket)
await ws.send(json.dumps(message))
async def receive_data():
while True:
response = await ws.recv()
data = json.loads(response)
print(data)
while True:
await receive_data()
if __name__ == '__main__':
asyncio.run(main())
As far as Coinbase documentation is concerned it looks like the signature generation is correct (hashed using secret key sha256 string using timestamp, channel name and product_ids - concatenated and comma separeted) and then sending subscribe message (type, channel, api_key, product_ids, signature and timestamp). Somehow I am unable to get rid of this authentication failure error…does someone know how to correct my code or if there are any mistakes? Thanks
Hi @wolf2023! Welcome to the forum. We see that you’re having troubles with authenticating through the websocket feed of Advanced trade API, but then we would like to ask the following:
- Have you tried creating a new API key, and testing your code afterwards?
- What programming language are you using?
Once we have this information, we will check on this for you with our team to see how we can best assist. We appreciate your patience and understanding.
1 Like
Hi @uncle_genie . Yes I did create a new API key but the result is the same.
I’m using Python.
message = {
"product_ids": product_ids,
}
Is your json message correct? Does Python automatically produce this:
"products_ids": ["ETH-USDT", "ETH-EUR"],
Should not it be something like this:
message = {
"product_ids": "[\"" + '","'.join(product_ids) + "\"]",
}
1 Like
Well I have a variable products_ids = ‘ETH-USDT’, ‘ETH-EUR’ that is just being referenced inside a message.
In case you’re talking about the signature then my prehash string variable contains:
str_to_sign_websocket = str(now) + channel_name + ‘,’.join(product_ids)
and that’s how the entire generated prehash string looks like:
1673371057level2ETH-USDT,ETH-EUR #again compliant with the documentation
But does it produce valid json message? Post generated message, don’t forget to remove your api_key
before posting.
1 Like
that’s the message:
{“type”: “subscribe”, “channel”: “level2”, “api_key”: “deleted”, “product_ids”: [“ETH-USDT”, “ETH-EUR”], “signature”: “6b17a88c51ae937ccb3d3ced9edd8ea4b41e0e932a9440b4dbe2e2304126efdb”, “timestamp”: “1673373784”}
Looks correct, are you sure you have correct api_key
and api_secret
? If you can provide minimal python code I will test it with my api key.
1 Like
here’s the code (with deleted keys):
import requests
import base64
import hmac
import hashlib
import time
import json
import uuid
import decimal
import websockets
import asyncio
api_key = ""
api_secret = ""
now = int(time.time())
# Get account info
url_accounts1 = 'https://coinbase.com/api/v3/brokerage/accounts'
str_to_sign_accounts1 = str(now) + 'GET' + '/api/v3/brokerage/accounts' + ''
signature_accounts1 = hmac.new(api_secret.encode('utf-8'), str_to_sign_accounts1.encode('utf-8'), hashlib.sha256).hexdigest()
headers_accounts1 = {
"CB-ACCESS-SIGN": signature_accounts1,
"CB-ACCESS-TIMESTAMP": str(now),
"CB-ACCESS-KEY": api_key,
}
response_accounts1 = requests.request('get', url_accounts1, headers=headers_accounts1)
print(response_accounts1.status_code)
print(response_accounts1.json())
# Get account balance of BTC
btc_balance1 = 0
for account1 in response_accounts1.json()['accounts']:
if account1['currency'] == 'BTC':
btc_balance1 = account1['available_balance']['value']
print(btc_balance1)
# Get account balance of ETH
eth_balance1 = 0
for account1 in response_accounts1.json()['accounts']:
if account1['currency'] == 'ETH':
eth_balance1 = account1['available_balance']['value']
print(eth_balance1)
# Get account balance of USDT
usdt_balance1 = 0
for account1 in response_accounts1.json()['accounts']:
if account1['currency'] == 'USDT':
usdt_balance1 = account1['available_balance']['value']
print(usdt_balance1)
# subscribe to and get websocket feed
url_websocket = 'wss://advanced-trade-ws.coinbase.com'
channel_name = 'level2'
product_ids = 'ETH-USDT', 'ETH-EUR'
str_to_sign_websocket = str(now) + channel_name + ','.join(product_ids)
print(str_to_sign_websocket)
signature_websocket = hmac.new(str_to_sign_websocket.encode('utf-8'), api_secret.encode('utf-8'), hashlib.sha256).hexdigest()
print(signature_websocket)
message = {
"type": "subscribe",
"channel": channel_name,
"api_key": api_key,
"product_ids": product_ids,
"signature": signature_websocket,
"timestamp": str(now)
}
async def main():
ws = await websockets.connect(url_websocket)
await ws.send(json.dumps(message))
print(json.dumps(message))
async def receive_data():
while True:
response = await ws.recv()
data = json.loads(response)
print(data)
while True:
await receive_data()
if __name__ == '__main__':
asyncio.run(main())
Your hmac.new
line is wrong! First parameter should be secret.
1 Like
Thank you @muktupavels . It works, I don’t know how I could’ve missed that
Again, thank you for your time