Я пытаюсь подписаться на API kraken websocket для OpenPositions. Я отправил запрос на вызов и получил запрос, я также правильно его подписал своим секретным ключом, но, похоже, после отправки запроса на подспозицию openpositions веб-сокет закрывается напрямую с кодом 1006 и причинами ''.
Я пишу в Nodejs, используя нативную библиотеку websocket и emiiter для отправки данных «kraken-update»
Это основной файл, который я запускаю:
const con = new Connection(key = keys.api_key, secret=keys.secret);
con.on('kraken-update', (data) => {
console.log(new Date, "DATA", data);
return;
});
const go = async(key, secret) => {
console.log(new Date, 'connecting...');
await con.connect();
console.log(new Date, 'connected');
await con.sendchallenge()
}
и вот класс Connection
const WebSocket = require('ws');
const crypto = require('crypto');
const EventEmitter = require('events');
class Connection extends EventEmitter {
constructor( key, secret, challenge = '') {
super();
this.url = 'wss://futures.kraken.com/ws/v1';
this.connected = false;
this.challenge = challenge;
this.lastMessageAt = 0;
this.key=key;
this.secret=secret;
}
disconnect() {
this.ws.disconnect();
}
connect() {
if(this.connected) {
console.log("ALREADY CONNECTED")
return;
}
let readyHook;
this.onOpen = new Promise(r => readyHook = r);
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
this.connected = true;
readyHook();
}
this.ws.onerror = (e) => {
console.log(new Date, '[KRAKEN] error', e);
}
this.ws.onclose = (e) => {
console.log(new Date, '[KRAKEN] close', e);
}
this.ws.onmessage = (e) => {
//console.log("MESSAGE ",e.data)
setImmediate(()=>this.handleMessage(e))
}
// initial book data coming in on the same tick as the subscription data
// we defer this so the subscription promise resloves before we send
// initial OB data.
return this.onOpen;
}
handleMessage(e){
this.lastMessageAt = new Date;
console.log(e)
const payload = JSON.parse(e.data);
if(payload.event === 'subscribed') {
this.emit('kraken-update', payload)
console.log(new Date, "SUBSCRIBED ",payload)
return;
}
if (payload.event === 'challenge'){
this.challenge = payload.message
this.emit('kraken-update', payload.message);
this.subscribeOpenPositions();
return;
}
if (payload.feed === "open_positions"){
this.emit('kraken-update', payload.message);
return;
}
else{
console.log(new Date, "UNDETECTED ",payload)
return;
}
}
sendchallenge(){
try{
let onReady = new Promise(e => e);
const data = JSON.stringify({'event': 'challenge','api_key':this.key})
this.ws.send(data);
return onReady;
}
catch(e){
console.log(new Date, 'ERROR SENDING CHALLENGE')
throw(e)
}
}
subscribeOpenPositions(){
//how to sign challenge:
//https://support.kraken.com/hc/en-us/articles/360022635652-Sign-Challenge-Web-Socket-API-
console.log(new Date, `SUBSCRIBING OPENPOSITION WITH ${this.challenge}....`);
try{
const secret_buffer = new Buffer.from(this.secret, 'base64');
const hash = new crypto.createHash('sha256');
const hmac = new crypto.createHmac('sha512', secret_buffer);
const hash_digest = hash.update(this.challenge).digest('binary');
const hmac_digest = hmac.update(hash_digest, 'binary').digest('base64');
this.ws.send(JSON.stringify({"event":"ping"}))
this.ws.send(JSON.stringify(
{"event":"subscribe",
"feed":"open_positions",
"api_key":this.key,
"original_challenge":this.challenge,
"signed_challenge":hmac_digest}
));
console.log("SENT");
}
catch(e){
console.log(new Date,"ERROR SENDING SUBSCRIPTION REQUEST")
throw(e)
}
}
}
module.exports = Connection;
Сводка того, что произошло:
подключиться к будущему серверу kraken => запрос вызова => обработать вызов, затем запросить подписку openorder при обработке вызова => закрытие веб-сокета