diff --git a/src/index.ts b/src/index.ts index 44392ca..1325998 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ export * from './spot-client'; export * from './spot-client-v3'; export * from './usdc-option-client'; export * from './usdc-perpetual-client'; +export * from './unified-margin-client'; export * from './websocket-client'; export * from './util/logger'; export * from './types'; diff --git a/src/types/request/usdc-options.ts b/src/types/request/usdc-options.ts index 0ba1971..125f766 100644 --- a/src/types/request/usdc-options.ts +++ b/src/types/request/usdc-options.ts @@ -1,5 +1,4 @@ import { OrderSide } from '../shared'; -import { USDCOrderFilter } from './usdc-perp'; import { USDCAPICategory, USDCOrderType, USDCTimeInForce } from './usdc-shared'; export interface USDCOptionsContractInfoRequest { diff --git a/src/unified-margin-client.ts b/src/unified-margin-client.ts index 9c5b045..3491833 100644 --- a/src/unified-margin-client.ts +++ b/src/unified-margin-client.ts @@ -52,7 +52,7 @@ export class UnifiedMarginClient extends BaseRestClient { /** Query order book info. Each side has a depth of 25 orders. */ getOrderBook( symbol: string, - category?: string, + category: string, limit?: number ): Promise> { return this.get('/derivatives/v3/public/order-book/L2', { diff --git a/test/unified-margin/private.read.test.ts b/test/unified-margin/private.read.test.ts new file mode 100644 index 0000000..ae86d70 --- /dev/null +++ b/test/unified-margin/private.read.test.ts @@ -0,0 +1,72 @@ +import { USDCPerpetualClient } from '../../../src'; +import { successResponseObjectV3 } from '../../response.util'; + +describe('Private Account Asset REST API Endpoints', () => { + const useLivenet = true; + const API_KEY = process.env.API_KEY_COM; + const API_SECRET = process.env.API_SECRET_COM; + + it('should have api credentials to test with', () => { + expect(API_KEY).toStrictEqual(expect.any(String)); + expect(API_SECRET).toStrictEqual(expect.any(String)); + }); + + const api = new USDCPerpetualClient(API_KEY, API_SECRET, useLivenet); + + const symbol = 'BTCPERP'; + const category = 'PERPETUAL'; + + it('getActiveOrders()', async () => { + expect(await api.getActiveOrders({ category })).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getHistoricOrders()', async () => { + expect(await api.getHistoricOrders({ category })).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getOrderExecutionHistory()', async () => { + expect(await api.getOrderExecutionHistory({ category })).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getTransactionLog()', async () => { + expect(await api.getTransactionLog({ type: 'TRADE' })).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getBalances()', async () => { + expect(await api.getBalances()).toMatchObject(successResponseObjectV3()); + }); + + it('getAssetInfo()', async () => { + expect(await api.getAssetInfo()).toMatchObject(successResponseObjectV3()); + }); + + it('getMarginMode()', async () => { + expect(await api.getMarginMode()).toMatchObject(successResponseObjectV3()); + }); + + it('getPositions()', async () => { + expect(await api.getPositions({ category })).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getSettlementHistory()', async () => { + expect(await api.getSettlementHistory({ symbol })).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getPredictedFundingRate()', async () => { + expect(await api.getPredictedFundingRate(symbol)).toMatchObject( + successResponseObjectV3() + ); + }); +}); diff --git a/test/unified-margin/private.write.test.ts b/test/unified-margin/private.write.test.ts new file mode 100644 index 0000000..97637a0 --- /dev/null +++ b/test/unified-margin/private.write.test.ts @@ -0,0 +1,86 @@ +import { API_ERROR_CODE, USDCPerpetualClient } from '../../../src'; +import { + successEmptyResponseObjectV3, + successResponseObjectV3, +} from '../../response.util'; + +describe('Private Account Asset REST API Endpoints', () => { + const useLivenet = true; + const API_KEY = process.env.API_KEY_COM; + const API_SECRET = process.env.API_SECRET_COM; + + it('should have api credentials to test with', () => { + expect(API_KEY).toStrictEqual(expect.any(String)); + expect(API_SECRET).toStrictEqual(expect.any(String)); + }); + + const api = new USDCPerpetualClient(API_KEY, API_SECRET, useLivenet); + + const symbol = 'BTCPERP'; + + it('submitOrder()', async () => { + expect( + await api.submitOrder({ + symbol, + side: 'Sell', + orderType: 'Limit', + orderFilter: 'Order', + orderQty: '1', + orderPrice: '20000', + orderLinkId: Date.now().toString(), + timeInForce: 'GoodTillCancel', + }) + ).toMatchObject({ + retCode: API_ERROR_CODE.INSUFFICIENT_BALANCE_FOR_ORDER_COST, + }); + }); + + it('modifyOrder()', async () => { + expect( + await api.modifyOrder({ + symbol, + orderId: 'somethingFake', + orderPrice: '20000', + orderFilter: 'Order', + }) + ).toMatchObject({ + retCode: API_ERROR_CODE.ORDER_NOT_FOUND_OR_TOO_LATE, + }); + }); + + it('cancelOrder()', async () => { + expect( + await api.cancelOrder({ + symbol, + orderId: 'somethingFake1', + orderFilter: 'Order', + }) + ).toMatchObject({ + retCode: API_ERROR_CODE.ORDER_NOT_FOUND_OR_TOO_LATE, + }); + }); + + it('cancelActiveOrders()', async () => { + expect(await api.cancelActiveOrders(symbol, 'Order')).toMatchObject( + successEmptyResponseObjectV3() + ); + }); + + it('setMarginMode()', async () => { + expect(await api.setMarginMode('REGULAR_MARGIN')).toMatchObject( + successResponseObjectV3() + ); + }); + + it('setLeverage()', async () => { + expect(await api.setLeverage(symbol, '10')).toMatchObject({ + retCode: API_ERROR_CODE.LEVERAGE_NOT_MODIFIED, + }); + }); + + it('setRiskLimit()', async () => { + expect(await api.setRiskLimit(symbol, 1)).toMatchObject({ + retCode: API_ERROR_CODE.RISK_LIMIT_NOT_EXISTS, + }); + }); +}); diff --git a/test/unified-margin/public.read.test.ts b/test/unified-margin/public.read.test.ts new file mode 100644 index 0000000..26a6ab3 --- /dev/null +++ b/test/unified-margin/public.read.test.ts @@ -0,0 +1,108 @@ +import { + USDCKlineRequest, + UnifiedMarginClient, + UMCandlesRequest, +} from '../../src'; +import { + successResponseObject, + successResponseObjectV3, +} from '../response.util'; + +describe('Public USDC Options REST API Endpoints', () => { + const useLivenet = true; + const API_KEY = undefined; + const API_SECRET = undefined; + + const api = new UnifiedMarginClient(API_KEY, API_SECRET, useLivenet); + + const symbol = 'BTCUSDT'; + const category = 'linear'; + const start = Number((Date.now() / 1000).toFixed(0)); + const end = start + 1000 * 60 * 60 * 24; + const interval = '1'; + + const candleRequest: UMCandlesRequest = { + category, + symbol, + interval, + start, + end, + }; + + it('getOrderBook()', async () => { + expect(await api.getOrderBook(symbol, category)).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getCandles()', async () => { + expect(await api.getCandles(candleRequest)).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getSymbolTicker()', async () => { + expect(await api.getSymbolTicker(category)).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getInstrumentInfo()', async () => { + expect(await api.getInstrumentInfo({ category })).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getMarkPrice()', async () => { + expect(await api.getMarkPriceCandles(candleRequest)).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getIndexPrice()', async () => { + expect(await api.getIndexPriceCandles(candleRequest)).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getLastFundingRate()', async () => { + expect( + await api.getFundingRateHistory({ + category, + symbol, + }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getRiskLimit()', async () => { + expect(await api.getRiskLimit(category, symbol)).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getOptionDeliveryPrice()', async () => { + expect(await api.getOptionDeliveryPrice({ category })).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getTrades()', async () => { + expect(await api.getTrades({ category, symbol })).toMatchObject( + successResponseObjectV3() + ); + }); + + it('getOpenInterest()', async () => { + expect( + await api.getOpenInterest({ symbol, category, interval: '5min' }) + ).toMatchObject(successResponseObjectV3()); + }); + + it('getServerTime()', async () => { + expect(await api.getServerTime()).toMatchObject(successResponseObject()); + }); + + it('getAnnouncements()', async () => { + expect(await api.getAnnouncements()).toMatchObject(successResponseObject()); + }); +});