Skip to content

Commit

Permalink
feat(): refactoring, better types for WS API, add futures WS API with…
Browse files Browse the repository at this point in the history
… example
  • Loading branch information
tiagosiebler committed Jun 7, 2024
1 parent 04f893a commit 7c1bc2d
Show file tree
Hide file tree
Showing 28 changed files with 312 additions and 59 deletions.
129 changes: 129 additions & 0 deletions examples/ws-private-perp-futures-wsapi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

import { LogParams, WebsocketClient } from '../src';
import {
WSAPILoginResponse,
WSAPIResponse,
} from '../src/types/websockets/wsAPI';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const account = {
key: process.env.API_KEY || 'apiKeyHere',
secret: process.env.API_SECRET || 'apiSecretHere',
};

const customLogger = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
trace: (...params: LogParams): void => {
// console.log(new Date(), 'trace', ...params);
},
info: (...params: LogParams): void => {
console.log(new Date(), 'info', ...params);
},
error: (...params: LogParams): void => {
console.error(new Date(), 'error', ...params);
},
};

async function start() {
const client = new WebsocketClient(
{
apiKey: account.key,
apiSecret: account.secret,
reauthWSAPIOnReconnect: true,
},
customLogger,
);

client.on('open', (data) => {
console.log(new Date(), 'ws connected ', data?.wsKey);
});

// See comments below about event-driven vs promise-driven. Not needed if using the promise-driven approach
// client.on('update', (data) => {
// // console.info(new Date(), 'ws data received: ', JSON.stringify(data));
// console.info(new Date(), 'ws data received: ', JSON.stringify(data, null, 2));
// });

// Something happened, attempting to reconenct
client.on('reconnect', (data) => {
console.log(new Date(), 'ws reconnect: ', data);
});

// Reconnect successful
client.on('reconnected', (data) => {
console.log(new Date(), 'ws reconnected: ', data);
});

// Connection closed. If unexpected, expect reconnect -> reconnected.
client.on('close', (data) => {
console.error(new Date(), 'ws close: ', data);
});

// Reply to a request, e.g. "subscribe"/"unsubscribe"/"authenticate"
// See comments below about event-driven vs promise-driven. Not needed if using the promise-driven approach
// client.on('response', (data) => {
// console.info(
// new Date(),
// 'ws server reply ',
// JSON.stringify(data, null, 2),
// '\n',
// );
// });

client.on('exception', (data) => {
console.error(new Date(), 'ws exception: ', data);
});

// Optional, listen to this event if you prefer the event-driven approach.
// See below comments on event-driven vs promise-driven.
// client.on('authenticated', (data) => {
// console.error(new Date(), 'ws authenticated: ', data);
// });

try {
/**
* All WebSocket API (WS API) messaging should be done via the sendWSAPIRequest method.
*
* You have two ways to handle responses on the WS API. You can either:
* - event-driven: process async `response` and `update` events from the websocket client, OR
* - promise-driven: await every call to `client.sendWSAPIRequest`, this can behave similar to using a REST API (successful responses resolve, exceptions reject).
*/

/**
* To authenticate, send an empty request to "futures.login". The SDK will handle all the parameters.
*
* Optional - you can inject rich types to set the response type
* const loginResult = await client.sendWSAPIRequest<WSAPIResponse<WSAPILoginResponse>>('perpFuturesUSDTV4', 'futures.login');
*/
console.log(new Date(), 'try authenticate');
const loginResult = await client.sendWSAPIRequest(
'perpFuturesUSDTV4',
'futures.login',
);

client.sendWSAPIRequest('perpFuturesUSDTV4', 'futures.login');
console.log(new Date(), 'authenticated!', loginResult);

/**
* For other channels, the 3rd parameter should have any parameters for the request (the payload).
*
* Note that internal parameters such as "signature" etc are all handled automatically by the SDK.
*
*/
console.log(new Date(), 'try get order status');
const orderStatus = await client.sendWSAPIRequest(
'perpFuturesUSDTV4',
'futures.order_list',
{
status: 'finished',
},
);

console.log(new Date(), 'orderStatus result!', orderStatus);
} catch (e) {
console.error(`WS API Error: `, e);
}
}

