Merge pull request #54 from tiagosiebler/linter

feat(v2.2.0): bump build version to node LTS, fix linter, address linter conflicts, update gh action for linter check
This commit is contained in:
Tiago
2024-12-11 16:57:45 +00:00
committed by GitHub
45 changed files with 2039 additions and 1479 deletions

53
.eslintrc.cjs Normal file
View File

@@ -0,0 +1,53 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.linting.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: [
'@typescript-eslint/eslint-plugin',
'simple-import-sort',
// 'require-extensions', // only once moved to ESM
],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
// 'plugin:require-extensions/recommended', // only once moved to ESM
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js', 'webpack.config.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/ban-types': 'off',
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
'array-bracket-spacing': ['error', 'never'],
'linebreak-style': ['error', 'unix'],
'lines-between-class-members': ['warn', 'always'],
semi: ['error', 'always'],
'new-cap': 'off',
'no-console': 'off',
'no-debugger': 'off',
'no-mixed-spaces-and-tabs': 2,
'no-use-before-define': [2, 'nofunc'],
'no-unreachable': ['warn'],
// 'no-unused-vars': ['warn'],
'no-extra-parens': ['off'],
'no-mixed-operators': ['off'],
quotes: [2, 'single', 'avoid-escape'],
'block-scoped-var': 2,
'brace-style': [2, '1tbs', { allowSingleLine: true }],
'computed-property-spacing': [2, 'never'],
'keyword-spacing': 2,
'space-unary-ops': 2,
},
};

View File

@@ -1,36 +0,0 @@
module.exports = {
env: {
es6: true,
node: true,
},
extends: ['eslint:recommended'],
parserOptions: {
sourceType: 'module',
ecmaVersion: 9
},
plugins: [],
rules: {
'array-bracket-spacing': ['error', 'never'],
indent: ['warn', 2],
'linebreak-style': ['error', 'unix'],
'lines-between-class-members': ['warn', 'always'],
semi: ['error', 'always'],
'new-cap': 'off',
'no-console': 'off',
'no-debugger': 'off',
'no-mixed-spaces-and-tabs': 2,
'no-use-before-define': [2, 'nofunc'],
'no-unreachable': ['warn'],
'no-unused-vars': ['warn'],
'no-extra-parens': ['off'],
'no-mixed-operators': ['off'],
quotes: [2, 'single', 'avoid-escape'],
'block-scoped-var': 2,
'brace-style': [2, '1tbs', { allowSingleLine: true }],
'computed-property-spacing': [2, 'never'],
'keyword-spacing': 2,
'space-unary-ops': 2,
'max-len': ['warn', { 'code': 140 }]
}
};

View File

@@ -1,13 +1,9 @@
name: "Build & Test"
name: "Build, Lint & Test"
on: [push]
# on:
# # pull_request:
# # branches:
# # - "master"
# push:
# branches:
on:
push:
pull_request:
workflow_dispatch:
jobs:
build:
@@ -15,20 +11,27 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: "Checkout source code"
uses: actions/checkout@v3
- name: 'Checkout source code'
uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 16
node-version-file: '.nvmrc'
registry-url: 'https://registry.npmjs.org/'
cache: 'npm'
- name: Install
run: npm ci --ignore-scripts
- name: Build
- name: Clean
run: npm run clean
- name: Check Build
run: npm run build
- name: Check Lint
run: npm run lint
- name: Test
run: npm run test
env:

3
.gitignore vendored
View File

@@ -26,4 +26,5 @@ tiagoSpot.ts
restClientRegex.ts
localtest.sh
privaterepotracker
testfile.ts
testfile.ts
dist

2
.nvmrc
View File

@@ -1 +1 @@
v18.12.1
v22.11.0

