Search code examples
python-3.xauthenticationwebsockethmaccoinbase-api

CoinbaseProAPI/CBpro. Authentication. Websocket. Shouldn't be this hard?


Been at this for a week: every, single, day. Nothing is working. How hard is it for a minimal authentication? I bet so many people are looking for this answer too.

Here is rough-draft of what we've got so far:

import cbpro, hmac, hashlib, time,

api_key = "[YOUR_API_KEY]"
secret_key = "[YOUR_B64SECRET]"
passphrase = "[YOUR_PASSPHRASE]"

message = message.encode('ascii')
hmac_key = base64.b64decode(secret_key)
signature = hmac.new(hmac_key, message, hashlib.sha256)
signature_b64 = base64.b64encode(signature.digest()).decode('utf-8')

auth_client = cbpro.AuthenticatedClient(api_key, signature_b64, passphrase)

auth_client.get_accounts()

or while subscribing with websockets, something with this:

{
    "type": "subscribe",
    "product_ids": [
        "BTC-USD"
    ],
    "channels": ["full"],
    "signature": "...",
    "key": "...",
    "passphrase": "...",
    "timestamp": "..."
}

using:

socket = "wss://ws-feed.pro.coinbase.com"

ws = websocket.WebSocketApp(socket, on_open=on_open, on_message=on_message)

ws.run_forever()

I dont understand why a simply few lines of code to authenticate and view open orders/account is so hard, while subscribing to the websocket ticker and receiving price changes is so easy. Encoding the secret key shouldnt be too hard? Please help us with a super short and simple example (without all the "init"s and imports and different functions with passing). Sheesh


Solution

  • "I dont understand why a simply few lines of code to authenticate and view open orders/account is so hard, while subscribing to the websocket ticker and receiving price changes is so easy."

    This is because your code will not produce an authenticated websockets session. The session is secured using 'wss' aka TLS, but inside of this session, you are not authenticated to their server and therefore you do not receive enhanced data elements for trade messages in which your account is involved. Receiving price data does not require being authenticated.

    This is just like you are visiting a website at its "https" address, but are not logged in. "Public" data is being sent to you across a secure connection.

    The cbpro module creates an AuthenticatedClient instance by passing to it the unaltered api key, base64-encoded secret, and passphrase. You should really review any module's code base before trusting it with your authentication data, or even installing it on your machine, but to each their own.

    import cbpro #, hmac, hashlib, time,
    
    api_key = YOUR_API_KEY
    secret_key = YOUR_B64SECRET
    passphrase = YOUR_PASSPHRASE
    
    # message = message.encode('ascii')
    # hmac_key = base64.b64decode(secret_key)
    # signature = hmac.new(hmac_key, message, hashlib.sha256)
    # signature_b64 = base64.b64encode(signature.digest()).decode('utf-8')
    
    auth_client = cbpro.AuthenticatedClient(api_key, secret_key, passphrase)
    
    auth_client.get_accounts()
    

    You can test out what I am saying about how your websocket code is not properly authenticating either by running your wss client and subscribing to only the "user" channel for a product before placing a trade in for that product. With no other channels subscribed, you will receive a message indicating that the server received your new order. You can then cancel the order after testing. If your code does somehow allow you to receive messages in the "user" channel, then CoinbasePro is doing something different from what is published in its documentation.