From a7823ccc4df04d6f037d85bf290b776d956c8e87 Mon Sep 17 00:00:00 2001 From: Zaixin Cheng Date: Tue, 12 May 2026 05:19:03 -0400 Subject: [PATCH] feat: add current pending orders endpoint --- README.md | 2 +- ...ade-current-pending-orders.service.spec.ts | 71 +++++++++++++++++++ src/bingx-client/services/trade.service.ts | 13 ++++ .../bingx-current-pending-orders-endpoint.ts | 57 +++++++++++++++ src/bingx/endpoints/index.ts | 1 + 5 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/bingx-client/services/trade-current-pending-orders.service.spec.ts create mode 100644 src/bingx/endpoints/bingx-current-pending-orders-endpoint.ts diff --git a/README.md b/README.md index 6dd246f..95112bb 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ stream.latestTradeDetail$.subscribe((v) => {}) - [ ] Cancel an Order - [ ] Cancel a Batch of Orders - [ ] Cancel All Orders - - [ ] Query all current pending orders + - [x] Query all current pending orders - [ ] Query Order - [ ] Query Margin Mode - [ ] Switch Margin Mode diff --git a/src/bingx-client/services/trade-current-pending-orders.service.spec.ts b/src/bingx-client/services/trade-current-pending-orders.service.spec.ts new file mode 100644 index 0000000..d80c8bf --- /dev/null +++ b/src/bingx-client/services/trade-current-pending-orders.service.spec.ts @@ -0,0 +1,71 @@ +import { TradeService } from 'bingx-api/bingx-client/services/trade.service'; +import { AccountInterface } from 'bingx-api/bingx/account/account.interface'; +import { RequestExecutorInterface } from 'bingx-api/bingx/request-executor/request-executor.interface'; +import { EndpointInterface } from 'bingx-api/bingx/endpoints/endpoint.interface'; +import { BingxCurrentPendingOrdersEndpoint } from 'bingx-api/bingx/endpoints/bingx-current-pending-orders-endpoint'; + +describe('trade current pending orders service', () => { + let account: AccountInterface; + let capturedEndpoints: EndpointInterface[]; + let requestExecutor: RequestExecutorInterface; + let executeSpy: jest.SpyInstance; + let nowSpy: jest.SpyInstance; + + beforeEach(() => { + account = { + getApiKey: jest.fn(() => 'api-key'), + sign: jest.fn(() => ({ + toString: () => 'signature', + secretKey: () => 'secret-key', + })), + }; + + capturedEndpoints = []; + requestExecutor = { + execute(endpoint: EndpointInterface): Promise { + capturedEndpoints.push(endpoint as EndpointInterface); + return Promise.resolve(endpoint as unknown as T); + }, + }; + + executeSpy = jest.spyOn(requestExecutor, 'execute'); + nowSpy = jest.spyOn(Date, 'now').mockReturnValue(1770000000123); + }); + + afterEach(() => { + nowSpy.mockRestore(); + }); + + it('dispatches the signed current pending orders endpoint', async () => { + const service = new TradeService(requestExecutor); + + const endpoint = (await service.getCurrentPendingOrders( + { + symbol: 'BTC-USDT', + type: 'LIMIT', + recvWindow: 5000, + }, + account, + )) as unknown as BingxCurrentPendingOrdersEndpoint; + + expect(executeSpy).toHaveBeenCalledTimes(1); + expect(capturedEndpoints[0]).toBe(endpoint); + expect(endpoint).toBeInstanceOf(BingxCurrentPendingOrdersEndpoint); + expect(endpoint.method()).toBe('get'); + expect(endpoint.path()).toBe('/openApi/swap/v2/trade/openOrders'); + expect(endpoint.parameters().asRecord()).toEqual({ + symbol: 'BTC-USDT', + type: 'LIMIT', + recvWindow: '5000', + timestamp: '1770000000123', + }); + }); + + it('omits optional filters when no pending order options are provided', () => { + const endpoint = new BingxCurrentPendingOrdersEndpoint({}, account); + + expect(endpoint.parameters().asRecord()).toEqual({ + timestamp: '1770000000123', + }); + }); +}); diff --git a/src/bingx-client/services/trade.service.ts b/src/bingx-client/services/trade.service.ts index 65fa5bd..5294a3d 100644 --- a/src/bingx-client/services/trade.service.ts +++ b/src/bingx-client/services/trade.service.ts @@ -12,6 +12,10 @@ import { BingxSwitchLeverageEndpoint } from 'bingx-api/bingx/endpoints/bingx-swi import { OrderPositionSideEnum } from 'bingx-api/bingx'; import { BingxUserHistoryOrdersEndpoint } from 'bingx-api/bingx/endpoints/bingx-user-history-orders-endpoint'; import { BingxCancelOrderEndpoint } from 'bingx-api/bingx/endpoints/bingx-cancel-order-endpoint'; +import { + BingxCurrentPendingOrdersEndpoint, + BingxCurrentPendingOrdersOptions, +} from 'bingx-api/bingx/endpoints/bingx-current-pending-orders-endpoint'; export class TradeService { constructor(private readonly requestExecutor: RequestExecutorInterface) {} @@ -62,6 +66,15 @@ export class TradeService { ); } + public async getCurrentPendingOrders( + options: BingxCurrentPendingOrdersOptions, + account: AccountInterface, + ) { + return this.requestExecutor.execute( + new BingxCurrentPendingOrdersEndpoint(options, account), + ); + } + public closeAllPositions(account: AccountInterface) { return this.requestExecutor.execute( new BingxCloseAllPositionsEndpoint(account), diff --git a/src/bingx/endpoints/bingx-current-pending-orders-endpoint.ts b/src/bingx/endpoints/bingx-current-pending-orders-endpoint.ts new file mode 100644 index 0000000..b447d55 --- /dev/null +++ b/src/bingx/endpoints/bingx-current-pending-orders-endpoint.ts @@ -0,0 +1,57 @@ +import { + AccountInterface, + BingxResponse, + DefaultSignatureParameters, + EndpointInterface, + SignatureParametersInterface, +} from 'bingx-api/bingx'; +import { Endpoint } from 'bingx-api/bingx/endpoints/endpoint'; +import { BingxUserHistoryOrdersResponse } from 'bingx-api/bingx/endpoints/bingx-user-history-orders-response'; + +export interface BingxCurrentPendingOrdersOptions { + symbol?: string; + type?: string; + recvWindow?: string | number; +} + +export class BingxCurrentPendingOrdersEndpoint< + R extends BingxUserHistoryOrdersResponse = BingxUserHistoryOrdersResponse, + > + extends Endpoint> + implements EndpointInterface> +{ + constructor( + private readonly options: BingxCurrentPendingOrdersOptions, + account: AccountInterface, + ) { + super(account); + } + + method(): 'get' | 'post' | 'put' | 'patch' | 'delete' { + return 'get'; + } + + parameters(): SignatureParametersInterface { + const parameters: Record = {}; + + if (this.options.symbol !== undefined) { + parameters.symbol = this.options.symbol; + } + + if (this.options.type !== undefined) { + parameters.type = this.options.type; + } + + if (this.options.recvWindow !== undefined) { + parameters.recvWindow = this.options.recvWindow.toString(); + } + + return new DefaultSignatureParameters(parameters); + } + + path(): string { + return '/openApi/swap/v2/trade/openOrders'; + } + + readonly t!: BingxResponse; +} diff --git a/src/bingx/endpoints/index.ts b/src/bingx/endpoints/index.ts index 6866f8b..52ae080 100644 --- a/src/bingx/endpoints/index.ts +++ b/src/bingx/endpoints/index.ts @@ -1,5 +1,6 @@ export * from './bingx-cancel-all-orders-endpoint'; export * from './bingx-close-all-positions-endpoint'; +export * from './bingx-current-pending-orders-endpoint'; export * from './bingx-generate-listen-key-endpoint'; export * from './bingx-generate-listen-key-response'; export * from './bingx-get-perpetual-swap-account-asset-endpoint';