feat(): start websocket API client wrapper, chore(): misc typo fixes & cleaning
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
export * from './rest-client-v5';
|
export * from './rest-client-v5';
|
||||||
export * from './spot-client-v3';
|
export * from './spot-client-v3';
|
||||||
export * from './websocket-client';
|
export * from './websocket-client';
|
||||||
|
export * from './websocket-api-client';
|
||||||
export * from './util/logger';
|
export * from './util/logger';
|
||||||
export * from './util';
|
export * from './util';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export abstract class BaseWebsocketClient<
|
|||||||
*/
|
*/
|
||||||
private wsStore: WsStore<TWSKey, WsTopicRequest<string>>;
|
private wsStore: WsStore<TWSKey, WsTopicRequest<string>>;
|
||||||
|
|
||||||
protected logger: typeof DefaultLogger;
|
public logger: typeof DefaultLogger;
|
||||||
|
|
||||||
protected options: WebsocketClientOptions;
|
protected options: WebsocketClientOptions;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export type LogParams = null | any;
|
export type LogParams = null | any;
|
||||||
|
|
||||||
|
export type DefaultLogger = typeof DefaultLogger;
|
||||||
|
|
||||||
export const DefaultLogger = {
|
export const DefaultLogger = {
|
||||||
/** Ping/pong events and other raw messages that might be noisy. Enable this while troubleshooting. */
|
/** Ping/pong events and other raw messages that might be noisy. Enable this while troubleshooting. */
|
||||||
trace: (..._params: LogParams): void => {
|
trace: (..._params: LogParams): void => {
|
||||||
|
|||||||
134
src/websocket-api-client.ts
Normal file
134
src/websocket-api-client.ts
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import { OrderParamsV5, OrderResultV5 } from './types';
|
||||||
|
import { WSAPIResponse } from './types/websockets/ws-api';
|
||||||
|
import { WSClientConfigurableOptions } from './types/websockets/ws-general';
|
||||||
|
import { DefaultLogger } from './util';
|
||||||
|
import { WS_KEY_MAP } from './util/websockets/websocket-util';
|
||||||
|
import { WebsocketClient } from './websocket-client';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configurable options specific to only the REST-like WebsocketAPIClient
|
||||||
|
*/
|
||||||
|
export interface WSAPIClientConfigurableOptions {
|
||||||
|
/**
|
||||||
|
* Default: true
|
||||||
|
*
|
||||||
|
* Attach default event listeners, which will console log any high level
|
||||||
|
* events (opened/reconnecting/reconnected/etc).
|
||||||
|
*
|
||||||
|
* If you disable this, you should set your own event listeners
|
||||||
|
* on the embedded WS Client `wsApiClient.getWSClient().on(....)`.
|
||||||
|
*/
|
||||||
|
attachEventListeners: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a minimal Websocket API wrapper around the WebsocketClient.
|
||||||
|
*
|
||||||
|
* Some methods support passing in a custom "wsKey". This is a reference to which WS connection should
|
||||||
|
* be used to transmit that message. This is only useful if you wish to use an alternative wss
|
||||||
|
* domain that is supported by the SDK.
|
||||||
|
*
|
||||||
|
* Note: To use testnet, don't set the wsKey - use `testnet: true` in
|
||||||
|
* the constructor instead.
|
||||||
|
*
|
||||||
|
* Note: You can also directly use the sendWSAPIRequest() method to make WS API calls, but some
|
||||||
|
* may find the below methods slightly more intuitive.
|
||||||
|
*
|
||||||
|
* Refer to the WS API promises example for a more detailed example on using sendWSAPIRequest() directly:
|
||||||
|
* https://github.com/tiagosiebler/binance/blob/master/examples/WebSockets/ws-api-raw-promises.ts#L108
|
||||||
|
*/
|
||||||
|
export class WebsocketAPIClient {
|
||||||
|
private wsClient: WebsocketClient;
|
||||||
|
|
||||||
|
private logger: DefaultLogger;
|
||||||
|
|
||||||
|
private options: WSClientConfigurableOptions & WSAPIClientConfigurableOptions;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
options?: WSClientConfigurableOptions &
|
||||||
|
Partial<WSAPIClientConfigurableOptions>,
|
||||||
|
logger?: DefaultLogger,
|
||||||
|
) {
|
||||||
|
this.wsClient = new WebsocketClient(options, logger);
|
||||||
|
|
||||||
|
this.options = {
|
||||||
|
attachEventListeners: true,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.logger = this.wsClient.logger;
|
||||||
|
|
||||||
|
this.setupDefaultEventListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getWSClient(): WebsocketClient {
|
||||||
|
return this.wsClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setTimeOffsetMs(newOffset: number): void {
|
||||||
|
return this.getWSClient().setTimeOffsetMs(newOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bybit WebSocket API Methods
|
||||||
|
* https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit a new order
|
||||||
|
*
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
submitNewOrder(
|
||||||
|
params: OrderParamsV5,
|
||||||
|
): Promise<WSAPIResponse<OrderResultV5, 'order.create'>> {
|
||||||
|
return this.wsClient.sendWSAPIRequest(
|
||||||
|
WS_KEY_MAP.v5PrivateTrade,
|
||||||
|
'order.create',
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Private methods for handling some of the convenience/automation provided by the WS API Client
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
private setupDefaultEventListeners() {
|
||||||
|
if (this.options.attachEventListeners) {
|
||||||
|
/**
|
||||||
|
* General event handlers for monitoring the WebsocketClient
|
||||||
|
*/
|
||||||
|
this.wsClient
|
||||||
|
.on('open', (data) => {
|
||||||
|
console.log(new Date(), 'ws connected', data.wsKey);
|
||||||
|
})
|
||||||
|
.on('reconnect', ({ wsKey }) => {
|
||||||
|
console.log(new Date(), 'ws automatically reconnecting.... ', wsKey);
|
||||||
|
})
|
||||||
|
.on('reconnected', (data) => {
|
||||||
|
console.log(new Date(), 'ws has reconnected ', data?.wsKey);
|
||||||
|
})
|
||||||
|
.on('authenticated', (data) => {
|
||||||
|
console.info(new Date(), 'ws has authenticated ', data?.wsKey);
|
||||||
|
})
|
||||||
|
.on('exception', (data) => {
|
||||||
|
console.error(new Date(), 'ws exception: ', JSON.stringify(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -343,23 +343,23 @@ export class WebsocketClient extends BaseWebsocketClient<
|
|||||||
// do not trigger excess property checks
|
// do not trigger excess property checks
|
||||||
// Without these overloads, TypeScript won't complain if you include an
|
// Without these overloads, TypeScript won't complain if you include an
|
||||||
// unexpected property with your request (if it doesn't clash with an existing property)
|
// unexpected property with your request (if it doesn't clash with an existing property)
|
||||||
sendWSAPIRequest<TWSOpreation extends WSAPIOperation = 'order.create'>(
|
sendWSAPIRequest<TWSOperation extends WSAPIOperation = 'order.create'>(
|
||||||
wsKey: typeof WS_KEY_MAP.v5PrivateTrade,
|
wsKey: typeof WS_KEY_MAP.v5PrivateTrade,
|
||||||
operation: TWSOpreation,
|
operation: TWSOperation,
|
||||||
params: WsAPITopicRequestParamMap[TWSOpreation],
|
params: WsAPITopicRequestParamMap[TWSOperation],
|
||||||
): Promise<WsAPIOperationResponseMap[TWSOpreation]>;
|
): Promise<WsAPIOperationResponseMap[TWSOperation]>;
|
||||||
|
|
||||||
sendWSAPIRequest<TWSOpreation extends WSAPIOperation = 'order.amend'>(
|
sendWSAPIRequest<TWSOperation extends WSAPIOperation = 'order.amend'>(
|
||||||
wsKey: typeof WS_KEY_MAP.v5PrivateTrade,
|
wsKey: typeof WS_KEY_MAP.v5PrivateTrade,
|
||||||
operation: TWSOpreation,
|
operation: TWSOperation,
|
||||||
params: WsAPITopicRequestParamMap[TWSOpreation],
|
params: WsAPITopicRequestParamMap[TWSOperation],
|
||||||
): Promise<WsAPIOperationResponseMap[TWSOpreation]>;
|
): Promise<WsAPIOperationResponseMap[TWSOperation]>;
|
||||||
|
|
||||||
sendWSAPIRequest<TWSOpreation extends WSAPIOperation = 'order.cancel'>(
|
sendWSAPIRequest<TWSOperation extends WSAPIOperation = 'order.cancel'>(
|
||||||
wsKey: typeof WS_KEY_MAP.v5PrivateTrade,
|
wsKey: typeof WS_KEY_MAP.v5PrivateTrade,
|
||||||
operation: TWSOpreation,
|
operation: TWSOperation,
|
||||||
params: WsAPITopicRequestParamMap[TWSOpreation],
|
params: WsAPITopicRequestParamMap[TWSOperation],
|
||||||
): Promise<WsAPIOperationResponseMap[TWSOpreation]>;
|
): Promise<WsAPIOperationResponseMap[TWSOperation]>;
|
||||||
|
|
||||||
async sendWSAPIRequest<
|
async sendWSAPIRequest<
|
||||||
TWSKey extends keyof WsAPIWsKeyTopicMap,
|
TWSKey extends keyof WsAPIWsKeyTopicMap,
|
||||||
|
|||||||
Reference in New Issue
Block a user