Skip to main content

Websockets

Authentication

To get access to DLT WebSocket information, you must confirm your identity by providing a valid authenticate request. You can provide this information as a JSON construct, as seen below:

{
"event": "authenticate",
"auth": {
"type": "api_token",
"public_key": "<Public Key>",
"signature": "<Signature>",
"nonce": 1679666809998303687 // 64-bit integer
}
}

The signature is generated in way that similar to a signature is generated for the REST API. With the exception that message has the following format:

message = ${nonce}

Once the authentication request succeeds, the response will contain a collection of all the channels the user is allowed to subscribe.

Example of an authentication request

const nacl = require("tweetnacl");
const tools = require("tweetnacl-util");
const now = require("nano-time");

const PUBLIC_KEY_HEX = ""; // public key from DLT dashboard
const PRIVATE_KEY_HEX = ""; // private key from DLT dashboard
const PRIVATE_KEY = fromHex(PRIVATE_KEY_HEX);

function fromHex(hex) {
return Uint8Array.from(Buffer.from(hex, "hex"));
}
function toHex(bytes) {
return Buffer.from(bytes).toString("hex");
}

const nonce = now();
const signature = nacl.sign.detached(tools.decodeUTF8(nonce), PRIVATE_KEY);
const signatureHex = toHex(signature);

console.log(
`{"event":"authenticate", "auth": {"type":"api_token", "public_key":"${PUBLIC_KEY_HEX}", "signature":"${signatureHex}", "nonce":${nonce}}}`
);

And you can use the following command to send the request to the server (code to be executed in a browser environment):

const socket = new WebSocket(
"wss://api.stage.dltm.quanttradingfactory.com/v1/trade/ws"
);

socket.onopen = function (e) {
socket.send(
`{"event":"authenticate", "auth": {"type":"api_token", "public_key":"d9f06a30fecbe43ae13817da22931f192eeb089f09a2c22083005f0af5d83dbe", "signature":"04588aeabbfcbfd00a9a48ff4408e6235fcf64d1e147dc0784665144b1a9017557cdf04e88a5cb8a8e5c1c75a692481c8e0f0577410fd59599b4faabd0b99406", "nonce":1679678081034076524}}`
); //authentication request
};

socket.onmessage = function (event) {
console.log(`[message] Data received from server: ${event.data}`);
};

socket.onclose = function (event) {
if (event.wasClean) {
console.log(
`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`
);
} else {
// e.g. server process killed or network down
// event.code is usually 1006 in this case
console.log("[close] Connection died");
}
};

socket.onerror = (error) => {
console.log(`[error] ${error.message}`);
};

Subscription

A subscription request can be requested to retrieve information from one, or multiple channels simultaneiously:

{
"event": "subscribe",
"channels": [
"orderbook-simple-bitstamp-btc/usd",
"orderbook-simple-bitstamp-btc/eur"
]
}

The example above will produce the following output response:

{
"channel": "orderbook-simple-bitstamp-btc/usd",
"payload": {
"bids": [
{ "price": "43981.5", "volume": "2.5" },
{ "price": "43981", "volume": "2.5" },
{ "price": "43980.55", "volume": "0.44" },
{ "price": "43980", "volume": "1" },
{ "price": "43972", "volume": "1" },
{ "price": "43971.8", "volume": "1" },
{ "price": "43971.5", "volume": "0.2" },
{ "price": "43971", "volume": "1" }
],
"asks": [
{ "price": "43987.5", "volume": "2.81" },
{ "price": "43990", "volume": "0.33" },
{ "price": "43990.5", "volume": "0.89" },
{ "price": "44015", "volume": "5" },
{ "price": "44016", "volume": "0.1" },
{ "price": "44017.5", "volume": "5" },
{ "price": "44021", "volume": "0.1" },
{ "price": "44024", "volume": "0.2" }
],
"version": 12096,
"time": 1644500306,
"hit_bid": "43981.5",
"lift_ask": "43987.5",
"total_bid": "750.77",
"total_ask": "1532.79",
"refresh": true
}
}

Channel Availability

DLT will always dynamically provide the neccesary channels given the specific demand requests, as necessary.

For instance, given support for a single channel, Bitstamp, and two trading pairs, BTC/USD and BTC/EUR, after a successful connection, the server will output this response as the list of available channels for subscription:

