WebSocket Authentication

HMAC Authentication

  • Endpoint: wss://ws-feed-pro.btcturk.com
  • The WebSocket feed provides real-time market data updates for orders and trades.
  • The WebSocket feed uses a bidirectional protocol, which encodes all messages as JSON objects. All messages have a type attribute that can be used to handle the message appropriately.
  • Please note that new message types can be added at any point in time. Clients are expected to ignore messages they do not support.
HMAC login mechanism for WebSocket:
From BtcTurk | PRO go to ACCOUNT>API Access
In the form select WebSocket, enter you are IP address and submit. This action will create public key and private key to achieve WebSocket login.
Code Example
C#
Python
GoLang
Node.js
// You can download ApiClient .net core complete library from github https://github.com/BTCTrader/broker-api-csharp-v2
private static async Task HmacTest()
{
Uri _uri = new Uri("wss://ws-feed-pro.btcturk.com");
ClientWebSocket client = new ClientWebSocket();
await client.ConnectAsync(_uri, CancellationToken.None);
string publicKey = "YOUR_PUBLIC_KEY";
string privateKey = "YOUR_PRIVATE_KEY";
long nonce = 3000;
string baseString = $"{publicKey}{nonce}";
string signature = ComputeHash(privateKey, baseString);
long timestamp = ToUnixTime(DateTime.UtcNow);
object[] hmacMessageObject = { 114, new { type = 114, publicKey = publicKey, timestamp = timestamp, nonce = nonce, signature = signature } };
string message = JsonSerializer.Serialize(hmacMessageObject);
await client.SendAsync(buffer: new ArraySegment<byte>(array: Encoding.UTF8.GetBytes(message),
offset: 0,
count: message.Length),
messageType: WebSocketMessageType.Text,
endOfMessage: true,
cancellationToken: CancellationToken.None);
}
private static string ComputeHash(string privateKey, string baseString)
{
var key = Convert.FromBase64String(privateKey);
string hashString;
using (var hmac = new HMACSHA256(key))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(baseString));
hashString = Convert.ToBase64String(hash);
}
return hashString;
}
private static long ToUnixTime(DateTime date)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64((date - epoch).TotalMilliseconds);
}
import asyncio
import base64
import hashlib
import hmac
import json
import time
import websockets
class InterfaceWS:
def __init__(self, exchange_name: str = None) -> None:
self.exchange_name = "BTC Turk"
self.uri = "wss://ws-feed-pro.btcturk.com/"
async def authenticate_ws(self) -> bool:
self.ws = await websockets.connect(self.uri)
publicKey = "PUBLIC_KEY_HERE";
privateKey = "PRIVATE_KEY_HERE";
nonce = 3000
print("\nnonce", nonce)
baseString = "{}{}".format(publicKey, nonce).encode("utf-8")
print("\nbaseString", baseString)
signature = hmac.new(
base64.b64decode(privateKey), baseString, hashlib.sha256
).digest()
print("\nsignature", signature)
signature = base64.b64encode(signature)
print("\nsignature", signature)
timestamp = round(time.time() * 1000)
print("\ntimestamp", timestamp)
hmacMessageObject = [
114,
{
"nonce": nonce,
"publicKey": publicKey,
"signature": signature.decode("utf-8"),
"timestamp": timestamp,
"type": 114,
},
]
print("hmacMessageObject", hmacMessageObject)
await self.ws.send(json.dumps(hmacMessageObject))
while True:
try:
response = await asyncio.wait_for(self.ws.recv(), timeout=0.5)
print("response after auth: ", response)
except Exception as e:
print(e)
async def main():
w = InterfaceWS()
await w.authenticate_ws()
if __name__ == "__main__":
asyncio.run(main())
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"flag"
"fmt"
"github.com/gorilla/websocket"
"log"
"net/url"
"time"
)
var addr = flag.String("addr", "wss://ws-feed-pro.btcturk.com", "BtcTurk Websocket Feed")
func main() {
u := url.URL{Scheme: "wss", Host: *addr, Path: "/"}
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("Dial Error:", err)
}
publicKey := "PUBLIC_KEY_HERE"
privateKey := "PRIVATE_KEY_HERE"
key, err := base64.StdEncoding.DecodeString(privateKey)
if err != nil {
log.Println("ERROR:", err)
return
}
stamp := fmt.Sprint(time.Now().UTC().UnixMilli())
nonce := 3000
baseString := fmt.Sprint(publicKey, nonce)
hmac := hmac.New(sha256.New, key)
hmac.Write([]byte(baseString))
signature := base64.StdEncoding.EncodeToString(hmac.Sum(nil))
request := fmt.Sprintf(`[114,{"type":114, "publicKey":"%s", "timestamp":%s, "nonce":3000, "signature": "%s"}]`, publicKey, stamp, signature)
message := []byte(request)
err = c.WriteMessage(websocket.TextMessage, message)
if err != nil {
log.Println("ERROR:", err)
return
}
for {
messageType, p, err := c.ReadMessage()
if err != nil {
log.Println(err)
return
}
log.Println(string(p))
if err = c.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
const crypto = require('crypto');
const WebSocket = require('ws');
const url = 'wss://ws-feed-pro.btcturk.com/';
const connection = new WebSocket(url);
const publicKey = "PUBLIC_KEY_HERE"
const privateKey = "PRIVATE_KEY_HERE"
const nonce = 3000;
const stamp = (new Date()).getTime()
const baseString = `${publicKey}${nonce}`
const data = Buffer.from(`${baseString}`, 'utf8')
const buffer = crypto.createHmac('sha256', Buffer.from(privateKey, 'base64'))
buffer.update(data)
const signature = Buffer.from(buffer.digest().toString('base64'), 'utf8').toString('utf8')
const message = `[114,{"type":114, "publicKey":"${publicKey}", "timestamp":${stamp}, "nonce":${nonce}, "signature": "${signature}"}]`
connection.onopen = () => {
connection.send(message)
}
connection.onerror = (error) => {
console.log(`WebSocket error: ${error}`)
}
connection.onmessage = (e) => {
console.log(e.data)
}