UNPKG

@hydro-protocol/hydro-client-js

Version:
149 lines (148 loc) 6.49 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var ws_1 = __importDefault(require("ws")); var Channel_1 = require("../models/Channel"); var Order_1 = require("../models/Order"); var Orderbook_1 = require("../models/Orderbook"); var Ticker_1 = require("../models/Ticker"); var Trade_1 = require("../models/Trade"); var PriceLevel_1 = require("../models/PriceLevel"); /** * The Hydro API provides a websocket connection that can push updates * about the exchange to clients. This watcher lets you create a listener * function to handle updates, and a subscription function to choose which * channels you wish to get updates on. * * See https://docs.ddex.io/#websocket */ var HydroWatcher = /** @class */ (function () { /** * Initialize a new watcher with a set of listener functions that will * be called when a message of that type is received. The watcher will * not connect to the server until you subscribe to at least one channel. * * @param listener Object containing the functions to handle the updates you care about */ function HydroWatcher(listener, options) { this.messageQueue = []; this.listener = listener; this.options = options; } /** * Subscribe to a channel and begin receiving updates from the exchange * for a set of market ids * * See https://docs.ddex.io/#subscribe * * @param channel The name of the channel you want to subscribe to * @param marketIds A list of market ids you want updates for */ HydroWatcher.prototype.subscribe = function (channel, marketIds) { this.initIfNeeded(); this.sendMessage(this.generateMessage('subscribe', channel, marketIds)); }; /** * Unsubscribe to stop receiving updates from the exchange for a particular * channel/market ids * * See https://docs.ddex.io/#unsubscribe * * @param channel The name of the channel you want to unsubscribe from * @param marketIds A list of market ids you no longer want updates for */ HydroWatcher.prototype.unsubscribe = function (channel, marketIds) { this.initIfNeeded(); this.sendMessage(this.generateMessage('unsubscribe', channel, marketIds)); }; HydroWatcher.prototype.initIfNeeded = function () { var _this = this; if (!this.socket || this.socket.readyState === ws_1.default.CLOSED) { this.socket = new ws_1.default(this.getWebsocketUrl()); this.socket.on('message', function (message) { _this.receiveMessage(message); }); this.socket.on('close', function () { _this.initIfNeeded(); }); this.socket.on('open', function () { while (_this.messageQueue.length > 0) { var message = _this.messageQueue.shift(); _this.socket && _this.socket.send(message); } }); } }; HydroWatcher.prototype.getWebsocketUrl = function () { return this.options && this.options.websocketUrl ? this.options.websocketUrl : HydroWatcher.SOCKET_URL; }; HydroWatcher.prototype.sendMessage = function (message) { if (this.socket && this.socket.readyState === ws_1.default.OPEN) { this.socket.send(message); } else { this.messageQueue.push(message); } }; HydroWatcher.prototype.receiveMessage = function (message) { var _this = this; if (!this.listener) { return; } var json = JSON.parse(message); switch (json.type) { case 'subscriptions': return (this.listener.subscriptionsUpdate && this.listener.subscriptionsUpdate(json.channels.map(function (channel) { return new Channel_1.Channel(channel); }))); case 'ticker': return this.listener.tickerUpdate && this.listener.tickerUpdate(new Ticker_1.Ticker(json)); case 'level2OrderbookSnapshot': return (this.listener.orderbookSnapshot && this.listener.orderbookSnapshot(new Orderbook_1.Orderbook(json))); case 'level2OrderbookUpdate': return (json.changes && json.changes.forEach(function (change) { _this.listener.orderbookUpdate && _this.listener.orderbookUpdate(change.side, new PriceLevel_1.PriceLevel(change)); })); case 'level3OrderbookSnapshot': return (this.listener.fullSnapshot && this.listener.fullSnapshot(new Orderbook_1.Orderbook(json), json.sequence)); case 'receive': return (this.listener.orderReceived && this.listener.orderReceived(new Order_1.Order(json), json.sequence, new Date(json.time))); case 'open': return (this.listener.orderOpened && this.listener.orderOpened(new Order_1.Order(json), json.sequence, new Date(json.time))); case 'done': return (this.listener.orderDone && this.listener.orderDone(new Order_1.Order(json), json.sequence, new Date(json.time))); case 'change': return (this.listener.orderChanged && this.listener.orderChanged(new Order_1.Order(json), json.sequence, new Date(json.time))); case 'trade': return (this.listener.tradeBegin && this.listener.tradeBegin(new Trade_1.Trade(json), json.sequence, new Date(json.time))); case 'trade_success': return (this.listener.tradeSuccess && this.listener.tradeSuccess(new Trade_1.Trade(json), json.sequence, new Date(json.time))); } }; HydroWatcher.prototype.generateMessage = function (type, channel, marketIds) { return JSON.stringify({ type: type, channels: [ { name: channel, marketIds: marketIds, }, ], }); }; HydroWatcher.SOCKET_URL = 'wss://ws.ddex.io/v3'; return HydroWatcher; }()); exports.HydroWatcher = HydroWatcher;