{
"channel": "system",
"payload": {
"available_channels": [
"orderbook-bitstamp-aggregated-5-btc/eur",
"orderbook-bitstamp-aggregated-10-btc/usd",
"orderbook-bitstamp-btc/usd",
"orderbook-consolidated-aggregated-5-btc/usd",
"orderbook-simple-consolidated-aggregated-1-btc/eur",
"orderbook-bitstamp-aggregated-5-btc/usd",
"orderbook-simple-consolidated-btc/eur",
"orderbook-consolidated-aggregated-10-btc/usd",
"orderbook-simple-bitstamp-aggregated-10-btc/usd",
"orderbook-bitstamp-aggregated-1-btc/eur",
"orderbook-bitstamp-aggregated-0.5-btc/eur",
"orderbook-simple-bitstamp-aggregated-5-btc/eur",
"orderbook-consolidated-btc/usd",
"orderbook-simple-consolidated-aggregated-5-btc/usd",
"orderbook-consolidated-aggregated-10-btc/eur",
"orderbook-simple-consolidated-btc/usd",
"orderbook-simple-consolidated-aggregated-0.5-btc/usd",
"orderbook-consolidated-btc/eur",
"orderbook-simple-consolidated-aggregated-10-btc/eur",
"orderbook-simple-bitstamp-aggregated-0.5-btc/usd",
"orderbook-simple-bitstamp-aggregated-5-btc/usd",
"orderbook-simple-bitstamp-btc/eur",
"orderbook-consolidated-aggregated-0.5-btc/usd",
"trade-bitstamp-btc/usd",
"trade-consolidated-btc/eur",
"orderbook-consolidated-aggregated-1-btc/eur",
"orderbook-simple-bitstamp-aggregated-1-btc/usd",
"orderbook-consolidated-aggregated-5-btc/eur",
"orderbook-bitstamp-aggregated-0.5-btc/usd",
"orderbook-simple-consolidated-aggregated-5-btc/eur",
"orderbook-bitstamp-aggregated-1-btc/usd",
"trade-bitstamp-btc/eur",
"orderbook-bitstamp-btc/eur",
"orderbook-bitstamp-aggregated-10-btc/eur",
"trade-consolidated-btc/usd",
"orderbook-simple-consolidated-aggregated-0.5-btc/eur",
"orderbook-simple-bitstamp-aggregated-10-btc/eur",
"orderbook-simple-bitstamp-btc/usd",
"orderbook-consolidated-aggregated-0.5-btc/eur",
"orderbook-consolidated-aggregated-1-btc/usd",
"orderbook-simple-consolidated-aggregated-10-btc/usd",
"orderbook-simple-bitstamp-aggregated-0.5-btc/eur",
"orderbook-simple-bitstamp-aggregated-1-btc/eur",
"orderbook-simple-consolidated-aggregated-1-btc/usd"
]
}
}

Request For Quote (RFQ)

In the case that a Client is enrolled at DLT to use Request For Quote (RFQ) features, then the list of available channels will include specific, custom RFQ channels, that will stream all the RFQ pricing DLT offers, using the same format specifications as any other regular channels.

For instance, if a Client were to have RFQ features only on the BTC/USD pair, then the following channel will provide a stream of the latest prices,

rfq-orderbook-btc/usd

Responses from such channels will follow this structure:

{
"channel": "rfq-orderbook-btc/usd",
"payload": {
"bids": [{ "price": "38595.580056", "volume": "0.04" }],
"asks": [{ "price": "38658.615475", "volume": "0.04" }]
}
}

Timeouts

Websocket connections will be automatically closed after 12 hours. Clients should reconnect and re-subscribe after this time.

Own Trades messages

{
"channel": "own-trade",
"payload": [
{
"action": "Buy",
"amount": "0.001",
"client_code": "098681ed-3829-4215-b57b-37c27c5cdebf",
"code": "4ce0f583-b66e-4148-a90a-51f361a061bf",
"created": "2025-05-13T12:16:22.801Z",
"customer_code": "3a034186-9833-40cf-939f-81f3f57cc530",
"exchange_time": "2025-05-13T12:16:21.880Z",
"external_code": "14f7e047-2ff4-11f0-bfd4-99c089d3d707",
"fees": {
"bank": "0.24",
"dlt": "0.27",
"dltCurencyCode": "EUR",
"exchange": "0",
"exchangeCurencyCode": "EUR"
},
"market_item": {
"base": "BTC",
"exchange_code": "b2c2",
"quote": "EUR"
},
"order": {
"action": "Buy",
"amount": "0.001",
"client_code": "098681ed-3829-4215-b57b-37c27c5cdebf",
"code": "cb8b8f86-4316-46ca-8d11-bcecee530fd4",
"created": "2025-05-13T12:16:21.780Z",
"creator_code": "68763ea7-fb3b-11e9-be97-3a49be520cae",
"customer_code": "3a034186-9833-40cf-939f-81f3f57cc530",
"deposit_holder_code": "4b99350c-70f5-4d20-ac45-22d11709f4a9",
"executed": {
"amount": "0.001",
"bank_fee": "0.24",
"broker_fee": "0.27",
"price": "93457.8",
"value": "93.4578"
},
"external_code": "14f7b936-2ff4-11f0-bfd4-99c089d3d707",
"finished": "2025-05-13T12:16:22.836Z",
"kind": "Regular",
"limit_price": "0",
"market_item": {
"base": "BTC",
"exchange_code": "b2c2",
"quote": "EUR"
},
"status": "Filled",
"type": "Market",
"updated": "2025-05-13T12:16:21.916Z"
},
"price": "93457.8"
}
]
}

Trades messages

{
"channel": "trade-kraken-btc/eur",
"payload": [
{
"action": "Buy",
"amount": "0.00026213",
"created": "2025-05-13T12:31:09.107Z",
"exchange": "kraken",
"external_code": "T93304.1",
"price": "93304.1"
}
]
}