Authenticate the connection with the following message:


wscat -c wss://ws.testnet.bsx.exchange/ws -x '{"op":"auth","data":{"key":"secret-key-here","timestamp":"12345","signature":"easy-signature"}}'
{"type":"message", "connection_id":"8fdad76b-bf71-42ea-9792-a1bdfbc245d2"}
{"type":"error","message":"timestamp should be close to current timestamp","code":400}
{
    "op": "auth", 
    "data": {
      "key": "<api_key>",
      "timestamp": "<unix_timestamp_ns>", // current unix timestamp in nanosecond
      "signature": "<signature>"   // encoded hmac sha256 signature
    }
}
{
  "channel": "auth",
  "type": "authenticated"
}
{
  "channel": "auth",
  "type": "error",
  "message": "api key not found",
  "code": 400
}
{
  "channel": "auth",
  "type": "error",
  "message": "timestamp should be closed to current timestamp (100.854776s)",
  "code": 400
}

One websocket connection may be logged in to at most one user. If the connection is already authenticated, further attempts to log in will result nothing.

  • signature = hex_encoding(hmacsha256(message, secret))
  • message = <api_key>,timestamp

Example

  • api_key = 1fda404d8f84ce7de5611a7f0d310325
  • secret = 1fda404d8f84ce7de5611a7f0d3103251fda404d8f84ce7de5611a7f0d310325
  • timestamp=1701918382000000000

Then:

  • message=1fda404d8f84ce7de5611a7f0d310325,1701918382000000000
  • signature = 38dbb4921a2b7ac974aa24d3a832f722a03c1b94126972fff538f39beb73caac

And you send this

{
    "op": "auth", 
    "data": {
      "key": "1fda404d8f84ce7de5611a7f0d310325",
      "timestamp": "1701918382000000000", // current unix timestamp in nanosecond
      "signature": "38dbb4921a2b7ac974aa24d3a832f722a03c1b94126972fff538f39beb73caac"   // encoded hmac sha256 signature
    }
}

HMAC SHA256

HMAC SHA256 signature is available in many language.

This is some example code to compute HMAC SHA256

package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
)

func computeHmacSHA256(message, secret string) string {
	// create a new HMAC by defining the hash type and the key
	hm := hmac.New(sha256.New, []byte(secret))
	hm.Write([]byte(message))
	dataHmac := hm.Sum(nil)
	return string(dataHmac)
}

func main() {
	message := "1fda404d8f84ce7de5611a7f0d310325,1701918382000000000"
	secret := "1fda404d8f84ce7de5611a7f0d3103251fda404d8f84ce7de5611a7f0d310325"
	fmt.Print(hex.EncodeToString([]byte(computeHmacSHA256(message, secret))))
    // 38dbb4921a2b7ac974aa24d3a832f722a03c1b94126972fff538f39beb73caac
}

# Python 3.11.6
import hashlib
import hmac
import codecs

def compute_hmac_sha256(message, secret):
    return hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()

def main():
    message = "1fda404d8f84ce7de5611a7f0d310325,1701918382000000000"
    secret = "1fda404d8f84ce7de5611a7f0d3103251fda404d8f84ce7de5611a7f0d310325"
    print(compute_hmac_sha256(message, secret))
    # Output: 38dbb4921a2b7ac974aa24d3a832f722a03c1b94126972fff538f39beb73caac

if __name__ == "__main__":
    main()

const crypto = require('crypto');

function computeHmacSHA256(message: string, secret: string) {
  const encodedMessage = crypto
    .createHmac('sha256', secret)
    .update(message)
    .digest('hex');
  return encodedMessage;
}

function main() {
    const message = "1fda404d8f84ce7de5611a7f0d310325,1701918382000000000";
    const secret = "1fda404d8f84ce7de5611a7f0d3103251fda404d8f84ce7de5611a7f0d310325";
    console.log(computeHmacSHA256(message, secret));
    // Output: 38dbb4921a2b7ac974aa24d3a832f722a03c1b94126972fff538f39beb73caac
}

main();

test script

#!/bin/bash

# ws_auth.sh

api_key="$1"
secret="$2"

# Function to compute HMAC SHA256
computeHmacSHA256() {
    message=$1
    secret=$2
    echo -n "$message" | openssl dgst -sha256 -hmac "$secret" -binary | xxd -p | tr -d '\n'
}

# Function to get current timestamp in nanoseconds
getCurrentTimestamp() {
    echo $(date +%s%N)
}

# Set the websocket URL
websocket_url="wss://ws.testnet.bsx.exchange/ws"

# Set the message and timestamp
timestamp=$(getCurrentTimestamp)
message="$api_key,$timestamp"

# Compute the signature and encode using hex
signature=$(computeHmacSHA256 "$message" "$secret")
# Call wscat with the formatted JSON
echo "$api_key" "$timestamp" "$message" "$secret" "$signature"


echo "{\"op\":\"auth\",\"data\":{\"key\":\"$api_key\",\"timestamp\":\"$timestamp\",\"signature\":\"$signature\"}}"

wscat -c "$websocket_url" -x "{\"op\":\"auth\",\"data\":{\"key\":\"$api_key\",\"timestamp\":\"$timestamp\",\"signature\":\"$signature\"}}"

run the script

bash ws_auth.sh $apikey $secret