Merge pull request #250 from tiagosiebler/wsspot
v3.5.6, feat(#249): add 10-per-event limiter to spot v5 subscriptions, chore(): enable trailing comma linting rule
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
||||
|
||||
@@ -17,9 +17,10 @@ const wsClient = new WebsocketClient(
|
||||
// market: 'spot',
|
||||
// market: 'spotv3',
|
||||
// market: 'usdcOption',
|
||||
market: 'usdcPerp',
|
||||
// market: 'usdcPerp',
|
||||
// market: 'unifiedPerp',
|
||||
// market: 'unifiedOption',
|
||||
market: 'contractUSDT',
|
||||
},
|
||||
logger
|
||||
);
|
||||
@@ -139,7 +140,7 @@ wsClient.on('reconnected', (data) => {
|
||||
// usdc perps (note: the syntax is different for the unified perp market)
|
||||
// (market: 'usdcPerp')
|
||||
// wsClient.subscribe('trade.BTCUSDC');
|
||||
wsClient.subscribe('instrument_info.100ms.BTCPERP');
|
||||
// wsClient.subscribe('instrument_info.100ms.BTCPERP');
|
||||
|
||||
// unified perps
|
||||
// wsClient.subscribe('publicTrade.BTCUSDT');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bybit-api",
|
||||
"version": "3.5.5",
|
||||
"version": "3.5.6",
|
||||
"description": "Complete & robust Node.js SDK for Bybit's REST APIs and WebSockets, with TypeScript & strong end to end tests.",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
|
||||
@@ -31,6 +31,7 @@ if (
|
||||
method: response.config.method,
|
||||
data: response.config.data,
|
||||
headers: response.config.headers,
|
||||
params: response.config.params,
|
||||
},
|
||||
response: {
|
||||
status: response.status,
|
||||
@@ -101,7 +102,7 @@ export default abstract class BaseRestClient {
|
||||
*/
|
||||
constructor(
|
||||
restOptions: RestClientOptions = {},
|
||||
networkOptions: AxiosRequestConfig = {}
|
||||
networkOptions: AxiosRequestConfig = {},
|
||||
) {
|
||||
this.clientType = this.getClientType();
|
||||
|
||||
@@ -134,7 +135,7 @@ export default abstract class BaseRestClient {
|
||||
|
||||
if (this.key && !this.secret) {
|
||||
throw new Error(
|
||||
'API Key & Secret are both required for private endpoints'
|
||||
'API Key & Secret are both required for private endpoints',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -172,21 +173,21 @@ export default abstract class BaseRestClient {
|
||||
method: Method,
|
||||
signMethod: SignMethod,
|
||||
params?: TParams,
|
||||
isPublicApi?: true
|
||||
isPublicApi?: true,
|
||||
): Promise<UnsignedRequest<TParams>>;
|
||||
|
||||
private async prepareSignParams<TParams = any>(
|
||||
method: Method,
|
||||
signMethod: SignMethod,
|
||||
params?: TParams,
|
||||
isPublicApi?: false | undefined
|
||||
isPublicApi?: false | undefined,
|
||||
): Promise<SignedRequest<TParams>>;
|
||||
|
||||
private async prepareSignParams<TParams extends SignedRequestContext = any>(
|
||||
method: Method,
|
||||
signMethod: SignMethod,
|
||||
params?: TParams,
|
||||
isPublicApi?: boolean
|
||||
isPublicApi?: boolean,
|
||||
) {
|
||||
if (isPublicApi) {
|
||||
return {
|
||||
@@ -211,7 +212,7 @@ export default abstract class BaseRestClient {
|
||||
method: Method,
|
||||
url: string,
|
||||
params?: any,
|
||||
isPublicApi?: boolean
|
||||
isPublicApi?: boolean,
|
||||
): Promise<AxiosRequestConfig> {
|
||||
const options: AxiosRequestConfig = {
|
||||
...this.globalRequestOptions,
|
||||
@@ -238,7 +239,7 @@ export default abstract class BaseRestClient {
|
||||
method,
|
||||
'v5auth',
|
||||
params,
|
||||
isPublicApi
|
||||
isPublicApi,
|
||||
);
|
||||
|
||||
const headers = {
|
||||
@@ -269,7 +270,7 @@ export default abstract class BaseRestClient {
|
||||
method,
|
||||
'v2auth',
|
||||
params,
|
||||
isPublicApi
|
||||
isPublicApi,
|
||||
);
|
||||
|
||||
if (method === 'GET' || this.isSpotV1Client()) {
|
||||
@@ -292,11 +293,11 @@ export default abstract class BaseRestClient {
|
||||
method: Method,
|
||||
endpoint: string,
|
||||
params?: any,
|
||||
isPublicApi?: boolean
|
||||
isPublicApi?: boolean,
|
||||
): Promise<any> {
|
||||
// Sanity check to make sure it's only ever prefixed by one forward slash
|
||||
const requestUrl = [this.baseUrl, endpoint].join(
|
||||
endpoint.startsWith('/') ? '' : '/'
|
||||
endpoint.startsWith('/') ? '' : '/',
|
||||
);
|
||||
|
||||
// Build a request and handle signature process
|
||||
@@ -304,7 +305,7 @@ export default abstract class BaseRestClient {
|
||||
method,
|
||||
requestUrl,
|
||||
params,
|
||||
isPublicApi
|
||||
isPublicApi,
|
||||
);
|
||||
|
||||
// Dispatch request
|
||||
@@ -355,7 +356,7 @@ export default abstract class BaseRestClient {
|
||||
private async signRequest<T extends SignedRequestContext | {} = {}>(
|
||||
data: T,
|
||||
method: Method,
|
||||
signMethod: SignMethod
|
||||
signMethod: SignMethod,
|
||||
): Promise<SignedRequest<T>> {
|
||||
const timestamp = Date.now() + (this.timeOffset || 0);
|
||||
|
||||
@@ -390,7 +391,7 @@ export default abstract class BaseRestClient {
|
||||
res.originalParams,
|
||||
strictParamValidation,
|
||||
sortProperties,
|
||||
encodeSerialisedValues
|
||||
encodeSerialisedValues,
|
||||
)
|
||||
: JSON.stringify(res.originalParams);
|
||||
|
||||
@@ -426,7 +427,7 @@ export default abstract class BaseRestClient {
|
||||
res.originalParams,
|
||||
strictParamValidation,
|
||||
sortProperties,
|
||||
encodeValues
|
||||
encodeValues,
|
||||
);
|
||||
res.sign = await signMessage(res.serializedParams, this.secret);
|
||||
|
||||
@@ -473,7 +474,7 @@ export default abstract class BaseRestClient {
|
||||
|
||||
if (!serverTime || isNaN(serverTime)) {
|
||||
throw new Error(
|
||||
`fetchServerTime() returned non-number: "${serverTime}" typeof(${typeof serverTime})`
|
||||
`fetchServerTime() returned non-number: "${serverTime}" typeof(${typeof serverTime})`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -292,7 +292,7 @@ export function getWsKeyForTopic(
|
||||
market: APIMarket,
|
||||
topic: string,
|
||||
isPrivate?: boolean,
|
||||
category?: CategoryV5
|
||||
category?: CategoryV5,
|
||||
): WsKey {
|
||||
const isPrivateTopic = isPrivate === true || PRIVATE_TOPICS.includes(topic);
|
||||
switch (market) {
|
||||
@@ -345,7 +345,7 @@ export function getWsKeyForTopic(
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Failed to determine wskey for unified perps topic: "${topic}"`
|
||||
`Failed to determine wskey for unified perps topic: "${topic}"`,
|
||||
);
|
||||
}
|
||||
case 'contractInverse': {
|
||||
@@ -382,7 +382,7 @@ export function getWsKeyForTopic(
|
||||
default: {
|
||||
throw neverGuard(
|
||||
category,
|
||||
'getWsKeyForTopic(v5): Unhandled v5 category'
|
||||
'getWsKeyForTopic(v5): Unhandled v5 category',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -396,7 +396,7 @@ export function getWsKeyForTopic(
|
||||
export function getWsUrl(
|
||||
wsKey: WsKey,
|
||||
wsUrl: string | undefined,
|
||||
isTestnet: boolean
|
||||
isTestnet: boolean,
|
||||
): string {
|
||||
if (wsUrl) {
|
||||
return wsUrl;
|
||||
@@ -489,8 +489,10 @@ export function getWsUrl(
|
||||
}
|
||||
|
||||
export function getMaxTopicsPerSubscribeEvent(
|
||||
market: APIMarket
|
||||
market: APIMarket,
|
||||
wsKey: WsKey,
|
||||
): number | null {
|
||||
const topicsPerEventSpot = 10;
|
||||
switch (market) {
|
||||
case 'inverse':
|
||||
case 'linear':
|
||||
@@ -502,10 +504,13 @@ export function getMaxTopicsPerSubscribeEvent(
|
||||
case 'contractInverse':
|
||||
case 'contractUSDT':
|
||||
case 'v5': {
|
||||
if (wsKey === WS_KEY_MAP.v5SpotPublic) {
|
||||
return topicsPerEventSpot;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case 'spotv3': {
|
||||
return 10;
|
||||
return topicsPerEventSpot;
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(market, 'getWsKeyForTopic(): Unhandled market');
|
||||
@@ -515,7 +520,7 @@ export function getMaxTopicsPerSubscribeEvent(
|
||||
|
||||
export function getUsdcWsKeyForTopic(
|
||||
topic: string,
|
||||
subGroup: 'option' | 'perp'
|
||||
subGroup: 'option' | 'perp',
|
||||
): WsKey {
|
||||
const isPrivateTopic = PRIVATE_TOPICS.includes(topic);
|
||||
if (subGroup === 'option') {
|
||||
|
||||
@@ -74,7 +74,7 @@ interface WebsocketClientEvents {
|
||||
export declare interface WebsocketClient {
|
||||
on<U extends keyof WebsocketClientEvents>(
|
||||
event: U,
|
||||
listener: WebsocketClientEvents[U]
|
||||
listener: WebsocketClientEvents[U],
|
||||
): this;
|
||||
|
||||
emit<U extends keyof WebsocketClientEvents>(
|
||||
@@ -95,7 +95,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
|
||||
constructor(
|
||||
options: WSClientConfigurableOptions,
|
||||
logger?: typeof DefaultLogger
|
||||
logger?: typeof DefaultLogger,
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -140,7 +140,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
public subscribeV5(
|
||||
wsTopics: WsTopic[] | WsTopic,
|
||||
category: CategoryV5,
|
||||
isPrivateTopic?: boolean
|
||||
isPrivateTopic?: boolean,
|
||||
) {
|
||||
const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
|
||||
|
||||
@@ -149,7 +149,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
this.options.market,
|
||||
topic,
|
||||
isPrivateTopic,
|
||||
category
|
||||
category,
|
||||
);
|
||||
|
||||
// Persist topic for reconnects
|
||||
@@ -166,11 +166,11 @@ export class WebsocketClient extends EventEmitter {
|
||||
if (
|
||||
!this.wsStore.isConnectionState(
|
||||
wsKey,
|
||||
WsConnectionStateEnum.CONNECTING
|
||||
WsConnectionStateEnum.CONNECTING,
|
||||
) &&
|
||||
!this.wsStore.isConnectionState(
|
||||
wsKey,
|
||||
WsConnectionStateEnum.RECONNECTING
|
||||
WsConnectionStateEnum.RECONNECTING,
|
||||
)
|
||||
) {
|
||||
return this.connect(wsKey);
|
||||
@@ -193,7 +193,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
topics.forEach((topic) => {
|
||||
if (!isPrivateWsTopic(topic)) {
|
||||
throw new Error(
|
||||
'For public "v5" websocket topics, use the subscribeV5() method & provide the category parameter'
|
||||
'For public "v5" websocket topics, use the subscribeV5() method & provide the category parameter',
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -203,7 +203,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
const wsKey = getWsKeyForTopic(
|
||||
this.options.market,
|
||||
topic,
|
||||
isPrivateTopic
|
||||
isPrivateTopic,
|
||||
);
|
||||
|
||||
// Persist topic for reconnects
|
||||
@@ -220,11 +220,11 @@ export class WebsocketClient extends EventEmitter {
|
||||
if (
|
||||
!this.wsStore.isConnectionState(
|
||||
wsKey,
|
||||
WsConnectionStateEnum.CONNECTING
|
||||
WsConnectionStateEnum.CONNECTING,
|
||||
) &&
|
||||
!this.wsStore.isConnectionState(
|
||||
wsKey,
|
||||
WsConnectionStateEnum.RECONNECTING
|
||||
WsConnectionStateEnum.RECONNECTING,
|
||||
)
|
||||
) {
|
||||
return this.connect(wsKey);
|
||||
@@ -241,7 +241,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
public unsubscribeV5(
|
||||
wsTopics: WsTopic[] | WsTopic,
|
||||
category: CategoryV5,
|
||||
isPrivateTopic?: boolean
|
||||
isPrivateTopic?: boolean,
|
||||
) {
|
||||
const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
|
||||
topics.forEach((topic) => {
|
||||
@@ -249,7 +249,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
this.options.market,
|
||||
topic,
|
||||
isPrivateTopic,
|
||||
category
|
||||
category,
|
||||
);
|
||||
|
||||
// Remove topic from persistence for reconnects
|
||||
@@ -278,7 +278,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
topics.forEach((topic) => {
|
||||
if (!isPrivateWsTopic(topic)) {
|
||||
throw new Error(
|
||||
'For public "v5" websocket topics, use the unsubscribeV5() method & provide the category parameter'
|
||||
'For public "v5" websocket topics, use the unsubscribeV5() method & provide the category parameter',
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -288,7 +288,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
const wsKey = getWsKeyForTopic(
|
||||
this.options.market,
|
||||
topic,
|
||||
isPrivateTopic
|
||||
isPrivateTopic,
|
||||
);
|
||||
|
||||
// Remove topic from persistence for reconnects
|
||||
@@ -312,21 +312,21 @@ export class WebsocketClient extends EventEmitter {
|
||||
case 'inverse': {
|
||||
this.restClient = new InverseClient(
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
this.options.requestOptions,
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'linear': {
|
||||
this.restClient = new LinearClient(
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
this.options.requestOptions,
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'spot': {
|
||||
this.restClient = new SpotClient(
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
this.options.requestOptions,
|
||||
);
|
||||
this.connectPublic();
|
||||
break;
|
||||
@@ -334,21 +334,21 @@ export class WebsocketClient extends EventEmitter {
|
||||
case 'spotv3': {
|
||||
this.restClient = new SpotClientV3(
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
this.options.requestOptions,
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'usdcOption': {
|
||||
this.restClient = new USDCOptionClient(
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
this.options.requestOptions,
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'usdcPerp': {
|
||||
this.restClient = new USDCPerpetualClient(
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
this.options.requestOptions,
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -356,7 +356,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
case 'unifiedPerp': {
|
||||
this.restClient = new UnifiedMarginClient(
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
this.options.requestOptions,
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -364,21 +364,21 @@ export class WebsocketClient extends EventEmitter {
|
||||
case 'contractUSDT': {
|
||||
this.restClient = new ContractClient(
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
this.options.requestOptions,
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'v5': {
|
||||
this.restClient = new RestClientV5(
|
||||
this.options.restOptions,
|
||||
this.options.requestOptions
|
||||
this.options.requestOptions,
|
||||
);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw neverGuard(
|
||||
this.options.market,
|
||||
'prepareRESTClient(): Unhandled market'
|
||||
'prepareRESTClient(): Unhandled market',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -478,7 +478,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
default: {
|
||||
throw neverGuard(
|
||||
this.options.market,
|
||||
'connectPublic(): Unhandled market'
|
||||
'connectPublic(): Unhandled market',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -518,7 +518,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
default: {
|
||||
throw neverGuard(
|
||||
this.options.market,
|
||||
'connectPrivate(): Unhandled market'
|
||||
'connectPrivate(): Unhandled market',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -529,7 +529,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
if (this.wsStore.isWsOpen(wsKey)) {
|
||||
this.logger.error(
|
||||
'Refused to connect to ws with existing active connection',
|
||||
{ ...loggerCategory, wsKey }
|
||||
{ ...loggerCategory, wsKey },
|
||||
);
|
||||
return this.wsStore.getWs(wsKey);
|
||||
}
|
||||
@@ -539,7 +539,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
) {
|
||||
this.logger.error(
|
||||
'Refused to connect to ws, connection attempt already active',
|
||||
{ ...loggerCategory, wsKey }
|
||||
{ ...loggerCategory, wsKey },
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -586,12 +586,12 @@ export class WebsocketClient extends EventEmitter {
|
||||
`${context} due to unexpected response error: "${
|
||||
error?.msg || error?.message || error
|
||||
}"`,
|
||||
{ ...loggerCategory, wsKey, error }
|
||||
{ ...loggerCategory, wsKey, error },
|
||||
);
|
||||
this.executeReconnectableClose(wsKey, 'unhandled onWsError');
|
||||
} else {
|
||||
this.logger.info(
|
||||
`${wsKey} socket forcefully closed. Will not reconnect.`
|
||||
`${wsKey} socket forcefully closed. Will not reconnect.`,
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -644,14 +644,14 @@ export class WebsocketClient extends EventEmitter {
|
||||
}
|
||||
|
||||
private async getWsAuthSignature(
|
||||
wsKey: WsKey
|
||||
wsKey: WsKey,
|
||||
): Promise<{ expiresAt: number; signature: string }> {
|
||||
const { key, secret } = this.options;
|
||||
|
||||
if (!key || !secret) {
|
||||
this.logger.warning(
|
||||
'Cannot authenticate websocket, either api or private keys missing.',
|
||||
{ ...loggerCategory, wsKey }
|
||||
{ ...loggerCategory, wsKey },
|
||||
);
|
||||
throw new Error('Cannot auth - missing api or secret in config');
|
||||
}
|
||||
@@ -669,7 +669,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
|
||||
const signature = await signMessage(
|
||||
'GET/realtime' + signatureExpiresAt,
|
||||
secret
|
||||
secret,
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -714,7 +714,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
|
||||
this.wsStore.get(wsKey, true).activePongTimer = setTimeout(
|
||||
() => this.executeReconnectableClose(wsKey, 'Pong timeout'),
|
||||
this.options.pongTimeout
|
||||
this.options.pongTimeout,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -743,7 +743,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
...loggerCategory,
|
||||
wsKey,
|
||||
reason,
|
||||
}
|
||||
},
|
||||
);
|
||||
this.reconnectWithDelay(wsKey, this.options.reconnectTimeout);
|
||||
}
|
||||
@@ -790,11 +790,12 @@ export class WebsocketClient extends EventEmitter {
|
||||
}
|
||||
|
||||
const maxTopicsPerEvent = getMaxTopicsPerSubscribeEvent(
|
||||
this.options.market
|
||||
this.options.market,
|
||||
wsKey,
|
||||
);
|
||||
if (maxTopicsPerEvent && topics.length > maxTopicsPerEvent) {
|
||||
this.logger.silly(
|
||||
`Subscribing to topics in batches of ${maxTopicsPerEvent}`
|
||||
`Subscribing to topics in batches of ${maxTopicsPerEvent}`,
|
||||
);
|
||||
for (let i = 0; i < topics.length; i += maxTopicsPerEvent) {
|
||||
const batch = topics.slice(i, i + maxTopicsPerEvent);
|
||||
@@ -802,7 +803,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
this.requestSubscribeTopics(wsKey, batch);
|
||||
}
|
||||
this.logger.silly(
|
||||
`Finished batch subscribing to ${topics.length} topics`
|
||||
`Finished batch subscribing to ${topics.length} topics`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -825,11 +826,12 @@ export class WebsocketClient extends EventEmitter {
|
||||
}
|
||||
|
||||
const maxTopicsPerEvent = getMaxTopicsPerSubscribeEvent(
|
||||
this.options.market
|
||||
this.options.market,
|
||||
wsKey,
|
||||
);
|
||||
if (maxTopicsPerEvent && topics.length > maxTopicsPerEvent) {
|
||||
this.logger.silly(
|
||||
`Unsubscribing to topics in batches of ${maxTopicsPerEvent}`
|
||||
`Unsubscribing to topics in batches of ${maxTopicsPerEvent}`,
|
||||
);
|
||||
for (let i = 0; i < topics.length; i += maxTopicsPerEvent) {
|
||||
const batch = topics.slice(i, i + maxTopicsPerEvent);
|
||||
@@ -837,7 +839,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
this.requestUnsubscribeTopics(wsKey, batch);
|
||||
}
|
||||
this.logger.silly(
|
||||
`Finished batch unsubscribing to ${topics.length} topics`
|
||||
`Finished batch unsubscribing to ${topics.length} topics`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -859,13 +861,13 @@ export class WebsocketClient extends EventEmitter {
|
||||
});
|
||||
if (!wsKey) {
|
||||
throw new Error(
|
||||
'Cannot send message due to no known websocket for this wsKey'
|
||||
'Cannot send message due to no known websocket for this wsKey',
|
||||
);
|
||||
}
|
||||
const ws = this.getWs(wsKey);
|
||||
if (!ws) {
|
||||
throw new Error(
|
||||
`${wsKey} socket not connected yet, call "connect(${wsKey}) first then try again when the "open" event arrives`
|
||||
`${wsKey} socket not connected yet, call "connect(${wsKey}) first then try again when the "open" event arrives`,
|
||||
);
|
||||
}
|
||||
ws.send(wsMessage);
|
||||
@@ -935,7 +937,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
|
||||
this.wsStore.get(wsKey, true)!.activePingTimer = setInterval(
|
||||
() => this.ping(wsKey),
|
||||
this.options.pingInterval
|
||||
this.options.pingInterval,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1022,7 +1024,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
|
||||
private wrongMarketError(market: APIMarket) {
|
||||
return new Error(
|
||||
`This WS client was instanced for the ${this.options.market} market. Make another WebsocketClient instance with "market: '${market}'" to listen to ${market} topics`
|
||||
`This WS client was instanced for the ${this.options.market} market. Make another WebsocketClient instance with "market: '${market}'" to listen to ${market} topics`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1041,7 +1043,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
params: {
|
||||
binary: !!binary,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1060,7 +1062,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
params: {
|
||||
binary: !!binary,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1068,7 +1070,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
public subscribePublicSpotV1Kline(
|
||||
symbol: string,
|
||||
candleSize: KlineInterval,
|
||||
binary?: boolean
|
||||
binary?: boolean,
|
||||
) {
|
||||
if (this.options.market !== 'spot') {
|
||||
throw this.wrongMarketError('spot');
|
||||
@@ -1083,7 +1085,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
params: {
|
||||
binary: !!binary,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1096,7 +1098,7 @@ export class WebsocketClient extends EventEmitter {
|
||||
symbol: string,
|
||||
depth: 'full' | 'merge' | 'delta',
|
||||
dumpScale?: number,
|
||||
binary?: boolean
|
||||
binary?: boolean,
|
||||
) {
|
||||
if (this.options.market !== 'spot') {
|
||||
throw this.wrongMarketError('spot');
|
||||
|
||||
@@ -28,7 +28,7 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
describe('Trade APIs', () => {
|
||||
it('getActiveOrders()', async () => {
|
||||
expect(
|
||||
await api.getActiveOrders({ category: 'linear', settleCoin })
|
||||
await api.getActiveOrders({ category: 'linear', settleCoin }),
|
||||
).toMatchObject({
|
||||
...successResponseObjectV3(),
|
||||
});
|
||||
@@ -36,11 +36,12 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
|
||||
it('getHistoricOrders()', async () => {
|
||||
expect(await api.getHistoricOrders({ category: 'linear' })).toMatchObject(
|
||||
{ ...successResponseObjectV3() }
|
||||
{ ...successResponseObjectV3() },
|
||||
);
|
||||
});
|
||||
|
||||
it('getSpotBorrowCheck()', async () => {
|
||||
// 10016 system errors if the account is not UTA upgraded
|
||||
it.skip('getSpotBorrowCheck()', async () => {
|
||||
expect(await api.getSpotBorrowCheck(linearSymbol, 'Buy')).toMatchObject({
|
||||
...successResponseObjectV3(),
|
||||
});
|
||||
@@ -50,7 +51,7 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
describe('Position APIs', () => {
|
||||
it('getPositionInfo()', async () => {
|
||||
expect(
|
||||
await api.getPositionInfo({ category: 'linear', settleCoin })
|
||||
await api.getPositionInfo({ category: 'linear', settleCoin }),
|
||||
).toMatchObject({
|
||||
...successResponseObjectV3(),
|
||||
});
|
||||
@@ -58,7 +59,10 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
|
||||
it('getExecutionList()', async () => {
|
||||
expect(
|
||||
await api.getExecutionList({ category: 'linear', symbol: linearSymbol })
|
||||
await api.getExecutionList({
|
||||
category: 'linear',
|
||||
symbol: linearSymbol,
|
||||
}),
|
||||
).toMatchObject({
|
||||
...successResponseObjectV3(),
|
||||
});
|
||||
@@ -66,7 +70,7 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
|
||||
it('getClosedPnL()', async () => {
|
||||
expect(
|
||||
await api.getClosedPnL({ category: 'linear', symbol: linearSymbol })
|
||||
await api.getClosedPnL({ category: 'linear', symbol: linearSymbol }),
|
||||
).toMatchObject({
|
||||
...successResponseObjectV3(),
|
||||
});
|
||||
@@ -76,7 +80,7 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
describe('Account APIs', () => {
|
||||
it('getWalletBalance()', async () => {
|
||||
expect(
|
||||
await api.getWalletBalance({ accountType: 'CONTRACT' })
|
||||
await api.getWalletBalance({ accountType: 'CONTRACT' }),
|
||||
).toMatchObject({ ...successResponseObjectV3() });
|
||||
});
|
||||
|
||||
@@ -138,13 +142,13 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
|
||||
it('getDeliveryRecord()', async () => {
|
||||
expect(await api.getDeliveryRecord({ category: 'option' })).toMatchObject(
|
||||
{ ...successResponseObjectV3() }
|
||||
{ ...successResponseObjectV3() },
|
||||
);
|
||||
});
|
||||
|
||||
it('getSettlementRecords()', async () => {
|
||||
expect(
|
||||
await api.getSettlementRecords({ category: 'linear' })
|
||||
await api.getSettlementRecords({ category: 'linear' }),
|
||||
).toMatchObject({ ...successResponseObjectV3() });
|
||||
});
|
||||
|
||||
@@ -156,19 +160,19 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
|
||||
it('getAllCoinsBalance()', async () => {
|
||||
expect(
|
||||
await api.getAllCoinsBalance({ accountType: 'SPOT' })
|
||||
await api.getAllCoinsBalance({ accountType: 'SPOT' }),
|
||||
).toMatchObject({ ...successResponseObjectV3() });
|
||||
});
|
||||
|
||||
it('getCoinBalance()', async () => {
|
||||
expect(
|
||||
await api.getCoinBalance({ accountType: 'SPOT', coin: settleCoin })
|
||||
await api.getCoinBalance({ accountType: 'SPOT', coin: settleCoin }),
|
||||
).toMatchObject({ ...successResponseObjectV3() });
|
||||
});
|
||||
|
||||
it('getTransferableCoinList()', async () => {
|
||||
expect(
|
||||
await api.getTransferableCoinList('SPOT', 'CONTRACT')
|
||||
await api.getTransferableCoinList('SPOT', 'CONTRACT'),
|
||||
).toMatchObject({ ...successResponseObjectV3() });
|
||||
});
|
||||
|
||||
@@ -204,7 +208,7 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
|
||||
it('getSubAccountDepositRecords()', async () => {
|
||||
expect(
|
||||
await api.getSubAccountDepositRecords({ subMemberId: 'fakeid' })
|
||||
await api.getSubAccountDepositRecords({ subMemberId: 'fakeid' }),
|
||||
).toMatchObject({
|
||||
// ...successResponseObjectV3(),
|
||||
// Expected, since sub account ID is fake
|
||||
@@ -220,7 +224,7 @@ describe('Private READ V5 REST API Endpoints', () => {
|
||||
|
||||
it('querySubMemberAddress()', async () => {
|
||||
expect(
|
||||
await api.querySubMemberAddress(settleCoin, 'TRC20', 'fakeid')
|
||||
await api.querySubMemberAddress(settleCoin, 'TRC20', 'fakeid'),
|
||||
).toMatchObject({
|
||||
// ...successResponseObjectV3(),
|
||||
// Expected, since sub account ID is fake
|
||||
|
||||
Reference in New Issue
Block a user