Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: parsing big int in json #68 #69

Merged
merged 1 commit into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"axios": "^1.5.1",
"axios-request-throttle": "^1.0.0",
"date-fns": "^3.3.1",
"json-bignumber": "^1.1.1",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
"ws": "^8.14.2"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { EnvProviderService } from '@ledius/env';
import {
ApiAccount,
HttpRequestExecutor,
OrderPositionSideEnum,
OrderSideEnum,
OrderTypeEnum,
} from 'bingx-api/bingx';
import { BingxApiClient } from 'bingx-api/bingx-client';

describe('create test order', () => {
const env = new EnvProviderService();

const account = new ApiAccount(
env.getOrFail('API_ACCOUNT_KEY'),
env.getOrFail('API_ACCOUNT_SECRET'),
);

let client: BingxApiClient;

beforeAll(() => {
client = new BingxApiClient(new HttpRequestExecutor());
});

describe('create test order', () => {
it('should be create order', async () => {
const response = await client.getTradeService().createTradeOrderTest(
{
clientOrderID: '',
side: OrderSideEnum.BUY,
positionSide: OrderPositionSideEnum.LONG,
price: '30000',
quantity: '0.001',
symbol: 'BTC-USDT',
type: OrderTypeEnum.MARKET,
},
account,
);

expect(response).toStrictEqual({});
});
});
});
9 changes: 9 additions & 0 deletions src/bingx-client/services/trade.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ export class TradeService {
);
}

public async createTradeOrderTest(
order: BingxCreateTradeOrderInterface,
account: AccountInterface,
) {
return this.requestExecutor.execute(
new BingxTradeOrderEndpoint(order, account),
);
}

public async getUserHistoryOrders(
symbol: string,
limit: number,
Expand Down
64 changes: 62 additions & 2 deletions src/bingx-socket/bingx-account-socket-stream.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ describe('bingx account socket stream', () => {
expect(e).toStrictEqual({
e: AccountWebsocketEventType.ORDER_TRADE_UPDATE,
o: {},
E: 111,
E: '111',
} as AccountOrderUpdatePushEvent);
done();
});
Expand All @@ -189,10 +189,70 @@ describe('bingx account socket stream', () => {
JSON.stringify({
e: AccountWebsocketEventType.ORDER_TRADE_UPDATE,
o: {},
E: 111,
E: '111',
} as AccountOrderUpdatePushEvent),
);
}, 1000);
});
});

describe('#68 fix big number in order identifier', () => {
const requestExecutorMock = {
execute: jest.fn().mockResolvedValueOnce({ data: { listenKey: '123' } }),
};
let stream: BingxAccountSocketStream;
beforeAll(() => {
const account = new ApiAccount('xxx', 'xxx');
stream = new BingxAccountSocketStream(account, {
requestExecutor: requestExecutorMock,
url: new URL('', `ws://0.0.0.0:${port}`),
});
});

afterAll(() => {
stream.disconnect();
});

it('must be got listen key', () => {
expect(requestExecutorMock.execute).toHaveBeenCalledTimes(1);
});

it('must be got order push', (done) => {
stream.accountOrderUpdatePushEvent$.subscribe((e) => {
expect(e).toStrictEqual({
e: AccountWebsocketEventType.ORDER_TRADE_UPDATE,
o: {
N: 'USDT',
S: 'BUY',
T: '0',
X: 'NEW',
c: '',
i: '172998235239792314304',
n: '0.00000000',
o: 'TRIGGER_MARKET',
p: '',
q: '0.00100000',
s: 'BTC-USDT',
x: 'TRADE',
z: '0.00000000',
ap: '0.00000000',
ps: 'LONG',
rp: '0.00000000',
sp: '43495.00000000',
wt: 'MARK_PRICE',
},
E: '1706736600541',
} as AccountOrderUpdatePushEvent);
done();
});
setTimeout(() => {
sendToSocket(
sockets[0],
'{"E":1706736600541,"e":"ORDER_TRADE_UPDATE","o":{"N":"USDT","S":"BUY","T":0,"X":"NEW","c":"","i":172998235239792314304,' +
'"n":"0.00000000","o":"TRIGGER_MARKET","p":"","q":"0.00100000","s":"BTC-USDT",' +
'"x":"TRADE","z":"0.00000000","ap":"0.00000000","ps":"LONG","rp":"0.00000000","sp":"43495.00000000","wt":"MARK_PRICE"}}',
);
}, 1000);
});
});
});
3 changes: 2 additions & 1 deletion src/bingx-socket/bingx-websocket-deserializer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { WebSocketSubjectConfig } from 'rxjs/internal/observable/dom/WebSocketSubject';
import * as zlib from 'zlib';
import * as JSONBigNumber from 'json-bignumber';

