import crypto from "node:crypto";
import WebSocket from "ws";
// Same recipe as REST, fixed to the WS handshake (GET, empty body).
function wsAuthHeaders({ secret, keyId }) {
const timestamp = Date.now().toString();
const nonce = crypto.randomUUID();
const bodyHash = crypto.createHash("sha256").update("", "utf8").digest("hex");
const canonical = [
timestamp,
nonce,
"GET",
"/api/v1/trading/ws",
"application/json",
bodyHash,
].join("\n");
const signature = crypto
.createHmac("sha256", secret)
.update(canonical, "utf8")
.digest("hex");
return {
"X-API-KEY": keyId,
"X-API-TIMESTAMP": timestamp,
"X-API-NONCE": nonce,
"X-API-SIGNATURE": signature,
"Content-Type": "application/json",
};
}
const ws = new WebSocket(
"wss://<your-host>/api/v1/trading/ws",
{
headers: wsAuthHeaders({
secret: process.env.XENIOS_API_SECRET,
keyId: process.env.XENIOS_API_KEY,
}),
},
);
ws.on("message", (raw) => {
const msg = JSON.parse(raw.toString());
if (msg.event === "auth_success") {
ws.send(
JSON.stringify({
action: "subscribe",
payload: { channel: "orderbook", scope: "product", key: "BTC-USD" },
}),
);
} else {
console.log(msg.event, msg);
}
});