start();
38 changes: 24 additions & 14 deletions examples/ws-private-spot-wsapi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

import { LogParams, WebsocketClient } from '../src';
import {
WSAPILoginResponse,
WSAPIResponse,
} from '../src/types/websockets/wsAPI';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const account = {
Expand Down Expand Up @@ -35,7 +39,7 @@ async function start() {
console.log(new Date(), 'ws connected ', data?.wsKey);
});

// // Data received
// See comments below about event-driven vs promise-driven. Not needed if using the promise-driven approach
// client.on('update', (data) => {
// // console.info(new Date(), 'ws data received: ', JSON.stringify(data));
// console.info(new Date(), 'ws data received: ', JSON.stringify(data, null, 2));
Expand All @@ -57,34 +61,40 @@ async function start() {
});

// Reply to a request, e.g. "subscribe"/"unsubscribe"/"authenticate"
client.on('response', (data) => {
console.info(
new Date(),
'ws server reply ',
JSON.stringify(data, null, 2),
'\n',
);
});
// See comments below about event-driven vs promise-driven. Not needed if using the promise-driven approach
// client.on('response', (data) => {
// console.info(
// new Date(),
// 'ws server reply ',
// JSON.stringify(data, null, 2),
// '\n',
// );
// });

client.on('exception', (data) => {
console.error(new Date(), 'ws exception: ', data);
});

client.on('authenticated', (data) => {
console.error(new Date(), 'ws authenticated: ', data);
});
// Optional, listen to this event if you prefer the event-driven approach.
// See below comments on event-driven vs promise-driven.
// client.on('authenticated', (data) => {
// console.error(new Date(), 'ws authenticated: ', data);
// });

