cleaning around tests
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { RestClientOptions, WS_KEY_MAP } from '../util';
|
||||
|
||||
export type APIMarket = 'inverse' | 'linear' | 'spot'; //| 'v3';
|
||||
export type APIMarket = 'inverse' | 'linear' | 'spot' | 'spotV3'; //| 'v3';
|
||||
|
||||
// Same as inverse futures
|
||||
export type WsPublicInverseTopic =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WsKey } from '../types';
|
||||
import { APIMarket, WsKey } from '../types';
|
||||
|
||||
interface NetworkMapV3 {
|
||||
livenet: string;
|
||||
@@ -10,42 +10,52 @@ interface NetworkMapV3 {
|
||||
type PublicPrivateNetwork = 'public' | 'private';
|
||||
|
||||
export const WS_BASE_URL_MAP: Record<
|
||||
string,
|
||||
APIMarket,
|
||||
Record<PublicPrivateNetwork, NetworkMapV3>
|
||||
> = {
|
||||
inverse: {
|
||||
private: {
|
||||
public: {
|
||||
livenet: 'wss://stream.bybit.com/realtime',
|
||||
testnet: 'wss://stream-testnet.bybit.com/realtime',
|
||||
},
|
||||
public: {
|
||||
private: {
|
||||
livenet: 'wss://stream.bybit.com/realtime',
|
||||
testnet: 'wss://stream-testnet.bybit.com/realtime',
|
||||
},
|
||||
},
|
||||
linear: {
|
||||
private: {
|
||||
livenet: 'wss://stream.bybit.com/realtime_private',
|
||||
livenet2: 'wss://stream.bytick.com/realtime_private',
|
||||
testnet: 'wss://stream-testnet.bybit.com/realtime_private',
|
||||
},
|
||||
public: {
|
||||
livenet: 'wss://stream.bybit.com/realtime_public',
|
||||
livenet2: 'wss://stream.bytick.com/realtime_public',
|
||||
testnet: 'wss://stream-testnet.bybit.com/realtime_public',
|
||||
},
|
||||
private: {
|
||||
livenet: 'wss://stream.bybit.com/realtime_private',
|
||||
livenet2: 'wss://stream.bytick.com/realtime_private',
|
||||
testnet: 'wss://stream-testnet.bybit.com/realtime_private',
|
||||
},
|
||||
},
|
||||
spot: {
|
||||
private: {
|
||||
livenet: 'wss://stream.bybit.com/spot/ws',
|
||||
testnet: 'wss://stream-testnet.bybit.com/spot/ws',
|
||||
},
|
||||
public: {
|
||||
livenet: 'wss://stream.bybit.com/spot/quote/ws/v1',
|
||||
livenet2: 'wss://stream.bybit.com/spot/quote/ws/v2',
|
||||
testnet: 'wss://stream-testnet.bybit.com/spot/quote/ws/v1',
|
||||
testnet2: 'wss://stream-testnet.bybit.com/spot/quote/ws/v2',
|
||||
},
|
||||
private: {
|
||||
livenet: 'wss://stream.bybit.com/spot/ws',
|
||||
testnet: 'wss://stream-testnet.bybit.com/spot/ws',
|
||||
},
|
||||
},
|
||||
spotV3: {
|
||||
public: {
|
||||
livenet: 'wss://stream.bybit.com/spot/public/v3',
|
||||
testnet: 'wss://stream-testnet.bybit.com/spot/public/v3',
|
||||
},
|
||||
private: {
|
||||
livenet: 'wss://stream.bybit.com/spot/private/v3',
|
||||
testnet: 'wss://stream-testnet.bybit.com/spot/private/v3',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -55,6 +65,8 @@ export const WS_KEY_MAP = {
|
||||
linearPublic: 'linearPublic',
|
||||
spotPrivate: 'spotPrivate',
|
||||
spotPublic: 'spotPublic',
|
||||
spotV3Private: 'spotV3Private',
|
||||
spotV3Public: 'spotV3Public',
|
||||
} as const;
|
||||
|
||||
export const PUBLIC_WS_KEYS = [
|
||||
@@ -77,7 +89,10 @@ export function getLinearWsKeyForTopic(topic: string): WsKey {
|
||||
return WS_KEY_MAP.linearPublic;
|
||||
}
|
||||
|
||||
export function getSpotWsKeyForTopic(topic: string): WsKey {
|
||||
export function getSpotWsKeyForTopic(
|
||||
topic: string,
|
||||
apiVersion: 'v1' | 'v3'
|
||||
): WsKey {
|
||||
const privateTopics = [
|
||||
'position',
|
||||
'execution',
|
||||
@@ -88,6 +103,13 @@ export function getSpotWsKeyForTopic(topic: string): WsKey {
|
||||
'ticketInfo',
|
||||
];
|
||||
|
||||
if (apiVersion === 'v3') {
|
||||
if (privateTopics.includes(topic)) {
|
||||
return WS_KEY_MAP.spotV3Private;
|
||||
}
|
||||
return WS_KEY_MAP.spotV3Public;
|
||||
}
|
||||
|
||||
if (privateTopics.includes(topic)) {
|
||||
return WS_KEY_MAP.spotPrivate;
|
||||
}
|
||||
|
||||
@@ -136,6 +136,17 @@ export class WebsocketClient extends EventEmitter {
|
||||
this.connectPublic();
|
||||
break;
|
||||
}
|
||||
case 'spotV3': {
|
||||
this.restClient = new SpotClientV3(
|
||||
undefined,
|
||||
undefined,
|
||||
!this.isTestnet(),
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
);
|
||||
this.connectPublic();
|
||||
break;
|
||||
}
|
||||
// if (this.isV3()) {
|
||||
// this.restClient = new SpotClientV3(
|
||||
// undefined,
|
||||
@@ -175,59 +186,6 @@ export class WebsocketClient extends EventEmitter {
|
||||
// return this.options.market === 'v3';
|
||||
// }
|
||||
|
||||
/**
|
||||
* Add topic/topics to WS subscription list
|
||||
*/
|
||||
public subscribe(wsTopics: WsTopic[] | WsTopic) {
|
||||
const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
|
||||
topics.forEach((topic) =>
|
||||
this.wsStore.addTopic(this.getWsKeyForTopic(topic), topic)
|
||||
);
|
||||
|
||||
// attempt to send subscription topic per websocket
|
||||
this.wsStore.getKeys().forEach((wsKey: WsKey) => {
|
||||
// if connected, send subscription request
|
||||
if (
|
||||
this.wsStore.isConnectionState(wsKey, WsConnectionStateEnum.CONNECTED)
|
||||
) {
|
||||
return this.requestSubscribeTopics(wsKey, topics);
|
||||
}
|
||||
|
||||
// start connection process if it hasn't yet begun. Topics are automatically subscribed to on-connect
|
||||
if (
|
||||
!this.wsStore.isConnectionState(
|
||||
wsKey,
|
||||
WsConnectionStateEnum.CONNECTING
|
||||
) &&
|
||||
!this.wsStore.isConnectionState(
|
||||
wsKey,
|
||||
WsConnectionStateEnum.RECONNECTING
|
||||
)
|
||||
) {
|
||||
return this.connect(wsKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove topic/topics from WS subscription list
|
||||
*/
|
||||
public unsubscribe(wsTopics: WsTopic[] | WsTopic) {
|
||||
const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
|
||||
topics.forEach((topic) =>
|
||||
this.wsStore.deleteTopic(this.getWsKeyForTopic(topic), topic)
|
||||
);
|
||||
|
||||
this.wsStore.getKeys().forEach((wsKey: WsKey) => {
|
||||
// unsubscribe request only necessary if active connection exists
|
||||
if (
|
||||
this.wsStore.isConnectionState(wsKey, WsConnectionStateEnum.CONNECTED)
|
||||
) {
|
||||
this.requestUnsubscribeTopics(wsKey, topics);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public close(wsKey: WsKey) {
|
||||
this.logger.info('Closing connection', { ...loggerCategory, wsKey });
|
||||
this.setWsState(wsKey, WsConnectionStateEnum.CLOSING);
|
||||
@@ -263,6 +221,12 @@ export class WebsocketClient extends EventEmitter {
|
||||
this.connect(WS_KEY_MAP.spotPrivate),
|
||||
];
|
||||
}
|
||||
case 'spotV3': {
|
||||
return [
|
||||
this.connect(WS_KEY_MAP.spotV3Public),
|
||||
this.connect(WS_KEY_MAP.spotV3Private),
|
||||
];
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(this.options.market, `connectAll(): Unhandled market`);
|
||||
}
|
||||
@@ -280,6 +244,9 @@ export class WebsocketClient extends EventEmitter {
|
||||
case 'spot': {
|
||||
return this.connect(WS_KEY_MAP.spotPublic);
|
||||
}
|
||||
case 'spotV3': {
|
||||
return this.connect(WS_KEY_MAP.spotV3Public);
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(
|
||||
this.options.market,
|
||||
@@ -300,6 +267,9 @@ export class WebsocketClient extends EventEmitter {
|
||||
case 'spot': {
|
||||
return this.connect(WS_KEY_MAP.spotPrivate);
|
||||
}
|
||||
case 'spotV3': {
|
||||
return this.connect(WS_KEY_MAP.spotV3Private);
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(
|
||||
this.options.market,
|
||||
@@ -503,7 +473,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
this.tryWsSend(wsKey, wsMessage);
|
||||
}
|
||||
|
||||
private tryWsSend(wsKey: WsKey, wsMessage: string) {
|
||||
public tryWsSend(wsKey: WsKey, wsMessage: string) {
|
||||
try {
|
||||
this.logger.silly(`Sending upstream ws message: `, {
|
||||
...loggerCategory,
|
||||
@@ -666,7 +636,13 @@ export class WebsocketClient extends EventEmitter {
|
||||
return WS_BASE_URL_MAP.spot.public[networkKey];
|
||||
}
|
||||
case WS_KEY_MAP.spotPrivate: {
|
||||
return WS_BASE_URL_MAP.linear.private[networkKey];
|
||||
return WS_BASE_URL_MAP.spot.private[networkKey];
|
||||
}
|
||||
case WS_KEY_MAP.spotV3Public: {
|
||||
return WS_BASE_URL_MAP.spot.public[networkKey];
|
||||
}
|
||||
case WS_KEY_MAP.spotV3Private: {
|
||||
return WS_BASE_URL_MAP.spot.private[networkKey];
|
||||
}
|
||||
case WS_KEY_MAP.inverse: {
|
||||
// private and public are on the same WS connection
|
||||
@@ -691,7 +667,10 @@ export class WebsocketClient extends EventEmitter {
|
||||
return getLinearWsKeyForTopic(topic);
|
||||
}
|
||||
case 'spot': {
|
||||
return getSpotWsKeyForTopic(topic);
|
||||
return getSpotWsKeyForTopic(topic, 'v1');
|
||||
}
|
||||
case 'spotV3': {
|
||||
return getSpotWsKeyForTopic(topic, 'v3');
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(
|
||||
@@ -708,6 +687,59 @@ export class WebsocketClient extends EventEmitter {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add topic/topics to WS subscription list
|
||||
*/
|
||||
public subscribe(wsTopics: WsTopic[] | WsTopic) {
|
||||
const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
|
||||
topics.forEach((topic) =>
|
||||
this.wsStore.addTopic(this.getWsKeyForTopic(topic), topic)
|
||||
);
|
||||
|
||||
// attempt to send subscription topic per websocket
|
||||
this.wsStore.getKeys().forEach((wsKey: WsKey) => {
|
||||
// if connected, send subscription request
|
||||
if (
|
||||
this.wsStore.isConnectionState(wsKey, WsConnectionStateEnum.CONNECTED)
|
||||
) {
|
||||
return this.requestSubscribeTopics(wsKey, topics);
|
||||
}
|
||||
|
||||
// start connection process if it hasn't yet begun. Topics are automatically subscribed to on-connect
|
||||
if (
|
||||
!this.wsStore.isConnectionState(
|
||||
wsKey,
|
||||
WsConnectionStateEnum.CONNECTING
|
||||
) &&
|
||||
!this.wsStore.isConnectionState(
|
||||
wsKey,
|
||||
WsConnectionStateEnum.RECONNECTING
|
||||
)
|
||||
) {
|
||||
return this.connect(wsKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove topic/topics from WS subscription list
|
||||
*/
|
||||
public unsubscribe(wsTopics: WsTopic[] | WsTopic) {
|
||||
const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
|
||||
topics.forEach((topic) =>
|
||||
this.wsStore.deleteTopic(this.getWsKeyForTopic(topic), topic)
|
||||
);
|
||||
|
||||
this.wsStore.getKeys().forEach((wsKey: WsKey) => {
|
||||
// unsubscribe request only necessary if active connection exists
|
||||
if (
|
||||
this.wsStore.isConnectionState(wsKey, WsConnectionStateEnum.CONNECTED)
|
||||
) {
|
||||
this.requestUnsubscribeTopics(wsKey, topics);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: persistance for subbed topics. Look at ftx-api implementation.
|
||||
public subscribePublicSpotTrades(symbol: string, binary?: boolean) {
|
||||
if (!this.isSpot()) {
|
||||
|
||||
Reference in New Issue
Block a user