1136
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "bitget-api",
"version": "2.1.0",
"version": "2.2.0",
"description": "Node.js & JavaScript SDK for Bitget REST APIs & WebSockets, with TypeScript & end-to-end tests.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
@@ -16,6 +16,7 @@
"build:clean": "npm run clean && npm run build",
"build:watch": "npm run clean && tsc --watch",
"pack": "webpack --config webpack/webpack.config.js",
"lint": "eslint src",
"prepublish": "npm run build:clean",
"betapublish": "npm publish --tag beta"
},
@@ -29,7 +30,12 @@
"devDependencies": {
"@types/jest": "^29.0.3",
"@types/node": "^18.7.23",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"eslint": "^8.24.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-require-extensions": "^0.1.3",
"eslint-plugin-simple-import-sort": "^12.1.1",
"jest": "^29.1.1",
"source-map-loader": "^4.0.0",
"ts-jest": "^29.0.2",

View File

@@ -1,9 +1,9 @@
import {
APIResponse,
BrokerProductType,
BrokerSubWithdrawalRequest,
BrokerSubAPIKeyModifyRequest,
BrokerSubListRequest,
BrokerSubWithdrawalRequest,
} from './types';
import { REST_CLIENT_TYPE_ENUM } from './util';
import BaseRestClient from './util/BaseRestClient';

View File

@@ -1,32 +1,32 @@
import {
APIResponse,
FuturesProductType,
CancelFuturesPlanTPSL,
FuturesAccount,
FuturesAccountBillRequest,
FuturesBusinessBillRequest,
NewFuturesOrder,
NewBatchFuturesOrder,
FuturesCandleData,
FuturesHistoricPositions,
FuturesKlineInterval,
FuturesMarginMode,
FuturesMarketTrade,
FuturesPagination,
NewFuturesPlanOrder,
FuturesPlanType,
FuturesPosition,
FuturesProductType,
FuturesSymbolRule,
GetHistoricTradesParams,
HistoricPlanOrderTPSLRequest,
ModifyFuturesOrder,
ModifyFuturesPlanOrder,
ModifyFuturesPlanOrderTPSL,
NewFuturesPlanPositionTPSL,
ModifyFuturesPlanStopOrder,
CancelFuturesPlanTPSL,
HistoricPlanOrderTPSLRequest,
NewBatchFuturesOrder,
NewFuturesOrder,
NewFuturesPlanOrder,
NewFuturesPlanPositionTPSL,
NewFuturesPlanStopOrder,
FuturesAccount,
FuturesSymbolRule,
FuturesMarginMode,
FuturesPosition,
NewFuturesPlanTrailingStopOrder,
VIPFeeRate,
GetHistoricTradesParams,
FuturesMarketTrade,
FuturesPlanType,
FuturesKlineInterval,
FuturesHistoricPositions,
ModifyFuturesOrder,
FuturesCandleData,
} from './types';
import { REST_CLIENT_TYPE_ENUM } from './util';
import BaseRestClient from './util/BaseRestClient';
@@ -105,9 +105,9 @@ export class FuturesClient extends BaseRestClient {
symbol: string,
granularity: FuturesKlineInterval,
startTime: string,
endTime: string,
endTime: string,
limit?: string,
kLineType?: 'market' | 'mark' | 'index'
kLineType?: 'market' | 'mark' | 'index',
): Promise<APIResponse<FuturesCandleData[]>> {
return this.get('/api/mix/v1/market/candles', {
symbol,
@@ -569,16 +569,16 @@ export class FuturesClient extends BaseRestClient {
return this.postPrivate('/api/mix/v1/plan/cancelPlan', params);
}
/** Cancel Symbol Plan Order (TPSL) */
cancelSymbolPlanOrders(
symbol: string,
planType: FuturesPlanType,
): Promise<APIResponse<any>> {
return this.postPrivate('/api/mix/v1/plan/cancelSymbolPlan', {
symbol,
planType,
});
}
/** Cancel Symbol Plan Order (TPSL) */
cancelSymbolPlanOrders(
symbol: string,
planType: FuturesPlanType,
): Promise<APIResponse<any>> {
return this.postPrivate('/api/mix/v1/plan/cancelSymbolPlan', {
symbol,
planType,
});
}
/** Cancel All Trigger Order (TPSL) */
cancelAllPlanOrders(

View File

@@ -1,10 +1,10 @@
export * from './rest-client-v2';
export * from './broker-client';
export * from './constants/enum';
export * from './futures-client';
export * from './rest-client-v2';
export * from './spot-client';
export * from './types';
export * from './util';
export * from './util/logger';
export * from './websocket-client';
export * from './websocket-client-v2';
export * from './util/logger';
export * from './util';
export * from './types';
export * from './constants/enum';

File diff suppressed because it is too large Load Diff

View File

@@ -1,27 +1,27 @@
import {
APIResponse,
BatchCancelSpotOrderV2,
CancelSpotOrderV2,
CancelSpotPlanOrderParams,
CoinBalance,
GetHistoricPlanOrdersParams,
GetHistoricTradesParams,
GetSpotPlanOrdersParams,
ModifySpotPlanOrder,
NewBatchSpotOrder,
NewSpotOrder,
NewWalletTransfer,
Pagination,
APIResponse,
CoinBalance,
SymbolRules,
NewSpotPlanOrder,
NewSpotSubTransfer,
NewSpotWithdraw,
CancelSpotOrderV2,
BatchCancelSpotOrderV2,
SpotOrderResult,
NewSpotPlanOrder,
ModifySpotPlanOrder,
CancelSpotPlanOrderParams,
GetSpotPlanOrdersParams,
SpotPlanOrder,
GetHistoricPlanOrdersParams,
SpotMarketTrade,
GetHistoricTradesParams,
VIPFeeRate,
SpotKlineInterval,
NewWalletTransfer,
Pagination,
SpotCandleData,
SpotKlineInterval,
SpotMarketTrade,
SpotOrderResult,
SpotPlanOrder,
SymbolRules,
VIPFeeRate,
} from './types';
import { REST_CLIENT_TYPE_ENUM } from './util';
import BaseRestClient from './util/BaseRestClient';
@@ -112,7 +112,7 @@ export class SpotClient extends BaseRestClient {
getCandles(
symbol: string,
period: SpotKlineInterval,
pagination?: Pagination,
pagination?: Pagination,
): Promise<APIResponse<SpotCandleData[]>> {
return this.get('/api/spot/v1/market/candles', {
symbol,

View File

@@ -1,4 +1,4 @@
export * from './response';
export * from './request';
export * from './response';
export * from './shared';
export * from './websockets';

View File

@@ -1,11 +1,11 @@
export * from './v1/brokerV1';
export * from './v1/futuresV1';
export * from './v1/spotV1';
export * from './v2/futures';
export * from './v2/spot';
export * from './v2/broker';
export * from './v2/margin';
export * from './v2/copytrading';
export * from './v2/earn';
export * from './shared';
export * from './v2/common';
export * from './shared';
export * from './v1/brokerV1';
export * from './v1/futuresV1';
export * from './v1/spotV1';
export * from './v2/broker';
export * from './v2/common';
export * from './v2/copytrading';
export * from './v2/earn';
export * from './v2/futures';
export * from './v2/margin';
export * from './v2/spot';

View File

@@ -1,39 +1,39 @@
/** Pagination */
export interface Pagination {
/** Time after */
after?: string;
/** Time before */
before?: string;
/** Elements per page */
limit?: string;
}
export type OrderTimeInForce = 'normal' | 'post_only' | 'fok' | 'ioc';
export interface GetHistoricTradesParams {
symbol: string;
limit?: string;
tradeId?: string;
startTime?: string;
endTime?: string;
}
/**
* The margin type, used directly in building the endpoint URL
*/
export type MarginType = 'crossed' | 'isolated';
export type FuturesProductTypeV2 =
| 'USDT-FUTURES'
| 'COIN-FUTURES'
| 'USDC-FUTURES'
| 'SUSDT-FUTURES'
| 'SCOIN-FUTURES'
| 'SUSDC-FUTURES';
export type FuturesPlanTypeV2 =
| 'profit_plan'
| 'loss_plan'
| 'moving_plan'
| 'pos_profit'
| 'pos_loss';
/** Pagination */
export interface Pagination {
/** Time after */
after?: string;
/** Time before */
before?: string;
/** Elements per page */
limit?: string;
}
export type OrderTimeInForce = 'normal' | 'post_only' | 'fok' | 'ioc';
export interface GetHistoricTradesParams {
symbol: string;
limit?: string;
tradeId?: string;
startTime?: string;
endTime?: string;
}
/**
* The margin type, used directly in building the endpoint URL
*/
export type MarginType = 'crossed' | 'isolated';
export type FuturesProductTypeV2 =
| 'USDT-FUTURES'
| 'COIN-FUTURES'
| 'USDC-FUTURES'
| 'SUSDT-FUTURES'
| 'SCOIN-FUTURES'
| 'SUSDC-FUTURES';
export type FuturesPlanTypeV2 =
| 'profit_plan'
| 'loss_plan'
| 'moving_plan'
| 'pos_profit'
| 'pos_loss';

View File

@@ -226,4 +226,4 @@ export interface HistoricPlanOrderTPSLRequest {
* @property {Array[5]} Base currency trading volume
* @property {Array[6]} Quote currency trading volume
*/
export type FuturesCandleData = string[6];
export type FuturesCandleData = string[6];

View File

@@ -3,23 +3,23 @@ import { OrderTimeInForce } from '../shared';
export type WalletType = 'spot' | 'mix_usdt' | 'mix_usd';
export type SpotKlineInterval =
| '1min'
| '5min'
| '15min'
| '30min'
| '1h'
| '4h'
| '6h'
| '12h'
| '1day'
| '3day'
| '1week'
| '1M'
| '6Hutc'
| '12Hutc'
| '1Dutc'
| '3Dutc'
| '1Wutc'
| '1min'
| '5min'
| '15min'
| '30min'
| '1h'
| '4h'
| '6h'
| '12h'
| '1day'
| '3day'
| '1week'
| '1M'
| '6Hutc'
| '12Hutc'
| '1Dutc'
| '3Dutc'
| '1Wutc'
| '1Mutc';
export interface NewWalletTransfer {
@@ -135,4 +135,4 @@ export interface SpotCandleData {
baseVol: string;
usdtVol: string;
ts: string;
}
}

View File

@@ -1,187 +1,187 @@
import { FuturesProductTypeV2, MarginType } from '../shared';
/**
*
* * Common | Notice
*
*/
export interface GetAnnouncementsRequestV2 {
annType?: string;
startTime?: string;
endTime?: string;
language: string;
}
/**
*
* * Common | Public
*
*/
export interface GetTradeRateRequestV2 {
symbol: string;
businessType: string;
}
/**
*
* * Common | Tax
*
*/
export interface GetSpotTransactionsRequestV2 {
coin?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
export interface GetFuturesTransactionsRequestV2 {
productType?: FuturesProductTypeV2;
marginCoin?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
export interface GetMarginTransactionsRequestV2 {
marginType?: MarginType;
coin?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
export interface GetP2PTransactionsRequestV2 {
coin?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
/**
*
* * Common | P2P
*
*/
export interface GetP2PMerchantsRequestV2 {
online?: 'yes' | 'no';
idLessThan?: string;
limit?: string;
}
export interface GetMerchantP2POrdersRequestV2 {
startTime: string;
endTime?: string;
idLessThan?: string;
limit?: string;
status?: string;
advNo: string;
side?: string;
coin?: string;
language: string;
fiat?: string;
orderNo?: string;
}
export interface GetMerchantAdvertisementsRequestV2 {
startTime: string;
endTime?: string;
idLessThan?: string;
limit?: string;
status: string;
advNo?: string;
side: string;
coin: string;
language?: string;
fiat: string;
orderBy?: string;
payMethodId?: string;
sourceType?: string;
}
/**
*
* * Common | Virtual Subaccount
*
*/
export interface ModifyVirtualSubRequestV2 {
subAccountUid: string;
permList: string[];
status: string;
}
export interface CreateVirtualSubRequestV2 {
subAccountName: string;
passphrase: string;
label: string;
ipList?: string[];
permList?: string[];
}
export interface CreateVirtualSubApiKeyRequestV2 {
subAccountUid: string;
passphrase: string;
label: string;
ipList?: string[];
permList?: string[];
}
export interface ModifyVirtualSubApiKeyRequestV2 {
subAccountUid: string;
subAccountApiKey: string;
passphrase: string;
label: string;
ipList?: string[];
permList?: string[];
}
/**
*
* * Common | Convert
*
*/
export interface ConvertQuoteRequestV2 {
fromCoin: string;
fromCoinSize?: string;
toCoin: string;
toCoinSize?: string;
}
export interface ConvertRequestV2 {
fromCoin: string;
fromCoinSize: string;
cnvtPrice: string;
toCoin: string;
toCoinSize: string;
traceId: string;
}
export interface GetConvertHistoryRequestV2 {
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
/**
*
* * Common | BGB Convert
*
*/
export interface GetConvertBGBHistoryRequestV2 {
orderId?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
import { FuturesProductTypeV2, MarginType } from '../shared';
/**
*
* * Common | Notice
*
*/
export interface GetAnnouncementsRequestV2 {
annType?: string;
startTime?: string;
endTime?: string;
language: string;
}
/**
*
* * Common | Public
*
*/
export interface GetTradeRateRequestV2 {
symbol: string;
businessType: string;
}
/**
*
* * Common | Tax
*
*/
export interface GetSpotTransactionsRequestV2 {
coin?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
export interface GetFuturesTransactionsRequestV2 {
productType?: FuturesProductTypeV2;
marginCoin?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
export interface GetMarginTransactionsRequestV2 {
marginType?: MarginType;
coin?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
export interface GetP2PTransactionsRequestV2 {
coin?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
/**
*
* * Common | P2P
*
*/
export interface GetP2PMerchantsRequestV2 {
online?: 'yes' | 'no';
idLessThan?: string;
limit?: string;
}
export interface GetMerchantP2POrdersRequestV2 {
startTime: string;
endTime?: string;
idLessThan?: string;
limit?: string;
status?: string;
advNo: string;
side?: string;
coin?: string;
language: string;
fiat?: string;
orderNo?: string;
}
export interface GetMerchantAdvertisementsRequestV2 {
startTime: string;
endTime?: string;
idLessThan?: string;
limit?: string;
status: string;
advNo?: string;
side: string;
coin: string;
language?: string;
fiat: string;
orderBy?: string;
payMethodId?: string;
sourceType?: string;
}
/**
*
* * Common | Virtual Subaccount
*
*/
export interface ModifyVirtualSubRequestV2 {
subAccountUid: string;
permList: string[];
status: string;
}
export interface CreateVirtualSubRequestV2 {
subAccountName: string;
passphrase: string;
label: string;
ipList?: string[];
permList?: string[];
}
export interface CreateVirtualSubApiKeyRequestV2 {
subAccountUid: string;
passphrase: string;
label: string;
ipList?: string[];
permList?: string[];
}
export interface ModifyVirtualSubApiKeyRequestV2 {
subAccountUid: string;
subAccountApiKey: string;
passphrase: string;
label: string;
ipList?: string[];
permList?: string[];
}
/**
*
* * Common | Convert
*
*/
export interface ConvertQuoteRequestV2 {
fromCoin: string;
fromCoinSize?: string;
toCoin: string;
toCoinSize?: string;
}
export interface ConvertRequestV2 {
fromCoin: string;
fromCoinSize: string;
cnvtPrice: string;
toCoin: string;
toCoinSize: string;
traceId: string;
}
export interface GetConvertHistoryRequestV2 {
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}
/**
*
* * Common | BGB Convert
*
*/
export interface GetConvertBGBHistoryRequestV2 {
orderId?: string;
startTime: string;
endTime: string;
limit?: string;
idLessThan?: string;
}

View File

@@ -1,351 +1,351 @@
type SpotKlineIntervalV2 =
| '1min'
| '5min'
| '15min'
| '30min'
| '1h'
| '4h'
| '6h'
| '12h'
| '1day'
| '3day'
| '1week'
| '1M'
| '6Hutc'
| '12Hutc'
| '1Dutc'
| '3Dutc'
| '1Wutc'
| '1Mutc';
export interface SpotCandlesRequestV2 {
symbol: string;
granularity: SpotKlineIntervalV2;
startTime?: string;
endTime?: string;
limit?: string;
}
export interface SpotHistoricCandlesRequestV2 {
symbol: string;
granularity: SpotKlineIntervalV2;
endTime?: string;
limit?: string;
}
export interface SpotHistoricTradesRequestV2 {
symbol: string;
limit?: string;
idLessThan?: string;
startTime?: string;
endTime?: string;
}
/**
*
* * Spot | Trade
*
*/
export type SpotOrderSideV2 = 'buy' | 'sell';
export type SpotOrderTypeV2 = 'limit' | 'market';
export type SpotOrderForceV2 = 'gtc' | 'post_only' | 'fok' | 'ioc';
export type SpotTPSLTypeV2 = 'normal' | 'tpsl';
export type SpotSTPModeV2 =
| 'none'
| 'cancel_taker'
| 'cancel_maker'
| 'cancel_both';
export type SpotBatchModeV2 = 'single' | 'multiple';
export interface SpotOrderRequestV2 {
symbol: string;
side: SpotOrderSideV2;
orderType: SpotOrderTypeV2;
force: SpotOrderForceV2;
price?: string;
size: string;
clientOid?: string;
triggerPrice?: string;
tpslType?: SpotTPSLTypeV2;
requestTime?: string;
receiveWindow?: string;
stpMode?: SpotSTPModeV2;
presetTakeProfitPrice?: string;
executeTakeProfitPrice?: string;
presetStopLossPrice?: string;
executeStopLossPrice?: string;
}
export interface SpotCancelandSubmitOrderRequestV2 {
symbol: string;
price: string;
size: string;
orderId?: string;
clientOid?: string;
newClientOid?: string;
presetTakeProfitPrice?: string;
executeTakeProfitPrice?: string;
presetStopLossPrice?: string;
executeStopLossPrice?: string;
}
export interface SpotCancelOrderRequestV2 {
symbol: string;
tpslType?: SpotTPSLTypeV2;
orderId?: string;
clientOid?: string;
}
export interface SpotBatchOrderRequestItemV2 {
symbol?: string;
side: SpotOrderSideV2;
orderType: SpotOrderTypeV2;
force: SpotOrderForceV2;
price?: string;
size: string;
clientOid?: string;
stpMode?: SpotSTPModeV2;
presetTakeProfitPrice?: string;
executeTakeProfitPrice?: string;
presetStopLossPrice?: string;
executeStopLossPrice?: string;
}
export interface SpotBatchOrderRequestV2 {
symbol?: string;
batchMode?: SpotBatchModeV2;
orderList: SpotBatchOrderRequestItemV2[];
}
export interface SpotBatchCancelOrderRequestV2 {
symbol?: string;
batchMode?: SpotBatchModeV2;
orderList: {
symbol?: string;
orderId?: string;
clientOid?: string;
}[];
}
export interface GetSpotOrderInfoRequestV2 {
orderId?: string;
clientOid?: string;
requestTime?: string;
receiveWindow?: string;
}
export interface GetSpotOpenOrdersRequestV2 {
symbol?: string;
startTime?: string;
endTime?: string;
idLessThan?: string;
limit?: string;
orderId?: string;
tpslType?: SpotTPSLTypeV2;
requestTime?: string;
receiveWindow?: string;
}
export interface GetSpotHistoryOrdersRequestV2 {
symbol?: string;
startTime?: string;
endTime?: string;
idLessThan?: string;
limit?: string;
orderId?: string;
tpslType?: SpotTPSLTypeV2;
requestTime?: string;
receiveWindow?: string;
}
export interface GetSpotFillsRequestV2 {
symbol: string;
orderId?: string;
startTime?: string;
endTime?: string;
limit?: string;
idLessThan?: string;
}
/**
*
* * Spot | Trigger Orders
*
*/
export type SpotPlanTypeV2 = 'amount' | 'total';
export type SpotTriggerTypeV2 = 'fill_price' | 'mark_price';
export interface SpotPlanOrderRequestV2 {
symbol: string;
side: SpotOrderSideV2;
triggerPrice: string;
orderType: SpotOrderTypeV2;
executePrice?: string;
planType?: SpotPlanTypeV2;
size: string;
triggerType: SpotTriggerTypeV2;
clientOid?: string;
force?: SpotOrderForceV2;
stpMode?: SpotSTPModeV2;
}
export interface SpotModifyPlanOrderRequestV2 {
orderId?: string;
clientOid?: string;
triggerPrice: string;
orderType: SpotOrderTypeV2;
executePrice?: string;
size: string;
}
export interface GetSpotCurrentPlanOrdersRequestV2 {
symbol: string;
limit?: string;
idLessThan?: string;
startTime?: string;
endTime?: string;
}
export interface GetSpotHistoryPlanOrdersRequestV2 {
symbol: string;
startTime: string;
endTime: string;
limit?: string;
}
/**
*
* * Spot | Account
*
*/
export type SpotBillGroupTypeV2 =
| 'deposit'
| 'withdraw'
| 'transaction'
| 'transfer'
| 'other';
export type SpotBusinessTypeV2 =
| 'deposit'
| 'withdraw'
| 'buy'
| 'sell'
| 'deduction of handling fee'
| 'transfer-in'
| 'transfer-out'
| 'rebate rewards'
| 'airdrop rewards'
| 'USDT contract rewards'
| 'mix contract rewards'
| 'system lock'
| 'user lock';
export type SpotAccountTypeV2 =
| 'spot'
| 'p2p'
| 'coin_futures'
| 'usdt_futures'
| 'usdc_futures'
| 'crossed_margin'
| 'isolated_margin';
export interface GetSpotAccountBillsRequestV2 {
coin?: string;
groupType?: SpotBillGroupTypeV2;
businessType?: SpotBusinessTypeV2;
startTime?: string;
endTime?: string;
limit?: string;
idLessThan?: string;
}
export interface SpotTransferRequestV2 {
fromType: SpotAccountTypeV2;
toType: SpotAccountTypeV2;
amount: string;
coin: string;
symbol: string;
clientOid?: string;
}
export interface SpotSubAccountTransferRequestV2 {
fromType: SpotAccountTypeV2;
toType: SpotAccountTypeV2;
amount: string;
coin: string;
symbol?: string;
clientOid?: string;
fromUserId: string;
toUserId: string;
}
export interface SpotWithdrawalRequestV2 {
coin: string;
transferType: 'on_chain' | 'internal_transfer';
address: string;
chain?: string;
innerToType?: 'email' | 'mobile' | 'uid';
areaCode?: string;
tag?: string;
size: string;
remark?: string;
clientOid?: string;
}
export interface SpotMainSubTransferRecordRequestV2 {
coin?: string;
role?: 'initiator' | 'receiver';
subUid?: string;
startTime?: string;
endTime?: string;
clientOid?: string;
limit?: string;
idLessThan?: string;
}
export interface GetSpotTransferRecordRequestV2 {
coin: string;
fromType: SpotAccountTypeV2;
startTime?: string;
endTime?: string;
clientOid?: string;
limit?: string;
idLessThan?: string;
}
export interface GetSpotSubAccountDepositRecordRequestV2 {
subUid: string;
coin?: string;
startTime?: string;
endTime?: string;
idLessThan?: string;
limit?: string;
}
export interface GetSpotWithdrawalRecordRequestV2 {
coin?: string;
clientOid?: string;
startTime: string;
endTime: string;
idLessThan?: string;
orderId?: string;
limit?: string;
}
export interface GetSpotDepositRecordRequestV2 {
coin?: string;
orderId?: string;
startTime: string;
endTime: string;
idLessThan?: string;
limit?: string;
}
type SpotKlineIntervalV2 =
| '1min'
| '5min'
| '15min'
| '30min'
| '1h'
| '4h'
| '6h'
| '12h'
| '1day'
| '3day'
| '1week'
| '1M'
| '6Hutc'
| '12Hutc'
| '1Dutc'
| '3Dutc'
| '1Wutc'
| '1Mutc';
export interface SpotCandlesRequestV2 {
symbol: string;
granularity: SpotKlineIntervalV2;
startTime?: string;
endTime?: string;
limit?: string;
}
export interface SpotHistoricCandlesRequestV2 {
symbol: string;
granularity: SpotKlineIntervalV2;
endTime?: string;
limit?: string;
}
export interface SpotHistoricTradesRequestV2 {
symbol: string;
limit?: string;
idLessThan?: string;
startTime?: string;
endTime?: string;
}
/**
*
* * Spot | Trade
*
*/
export type SpotOrderSideV2 = 'buy' | 'sell';
export type SpotOrderTypeV2 = 'limit' | 'market';
export type SpotOrderForceV2 = 'gtc' | 'post_only' | 'fok' | 'ioc';
export type SpotTPSLTypeV2 = 'normal' | 'tpsl';
export type SpotSTPModeV2 =
| 'none'
| 'cancel_taker'
| 'cancel_maker'
| 'cancel_both';
export type SpotBatchModeV2 = 'single' | 'multiple';
export interface SpotOrderRequestV2 {
symbol: string;
side: SpotOrderSideV2;
orderType: SpotOrderTypeV2;
force: SpotOrderForceV2;
price?: string;
size: string;
clientOid?: string;
triggerPrice?: string;
tpslType?: SpotTPSLTypeV2;
requestTime?: string;
receiveWindow?: string;
stpMode?: SpotSTPModeV2;
presetTakeProfitPrice?: string;
executeTakeProfitPrice?: string;
presetStopLossPrice?: string;
executeStopLossPrice?: string;
}
export interface SpotCancelandSubmitOrderRequestV2 {
symbol: string;
price: string;
size: string;
orderId?: string;
clientOid?: string;
newClientOid?: string;
presetTakeProfitPrice?: string;
executeTakeProfitPrice?: string;
presetStopLossPrice?: string;
executeStopLossPrice?: string;
}
export interface SpotCancelOrderRequestV2 {
symbol: string;
tpslType?: SpotTPSLTypeV2;
orderId?: string;
clientOid?: string;
}
export interface SpotBatchOrderRequestItemV2 {
symbol?: string;
side: SpotOrderSideV2;
orderType: SpotOrderTypeV2;
force: SpotOrderForceV2;
price?: string;
size: string;
clientOid?: string;
stpMode?: SpotSTPModeV2;
presetTakeProfitPrice?: string;
executeTakeProfitPrice?: string;
presetStopLossPrice?: string;
executeStopLossPrice?: string;
}
export interface SpotBatchOrderRequestV2 {
symbol?: string;
batchMode?: SpotBatchModeV2;
orderList: SpotBatchOrderRequestItemV2[];
}
export interface SpotBatchCancelOrderRequestV2 {
symbol?: string;
batchMode?: SpotBatchModeV2;
orderList: {
symbol?: string;
orderId?: string;
clientOid?: string;
}[];
}
export interface GetSpotOrderInfoRequestV2 {
orderId?: string;
clientOid?: string;
requestTime?: string;
receiveWindow?: string;
}
export interface GetSpotOpenOrdersRequestV2 {
symbol?: string;
startTime?: string;
endTime?: string;
idLessThan?: string;
limit?: string;
orderId?: string;
tpslType?: SpotTPSLTypeV2;
requestTime?: string;
receiveWindow?: string;
}
export interface GetSpotHistoryOrdersRequestV2 {
symbol?: string;
startTime?: string;
endTime?: string;
idLessThan?: string;
limit?: string;
orderId?: string;
tpslType?: SpotTPSLTypeV2;
requestTime?: string;
receiveWindow?: string;
}
export interface GetSpotFillsRequestV2 {
symbol: string;
orderId?: string;
startTime?: string;
endTime?: string;
limit?: string;
idLessThan?: string;
}
/**
*
* * Spot | Trigger Orders
*
*/
export type SpotPlanTypeV2 = 'amount' | 'total';
export type SpotTriggerTypeV2 = 'fill_price' | 'mark_price';
export interface SpotPlanOrderRequestV2 {
symbol: string;
side: SpotOrderSideV2;
triggerPrice: string;
orderType: SpotOrderTypeV2;
executePrice?: string;
planType?: SpotPlanTypeV2;
size: string;
triggerType: SpotTriggerTypeV2;
clientOid?: string;
force?: SpotOrderForceV2;
stpMode?: SpotSTPModeV2;
}
export interface SpotModifyPlanOrderRequestV2 {
orderId?: string;
clientOid?: string;
triggerPrice: string;
orderType: SpotOrderTypeV2;
executePrice?: string;
size: string;
}
export interface GetSpotCurrentPlanOrdersRequestV2 {
symbol: string;
limit?: string;
idLessThan?: string;
startTime?: string;
endTime?: string;
}
export interface GetSpotHistoryPlanOrdersRequestV2 {
symbol: string;
startTime: string;
endTime: string;
limit?: string;
}
/**
*
* * Spot | Account
*
*/
export type SpotBillGroupTypeV2 =
| 'deposit'
| 'withdraw'
| 'transaction'
| 'transfer'
| 'other';
export type SpotBusinessTypeV2 =
| 'deposit'
| 'withdraw'
| 'buy'
| 'sell'
| 'deduction of handling fee'
| 'transfer-in'
| 'transfer-out'
| 'rebate rewards'
| 'airdrop rewards'
| 'USDT contract rewards'
| 'mix contract rewards'
| 'system lock'
| 'user lock';
export type SpotAccountTypeV2 =
| 'spot'
| 'p2p'
| 'coin_futures'
| 'usdt_futures'
| 'usdc_futures'
| 'crossed_margin'
| 'isolated_margin';
export interface GetSpotAccountBillsRequestV2 {
coin?: string;
groupType?: SpotBillGroupTypeV2;
businessType?: SpotBusinessTypeV2;
startTime?: string;
endTime?: string;
limit?: string;
idLessThan?: string;
}
export interface SpotTransferRequestV2 {
fromType: SpotAccountTypeV2;
toType: SpotAccountTypeV2;
amount: string;
coin: string;
symbol: string;
clientOid?: string;
}
export interface SpotSubAccountTransferRequestV2 {
fromType: SpotAccountTypeV2;
toType: SpotAccountTypeV2;
amount: string;
coin: string;
symbol?: string;
clientOid?: string;
fromUserId: string;
toUserId: string;
}
export interface SpotWithdrawalRequestV2 {
coin: string;
transferType: 'on_chain' | 'internal_transfer';
address: string;
chain?: string;
innerToType?: 'email' | 'mobile' | 'uid';
areaCode?: string;
tag?: string;
size: string;
remark?: string;
clientOid?: string;
}
export interface SpotMainSubTransferRecordRequestV2 {
coin?: string;
role?: 'initiator' | 'receiver';
subUid?: string;
startTime?: string;
endTime?: string;
clientOid?: string;
limit?: string;
idLessThan?: string;
}
export interface GetSpotTransferRecordRequestV2 {
coin: string;
fromType: SpotAccountTypeV2;
startTime?: string;
endTime?: string;
clientOid?: string;
limit?: string;
idLessThan?: string;
}
export interface GetSpotSubAccountDepositRecordRequestV2 {
subUid: string;
coin?: string;
startTime?: string;
endTime?: string;
idLessThan?: string;
limit?: string;
}
export interface GetSpotWithdrawalRecordRequestV2 {
coin?: string;
clientOid?: string;
startTime: string;
endTime: string;
idLessThan?: string;
orderId?: string;
limit?: string;
}
export interface GetSpotDepositRecordRequestV2 {
coin?: string;
orderId?: string;
startTime: string;
endTime: string;
idLessThan?: string;
limit?: string;
}

View File

@@ -1,3 +1,3 @@
export * from './futures';
export * from './shared';
export * from './spot';
export * from './futures';

View File

@@ -27,4 +27,4 @@ export type KlineInterval =
| '1Mutc';
export type RestClientType =
typeof REST_CLIENT_TYPE_ENUM[keyof typeof REST_CLIENT_TYPE_ENUM];
(typeof REST_CLIENT_TYPE_ENUM)[keyof typeof REST_CLIENT_TYPE_ENUM];

View File

@@ -28,15 +28,6 @@ export interface WsSnapshotPositionsEvent extends WsBaseEvent<'snapshot'> {
};
}
export interface WsAccountSnapshotUMCBL extends WsBaseEvent<'snapshot'> {
arg: {
instType: 'umcbl';
channel: 'account';
instId: string;
};
data: WsAccountSnapshotDataUMCBL[];
}
export interface WsAccountSnapshotDataUMCBL {
marginCoin: string;
locked: string;
@@ -47,13 +38,13 @@ export interface WsAccountSnapshotDataUMCBL {
usdtEquity: string;
}
export interface WSPositionSnapshotUMCBL extends WsBaseEvent<'snapshot'> {
export interface WsAccountSnapshotUMCBL extends WsBaseEvent<'snapshot'> {
arg: {
instType: 'umcbl';
channel: 'positions';
channel: 'account';
instId: string;
};
data: WsPositionSnapshotDataUMCBL[];
data: WsAccountSnapshotDataUMCBL[];
}
export interface WsPositionSnapshotDataUMCBL {
@@ -80,3 +71,12 @@ export interface WsPositionSnapshotDataUMCBL {
uTime: string;
markPrice: string;
}
export interface WSPositionSnapshotUMCBL extends WsBaseEvent<'snapshot'> {
arg: {
instType: 'umcbl';
channel: 'positions';
instId: string;
};
data: WsPositionSnapshotDataUMCBL[];
}

View File

@@ -1,15 +1,15 @@
import axios, { AxiosRequestConfig, AxiosResponse, Method } from 'axios';
import { RestClientType } from '../types';
import { RestClientType } from '../types';
import { signMessage } from './node-support';
import {
getRestBaseUrl,
RestClientOptions,
serializeParams,
getRestBaseUrl,
} from './requestUtils';
import { neverGuard } from './websocket-util';
interface SignedRequest<T extends object | undefined = {}> {
interface SignedRequest<T extends object | undefined = object> {
originalParams: T;
paramsWithSign?: T & { sign: string };
serializedParams: string;
@@ -19,7 +19,7 @@ interface SignedRequest<T extends object | undefined = {}> {
recvWindow: number;
}
interface UnsignedRequest<T extends object | undefined = {}> {
interface UnsignedRequest<T extends object | undefined = object> {
originalParams: T;
paramsWithSign: T;
}
@@ -70,10 +70,15 @@ if (ENABLE_HTTP_TRACE) {
export default abstract class BaseRestClient {
private options: RestClientOptions;
private baseUrl: string;
private globalRequestOptions: AxiosRequestConfig;
private apiKey: string | undefined;
private apiSecret: string | undefined;
private apiPass: string | undefined;
/** Defines the client type (affecting how requests & signatures behave) */
@@ -229,7 +234,7 @@ export default abstract class BaseRestClient {
/**
* @private sign request and set recv window
*/
private async signRequest<T extends object | undefined = {}>(
private async signRequest<T extends object | undefined = object>(
data: T,
endpoint: string,
method: Method,
@@ -292,6 +297,7 @@ export default abstract class BaseRestClient {
params?: TParams,
isPublicApi?: true,
): Promise<UnsignedRequest<TParams>>;
private async prepareSignParams<TParams extends object | undefined>(
method: Method,
endpoint: string,
@@ -299,6 +305,7 @@ export default abstract class BaseRestClient {
params?: TParams,
isPublicApi?: false | undefined,
): Promise<SignedRequest<TParams>>;
private async prepareSignParams<TParams extends object | undefined>(
method: Method,
endpoint: string,

View File

@@ -1,12 +1,16 @@
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
import EventEmitter from 'events';
import WebSocket from 'isomorphic-ws';
import { WebsocketClientOptions, WSClientConfigurableOptions } from '../types';
import WsStore from './WsStore';
import { WsConnectionStateEnum } from './WsStore.types';
import {
WebsocketClientOptions,
WSClientConfigurableOptions,
} from '../types/index';
import { DefaultLogger } from './logger';
import { isWsPong } from './requestUtils';
import { getWsAuthSignature } from './websocket-util';
import WsStore from './WsStore';
import { WsConnectionStateEnum } from './WsStore.types';
interface WSClientEventMap<WsKey extends string> {
/** Connection opened. If this connection was previously opened and reconnected, expect the reconnected event instead */
@@ -30,6 +34,7 @@ interface WSClientEventMap<WsKey extends string> {
// Type safety for on and emit handlers: https://stackoverflow.com/a/61609010/880837
export interface BaseWebsocketClient<
TWSKey extends string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
TWSTopicSubscribeEventArgs extends object,
> {
on<U extends keyof WSClientEventMap<TWSKey>>(
@@ -43,8 +48,6 @@ export interface BaseWebsocketClient<
): boolean;
}
export interface BaseWSClientImpl {}
const LOGGER_CATEGORY = { category: 'bitget-ws' };
export abstract class BaseWebsocketClient<
@@ -54,6 +57,7 @@ export abstract class BaseWebsocketClient<
private wsStore: WsStore<TWSKey, TWSTopicSubscribeEventArgs>;
protected logger: typeof DefaultLogger;
protected options: WebsocketClientOptions;
constructor(
@@ -84,7 +88,9 @@ export abstract class BaseWebsocketClient<
): boolean;
protected abstract shouldAuthOnConnect(wsKey: TWSKey): boolean;
protected abstract getWsUrl(wsKey: TWSKey): string;
protected abstract getMaxTopicsPerSubscribeEvent(
wsKey: TWSKey,
): number | null;
@@ -277,7 +283,7 @@ export abstract class BaseWebsocketClient<
recvWindow,
);
this.logger.info(`Sending auth request...`, {
this.logger.info('Sending auth request...', {
...LOGGER_CATEGORY,
wsKey,
});
@@ -382,7 +388,7 @@ export abstract class BaseWebsocketClient<
this.logger.silly(
`Subscribing to topics in batches of ${maxTopicsPerEvent}`,
);
for (var i = 0; i < topics.length; i += maxTopicsPerEvent) {
for (let i = 0; i < topics.length; i += maxTopicsPerEvent) {
const batch = topics.slice(i, i + maxTopicsPerEvent);
this.logger.silly(`Subscribing to batch of ${batch.length}`);
this.requestSubscribeTopics(wsKey, batch);
@@ -417,7 +423,7 @@ export abstract class BaseWebsocketClient<
this.logger.silly(
`Unsubscribing to topics in batches of ${maxTopicsPerEvent}`,
);
for (var i = 0; i < topics.length; i += maxTopicsPerEvent) {
for (let i = 0; i < topics.length; i += maxTopicsPerEvent) {
const batch = topics.slice(i, i + maxTopicsPerEvent);
this.logger.silly(`Unsubscribing to batch of ${batch.length}`);
this.requestUnsubscribeTopics(wsKey, batch);
@@ -438,7 +444,7 @@ export abstract class BaseWebsocketClient<
public tryWsSend(wsKey: TWSKey, wsMessage: string) {
try {
this.logger.silly(`Sending upstream ws message: `, {
this.logger.silly('Sending upstream ws message: ', {
...LOGGER_CATEGORY,
wsMessage,
wsKey,
@@ -456,7 +462,7 @@ export abstract class BaseWebsocketClient<
}
ws.send(wsMessage);
} catch (e) {
this.logger.error(`Failed to send WS message`, {
this.logger.error('Failed to send WS message', {
...LOGGER_CATEGORY,
wsMessage,
wsKey,
@@ -549,7 +555,7 @@ export abstract class BaseWebsocketClient<
if (typeof msg === 'object') {
if (typeof msg['code'] === 'number') {
if (msg.event === 'login' && msg.code === 0) {
this.logger.info(`Successfully authenticated WS client`, {
this.logger.info('Successfully authenticated WS client', {
...LOGGER_CATEGORY,
wsKey,
});
@@ -562,7 +568,7 @@ export abstract class BaseWebsocketClient<
if (msg['event']) {
if (msg.event === 'error') {
this.logger.error(`WS Error received`, {
this.logger.error('WS Error received', {
...LOGGER_CATEGORY,
wsKey,
message: msg || 'no message',

View File

@@ -1,4 +1,5 @@
import WebSocket from 'isomorphic-ws';
import { DefaultLogger } from './logger';
import { WsConnectionStateEnum, WsStoredState } from './WsStore.types';
@@ -17,6 +18,7 @@ export default class WsStore<
> {
private wsState: Record<string, WsStoredState<TWSTopicSubscribeEventArgs>> =
{};
private logger: typeof DefaultLogger;
constructor(logger: typeof DefaultLogger) {
@@ -28,10 +30,12 @@ export default class WsStore<
key: WsKey,
createIfMissing?: true,
): WsStoredState<TWSTopicSubscribeEventArgs>;
get(
key: WsKey,
createIfMissing?: false,
): WsStoredState<TWSTopicSubscribeEventArgs> | undefined;
get(
key: WsKey,
createIfMissing?: boolean,

View File

@@ -40,6 +40,7 @@ export async function signMessage(
return _arrayBufferToBase64(signature);
}
default: {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
((x: never) => {})(method);
throw new Error(`Unhandled sign method: ${method}`);
}

View File

@@ -1,6 +1,6 @@
export * from './BaseRestClient';
export * from './requestUtils';
export * from './WsStore';
export * from './logger';
export * from './requestUtils';
export * from './type-guards';
export * from './websocket-util';
export * from './WsStore';

View File

@@ -1,6 +1,7 @@
export type LogParams = null | any;
export const DefaultLogger = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
silly: (...params: LogParams): void => {
// console.log(params);
},

View File

@@ -16,6 +16,7 @@ export async function signMessage(
return hmac.digest().toString('base64');
}
default: {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
((x: never) => {})(method);
throw new Error(`Unhandled sign method: ${method}`);
}

View File

@@ -34,7 +34,7 @@ export interface RestClientOptions {
parseExceptions?: boolean;
}
export function serializeParams<T extends object | undefined = {}>(
export function serializeParams<T extends object | undefined = object>(
params: T,
strict_validation = false,
encodeValues: boolean = true,

View File

@@ -78,7 +78,7 @@ export function isWsFuturesPositionsSnapshotEvent(
*/
export function assertMarginType(marginType: string): marginType is MarginType {
if (marginType !== 'isolated' && marginType !== 'crossed') {
throw new Error(`MarginType should be one of: crossed | isolated`);
throw new Error('MarginType should be one of: crossed | isolated');
}
return true;
}

View File

@@ -95,6 +95,7 @@ export function isPrivateChannel<TChannel extends string>(
export function getWsKeyForTopic(
subscribeEvent: WsTopicSubscribeEventArgs,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
isPrivate?: boolean,
): WsKey {
const instType = subscribeEvent.instType.toUpperCase() as BitgetInstType;
@@ -137,7 +138,7 @@ export function getMaxTopicsPerSubscribeEvent(wsKey: WsKey): number | null {
return 15;
}
default: {
throw neverGuard(wsKey, `getWsKeyForTopic(): Unhandled wsKey`);
throw neverGuard(wsKey, 'getWsKeyForTopic(): Unhandled wsKey');
}
}
}
@@ -161,7 +162,7 @@ export async function getWsAuthSignature(
}> {
if (!apiKey || !apiSecret || !apiPass) {
throw new Error(
`Cannot auth - missing api key, secret or passcode in config`,
'Cannot auth - missing api key, secret or passcode in config',
);
}
const signatureExpiresAt = ((Date.now() + recvWindow) / 1000).toFixed(0);

View File

@@ -12,17 +12,15 @@ import {
WsTopicSubscribePrivateInstIdArgsV2,
WsTopicV2,
} from './types';
import {
WS_AUTH_ON_CONNECT_KEYS,
WS_KEY_MAP,
DefaultLogger,
WS_BASE_URL_MAP,
neverGuard,
getMaxTopicsPerSubscribeEvent,
isPrivateChannel,
neverGuard,
WS_AUTH_ON_CONNECT_KEYS,
WS_BASE_URL_MAP,
WS_KEY_MAP,
} from './util';
import { BaseWebsocketClient } from './util/BaseWSClient';
const LOGGER_CATEGORY = { category: 'bitget-ws' };
@@ -38,6 +36,7 @@ export class WebsocketClientV2 extends BaseWebsocketClient<
WsTopicSubscribeEventArgsV2
> {
protected logger: typeof DefaultLogger;
protected options: WebsocketClientOptions;
protected getWsKeyForTopic(
@@ -70,7 +69,7 @@ export class WebsocketClientV2 extends BaseWebsocketClient<
case WS_KEY_MAP.spotv1:
case WS_KEY_MAP.mixv1: {
throw new Error(
`Use the WebsocketClient instead of WebsocketClientV2 for V1 websockets`,
'Use the WebsocketClient instead of WebsocketClientV2 for V1 websockets',
);
}
case WS_KEY_MAP.v2Private: {
@@ -84,7 +83,7 @@ export class WebsocketClientV2 extends BaseWebsocketClient<
...LOGGER_CATEGORY,
wsKey,
});
throw neverGuard(wsKey, `getWsUrl(): Unhandled wsKey`);
throw neverGuard(wsKey, 'getWsUrl(): Unhandled wsKey');
}
}
}

View File

@@ -1,8 +1,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
import { EventEmitter } from 'events';
import WebSocket from 'isomorphic-ws';
import WsStore from './util/WsStore';
import {
BitgetInstType,
WebsocketClientOptions,
@@ -11,19 +10,19 @@ import {
WsTopic,
WsTopicSubscribeEventArgs,
} from './types';
import {
isWsPong,
WS_AUTH_ON_CONNECT_KEYS,
WS_KEY_MAP,
DefaultLogger,
WS_BASE_URL_MAP,
getWsKeyForTopic,
neverGuard,
getMaxTopicsPerSubscribeEvent,
isPrivateChannel,
getWsAuthSignature,
getWsKeyForTopic,
isPrivateChannel,
isWsPong,
neverGuard,
WS_AUTH_ON_CONNECT_KEYS,
WS_BASE_URL_MAP,
WS_KEY_MAP,
} from './util';
import WsStore from './util/WsStore';
import { WsConnectionStateEnum } from './util/WsStore.types';
const LOGGER_CATEGORY = { category: 'bitget-ws' };
@@ -74,7 +73,9 @@ export declare interface WebsocketClient {
*/
export class WebsocketClient extends EventEmitter {
private logger: typeof DefaultLogger;
private options: WebsocketClientOptions;
private wsStore: WsStore<WsKey, WsTopicSubscribeEventArgs>;
constructor(
@@ -145,6 +146,7 @@ export class WebsocketClient extends EventEmitter {
}
});
}
/**
* Unsubscribe from topics & remove them from memory. They won't be re-subscribed to if the connection reconnects.
* @param wsTopics topic or list of topics
@@ -282,7 +284,7 @@ export class WebsocketClient extends EventEmitter {
recvWindow,
);
this.logger.info(`Sending auth request...`, {
this.logger.info('Sending auth request...', {
...LOGGER_CATEGORY,
wsKey,
});
@@ -387,7 +389,7 @@ export class WebsocketClient extends EventEmitter {
this.logger.silly(
`Subscribing to topics in batches of ${maxTopicsPerEvent}`,
);
for (var i = 0; i < topics.length; i += maxTopicsPerEvent) {
for (let i = 0; i < topics.length; i += maxTopicsPerEvent) {
const batch = topics.slice(i, i + maxTopicsPerEvent);
this.logger.silly(`Subscribing to batch of ${batch.length}`);
this.requestSubscribeTopics(wsKey, batch);
@@ -422,7 +424,7 @@ export class WebsocketClient extends EventEmitter {
this.logger.silly(
`Unsubscribing to topics in batches of ${maxTopicsPerEvent}`,
);
for (var i = 0; i < topics.length; i += maxTopicsPerEvent) {
for (let i = 0; i < topics.length; i += maxTopicsPerEvent) {
const batch = topics.slice(i, i + maxTopicsPerEvent);
this.logger.silly(`Unsubscribing to batch of ${batch.length}`);
this.requestUnsubscribeTopics(wsKey, batch);
@@ -443,7 +445,7 @@ export class WebsocketClient extends EventEmitter {
public tryWsSend(wsKey: WsKey, wsMessage: string) {
try {
this.logger.silly(`Sending upstream ws message: `, {
this.logger.silly('Sending upstream ws message: ', {
...LOGGER_CATEGORY,
wsMessage,
wsKey,
@@ -461,7 +463,7 @@ export class WebsocketClient extends EventEmitter {
}
ws.send(wsMessage);
} catch (e) {
this.logger.error(`Failed to send WS message`, {
this.logger.error('Failed to send WS message', {
...LOGGER_CATEGORY,
wsMessage,
wsKey,
@@ -554,7 +556,7 @@ export class WebsocketClient extends EventEmitter {
if (typeof msg === 'object') {
if (typeof msg['code'] === 'number') {
if (msg.event === 'login' && msg.code === 0) {
this.logger.info(`Successfully authenticated WS client`, {
this.logger.info('Successfully authenticated WS client', {
...LOGGER_CATEGORY,
wsKey,
});
@@ -567,7 +569,7 @@ export class WebsocketClient extends EventEmitter {
if (msg['event']) {
if (msg.event === 'error') {
this.logger.error(`WS Error received`, {
this.logger.error('WS Error received', {
...LOGGER_CATEGORY,
wsKey,
message: msg || 'no message',
@@ -649,14 +651,14 @@ export class WebsocketClient extends EventEmitter {
}
case WS_KEY_MAP.v2Private:
case WS_KEY_MAP.v2Public: {
throw new Error(`Use the WebsocketClientV2 for V2 websockets`);
throw new Error('Use the WebsocketClientV2 for V2 websockets');
}
default: {
this.logger.error('getWsUrl(): Unhandled wsKey: ', {
...LOGGER_CATEGORY,
wsKey,
});
throw neverGuard(wsKey, `getWsUrl(): Unhandled wsKey`);
throw neverGuard(wsKey, 'getWsUrl(): Unhandled wsKey');
}
}
}

View File

@@ -20,9 +20,9 @@ describe('Private Broker REST API GET Endpoints', () => {
const coin = 'BTC';
const subUid = '123456';
const timestampOneHourAgo = new Date().getTime() - 1000 * 60 * 60;
const from = timestampOneHourAgo.toFixed(0);
const to = String(Number(from) + 1000 * 60 * 30); // 30 minutes
// const timestampOneHourAgo = new Date().getTime() - 1000 * 60 * 60;
// const from = timestampOneHourAgo.toFixed(0);
// const to = String(Number(from) + 1000 * 60 * 30); // 30 minutes
it('getBrokerInfo()', async () => {
try {

View File

@@ -18,11 +18,11 @@ describe('Private Broker REST API POST Endpoints', () => {
apiPass: API_PASS,
});
const coin = 'BTC';
// const coin = 'BTC';
const subUid = '123456';
const timestampOneHourAgo = new Date().getTime() - 1000 * 60 * 60;
const from = timestampOneHourAgo.toFixed(0);
const to = String(Number(from) + 1000 * 60 * 30); // 30 minutes
// const timestampOneHourAgo = new Date().getTime() - 1000 * 60 * 60;
// const from = timestampOneHourAgo.toFixed(0);
// const to = String(Number(from) + 1000 * 60 * 30); // 30 minutes
it('createSubAccount()', async () => {
try {

View File

@@ -22,9 +22,9 @@ describe('Private Futures REST API POST Endpoints', () => {
const symbol = 'BTCUSDT_UMCBL';
const marginCoin = 'USDT';
const timestampOneHourAgo = new Date().getTime() - 1000 * 60 * 60;
const from = timestampOneHourAgo.toFixed(0);
const to = String(Number(from) + 1000 * 60 * 30); // 30 minutes
// const timestampOneHourAgo = new Date().getTime() - 1000 * 60 * 60;
// const from = timestampOneHourAgo.toFixed(0);
// const to = String(Number(from) + 1000 * 60 * 30); // 30 minutes
it('setLeverage()', async () => {
try {

View File

@@ -1,9 +1,5 @@
import { API_ERROR_CODE, FuturesClient } from '../../src';
import {
notAuthenticatedError,
successResponseString,
sucessEmptyResponseObject,
} from '../response.util';
import { FuturesClient } from '../../src';
import { sucessEmptyResponseObject } from '../response.util';
describe('Public Spot REST API Endpoints', () => {
const api = new FuturesClient();

View File

@@ -1,4 +1,4 @@
import { API_ERROR_CODE, SpotClient } from '../../src';
import { SpotClient } from '../../src';
import { sucessEmptyResponseObject } from '../response.util';
describe('Private Spot REST API GET Endpoints', () => {

View File

@@ -1,6 +1,5 @@
import { API_ERROR_CODE, SpotClient } from '../../src';
import { SpotClient } from '../../src';
import {
notAuthenticatedError,
successResponseString,
sucessEmptyResponseObject,
} from '../response.util';
@@ -9,8 +8,6 @@ describe('Public Spot REST API Endpoints', () => {
const api = new SpotClient();
const symbol = 'BTCUSDT_SPBL';
const timestampOneHourAgo = new Date().getTime() / 1000 - 1000 * 60 * 60;
const from = Number(timestampOneHourAgo.toFixed(0));
// it('should throw for unauthenticated private calls', async () => {
// expect(() => api.getOpenOrders()).rejects.toMatchObject(

View File

@@ -1,15 +1,10 @@
import {
WebsocketClient,
WSClientConfigurableOptions,
WS_ERROR_ENUM,
WS_KEY_MAP,
WSClientConfigurableOptions,
} from '../src';
import {
getSilentLogger,
listenToSocketEvents,
logAllEvents,
waitForSocketEvent,
} from './ws.util';
import { getSilentLogger, logAllEvents, waitForSocketEvent } from './ws.util';
describe.skip('Private Spot Websocket Client', () => {
const API_KEY = process.env.API_KEY_COM;
@@ -50,7 +45,7 @@ describe.skip('Private Spot Websocket Client', () => {
try {
await Promise.all([wsResponsePromise]);
} catch (e) {
// console.error()
console.error(e);
}
badClient.closeAll();
});

View File

@@ -1,9 +1,9 @@
import {
WebsocketClient,
WSClientConfigurableOptions,
WS_KEY_MAP,
WSClientConfigurableOptions,
} from '../src';
import { logAllEvents, getSilentLogger, waitForSocketEvent } from './ws.util';
import { getSilentLogger, logAllEvents, waitForSocketEvent } from './ws.util';
describe('Public Spot Websocket Client', () => {
let wsClient: WebsocketClient;

View File

@@ -1,5 +1,7 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { WebsocketClient } from '../src';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function getSilentLogger(logHint?: string) {
return {
silly: () => {},

18
tsconfig.linting.json Normal file
View File

@@ -0,0 +1,18 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "dist/cjs",
"target": "esnext",
"rootDir": "../",
"allowJs": true
},
"include": [
"src/**/*.*",
"test/**/*.*",
"examples/**/*.*",
".eslintrc.cjs",
"jest.config.ts",
"webpack/webpack.config.ts"
]
}

View File

@@ -1,6 +1,6 @@
const webpack = require('webpack');
const path = require('path');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const BundleAnalyzerPlugin =
require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
function generateConfig(name) {
var config = {
@@ -10,27 +10,29 @@ function generateConfig(name) {
filename: name + '.js',
sourceMapFilename: name + '.map',
library: name,
libraryTarget: 'umd'
libraryTarget: 'umd',
},
devtool: "source-map",
devtool: 'source-map',
mode: 'production',
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js"],
extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js'],
alias: {
[path.resolve(__dirname, "../lib/util/node-support.js")]:
path.resolve(__dirname, "../lib/util/browser-support.js"),
}
[path.resolve(__dirname, '../lib/util/node-support.js')]: path.resolve(
__dirname,
'../lib/util/browser-support.js',
),
},
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
{ test: /\.tsx?$/, loader: "ts-loader" },
{ test: /\.tsx?$/, loader: 'ts-loader' },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ test: /\.js$/, loader: "source-map-loader" },
{ test: /\.js$/, loader: 'source-map-loader' },
{
test: /\.m?js$/,
@@ -38,28 +40,30 @@ function generateConfig(name) {
use: {
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', {
'targets': {
'node': 'current'
}
}]]
}
}
}
]
}
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
},
},
},
],
},
};
config.plugins = [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}),
new BundleAnalyzerPlugin({
defaultSizes: 'stat',
analyzerMode: 'static',
reportFilename: '../doc/bundleReport.html',
openAnalyzer: false,
})
}),
];
return config;