unified margin support for ws
This commit is contained in:
@@ -2,6 +2,7 @@ import { InverseClient } from '../inverse-client';
|
||||
import { LinearClient } from '../linear-client';
|
||||
import { SpotClient } from '../spot-client';
|
||||
import { SpotClientV3 } from '../spot-client-v3';
|
||||
import { UnifiedMarginClient } from '../unified-margin-client';
|
||||
import { USDCOptionClient } from '../usdc-option-client';
|
||||
import { USDCPerpetualClient } from '../usdc-perpetual-client';
|
||||
|
||||
@@ -11,7 +12,8 @@ export type RESTClient =
|
||||
| SpotClient
|
||||
| SpotClientV3
|
||||
| USDCOptionClient
|
||||
| USDCPerpetualClient;
|
||||
| USDCPerpetualClient
|
||||
| UnifiedMarginClient;
|
||||
|
||||
export type numberInString = string;
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ export type APIMarket =
|
||||
| 'spot'
|
||||
| 'spotv3'
|
||||
| 'usdcOption'
|
||||
| 'usdcPerp';
|
||||
| 'usdcPerp'
|
||||
| 'unifiedPerp'
|
||||
| 'unifiedOption';
|
||||
|
||||
// Same as inverse futures
|
||||
export type WsPublicInverseTopic =
|
||||
|
||||
@@ -10,7 +10,7 @@ interface NetworkMapV3 {
|
||||
type PublicPrivateNetwork = 'public' | 'private';
|
||||
|
||||
export const WS_BASE_URL_MAP: Record<
|
||||
APIMarket,
|
||||
APIMarket | 'unifiedPerpUSDT' | 'unifiedPerpUSDC',
|
||||
Record<PublicPrivateNetwork, NetworkMapV3>
|
||||
> = {
|
||||
inverse: {
|
||||
@@ -81,6 +81,46 @@ export const WS_BASE_URL_MAP: Record<
|
||||
testnet: 'wss://stream-testnet.bybit.com/trade/option/usdc/private/v1',
|
||||
},
|
||||
},
|
||||
unifiedOption: {
|
||||
public: {
|
||||
livenet: 'wss://stream.bybit.com/option/usdc/public/v3',
|
||||
testnet: 'wss://stream-testnet.bybit.com/option/usdc/public/v3',
|
||||
},
|
||||
private: {
|
||||
livenet: 'wss://stream.bybit.com/unified/private/v3',
|
||||
testnet: 'wss://stream-testnet.bybit.com/unified/private/v3',
|
||||
},
|
||||
},
|
||||
unifiedPerp: {
|
||||
public: {
|
||||
livenet: 'useBaseSpecificEndpoint',
|
||||
testnet: 'useBaseSpecificEndpoint',
|
||||
},
|
||||
private: {
|
||||
livenet: 'wss://stream.bybit.com/unified/private/v3',
|
||||
testnet: 'wss://stream-testnet.bybit.com/unified/private/v3',
|
||||
},
|
||||
},
|
||||
unifiedPerpUSDT: {
|
||||
public: {
|
||||
livenet: 'wss://stream.bybit.com/contract/usdt/public/v3',
|
||||
testnet: 'wss://stream-testnet.bybit.com/contract/usdt/public/v3',
|
||||
},
|
||||
private: {
|
||||
livenet: 'useUnifiedEndpoint',
|
||||
testnet: 'useUnifiedEndpoint',
|
||||
},
|
||||
},
|
||||
unifiedPerpUSDC: {
|
||||
public: {
|
||||
livenet: 'wss://stream.bybit.com/contract/usdc/public/v3',
|
||||
testnet: 'wss://stream-testnet.bybit.com/contract/usdc/public/v3',
|
||||
},
|
||||
private: {
|
||||
livenet: 'useUnifiedEndpoint',
|
||||
testnet: 'useUnifiedEndpoint',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const WS_KEY_MAP = {
|
||||
@@ -95,6 +135,10 @@ export const WS_KEY_MAP = {
|
||||
usdcOptionPublic: 'usdcOptionPublic',
|
||||
usdcPerpPrivate: 'usdcPerpPrivate',
|
||||
usdcPerpPublic: 'usdcPerpPublic',
|
||||
unifiedPrivate: 'unifiedPrivate',
|
||||
unifiedOptionPublic: 'unifiedOptionPublic',
|
||||
unifiedPerpUSDTPublic: 'unifiedPerpUSDTPublic',
|
||||
unifiedPerpUSDCPublic: 'unifiedPerpUSDCPublic',
|
||||
} as const;
|
||||
|
||||
export const WS_AUTH_ON_CONNECT_KEYS: WsKey[] = [
|
||||
@@ -180,6 +224,29 @@ export function getWsKeyForTopic(
|
||||
? WS_KEY_MAP.usdcPerpPrivate
|
||||
: WS_KEY_MAP.usdcPerpPublic;
|
||||
}
|
||||
case 'unifiedOption': {
|
||||
return isPrivateTopic
|
||||
? WS_KEY_MAP.unifiedPrivate
|
||||
: WS_KEY_MAP.unifiedOptionPublic;
|
||||
}
|
||||
case 'unifiedPerp': {
|
||||
if (isPrivateTopic) {
|
||||
return WS_KEY_MAP.unifiedPrivate;
|
||||
}
|
||||
|
||||
const upperTopic = topic.toUpperCase();
|
||||
if (upperTopic.indexOf('USDT') !== -1) {
|
||||
return WS_KEY_MAP.unifiedPerpUSDTPublic;
|
||||
}
|
||||
|
||||
if (upperTopic.indexOf('USDC') !== -1) {
|
||||
return WS_KEY_MAP.unifiedPerpUSDCPublic;
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Failed to determine wskey for unified perps topic: "${topic}`
|
||||
);
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(market, `getWsKeyForTopic(): Unhandled market`);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
} from './util';
|
||||
import { USDCOptionClient } from './usdc-option-client';
|
||||
import { USDCPerpetualClient } from './usdc-perpetual-client';
|
||||
import { UnifiedMarginClient } from './unified-margin-client';
|
||||
|
||||
const loggerCategory = { category: 'bybit-ws' };
|
||||
|
||||
@@ -163,6 +164,17 @@ export class WebsocketClient extends EventEmitter {
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'unifiedOption':
|
||||
case 'unifiedPerp': {
|
||||
this.restClient = new UnifiedMarginClient(
|
||||
undefined,
|
||||
undefined,
|
||||
!this.isTestnet(),
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(
|
||||
this.options.market,
|
||||
@@ -198,15 +210,17 @@ export class WebsocketClient extends EventEmitter {
|
||||
switch (this.options.market) {
|
||||
case 'inverse': {
|
||||
// only one for inverse
|
||||
return [this.connectPublic()];
|
||||
return [...this.connectPublic()];
|
||||
}
|
||||
// these all have separate public & private ws endpoints
|
||||
case 'linear':
|
||||
case 'spot':
|
||||
case 'spotv3':
|
||||
case 'usdcOption':
|
||||
case 'usdcPerp': {
|
||||
return [this.connectPublic(), this.connectPrivate()];
|
||||
case 'usdcPerp':
|
||||
case 'unifiedPerp':
|
||||
case 'unifiedOption': {
|
||||
return [...this.connectPublic(), this.connectPrivate()];
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(this.options.market, `connectAll(): Unhandled market`);
|
||||
@@ -214,25 +228,34 @@ export class WebsocketClient extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
public connectPublic(): Promise<WebSocket | undefined> {
|
||||
public connectPublic(): Promise<WebSocket | undefined>[] {
|
||||
switch (this.options.market) {
|
||||
case 'inverse': {
|
||||
return this.connect(WS_KEY_MAP.inverse);
|
||||
return [this.connect(WS_KEY_MAP.inverse)];
|
||||
}
|
||||
case 'linear': {
|
||||
return this.connect(WS_KEY_MAP.linearPublic);
|
||||
return [this.connect(WS_KEY_MAP.linearPublic)];
|
||||
}
|
||||
case 'spot': {
|
||||
return this.connect(WS_KEY_MAP.spotPublic);
|
||||
return [this.connect(WS_KEY_MAP.spotPublic)];
|
||||
}
|
||||
case 'spotv3': {
|
||||
return this.connect(WS_KEY_MAP.spotV3Public);
|
||||
return [this.connect(WS_KEY_MAP.spotV3Public)];
|
||||
}
|
||||
case 'usdcOption': {
|
||||
return this.connect(WS_KEY_MAP.usdcOptionPublic);
|
||||
return [this.connect(WS_KEY_MAP.usdcOptionPublic)];
|
||||
}
|
||||
case 'usdcPerp': {
|
||||
return this.connect(WS_KEY_MAP.usdcPerpPublic);
|
||||
return [this.connect(WS_KEY_MAP.usdcPerpPublic)];
|
||||
}
|
||||
case 'unifiedOption': {
|
||||
return [this.connect(WS_KEY_MAP.unifiedOptionPublic)];
|
||||
}
|
||||
case 'unifiedPerp': {
|
||||
return [
|
||||
this.connect(WS_KEY_MAP.unifiedPerpUSDTPublic),
|
||||
this.connect(WS_KEY_MAP.unifiedPerpUSDCPublic),
|
||||
];
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(
|
||||
@@ -263,6 +286,10 @@ export class WebsocketClient extends EventEmitter {
|
||||
case 'usdcPerp': {
|
||||
return this.connect(WS_KEY_MAP.usdcPerpPrivate);
|
||||
}
|
||||
case 'unifiedPerp':
|
||||
case 'unifiedOption': {
|
||||
return this.connect(WS_KEY_MAP.unifiedPrivate);
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(
|
||||
this.options.market,
|
||||
@@ -719,6 +746,18 @@ export class WebsocketClient extends EventEmitter {
|
||||
case WS_KEY_MAP.usdcPerpPrivate: {
|
||||
return WS_BASE_URL_MAP.usdcPerp.private[networkKey];
|
||||
}
|
||||
case WS_KEY_MAP.unifiedOptionPublic: {
|
||||
return WS_BASE_URL_MAP.unifiedOption.public[networkKey];
|
||||
}
|
||||
case WS_KEY_MAP.unifiedPerpUSDTPublic: {
|
||||
return WS_BASE_URL_MAP.unifiedPerpUSDT.public[networkKey];
|
||||
}
|
||||
case WS_KEY_MAP.unifiedPerpUSDCPublic: {
|
||||
return WS_BASE_URL_MAP.unifiedPerpUSDC.public[networkKey];
|
||||
}
|
||||
case WS_KEY_MAP.unifiedPrivate: {
|
||||
return WS_BASE_URL_MAP.unifiedPerp.private[networkKey];
|
||||
}
|
||||
default: {
|
||||
this.logger.error('getWsUrl(): Unhandled wsKey: ', {
|
||||
...loggerCategory,
|
||||
|
||||
Reference in New Issue
Block a user