public usdc perp ws test

This commit is contained in:
tiagosiebler
2022-09-16 13:25:25 +01:00
parent d2ba5d3e01
commit 9b673f08d5
6 changed files with 139 additions and 12 deletions

View File

@@ -3,13 +3,15 @@ import { LinearClient } from '../linear-client';
import { SpotClient } from '../spot-client';
import { SpotClientV3 } from '../spot-client-v3';
import { USDCOptionClient } from '../usdc-option-client';
import { USDCPerpetualClient } from '../usdc-perpetual-client';
export type RESTClient =
| InverseClient
| LinearClient
| SpotClient
| SpotClientV3
| USDCOptionClient;
| USDCOptionClient
| USDCPerpetualClient;
export type numberInString = string;

View File

@@ -1,7 +1,13 @@
import { RestClientOptions, WS_KEY_MAP } from '../util';
/** For spot markets, spotV3 is recommended */
export type APIMarket = 'inverse' | 'linear' | 'spot' | 'spotv3' | 'usdcOption';
export type APIMarket =
| 'inverse'
| 'linear'
| 'spot'
| 'spotv3'
| 'usdcOption'
| 'usdcPerp';
// Same as inverse futures
export type WsPublicInverseTopic =

View File

@@ -69,6 +69,18 @@ export const WS_BASE_URL_MAP: Record<
testnet: 'wss://stream-testnet.bybit.com/trade/option/usdc/private/v1',
},
},
usdcPerp: {
public: {
livenet: 'wss://stream.bybit.com/perpetual/ws/v1/realtime_public',
livenet2: 'wss://stream.bytick.com/perpetual/ws/v1/realtime_public',
testnet: 'wss://stream-testnet.bybit.com/perpetual/ws/v1/realtime_public',
},
private: {
livenet: 'wss://stream.bybit.com/trade/option/usdc/private/v1',
livenet2: 'wss://stream.bytick.com/trade/option/usdc/private/v1',
testnet: 'wss://stream-testnet.bybit.com/trade/option/usdc/private/v1',
},
},
};
export const WS_KEY_MAP = {
@@ -81,8 +93,8 @@ export const WS_KEY_MAP = {
spotV3Public: 'spotV3Public',
usdcOptionPrivate: 'usdcOptionPrivate',
usdcOptionPublic: 'usdcOptionPublic',
// usdcPerpPrivate: 'usdcPerpPrivate',
// usdcPerpPublic: 'usdcPerpPublic',
usdcPerpPrivate: 'usdcPerpPrivate',
usdcPerpPublic: 'usdcPerpPublic',
} as const;
export const WS_AUTH_ON_CONNECT_KEYS: WsKey[] = [WS_KEY_MAP.spotV3Private];
@@ -92,6 +104,7 @@ export const PUBLIC_WS_KEYS = [
WS_KEY_MAP.spotPublic,
WS_KEY_MAP.spotV3Public,
WS_KEY_MAP.usdcOptionPublic,
WS_KEY_MAP.usdcPerpPublic,
] as string[];
/** Used to automatically determine if a sub request should be to the public or private ws (when there's two) */
@@ -158,6 +171,11 @@ export function getWsKeyForTopic(
? WS_KEY_MAP.usdcOptionPrivate
: WS_KEY_MAP.usdcOptionPublic;
}
case 'usdcPerp': {
return isPrivateTopic
? WS_KEY_MAP.usdcPerpPrivate
: WS_KEY_MAP.usdcPerpPublic;
}
default: {
throw neverGuard(market, `getWsKeyForTopic(): Unhandled market`);
}

View File

@@ -32,6 +32,7 @@ import {
neverGuard,
} from './util';
import { USDCOptionClient } from './usdc-option-client';
import { USDCPerpetualClient } from './usdc-perpetual-client';
const loggerCategory = { category: 'bybit-ws' };
@@ -165,6 +166,17 @@ export class WebsocketClient extends EventEmitter {
this.connectPublic();
break;
}
case 'usdcPerp': {
this.restClient = new USDCPerpetualClient(
undefined,
undefined,
!this.isTestnet(),
this.options.restOptions,
this.options.requestOptions
);
this.connectPublic();
break;
}
default: {
throw neverGuard(
this.options.market,
@@ -223,7 +235,8 @@ export class WebsocketClient extends EventEmitter {
case 'linear':
case 'spot':
case 'spotv3':
case 'usdcOption': {
case 'usdcOption':
case 'usdcPerp': {
return [this.connectPublic(), this.connectPrivate()];
}
default: {
@@ -249,6 +262,9 @@ export class WebsocketClient extends EventEmitter {
case 'usdcOption': {
return this.connect(WS_KEY_MAP.usdcOptionPublic);
}
case 'usdcPerp': {
return this.connect(WS_KEY_MAP.usdcPerpPublic);
}
default: {
throw neverGuard(
this.options.market,
@@ -275,6 +291,9 @@ export class WebsocketClient extends EventEmitter {
case 'usdcOption': {
return this.connect(WS_KEY_MAP.usdcOptionPrivate);
}
case 'usdcPerp': {
return this.connect(WS_KEY_MAP.usdcPerpPrivate);
}
default: {
throw neverGuard(
this.options.market,
@@ -719,12 +738,12 @@ export class WebsocketClient extends EventEmitter {
case WS_KEY_MAP.usdcOptionPrivate: {
return WS_BASE_URL_MAP.usdcOption.private[networkKey];
}
// case WS_KEY_MAP.usdcPerpPublic: {
// return WS_BASE_URL_MAP.usdcOption.public[networkKey];
// }
// case WS_KEY_MAP.usdcPerpPrivate: {
// return WS_BASE_URL_MAP.usdcOption.private[networkKey];
// }
case WS_KEY_MAP.usdcPerpPublic: {
return WS_BASE_URL_MAP.usdcPerp.public[networkKey];
}
case WS_KEY_MAP.usdcPerpPrivate: {
return WS_BASE_URL_MAP.usdcPerp.private[networkKey];
}
default: {
this.logger.error('getWsUrl(): Unhandled wsKey: ', {
...loggerCategory,

View File

@@ -22,11 +22,11 @@ describe('Public USDC Option Websocket Client', () => {
wsClientOptions,
getSilentLogger('expectSuccessNoAuth')
);
// logAllEvents(wsClient);
});
beforeEach(() => {
wsClient.removeAllListeners();
// logAllEvents(wsClient);
});
afterAll(() => {

View File

@@ -0,0 +1,82 @@
import {
WebsocketClient,
WSClientConfigurableOptions,
WS_KEY_MAP,
} from '../../../src';
import {
logAllEvents,
getSilentLogger,
waitForSocketEvent,
WS_OPEN_EVENT_PARTIAL,
} from '../../ws.util';
describe('Public USDC Perp Websocket Client', () => {
let wsClient: WebsocketClient;
const wsClientOptions: WSClientConfigurableOptions = {
market: 'usdcPerp',
};
beforeAll(() => {
wsClient = new WebsocketClient(
wsClientOptions,
getSilentLogger('expectSuccessNoAuth')
);
// logAllEvents(wsClient);
});
beforeEach(() => {
wsClient.removeAllListeners();
// logAllEvents(wsClient);
});
afterAll(() => {
wsClient.closeAll();
});
it('should open a public ws connection', async () => {
const wsOpenPromise = waitForSocketEvent(wsClient, 'open');
expect(wsOpenPromise).resolves.toMatchObject({
event: WS_OPEN_EVENT_PARTIAL,
wsKey: WS_KEY_MAP.usdcPerpPublic,
});
await Promise.all([wsOpenPromise]);
});
it('should subscribe to public trade events', async () => {
const wsResponsePromise = waitForSocketEvent(wsClient, 'response');
const wsUpdatePromise = waitForSocketEvent(wsClient, 'update');
const topic = 'orderBook_200.100ms.BTCPERP';
wsClient.subscribe(topic);
try {
expect(await wsResponsePromise).toMatchObject({
success: true,
ret_msg: '',
request: {
op: 'subscribe',
args: [topic],
},
});
} catch (e) {
// sub failed
expect(e).toBeFalsy();
}
try {
expect(await wsUpdatePromise).toMatchSnapshot({
crossSeq: expect.any(String),
data: { orderBook: expect.any(Array) },
timestampE6: expect.any(String),
topic: topic,
type: 'snapshot',
});
} catch (e) {
// no data
expect(e).toBeFalsy();
}
});
});