add support for contract v3 websockets

This commit is contained in:
tiagosiebler
2022-11-12 12:40:43 +00:00
parent 7c6d02ea8b
commit 5df19e83bc
4 changed files with 79 additions and 4 deletions

View File

@@ -1,3 +1,4 @@
import { ContractClient } from '../contract-client';
import { InverseClient } from '../inverse-client'; import { InverseClient } from '../inverse-client';
import { LinearClient } from '../linear-client'; import { LinearClient } from '../linear-client';
import { SpotClient } from '../spot-client'; import { SpotClient } from '../spot-client';
@@ -13,7 +14,8 @@ export type RESTClient =
| SpotClientV3 | SpotClientV3
| USDCOptionClient | USDCOptionClient
| USDCPerpetualClient | USDCPerpetualClient
| UnifiedMarginClient; | UnifiedMarginClient
| ContractClient;
export type numberInString = string; export type numberInString = string;

View File

@@ -9,7 +9,9 @@ export type APIMarket =
| 'usdcOption' | 'usdcOption'
| 'usdcPerp' | 'usdcPerp'
| 'unifiedPerp' | 'unifiedPerp'
| 'unifiedOption'; | 'unifiedOption'
| 'contractUSDT'
| 'contractInverse';
// Same as inverse futures // Same as inverse futures
export type WsPublicInverseTopic = export type WsPublicInverseTopic =

View File

