feat(): finish implementing v2 private websockets

This commit is contained in:
Tiago Siebler
2023-11-14 16:13:29 +00:00
parent de9fb8f2cd
commit a54058a205
4 changed files with 117 additions and 48 deletions

View File

@@ -1,7 +1,7 @@
import { WebsocketClient, DefaultLogger } from '../src'; import { WebsocketClientV2, DefaultLogger } from '../src';
// or // or
// import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bitget-api'; // import { DefaultLogger, WS_KEY_MAP, WebsocketClientV2 } from 'bitget-api';
(async () => { (async () => {
const logger = { const logger = {
@@ -13,7 +13,7 @@ import { WebsocketClient, DefaultLogger } from '../src';
const API_SECRET = process.env.API_SECRET_COM; const API_SECRET = process.env.API_SECRET_COM;
const API_PASS = process.env.API_PASS_COM; const API_PASS = process.env.API_PASS_COM;
const wsClient = new WebsocketClient( const wsClient = new WebsocketClientV2(
{ {
apiKey: API_KEY, apiKey: API_KEY,
apiSecret: API_SECRET, apiSecret: API_SECRET,
@@ -57,17 +57,21 @@ import { WebsocketClient, DefaultLogger } from '../src';
// spot private // spot private
// : account updates // : account updates
// wsClient.subscribeTopic('SPBL', 'account'); // wsClient.subscribeTopic('SPOT', 'account');
// : order updates
// wsClient.subscribeTopic('SPBL', 'orders'); // : order updates (note: symbol is required)
// wsClient.subscribeTopic('SPOT', 'orders', 'BTCUSDT');
// futures private // futures private
// : account updates // : account updates
// wsClient.subscribeTopic('UMCBL', 'account'); // wsClient.subscribeTopic('USDT-FUTURES', 'account');
// // : position updates
// wsClient.subscribeTopic('UMCBL', 'positions'); // : position updates
// // : order updates // wsClient.subscribeTopic('USDT-FUTURES', 'positions');
// wsClient.subscribeTopic('UMCBL', 'orders');
// // : plan order updates // : order updates
// wsClient.subscribeTopic('UMCBL', 'ordersAlgo'); // wsClient.subscribeTopic('USDT-FUTURES', 'orders');
// : plan order updates
wsClient.subscribeTopic('USDT-FUTURES', 'orders-algo');
})(); })();

View File

@@ -66,9 +66,19 @@ export type WSPrivateTopicFuturesV2 =
| 'orders-algo' | 'orders-algo'
| 'positions-history'; | 'positions-history';
export type WsPrivateTopicV2 = 'account' | 'orders' | WSPrivateTopicFuturesV2; export type WSPrivateTopicMarginV2 =
| 'orders-crossed'
| 'account-crossed'
| 'account-isolated'
| 'orders-isolated';
export type WsTopicV2 = WsPublicTopicV2; export type WsPrivateTopicV2 =
| 'account'
| 'orders'
| WSPrivateTopicFuturesV2
| WSPrivateTopicMarginV2;
export type WsTopicV2 = WsPublicTopicV2 | WsPrivateTopicV2;
/** This is used to differentiate between each of the available websocket streams */ /** This is used to differentiate between each of the available websocket streams */
export type WsKey = (typeof WS_KEY_MAP)[keyof typeof WS_KEY_MAP]; export type WsKey = (typeof WS_KEY_MAP)[keyof typeof WS_KEY_MAP];
@@ -77,25 +87,50 @@ export type WsKey = (typeof WS_KEY_MAP)[keyof typeof WS_KEY_MAP];
* Event args for subscribing/unsubscribing * Event args for subscribing/unsubscribing
*/ */
// TODO: generalise so this can be made a reusable module for other clients
export interface WsTopicSubscribeEventArgs { export interface WsTopicSubscribeEventArgs {
instType: BitgetInstType; instType: BitgetInstType;
channel: WsTopic; channel: WsTopic;
/** The symbol, e.g. "BTCUSDT" */ instId?: string;
instId: string;
} }
export type WsTopicSubscribeCommonArgsV2 = { export type WsTopicSubscribePublicArgsV2 = {
instType: BitgetInstTypeV2; instType: BitgetInstTypeV2;
channel: WsTopicV2;
};
export type WsTopicSubscribePublicArgsV2 = WsTopicSubscribeCommonArgsV2 & {
channel: WsPublicTopicV2; channel: WsPublicTopicV2;
/** The symbol, e.g. "BTCUSDT" */
instId: string; instId: string;
}; };
export type WsTopicSubscribeEventArgsV2 = WsTopicSubscribePublicArgsV2; export type WsInstIdChannelsV2 =
| 'orders'
| WSPrivateTopicFuturesV2
| 'orders-crossed'
| 'orders-isolated';
export type WsTopicSubscribePrivateInstIdArgsV2 = {
instType: BitgetInstTypeV2;
channel: WsInstIdChannelsV2;
/** The symbol, e.g. "BTCUSDT" */
instId?: string;
};
export type WsCoinChannelsV2 =
| 'account'
| 'account-crossed'
| 'account-isolated';
export type WsTopicSubscribePrivateCoinArgsV2 = {
instType: BitgetInstTypeV2;
channel: WsCoinChannelsV2;
coin: 'default' | string;
};
export type WsTopicSubscribePrivateArgsV2 =
| WsTopicSubscribePrivateInstIdArgsV2
| WsTopicSubscribePrivateCoinArgsV2;
export type WsTopicSubscribeEventArgsV2 =
| WsTopicSubscribePublicArgsV2
| WsTopicSubscribePrivateArgsV2;
/** General configuration for the WebsocketClient */ /** General configuration for the WebsocketClient */
export interface WSClientConfigurableOptions { export interface WSClientConfigurableOptions {

View File

@@ -75,9 +75,13 @@ export const PRIVATE_TOPICS = ['account', 'orders', 'positions', 'ordersAlgo'];
export const PRIVATE_TOPICS_V2: WsPrivateTopicV2[] = [ export const PRIVATE_TOPICS_V2: WsPrivateTopicV2[] = [
'account', 'account',
'orders', 'orders',
'orders-algo',
'positions', 'positions',
'orders-algo',
'positions-history', 'positions-history',
'orders-crossed',
'account-crossed',
'account-isolated',
'orders-isolated',
]; ];
export function isPrivateChannel<TChannel extends string>( export function isPrivateChannel<TChannel extends string>(

View File

@@ -3,8 +3,13 @@ import WebSocket from 'isomorphic-ws';
import { import {
BitgetInstTypeV2, BitgetInstTypeV2,
WebsocketClientOptions, WebsocketClientOptions,
WsCoinChannelsV2,
WsInstIdChannelsV2,
WsKey, WsKey,
WsPublicTopicV2,
WsTopicSubscribeEventArgsV2, WsTopicSubscribeEventArgsV2,
WsTopicSubscribePrivateCoinArgsV2,
WsTopicSubscribePrivateInstIdArgsV2,
WsTopicV2, WsTopicV2,
} from './types'; } from './types';
@@ -22,6 +27,12 @@ import { BaseWebsocketClient } from './util/BaseWSClient';
const LOGGER_CATEGORY = { category: 'bitget-ws' }; const LOGGER_CATEGORY = { category: 'bitget-ws' };
const COIN_CHANNELS: WsTopicV2[] = [
'account',
'account-crossed',
'account-isolated',
];
export class WebsocketClientV2 extends BaseWebsocketClient< export class WebsocketClientV2 extends BaseWebsocketClient<
WsKey, WsKey,
WsTopicSubscribeEventArgsV2 WsTopicSubscribeEventArgsV2
@@ -92,6 +103,38 @@ export class WebsocketClientV2 extends BaseWebsocketClient<
]; ];
} }
/** Some private channels use `coin` instead of `instId`. This method handles building the sub/unsub request */
private getSubRequest(
instType: BitgetInstTypeV2,
topic: WsTopicV2,
coin: string = 'default',
): WsTopicSubscribeEventArgsV2 {
if (isPrivateChannel(topic)) {
if (COIN_CHANNELS.includes(topic)) {
const subscribeRequest: WsTopicSubscribePrivateCoinArgsV2 = {
instType,
channel: topic as WsCoinChannelsV2,
coin,
};
return subscribeRequest;
}
const subscribeRequest: WsTopicSubscribePrivateInstIdArgsV2 = {
instType,
channel: topic as WsInstIdChannelsV2,
instId: coin,
};
return subscribeRequest;
}
return {
instType,
channel: topic as WsPublicTopicV2,
instId: coin,
};
}
/** /**
* Subscribe to a PUBLIC topic * Subscribe to a PUBLIC topic
* @param instType instrument type (refer to API docs). * @param instType instrument type (refer to API docs).
@@ -101,41 +144,24 @@ export class WebsocketClientV2 extends BaseWebsocketClient<
public subscribeTopic( public subscribeTopic(
instType: BitgetInstTypeV2, instType: BitgetInstTypeV2,
topic: WsTopicV2, topic: WsTopicV2,
instId: string = 'default', coin: string = 'default',
) { ) {
return this.subscribe({ const subRequest = this.getSubRequest(instType, topic, coin);
instType, return this.subscribe(subRequest);
instId,
channel: topic,
});
} }
// public subscribeTopicV2(
// instType: BitgetInstTypeV2,
// topic: WsTopicV2,
// instId: string = 'default',
// ) {
// if (isPrivateChannel(topic)) {
// }
// }
/** /**
* Unsubscribe from a topic * Unsubscribe from a topic
* @param instType instrument type (refer to API docs). * @param instType instrument type (refer to API docs).
* @param topic topic name (e.g. "ticker"). * @param topic topic name (e.g. "ticker").
* @param instId instrument ID (e.g. "BTCUSDT"). Use "default" for private topics to get all symbols. * @param instId instrument ID (e.g. "BTCUSDT"). Use "default" for private topics to get all symbols.
*
* @deprecated, use `subscribe(topics, isPrivate) instead
*/ */
public unsubscribeTopic( public unsubscribeTopic(
instType: BitgetInstTypeV2, instType: BitgetInstTypeV2,
topic: WsTopicV2, topic: WsTopicV2,
instId: string = 'default', coin: string = 'default',
) { ) {
return this.unsubscribe({ const subRequest = this.getSubRequest(instType, topic, coin);
instType, return this.unsubscribe(subRequest);
instId,
channel: topic,
});
} }
} }