diff --git a/package.json b/package.json index e8e4092..f3c1f23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bybit-api", - "version": "2.3.0", + "version": "2.3.1", "description": "Node.js connector for Bybit's REST APIs and WebSockets, with TypeScript & integration tests.", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/constants/enum.ts b/src/constants/enum.ts index eca2751..efa97af 100644 --- a/src/constants/enum.ts +++ b/src/constants/enum.ts @@ -40,3 +40,13 @@ export const API_ERROR_CODE = { SAME_SLTP_MODE_LINEAR: 130150, RISK_ID_NOT_MODIFIED: 134026, } as const; + +/** + * Position idx, used to identify positions in different position modes. + * Required if you are under One-Way Mode: + */ +export enum LinearPositionIdx { + OneWayMode = 0, + BuySide = 1, + SellSide = 2, +} diff --git a/src/index.ts b/src/index.ts index 75c64d5..97c7ede 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,6 @@ export * from './linear-client'; export * from './spot-client'; export * from './websocket-client'; export * from './logger'; -export * from './types/shared'; -export * from './types/spot'; +export * from './types'; export * from './util/WsStore'; export * from './constants/enum'; diff --git a/src/linear-client.ts b/src/linear-client.ts index dd34456..4a64ab3 100644 --- a/src/linear-client.ts +++ b/src/linear-client.ts @@ -9,14 +9,19 @@ import { APIResponseWithTime, AssetExchangeRecordsReq, CoinParam, + LinearOrder, + NewLinearOrder, + PerpPosition, + PerpPositionRoot, SymbolInfo, SymbolIntervalFromLimitParam, SymbolLimitParam, SymbolParam, SymbolPeriodLimitParam, + WalletBalances, WalletFundRecordsReq, WithdrawRecordsReq, -} from './types/shared'; +} from './types'; import { linearPositionModeEnum, positionTpSlModeEnum } from './constants/enum'; import BaseRestClient from './util/BaseRestClient'; @@ -150,7 +155,7 @@ export class LinearClient extends BaseRestClient { getWalletBalance( params?: Partial - ): Promise> { + ): Promise> { return this.getPrivate('v2/private/wallet/balance', params); } @@ -192,22 +197,9 @@ export class LinearClient extends BaseRestClient { * */ - placeActiveOrder(params: { - side: string; - symbol: string; - order_type: string; - qty: number; - price?: number; - time_in_force: string; - take_profit?: number; - stop_loss?: number; - tp_trigger_by?: string; - sl_trigger_by?: string; - reduce_only: boolean; - close_on_trigger: boolean; - order_link_id?: string; - position_idx?: number; - }): Promise> { + placeActiveOrder( + params: NewLinearOrder + ): Promise> { return this.postPrivate('private/linear/order/create', params); } @@ -337,9 +329,14 @@ export class LinearClient extends BaseRestClient { * Position */ + getPosition(): Promise>; + getPosition( + params: Partial + ): Promise>; + getPosition( params?: Partial - ): Promise> { + ): Promise> { return this.getPrivate('private/linear/position/list', params); } diff --git a/src/logger.ts b/src/logger.ts index e74187c..a0b2379 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -2,7 +2,7 @@ export type LogParams = null | any; export const DefaultLogger = { silly: (...params: LogParams): void => { - console.log(params); + // console.log(params); }, debug: (...params: LogParams): void => { console.log(params); diff --git a/src/spot-client.ts b/src/spot-client.ts index 9dff7c5..a31b467 100644 --- a/src/spot-client.ts +++ b/src/spot-client.ts @@ -1,12 +1,15 @@ import { AxiosRequestConfig } from 'axios'; -import { APIResponse, KlineInterval } from './types/shared'; import { NewSpotOrder, + APIResponse, + KlineInterval, OrderSide, OrderTypeSpot, + SpotBalances, + SpotLastPrice, SpotOrderQueryById, SpotSymbolInfo, -} from './types/spot'; +} from './types'; import BaseRestClient from './util/BaseRestClient'; import { agentSource, @@ -109,7 +112,11 @@ export class SpotClient extends BaseRestClient { return this.get('/spot/quote/v1/ticker/24hr', { symbol }); } - getLastTradedPrice(symbol?: string): Promise> { + getLastTradedPrice(): Promise>; + getLastTradedPrice(symbol: string): Promise>; + getLastTradedPrice( + symbol?: string + ): Promise> { return this.get('/spot/quote/v1/ticker/price', { symbol }); } @@ -192,7 +199,7 @@ export class SpotClient extends BaseRestClient { * Wallet Data Endpoints */ - getBalances(): Promise> { + getBalances(): Promise> { return this.getPrivate('/spot/v1/account'); } } diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..78f54db --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,4 @@ +export * from './response'; +export * from './request'; +export * from './shared'; +export * from './spot'; diff --git a/src/types/request/index.ts b/src/types/request/index.ts new file mode 100644 index 0000000..747a7f0 --- /dev/null +++ b/src/types/request/index.ts @@ -0,0 +1 @@ +export * from './usdt-perp'; diff --git a/src/types/request/usdt-perp.ts b/src/types/request/usdt-perp.ts new file mode 100644 index 0000000..f9bf6e7 --- /dev/null +++ b/src/types/request/usdt-perp.ts @@ -0,0 +1,27 @@ +import { LinearPositionIdx } from '../../constants/enum'; +import { OrderSide } from '../shared'; + +export type LinearOrderType = 'Limit' | 'Market'; + +export type LinearTimeInForce = + | 'GoodTillCancel' + | 'ImmediateOrCancel' + | 'FillOrKill' + | 'PostOnly'; + +export interface NewLinearOrder { + side: OrderSide; + symbol: string; + order_type: LinearOrderType; + qty: number; + price?: number; + time_in_force: LinearTimeInForce; + take_profit?: number; + stop_loss?: number; + tp_trigger_by?: string; + sl_trigger_by?: string; + reduce_only: boolean; + close_on_trigger: boolean; + order_link_id?: string; + position_idx?: LinearPositionIdx; +} diff --git a/src/types/response/index.ts b/src/types/response/index.ts new file mode 100644 index 0000000..23d9753 --- /dev/null +++ b/src/types/response/index.ts @@ -0,0 +1,3 @@ +export * from './shared'; +export * from './spot'; +export * from './usdt-perp'; diff --git a/src/types/response/shared.ts b/src/types/response/shared.ts new file mode 100644 index 0000000..c8cf376 --- /dev/null +++ b/src/types/response/shared.ts @@ -0,0 +1,19 @@ +export interface SymbolWalletBalance { + equity: number; + available_balance: number; + used_margin: number; + order_margin: number; + position_margin: number; + occ_closing_fee: number; + occ_funding_fee: number; + wallet_balance: number; + realised_pnl: number; + unrealised_pnl: number; + cum_realised_pnl: number; + given_cash: number; + service_cash: number; +} + +export interface WalletBalances { + [symbol: string]: SymbolWalletBalance | undefined; +} diff --git a/src/types/response/spot.ts b/src/types/response/spot.ts new file mode 100644 index 0000000..dc1c969 --- /dev/null +++ b/src/types/response/spot.ts @@ -0,0 +1,17 @@ +export interface SpotBalance { + coin: string; + coinId: string; + coinName: string; + total: string; + free: string; + locked: string; +} + +export interface SpotBalances { + balances: SpotBalance[]; +} + +export interface SpotLastPrice { + symbol: string; + price: string; +} diff --git a/src/types/response/usdt-perp.ts b/src/types/response/usdt-perp.ts new file mode 100644 index 0000000..2a0db9c --- /dev/null +++ b/src/types/response/usdt-perp.ts @@ -0,0 +1,58 @@ +export interface PerpPosition { + user_id: number; + symbol: string; + side: string; + size: number; + position_value: number; + entry_price: number; + liq_price: number; + bust_price: number; + leverage: number; + auto_add_margin: number; + is_isolated: boolean; + position_margin: number; + occ_closing_fee: number; + realised_pnl: number; + cum_realised_pnl: number; + free_qty: number; + tp_sl_mode: string; + unrealised_pnl: number; + deleverage_indicator: number; + risk_id: number; + stop_loss: number; + take_profit: number; + trailing_stop: number; + position_idx: number; + mode: string; +} + +export interface PerpPositionRoot { + data: PerpPosition; + is_valid: boolean; +} + +export interface LinearOrder { + order_id: string; + user_id: number; + symbol: string; + side: string; + order_type: string; + price: number; + qty: number; + time_in_force: string; + order_status: string; + last_exec_price: number; + cum_exec_qty: number; + cum_exec_value: number; + cum_exec_fee: number; + reduce_only: boolean; + close_on_trigger: boolean; + order_link_id: string; + created_time: string; + updated_time: string; + take_profit: number; + stop_loss: number; + tp_trigger_by: string; + sl_trigger_by: string; + position_idx: number; +} diff --git a/src/types/shared.ts b/src/types/shared.ts index 7bc7e9d..0b41875 100644 --- a/src/types/shared.ts +++ b/src/types/shared.ts @@ -1,3 +1,7 @@ +export type numberInString = string; + +export type OrderSide = 'Buy' | 'Sell'; + export type KlineInterval = | '1m' | '3m' @@ -13,8 +17,6 @@ export type KlineInterval = | '1w' | '1M'; -export type numberInString = string; - export interface APIResponse { ret_code: number; ret_msg: 'OK' | string; diff --git a/src/types/spot.ts b/src/types/spot.ts index a514686..24a581d 100644 --- a/src/types/spot.ts +++ b/src/types/spot.ts @@ -1,6 +1,5 @@ -import { numberInString } from './shared'; +import { numberInString, OrderSide } from './shared'; -export type OrderSide = 'Buy' | 'Sell'; export type OrderTypeSpot = 'LIMIT' | 'MARKET' | 'LIMIT_MAKER'; export type OrderTimeInForce = 'GTC' | 'FOK' | 'IOC'; diff --git a/test/spot/private.read.test.ts b/test/spot/private.read.test.ts index 34a6870..6f61734 100644 --- a/test/spot/private.read.test.ts +++ b/test/spot/private.read.test.ts @@ -24,20 +24,20 @@ describe('Private Spot REST API Endpoints', () => { it('getOrder()', async () => { // No auth error == test pass expect(await api.getOrder({ orderId: '123123' })).toMatchObject( - errorResponseObject(null, -2013, 'Order does not exist.') + errorResponseObject({}, -2013, 'Order does not exist.') ); }); it('getOpenOrders()', async () => { - expect(await api.getOpenOrders()).toMatchObject(successResponseList('')); + expect(await api.getOpenOrders()).toMatchObject(successResponseList()); }); it('getPastOrders()', async () => { - expect(await api.getPastOrders()).toMatchObject(successResponseList('')); + expect(await api.getPastOrders()).toMatchObject(successResponseList()); }); it('getMyTrades()', async () => { - expect(await api.getMyTrades()).toMatchObject(successResponseList('')); + expect(await api.getMyTrades()).toMatchObject(successResponseList()); }); it('getBalances()', async () => { @@ -46,7 +46,7 @@ describe('Private Spot REST API Endpoints', () => { balances: expect.any(Array), }, ret_code: 0, - ret_msg: '', + ret_msg: 'OK', }); }); }); diff --git a/test/spot/private.write.test.ts b/test/spot/private.write.test.ts index 1140755..e1b1b60 100644 --- a/test/spot/private.write.test.ts +++ b/test/spot/private.write.test.ts @@ -18,7 +18,7 @@ describe('Private Inverse-Futures REST API POST Endpoints', () => { // These tests are primarily check auth is working by expecting balance or order not found style errors - it('submitOrder()', async () => { + it.skip('submitOrder()', async () => { expect( await api.submitOrder({ side: 'Buy', @@ -49,6 +49,6 @@ describe('Private Inverse-Futures REST API POST Endpoints', () => { symbol, orderTypes: ['LIMIT', 'LIMIT_MAKER'], }) - ).toMatchObject(successResponseObject('')); + ).toMatchObject(successResponseObject()); }); }); diff --git a/test/spot/public.test.ts b/test/spot/public.test.ts index c3c7c76..f0d261c 100644 --- a/test/spot/public.test.ts +++ b/test/spot/public.test.ts @@ -24,7 +24,7 @@ describe('Public Spot REST API Endpoints', () => { }); it('getSymbols()', async () => { - expect(await api.getSymbols()).toMatchObject(successResponseList('')); + expect(await api.getSymbols()).toMatchObject(successResponseList()); }); it('getOrderBook()', async () => {