@@ -121,6 +121,26 @@ export const WS_BASE_URL_MAP: Record<
testnet: 'useUnifiedEndpoint', testnet: 'useUnifiedEndpoint',
}, },
}, },
contractUSDT: {
public: {
livenet: 'wss://stream.bybit.com/contract/usdt/public/v3',
testnet: 'wss://stream-testnet.bybit.com/contract/usdt/public/v3',
},
private: {
livenet: 'wss://stream.bybit.com/contract/private/v3',
testnet: 'wss://stream-testnet.bybit.com/contract/private/v3',
},
},
contractInverse: {
public: {
livenet: 'wss://stream.bybit.com/contract/inverse/public/v3',
testnet: 'wss://stream-testnet.bybit.com/contract/inverse/public/v3',
},
private: {
livenet: 'wss://stream.bybit.com/contract/private/v3',
testnet: 'wss://stream-testnet.bybit.com/contract/private/v3',
},
},
}; };
export const WS_KEY_MAP = { export const WS_KEY_MAP = {
@@ -139,6 +159,10 @@ export const WS_KEY_MAP = {
unifiedOptionPublic: 'unifiedOptionPublic', unifiedOptionPublic: 'unifiedOptionPublic',
unifiedPerpUSDTPublic: 'unifiedPerpUSDTPublic', unifiedPerpUSDTPublic: 'unifiedPerpUSDTPublic',
unifiedPerpUSDCPublic: 'unifiedPerpUSDCPublic', unifiedPerpUSDCPublic: 'unifiedPerpUSDCPublic',
contractUSDTPublic: 'contractUSDTPublic',
contractUSDTPrivate: 'contractUSDTPrivate',
contractInversePublic: 'contractInversePublic',
contractInversePrivate: 'contractInversePrivate',
} as const; } as const;
export const WS_AUTH_ON_CONNECT_KEYS: WsKey[] = [ export const WS_AUTH_ON_CONNECT_KEYS: WsKey[] = [
@@ -146,6 +170,8 @@ export const WS_AUTH_ON_CONNECT_KEYS: WsKey[] = [
WS_KEY_MAP.usdcOptionPrivate, WS_KEY_MAP.usdcOptionPrivate,
WS_KEY_MAP.usdcPerpPrivate, WS_KEY_MAP.usdcPerpPrivate,
WS_KEY_MAP.unifiedPrivate, WS_KEY_MAP.unifiedPrivate,
WS_KEY_MAP.contractUSDTPrivate,
WS_KEY_MAP.contractInversePrivate,
]; ];
export const PUBLIC_WS_KEYS = [ export const PUBLIC_WS_KEYS = [
@@ -157,6 +183,8 @@ export const PUBLIC_WS_KEYS = [
WS_KEY_MAP.unifiedOptionPublic, WS_KEY_MAP.unifiedOptionPublic,
WS_KEY_MAP.unifiedPerpUSDTPublic, WS_KEY_MAP.unifiedPerpUSDTPublic,
WS_KEY_MAP.unifiedPerpUSDCPublic, WS_KEY_MAP.unifiedPerpUSDCPublic,
WS_KEY_MAP.contractUSDTPublic,
WS_KEY_MAP.contractInversePublic,
] as string[]; ] as string[];
/** Used to automatically determine if a sub request should be to the public or private ws (when there's two) */ /** Used to automatically determine if a sub request should be to the public or private ws (when there's two) */
@@ -251,6 +279,16 @@ export function getWsKeyForTopic(
`Failed to determine wskey for unified perps topic: "${topic}` `Failed to determine wskey for unified perps topic: "${topic}`
); );
} }
case 'contractInverse': {
return isPrivateTopic
? WS_KEY_MAP.contractInversePrivate
: WS_KEY_MAP.contractInversePublic;
}
case 'contractUSDT': {
return isPrivateTopic
? WS_KEY_MAP.contractUSDTPrivate
: WS_KEY_MAP.contractUSDTPublic;
}
default: { default: {
throw neverGuard(market, `getWsKeyForTopic(): Unhandled market`); throw neverGuard(market, `getWsKeyForTopic(): Unhandled market`);
} }
@@ -267,7 +305,9 @@ export function getMaxTopicsPerSubscribeEvent(
case 'usdcPerp': case 'usdcPerp':
case 'unifiedOption': case 'unifiedOption':
case 'unifiedPerp': case 'unifiedPerp':
case 'spot': { case 'spot':
case 'contractInverse':
case 'contractUSDT': {
return null; return null;
} }
case 'spotv3': { case 'spotv3': {

View File

@@ -35,6 +35,7 @@ import {
import { USDCOptionClient } from './usdc-option-client'; import { USDCOptionClient } from './usdc-option-client';
import { USDCPerpetualClient } from './usdc-perpetual-client'; import { USDCPerpetualClient } from './usdc-perpetual-client';
import { UnifiedMarginClient } from './unified-margin-client'; import { UnifiedMarginClient } from './unified-margin-client';
import { ContractClient } from './contract-client';
const loggerCategory = { category: 'bybit-ws' }; const loggerCategory = { category: 'bybit-ws' };
@@ -232,6 +233,14 @@ export class WebsocketClient extends EventEmitter {
); );
break; break;
} }
case 'contractInverse':
case 'contractUSDT': {
this.restClient = new ContractClient(
this.options.restOptions,
this.options.requestOptions
);
break;
}
default: { default: {
throw neverGuard( throw neverGuard(
this.options.market, this.options.market,
@@ -285,7 +294,9 @@ export class WebsocketClient extends EventEmitter {
case 'usdcOption': case 'usdcOption':
case 'usdcPerp': case 'usdcPerp':
case 'unifiedPerp': case 'unifiedPerp':
case 'unifiedOption': { case 'unifiedOption':
case 'contractUSDT':
case 'contractInverse': {
return [...this.connectPublic(), this.connectPrivate()]; return [...this.connectPublic(), this.connectPrivate()];
} }
default: { default: {
@@ -323,6 +334,10 @@ export class WebsocketClient extends EventEmitter {
this.connect(WS_KEY_MAP.unifiedPerpUSDCPublic), this.connect(WS_KEY_MAP.unifiedPerpUSDCPublic),
]; ];
} }
case 'contractUSDT':
return [this.connect(WS_KEY_MAP.contractUSDTPublic)];
case 'contractInverse':
return [this.connect(WS_KEY_MAP.contractInversePublic)];
default: { default: {
throw neverGuard( throw neverGuard(
this.options.market, this.options.market,
@@ -356,6 +371,10 @@ export class WebsocketClient extends EventEmitter {
case 'unifiedOption': { case 'unifiedOption': {
return this.connect(WS_KEY_MAP.unifiedPrivate); return this.connect(WS_KEY_MAP.unifiedPrivate);
} }
case 'contractUSDT':
return this.connect(WS_KEY_MAP.contractUSDTPrivate);
case 'contractInverse':
return this.connect(WS_KEY_MAP.contractInversePrivate);
default: { default: {
throw neverGuard( throw neverGuard(
this.options.market, this.options.market,
@@ -899,6 +918,18 @@ export class WebsocketClient extends EventEmitter {
case WS_KEY_MAP.unifiedPrivate: { case WS_KEY_MAP.unifiedPrivate: {
return WS_BASE_URL_MAP.unifiedPerp.private[networkKey]; return WS_BASE_URL_MAP.unifiedPerp.private[networkKey];
} }
case WS_KEY_MAP.contractInversePrivate: {
return WS_BASE_URL_MAP.contractInverse.private[networkKey];
}
case WS_KEY_MAP.contractInversePublic: {
return WS_BASE_URL_MAP.contractInverse.public[networkKey];
}
case WS_KEY_MAP.contractUSDTPrivate: {
return WS_BASE_URL_MAP.contractUSDT.private[networkKey];
}
case WS_KEY_MAP.contractUSDTPublic: {
return WS_BASE_URL_MAP.contractUSDT.public[networkKey];
}
default: { default: {
this.logger.error('getWsUrl(): Unhandled wsKey: ', { this.logger.error('getWsUrl(): Unhandled wsKey: ', {
...loggerCategory, ...loggerCategory,