WebSocket Authentication
All API calls related to a user account, require authentication. You need to provide 4 parameters to authenticate a request:
| Key | Value |
|---|---|
| X-PCK | API Public Key |
| X-Stamp | Timestamp |
| X-Nonce | Delay Tolerance |
| X-Signature | Signature of Request |
All these parameters must be transmitted from the header before opening a connection to the socket.
Signature
Signature is a HMAC-SHA256 encoded message. The HMAC-SHA256 code must be generated using a private key that contains a current timestamp and your API key.
Nonce
Nonce is a integer number. The value sent determines the connection delay tolerance. For example, if the Nonce value is 15000 (15 seconds), and your request meets the condition (X-Stamp + X-Nonce < Current Server Timestamp), your request will fail. This is because the request you sent reaches the server later than the Nonce value
TLS URL Scheme and Ports
WebSocket connections must be established over TLS using the secure WebSocket scheme.
New API Endpoints
Simply update your WebSocket URLs as shown below:
-
HTTPS (REST / Auth related calls)
https://<host> -
Secure WebSocket (TLS)
wss://<host>:8443
The
wssscheme indicates a WebSocket connection secured with TLS.
Port 8443 is required for secure WebSocket communication.
TLS URL Scheme and Ports
WebSocket connections must be established over TLS using the secure WebSocket scheme.
New API Endpoints
Simply update your WebSocket URLs as shown below:
-
HTTPS (REST / Auth related calls)
https://<host> -
Secure WebSocket (TLS)
wss://<host>:8443
The
wssscheme indicates a WebSocket connection secured with TLS.
Port 8443 is required for secure WebSocket communication.
Code Examples:
- C#
- Python
- Node.js
public async Task Connect()
{
ClientWebSocket clientWebSocket = new ClientWebSocket();
string publicKey = "PUBLIC_KEY";
string privateKey = "PRIVATE_KEY";
long nonce = 15000;
long timestamp = DateTimeExtension.ToUnixTime(DateTime.UtcNow);
string baseString = $"{publicKey}{timestamp}";
string signature = ComputeHash(privateKey, baseString);
clientWebSocket .Options.SetRequestHeader("X-PCK", publicKey);
clientWebSocket .Options.SetRequestHeader("X-Signature", signature);
clientWebSocket .Options.SetRequestHeader("X-Stamp", timestamp.ToString());
clientWebSocket .Options.SetRequestHeader("X-Nonce", nonce.ToString());
await clientWebSocket .ConnectAsync(new Uri("wss://{BASEURL}:8443"), CancellationToken.None);
}
private string ComputeHash(string privateKey, string message)
{
byte[] key = Convert.FromBase64String(privateKey);
string hashString;
using (HMACSHA256 hmac = new HMACSHA256(key))
{
byte[] hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
hashString = Convert.ToBase64String(hash);
}
return hashString;
}
class InterfaceWS:
def __init__(self, exchange_name: str = None) -> None:
self.exchange_name = "HFT API"
self.uri = "wss://{BASEURL}:8443"
async def authenticate_ws(self) -> bool:
publicKey = "PUBLIC_KEY"
privateKey = "PRIVATE_KEY"
nonce = 15000 //
timestamp = round(time.time() * 1000)
baseString = "{}{}".format(publicKey, timestamp).encode("utf-8")
signature = hmac.new(
base64.b64decode(privateKey), baseString, hashlib.sha256
).digest()
signature = base64.b64encode(signature)
headers = {
"X-PCK": publicKey,
"X-Nonce": str(nonce),
"X-Stamp": str(timestamp),
"X-Signature": signature.decode("utf-8")
}
try:
async with websockets.connect(self.uri, extra_headers=headers) as websocket:
while True:
response = await websocket.recv()
print(response)
except websockets.exceptions.ConnectionClosed as e:
print("Connection closed:", e)
async def main():
w = InterfaceWS()
await w.authenticate_ws()
if __name__ == "__main__":
asyncio.run(main())
const crypto = require('crypto');
const WebSocket = require('ws');
const url = 'wss://{BASEURL}:8443';
const publicKey = "PUBLIC_KEY";
const privateKey = "PRIVATE_KEY";
const nonce = 15000;
const stamp = (new Date()).getTime();
const baseString = `${publicKey}${stamp}`;
const data = Buffer.from(baseString, 'utf8');
const buffer = crypto.createHmac('sha256', Buffer.from(privateKey, 'base64'));
buffer.update(data);
const signature = buffer.digest().toString('base64');
const headers = {
"X-PCK": publicKey,
"X-Nonce": String(nonce),
"X-Stamp": String(stamp),
"X-Signature": signature
};
const connection = new WebSocket(url, { headers: headers });
connection.onopen = () => {
console.log("WebSocket connection established.");
};
connection.onerror = (error) => {
console.log(`WebSocket error: ${error}`);
};
connection.onmessage = (e) => {
console.log(e.data);
};