export class BingxWebsocketDeserializer
implements Required<Pick<WebSocketSubjectConfig<any>, 'deserializer'>>
Expand All @@ -8,7 +9,7 @@ export class BingxWebsocketDeserializer
const message = zlib.unzipSync(e.data).toString('utf-8');

try {
return JSON.parse(message);
return JSON.parse(JSON.stringify(JSONBigNumber.parse(message)));
} catch (e) {
return message;
}
Expand Down
17 changes: 9 additions & 8 deletions src/bingx-socket/events/account-websocket-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export enum WebSocketOrderType {
STOP = 'STOP',
TAKE_PROFIT = 'TAKE_PROFIT',
LIQUIDATION = 'LIQUIDATION',
TRIGGER_MARKET = 'TRIGGER_MARKET',
}

export enum WebSocketOrderExecutionType {
Expand All @@ -44,7 +45,7 @@ export enum WebSocketTriggerPriceType {
INDEX_PRICE = 'INDEX_PRICE',
}

export type EventTimeInMilliseconds = number;
export type EventTimeInMilliseconds = string;

/**
* Relates account events
Expand All @@ -65,13 +66,13 @@ export type IsolatedPositionMargin = number;
*/
export type ClientCustomOrderId = string;
export type OrderId = string;
export type Quantity = number;
export type Price = number;
export type AveragePrice = number;
export type HandlingFee = number;
export type TransactionTime = number;
export type TransactionAchievedProfitAndLoss = number;
export type OrderFilledAccumulatedQuantity = number;
export type Quantity = string;
export type Price = string;
export type AveragePrice = string;
export type HandlingFee = string;
export type TransactionTime = string;
export type TransactionAchievedProfitAndLoss = string;
export type OrderFilledAccumulatedQuantity = string;
export type FeeAssetType = string;

export interface AccountBalanceInformation {
Expand Down
9 changes: 9 additions & 0 deletions src/bingx/endpoints/bingx-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { lastValueFrom } from 'rxjs';
import { BingxRequestInterface } from 'bingx-api/bingx/endpoints/bingx-request.interface';
import { HttpService } from '@nestjs/axios';
import axios from 'axios';
import * as JSONBigNumber from 'json-bignumber';

export class BingxRequest<R> implements BingxRequestInterface<R> {
private readonly http = new HttpService(
Expand All @@ -11,6 +12,14 @@ export class BingxRequest<R> implements BingxRequestInterface<R> {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
transformResponse: (res) => {
try {
return JSON.parse(JSON.stringify(JSONBigNumber.parse(res)));
} catch (e) {
console.error(e);
return res;
}
},
}),
);

Expand Down
48 changes: 48 additions & 0 deletions src/bingx/endpoints/bingx-trade-order-test-endpoint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { EndpointInterface } from 'bingx-api/bingx/endpoints/endpoint.interface';
import { Endpoint } from 'bingx-api/bingx/endpoints/endpoint';
import { BingxResponse, SignatureParametersInterface } from 'bingx-api/bingx';
import { AccountInterface } from 'bingx-api/bingx/account/account.interface';
import { BingxCreateTradeOrderInterface } from 'bingx-api/bingx/interfaces/trade-order.interface';
import { DefaultSignatureParameters } from 'bingx-api/bingx/account/default-signature-parameters';
import { OrderSideEnum } from 'bingx-api/bingx/enums/order-side.enum';
import { OrderTypeEnum } from 'bingx-api/bingx/enums/order-type.enum';
import { OrderPositionSideEnum } from 'bingx-api/bingx/enums/order-position-side.enum';

export interface BingxOrderResponseInterface {
order: {
symbol: string;
side: OrderSideEnum;
type: OrderTypeEnum;
positionSide: OrderPositionSideEnum;
orderId: number;
clientOrderId: string;
};
}

export class BingxTradeOrderTestEndpoint<R = BingxOrderResponseInterface>
extends Endpoint
implements EndpointInterface<BingxResponse<R>>
{
constructor(
private readonly order: BingxCreateTradeOrderInterface,
account: AccountInterface,
) {
super(account);
}

readonly t!: BingxResponse<R>;

method(): 'get' | 'post' | 'put' | 'patch' | 'delete' {
return 'post';
}

parameters(): SignatureParametersInterface {
return new DefaultSignatureParameters({
...this.order,
});
}

path(): string {
return '/openApi/swap/v2/trade/order/test';
}
}
3 changes: 3 additions & 0 deletions src/json-bignumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module 'json-bignumber' {
function parse(input: string): Record<string, unknown>;
}
Loading