try {
/**
* All WebSocket API (WS API) messaging should be done via the sendWSAPIRequest method.
*
* You have two ways to handle responses on the WS API. You can either:
* - process async `response` and `update` events from the websocket client, OR
* - await every call to `client.sendWSAPIRequest`, this can behave similar to using a REST API (successful responses resolve, exceptions reject).
* - event-driven: process async `response` and `update` events from the websocket client, OR
* - promise-driven: await every call to `client.sendWSAPIRequest`, this can behave similar to using a REST API (successful responses resolve, exceptions reject).
*/

/**
* To authenticate, send an empty request to "spot.login". The SDK will handle all the parameters.
*
* Optional - you can inject rich types to set the response type
* const loginResult = await client.sendWSAPIRequest<WSAPIResponse<WSAPILoginResponse>>('spotV4', 'spot.login');
*/
console.log(new Date(), 'try authenticate');
const loginResult = await client.sendWSAPIRequest('spotV4', 'spot.login');
Expand Down
34 changes: 17 additions & 17 deletions src/RestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import {
RestClientType,
} from './lib/BaseRestClient.js';
import { RestClientOptions } from './lib/requestUtils.js';
import { CreateStpGroupReq } from './types/requests/account.js';
import { CreateStpGroupReq } from './types/request/account.js';
import {
GetLoanCollateralRecordsReq,
GetLoanOrdersReq,
GetLoanRepaymentHistoryReq,
SubmitLoanOrderReq,
UpdateLoanCollateralReq,
} from './types/requests/collateralLoan.js';
} from './types/request/collateralLoan.js';
import {
GetDeliveryAutoOrdersReq,
GetDeliveryBookReq,
Expand All @@ -27,22 +27,22 @@ import {
GetDeliveryTradingHistoryReq,
SubmitDeliveryFuturesOrderReq,
submitDeliveryTriggeredOrderReq,
} from './types/requests/delivery.js';
} from './types/request/delivery.js';
import {
GetStructuredProductListReq,
GetStructuredProductOrdersReq,
} from './types/requests/earn.js';
} from './types/request/earn.js';
import {
GetLendingInterestRecordsReq,
GetLendingOrdersReq,
GetLendingRecordsReq,
SubmitLendOrRedeemReq,
} from './types/requests/earnuni.js';
} from './types/request/earnuni.js';
import {
GetFlashSwapOrdersReq,
SubmitFlashSwapOrderPreviewReq,
SubmitFlashSwapOrderReq,
} from './types/requests/flashswap.js';
} from './types/request/flashswap.js';
import {
DeleteAllFuturesOrdersReq,
GetFuturesAccountBookReq,
Expand All @@ -64,29 +64,29 @@ import {
SubmitFuturesPriceTriggeredOrderReq,
UpdateDualModePositionLeverageReq,
UpdateDualModePositionMarginReq,
} from './types/requests/futures.js';
} from './types/request/futures.js';
import {
GetCrossMarginAccountHistoryReq,
GetCrossMarginBorrowHistoryReq,
GetCrossMarginInterestRecordsReq,
GetCrossMarginRepaymentsReq,
GetMarginBalanceHistoryReq,
SubmitCrossMarginBorrowLoanReq,
} from './types/requests/margin.js';
} from './types/request/margin.js';
import {
GetMarginUNIInterestRecordsReq,
GetMarginUNILoanRecordsReq,
GetMarginUNILoansReq,
GetMarginUNIMaxBorrowReq,
} from './types/requests/marginuni.js';
} from './types/request/marginuni.js';
import {
GetMultiLoanAdjustmentRecordsReq,
GetMultiLoanOrdersReq,
GetMultiLoanRepayRecordsReq,
RepayMultiLoanReq,
SubmitMultiLoanOrderReq,
UpdateMultiLoanReq,
} from './types/requests/multicollateralLoan.js';
} from './types/request/multicollateralLoan.js';
import {
GetOptionsAccountChangeReq,
GetOptionsCandlesticksReq,
Expand All @@ -98,13 +98,13 @@ import {
GetOptionsTradesReq,
GetOptionsUnderlyingCandlesticksReq,
SubmitOptionsOrderReq,
} from './types/requests/options.js';
} from './types/request/options.js';
import {
GetAgencyCommissionHistoryReq,
GetAgencyTransactionHistoryReq,
GetBrokerCommissionHistoryReq,
GetBrokerTransactionHistoryReq,
} from './types/requests/rebate.js';
} from './types/request/rebate.js';
import {
DeleteSpotOrderReq,
GetSpotAccountBookReq,
Expand All @@ -118,20 +118,20 @@ import {
SubmitSpotOrderReq,
UpdateSpotBatchOrdersReq,
UpdateSpotOrderReq,
} from './types/requests/spot.js';
} from './types/request/spot.js';
import {
CreateSubAccountApiKeyReq,
CreateSubAccountReq,
UpdateSubAccountApiKeyReq,
} from './types/requests/subaccount.js';
} from './types/request/subaccount.js';
import {
GetUnifiedInterestRecordsReq,
GetUnifiedLoanRecordsReq,
GetUnifiedLoansReq,
PortfolioMarginCalculatorReq,
SetUnifiedAccountModeReq,
SubmitUnifiedBorrowOrRepayReq,
} from './types/requests/unified.js';
} from './types/request/unified.js';
import {
GetMainSubTransfersReq,
GetSavedAddressReq,
Expand All @@ -140,8 +140,8 @@ import {
SubmitMainSubTransferReq,
SubmitSubToSubTransferReq,
SubmitTransferReq,
} from './types/requests/wallet.js';
import { SubmitWithdrawReq } from './types/requests/withdrawal.js';
} from './types/request/wallet.js';
import { SubmitWithdrawReq } from './types/request/withdrawal.js';
import {
CreateStpGroupResp,
GetAccountDetailResp,
Expand Down
Loading

0 comments on commit 7c1bc2d

Please sign in to comment.