Websocket Subscribe Authentication Error

I am following the example here: WebSocket Overview | Coinbase Cloud
However, I am using C++. Here is my code:

  websocket_client websocket;
  websocket.connect("advanced-trade-ws.coinbase.com", "443");

  epoch_time = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
  string concat = fmt::format("{}level2ETH-USD,ETH-EUR", epoch_time);
  signature = hmac_sha256(api_secret, concat);
  string subscribe_message = fmt::format(R"({{
    "type": "subscribe",
    "product_ids": [
        "ETH-USD",
        "ETH-EUR"
    ],
    "channel": "level2",
    "api_key": "{}",
    "timestamp": {},
    "signature": "{}"
  }})", api_key, epoch_time, signature);

  cout << "Writing to websocket:\n" << subscribe_message << endl;
  websocket.write(subscribe_message);

The output from this is as follows:

Writing to websocket:
{
    "type": "subscribe",
    "product_ids": [
        "ETH-USD",
        "ETH-EUR"
    ],
    "channel": "level2",
    "api_key": "redacted",
    "timestamp": 1676174456,
    "signature": "redacted"
  }

The response is

{"type":"error","message":"authentication failure"}

I have already successfully authenticated against the REST API using the same key, and my key has all permissions enabled.
The example in the documentation uses the following code

CryptoJS.HmacSHA256(str, secret).toString()

I double checked to make sure that my hmac_sha256 method produces the same output given the same secret and string. Also, as I have mentioned, I can successfully authenticate against the REST API when using this method and my same key and secret.

I was just thinking that it might be helpful if I can show what an unredacted version of the output looks like, so I ran it with an api-key of “key” and a secret of “secret”, and this was the output:

Writing to websocket:
{
    "type": "subscribe",
    "product_ids": [
        "ETH-USD",
        "ETH-EUR"
    ],
    "channel": "level2",
    "api_key": "key",
    "timestamp": 1676178799,
    "signature": "e2d08ba95fe70187e84c1d500fa1ca11ceb0b62eca07994158533475f53940c4"
  }

Now theoretically other people can verify that the signature is being generated correctly.

I figured out the issue. In the example provided in the documentation, the timestamp is included in the subscribe message as an integer (ie. without quotation marks). However, it needs to be a string. As soon as I put quotes around it, it started working as expected. The documentation should be updated to correct this error. Additionally, the documentation has a stray comma at the end of the subscribe message (after the signature) which should also be corrected.

1 Like

Hello @Herb! We are glad to know that you already figured out the issue. We can see that there’s an inaccuracy on the sample request on the documentation and we really appreciate you for bringing this up to our attention. Rest assured that we will log this feedback on the documentation with our internal teams so we can continue improving our user experience. Most new features and improvements to our products come directly from feedback like yours, so it’s very valuable to us. While we can’t offer any specific timeline for adding features, we are constantly working to build products our customers will love.

If you want to stay up to date on the latest from Coinbase Cloud, you can also bookmark the following webpage and subscribe to email updates at the bottom of the page: https://www.coinbase.com/cloud/discover

Thank you and welcome to the community!

A post was merged into an existing topic: Websocket in Advanced Trading is a hot mess. Here’s a PHP example for those who need it

Hi @Herb can you please share your hmac_sha256 function? Thanks