From 923b1b02e01de96d84c3b34d2f931c4cfc2a6e25 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 22 Dec 2023 10:53:22 +0000 Subject: [PATCH 1/9] feat(): safer websocket timer cleanup --- src/websocket-client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/websocket-client.ts b/src/websocket-client.ts index ade0eeb0..e8f0d5e1 100644 --- a/src/websocket-client.ts +++ b/src/websocket-client.ts @@ -808,11 +808,11 @@ export class WebsocketClient extends EventEmitter { const wasOpen = this.wsStore.isWsOpen(wsKey); - this.getWs(wsKey)?.terminate(); - delete this.wsStore.get(wsKey, true).activePongTimer; this.clearPingTimer(wsKey); this.clearPongTimer(wsKey); + this.getWs(wsKey)?.terminate(); + if (!wasOpen) { this.logger.info( `${reason} - socket already closed - trigger immediate reconnect`, From 48eaa4785d10d04419ea42d13dca6881325fd910 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 22 Dec 2023 11:47:54 +0000 Subject: [PATCH 2/9] feat(#186): add proxy & rate limits example. Misc doc updates. --- README.md | 115 ++++++++++-------- examples/deprecated/README.md | 5 + .../{ => deprecated}/rest-contract-private.ts | 2 +- .../{ => deprecated}/rest-contract-public.js | 0 .../{ => deprecated}/rest-contract-public.ts | 2 +- .../{ => deprecated}/rest-copy-private.ts | 2 +- .../{ => deprecated}/rest-linear-public.ts | 2 +- examples/{ => deprecated}/rest-raw-v3sign.ts | 2 +- examples/{ => deprecated}/rest-spot-public.ts | 2 +- examples/{ => deprecated}/rest-spot-tpsl.ts | 6 +- .../rest-unified-margin-private-cursor.ts | 4 +- .../rest-unified-margin-public-cursor.ts | 2 +- .../ws-private-copytrading-v3.ts | 2 +- examples/{ => deprecated}/ws-private.ts | 2 +- examples/{ => deprecated}/ws-public.ts | 4 +- examples/rest-v5-proxies.ts | 66 ++++++++++ examples/rest-v5-public.ts | 66 ++++++++++ 17 files changed, 216 insertions(+), 68 deletions(-) create mode 100644 examples/deprecated/README.md rename examples/{ => deprecated}/rest-contract-private.ts (90%) rename examples/{ => deprecated}/rest-contract-public.js (100%) rename examples/{ => deprecated}/rest-contract-public.ts (91%) rename examples/{ => deprecated}/rest-copy-private.ts (90%) rename examples/{ => deprecated}/rest-linear-public.ts (90%) rename examples/{ => deprecated}/rest-raw-v3sign.ts (94%) rename examples/{ => deprecated}/rest-spot-public.ts (89%) rename examples/{ => deprecated}/rest-spot-tpsl.ts (92%) rename examples/{ => deprecated}/rest-unified-margin-private-cursor.ts (90%) rename examples/{ => deprecated}/rest-unified-margin-public-cursor.ts (94%) rename examples/{ => deprecated}/ws-private-copytrading-v3.ts (95%) rename examples/{ => deprecated}/ws-private.ts (95%) rename examples/{ => deprecated}/ws-public.ts (98%) create mode 100644 examples/rest-v5-proxies.ts create mode 100644 examples/rest-v5-public.ts diff --git a/README.md b/README.md index 1239f734..ee706243 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,8 @@ Node.js & JavaScript SDK for the Bybit REST APIs and WebSockets: Check out my related projects: - Try my connectors: - - [binance](https://www.npmjs.com/package/binance) - [bybit-api](https://www.npmjs.com/package/bybit-api) + - [binance](https://www.npmjs.com/package/binance) - [okx-api](https://www.npmjs.com/package/okx-api) - [bitget-api](https://www.npmjs.com/package/bitget-api) - Try my misc utilities: @@ -66,29 +66,44 @@ Refer to the [V5 interface mapping page](https://bybit-exchange.github.io/docs/v Here are the available REST clients and the corresponding API groups described in the documentation: -| Class | Description | -| :------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| [ **V5 API** ] | The new unified V5 APIs (successor to previously fragmented APIs for all API groups). To learn more about the V5 API, please read the [V5 upgrade guideline](https://bybit-exchange.github.io/docs/v5/upgrade-guide). | -| [RestClientV5](src/rest-client-v5.ts) | Unified V5 all-in-one REST client for all [V5 REST APIs](https://bybit-exchange.github.io/docs/v5/intro) | -| [ **Derivatives v3** ] | The Derivatives v3 APIs (successor to the Futures V2 APIs) | -| [UnifiedMarginClient](src/unified-margin-client.ts) | [Derivatives (v3) Unified Margin APIs](https://bybit-exchange.github.io/docs/derivatives/unified/place-order) | -| [ContractClient](src/contract-client.ts) | [Derivatives (v3) Contract APIs](https://bybit-exchange.github.io/docs/derivatives/contract/place-order). | -| [ **Futures v2** ] | The Futures v2 APIs | -| Deprecated! RestClientV5 recommended | Please read the [V5 interface mapping page](https://bybit-exchange.github.io/docs/v5/intro#v5-and-v3-interface-mapping-list) | -| [~InverseClient~](src/inverse-client.ts) | [Inverse Perpetual Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/inverse/) | -| [~LinearClient~](src/linear-client.ts) | [USDT Perpetual Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/linear/#t-introduction) | -| [~InverseFuturesClient~](src/inverse-futures-client.ts) | [Inverse Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/inverse_futures/#t-introduction) | -| [ **Spot** ] | The spot APIs | -| [SpotClientV3](src/spot-client-v3.ts) | [Spot Market (v3) APIs](https://bybit-exchange.github.io/docs/spot/public/instrument) | -| [~SpotClient~](src/spot-client.ts) (deprecated, SpotClientV3 recommended) | [Spot Market (v1) APIs](https://bybit-exchange.github.io/docs/spot/v1/#t-introduction) | -| [ **USDC Contract** ] | The USDC Contract APIs | -| [USDCPerpetualClient](src/usdc-perpetual-client.ts) | [USDC Perpetual APIs](https://bybit-exchange.github.io/docs/usdc/option/?console#t-querydeliverylog) | -| [USDCOptionClient](src/usdc-option-client.ts) | [USDC Option APIs](https://bybit-exchange.github.io/docs/usdc/option/#t-introduction) | -| [ **Other** ] | Other standalone API groups | -| [CopyTradingClient](src/copy-trading-client.ts) | [Copy Trading APIs](https://bybit-exchange.github.io/docs/category/copy-trade) | -| [AccountAssetClientV3](src/account-asset-client-v3.ts) | [Account Asset V3 APIs](https://bybit-exchange.github.io/docs/account-asset/internal-transfer) | -| [~AccountAssetClient~](src/account-asset-client.ts) (deprecated, AccountAssetClientV3 recommended) | [Account Asset V1 APIs](https://bybit-exchange.github.io/docs/account_asset/v1/#t-introduction) | -| [WebsocketClient](src/websocket-client.ts) | All WebSocket Events (Public & Private for all API categories) | +| Class | Description | +| :----------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| [ **V5 API** ] | The new unified V5 APIs (successor to previously fragmented APIs for all API groups). To learn more about the V5 API, please read the [V5 upgrade guideline](https://bybit-exchange.github.io/docs/v5/upgrade-guide). | +| [RestClientV5](src/rest-client-v5.ts) | Unified V5 all-in-one REST client for all [V5 REST APIs](https://bybit-exchange.github.io/docs/v5/intro) | +| [WebsocketClient](src/websocket-client.ts) | All WebSocket Events (Public & Private for all API categories) | +| [ **Derivatives v3** ] | The Derivatives v3 APIs (successor to the Futures V2 APIs) | +| [UnifiedMarginClient](src/unified-margin-client.ts) | [Derivatives (v3) Unified Margin APIs](https://bybit-exchange.github.io/docs/derivatives/unified/place-order) | +| [ContractClient](src/contract-client.ts) | [Derivatives (v3) Contract APIs](https://bybit-exchange.github.io/docs/derivatives/contract/place-order). | +| [ **Other** ] | Other standalone API groups | +| [CopyTradingClient](src/copy-trading-client.ts) | [Copy Trading APIs](https://bybit-exchange.github.io/docs/category/copy-trade) | +| [AccountAssetClientV3](src/account-asset-client-v3.ts) | [Account Asset V3 APIs](https://bybit-exchange.github.io/docs/account-asset/internal-transfer) | + +--- + +### Deprecated/Obsolete APIs + +The following API clients are for previous generation REST APIs and will be removed in the next major release. Some have already stopped working (because bybit stopped supporting them). You should use the V5 APIs for all new development. + +
+ Click me to see the list of APIs + +| Class | Description | +| :--------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------: | +| [ **Futures v2** ] | The Futures v2 APIs | +| [~~InverseClient~~](src/inverse-client.ts) | [Inverse Perpetual Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/inverse/) | +| [~~LinearClient~~](src/linear-client.ts) | [USDT Perpetual Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/linear/#t-introduction) | +| [~~InverseFuturesClient~~](src/inverse-futures-client.ts) | [Inverse Futures (v2) APIs](https://bybit-exchange.github.io/docs/futuresV2/inverse_futures/#t-introduction) | +| [ **Spot** ] | The spot APIs | +| [SpotClientV3](src/spot-client-v3.ts) | [Spot Market (v3) APIs](https://bybit-exchange.github.io/docs/spot/public/instrument) | +| [~~SpotClient~~](src/spot-client.ts) (deprecated, SpotClientV3 recommended) | [Spot Market (v1) APIs](https://bybit-exchange.github.io/docs/spot/v1/#t-introduction) | +| [ **USDC Contract** ] | The USDC Contract APIs | +| [USDCPerpetualClient](src/usdc-perpetual-client.ts) | [USDC Perpetual APIs](https://bybit-exchange.github.io/docs/usdc/option/?console#t-querydeliverylog) | +| [USDCOptionClient](src/usdc-option-client.ts) | [USDC Option APIs](https://bybit-exchange.github.io/docs/usdc/option/#t-introduction) | +| [~~AccountAssetClient~~](src/account-asset-client.ts) (deprecated, AccountAssetClientV3 recommended) | [Account Asset V1 APIs](https://bybit-exchange.github.io/docs/account_asset/v1/#t-introduction) | + +
+ +--- Examples for using each client can be found in: @@ -137,12 +152,6 @@ const restClientOptions = { /** Override the max size of the request window (in ms) */ recv_window?: number; - /** Disabled by default. This can help on machines with consistent latency problems. */ - enable_time_sync?: boolean; - - /** How often to sync time drift with bybit servers */ - sync_interval_ms?: number | string; - /** Default: false. If true, we'll throw errors if any params are undefined */ strict_param_validation?: boolean; @@ -169,7 +178,9 @@ const useTestnet = false; const client = new RestClientV5({ key: API_KEY, secret: API_SECRET, - testnet: useTestnet + testnet: useTestnet, + // Optional: enable to try parsing rate limit values from responses + // parseAPIRateLimits: true }, // requestLibraryOptions ); @@ -201,20 +212,29 @@ All API groups can be used via a shared `WebsocketClient`. However, to listen to The WebsocketClient can be configured to a specific API group using the market parameter. These are the currently available API groups: | API Category | Market | Description | |:----------------------------: |:-------------------: |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Unified Margin - Options | `market: 'unifiedOption'`| The [derivatives v3](https://bybit-exchange.github.io/docs/derivativesV3/unified_margin/#t-websocket) category for unified margin. Note: public topics only support options topics. If you need USDC/USDT perps, use `unifiedPerp` instead. | -| Unified Margin - Perps | `market: 'unifiedPerp'` | The [derivatives v3](https://bybit-exchange.github.io/docs/derivativesV3/unified_margin/#t-websocket) category for unified margin. Note: public topics only support USDT/USDC perpetual topics - use `unifiedOption` if you need public options topics. | -| Futures v2 - Inverse Perps | `market: 'inverse'` | The [inverse v2 perps](https://bybit-exchange.github.io/docs/futuresV2/inverse/#t-websocket) category. | -| Futures v2 - USDT Perps | `market: 'linear'` | The [USDT/linear v2 perps](https://bybit-exchange.github.io/docs/futuresV2/linear/#t-websocket) category. | -| Futures v2 - Inverse Futures | `market: 'inverse'` | The [inverse futures v2](https://bybit-exchange.github.io/docs/futuresV2/inverse_futures/#t-websocket) category uses the same market as inverse perps. | -| Spot v3 | `market: 'spotv3'` | The [spot v3](https://bybit-exchange.github.io/docs/spot/v3/#t-websocket) category. | -| Spot v1 | `market: 'spot'` | The older [spot v1](https://bybit-exchange.github.io/docs/spot/v1/#t-websocket) category. Use the `spotv3` market if possible, as the v1 category does not have automatic re-subscribe if reconnected. | -| Copy Trading | `market: 'linear'` | The [copy trading](https://bybit-exchange.github.io/docs/copy_trading/#t-websocket) category. Use the linear market to listen to all copy trading topics. | -| USDC Perps | `market: 'usdcPerp` | The [USDC perps](https://bybit-exchange.github.io/docs/usdc/perpetual/#t-websocket) category. | -| USDC Options | `market: 'usdcOption'`| The [USDC options](https://bybit-exchange.github.io/docs/usdc/option/#t-websocket) category. | -| Contract v3 USDT | `market: 'contractUSDT'`| The [Contract V3](https://bybit-exchange.github.io/docs/derivativesV3/contract/#t-websocket) category (USDT perps) | -| Contract v3 Inverse | `market: 'contractInverse'`| The [Contract V3](https://bybit-exchange.github.io/docs/derivativesV3/contract/#t-websocket) category (inverse perps) | | V5 Subscriptions | `market: 'v5'` | The [v5](https://bybit-exchange.github.io/docs/v5/ws/connect) websocket topics for all categories under one market. Use the subscribeV5 method when subscribing to v5 topics. | +--- + +### Older Websocket APIs + +The following API groups are still available in the WebsocketClient but are deprecated and may no longer work. They will be removed in the next major release: + +| API Category | Market | Description | +| :------------------------------: | :-------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ~~Unified Margin - Options~~ | `market: 'unifiedOption'` | The [derivatives v3](https://bybit-exchange.github.io/docs/derivativesV3/unified_margin/#t-websocket) category for unified margin. Note: public topics only support options topics. If you need USDC/USDT perps, use `unifiedPerp` instead. | +| ~~Unified Margin - Perps~~ | `market: 'unifiedPerp'` | The [derivatives v3](https://bybit-exchange.github.io/docs/derivativesV3/unified_margin/#t-websocket) category for unified margin. Note: public topics only support USDT/USDC perpetual topics - use `unifiedOption` if you need public options topics. | +| ~~Futures v2 - Inverse Perps~~ | `market: 'inverse'` | The [inverse v2 perps](https://bybit-exchange.github.io/docs/futuresV2/inverse/#t-websocket) category. | +| ~~Futures v2 - USDT Perps~~ | `market: 'linear'` | The [USDT/linear v2 perps](https://bybit-exchange.github.io/docs/futuresV2/linear/#t-websocket) category. | +| ~~Futures v2 - Inverse Futures~~ | `market: 'inverse'` | The [inverse futures v2](https://bybit-exchange.github.io/docs/futuresV2/inverse_futures/#t-websocket) category uses the same market as inverse perps. | +| ~~Spot v3~~ | `market: 'spotv3'` | The [spot v3](https://bybit-exchange.github.io/docs/spot/v3/#t-websocket) category. | +| ~~Spot v1~~ | `market: 'spot'` | The older [spot v1](https://bybit-exchange.github.io/docs/spot/v1/#t-websocket) category. Use the `spotv3` market if possible, as the v1 category does not have automatic re-subscribe if reconnected. | +| ~~Copy Trading~~ | `market: 'linear'` | The [copy trading](https://bybit-exchange.github.io/docs/copy_trading/#t-websocket) category. Use the linear market to listen to all copy trading topics. | +| ~~USDC Perps~~ | `market: 'usdcPerp` | The [USDC perps](https://bybit-exchange.github.io/docs/usdc/perpetual/#t-websocket) category. | +| ~~USDC Options~~ | `market: 'usdcOption'` | The [USDC options](https://bybit-exchange.github.io/docs/usdc/option/#t-websocket) category. | +| ~~Contract v3 USDT~~ | `market: 'contractUSDT'` | The [Contract V3](https://bybit-exchange.github.io/docs/derivativesV3/contract/#t-websocket) category (USDT perps) | +| ~~Contract v3 Inverse~~ | `market: 'contractInverse'` | The [Contract V3](https://bybit-exchange.github.io/docs/derivativesV3/contract/#t-websocket) category (inverse perps) | + For more complete examples, look into the ws-\* examples in the [examples](./examples/) folder in the repo on GitHub. Here's a minimal example for using the websocket client: ```javascript @@ -237,15 +257,6 @@ const wsConfig = { // If you can, use the v5 market (the newest generation of Bybit's websockets) market: 'v5', - // The older generations of Bybit's websockets are still available under the previous markets: - // market: 'linear', - // market: 'inverse', - // market: 'spotv3', - // market: 'usdcOption', - // market: 'usdcPerp', - // market: 'unifiedPerp', - // market: 'unifiedOption', - // how long to wait (in ms) before deciding the connection should be terminated & reconnected // pongTimeout: 1000, diff --git a/examples/deprecated/README.md b/examples/deprecated/README.md new file mode 100644 index 00000000..ed961e99 --- /dev/null +++ b/examples/deprecated/README.md @@ -0,0 +1,5 @@ +# Deprecated Examples + +The examples in this folder use old/deprecated/obsolete APIs. They should all have a modern alternative. + +As of December 2023, use the V5 APIs & WebSockets. diff --git a/examples/rest-contract-private.ts b/examples/deprecated/rest-contract-private.ts similarity index 90% rename from examples/rest-contract-private.ts rename to examples/deprecated/rest-contract-private.ts index 8a0801b5..59e14848 100644 --- a/examples/rest-contract-private.ts +++ b/examples/deprecated/rest-contract-private.ts @@ -1,4 +1,4 @@ -import { ContractClient } from '../src/index'; +import { ContractClient } from '../../src/index'; // or // import { ContractClient } from 'bybit-api'; diff --git a/examples/rest-contract-public.js b/examples/deprecated/rest-contract-public.js similarity index 100% rename from examples/rest-contract-public.js rename to examples/deprecated/rest-contract-public.js diff --git a/examples/rest-contract-public.ts b/examples/deprecated/rest-contract-public.ts similarity index 91% rename from examples/rest-contract-public.ts rename to examples/deprecated/rest-contract-public.ts index 99b3a0e4..1fecb0b7 100644 --- a/examples/rest-contract-public.ts +++ b/examples/deprecated/rest-contract-public.ts @@ -3,7 +3,7 @@ */ // For testing with the repo directly, import from the src folder -import { ContractClient } from '../src'; +import { ContractClient } from '../../src'; // or, use the version installed with npm // import { ContractClient } from 'bybit-api'; diff --git a/examples/rest-copy-private.ts b/examples/deprecated/rest-copy-private.ts similarity index 90% rename from examples/rest-copy-private.ts rename to examples/deprecated/rest-copy-private.ts index 724ced07..ebced304 100644 --- a/examples/rest-copy-private.ts +++ b/examples/deprecated/rest-copy-private.ts @@ -1,4 +1,4 @@ -import { CopyTradingClient } from '../src/index'; +import { CopyTradingClient } from '../../src/index'; // or // import { CopyTradingClient } from 'bybit-api'; diff --git a/examples/rest-linear-public.ts b/examples/deprecated/rest-linear-public.ts similarity index 90% rename from examples/rest-linear-public.ts rename to examples/deprecated/rest-linear-public.ts index 84f4df4f..d241ee6f 100644 --- a/examples/rest-linear-public.ts +++ b/examples/deprecated/rest-linear-public.ts @@ -1,4 +1,4 @@ -import { LinearClient } from '../src/index'; +import { LinearClient } from '../../src/index'; // or // import { LinearClient } from 'bybit-api'; diff --git a/examples/rest-raw-v3sign.ts b/examples/deprecated/rest-raw-v3sign.ts similarity index 94% rename from examples/rest-raw-v3sign.ts rename to examples/deprecated/rest-raw-v3sign.ts index 4bb25fee..35308a3b 100644 --- a/examples/rest-raw-v3sign.ts +++ b/examples/deprecated/rest-raw-v3sign.ts @@ -1,4 +1,4 @@ -import { ContractClient } from '../src/index'; +import { ContractClient } from '../../src/index'; // or // import { ContractClient } from 'bybit-api'; diff --git a/examples/rest-spot-public.ts b/examples/deprecated/rest-spot-public.ts similarity index 89% rename from examples/rest-spot-public.ts rename to examples/deprecated/rest-spot-public.ts index cfbe9503..05743659 100644 --- a/examples/rest-spot-public.ts +++ b/examples/deprecated/rest-spot-public.ts @@ -1,4 +1,4 @@ -import { SpotClientV3 } from '../src/index'; +import { SpotClientV3 } from '../../src/index'; // or // import { SpotClientV3 } from 'bybit-api'; diff --git a/examples/rest-spot-tpsl.ts b/examples/deprecated/rest-spot-tpsl.ts similarity index 92% rename from examples/rest-spot-tpsl.ts rename to examples/deprecated/rest-spot-tpsl.ts index 1cd29e89..d296d6b8 100644 --- a/examples/rest-spot-tpsl.ts +++ b/examples/deprecated/rest-spot-tpsl.ts @@ -1,4 +1,4 @@ -import { SpotClientV3 } from '../src/index'; +import { SpotClientV3 } from '../../src/index'; // or // import { SpotClientV3 } from 'bybit-api'; @@ -25,7 +25,7 @@ const client = new SpotClientV3({ symbol, orderId, ordersPerPage, - 0 + 0, ); console.log('normal orders:', normalOrders); @@ -33,7 +33,7 @@ const client = new SpotClientV3({ symbol, orderId, ordersPerPage, - 1 + 1, ); console.log('tpSlOrders:', tpSlOrders); } catch (e) { diff --git a/examples/rest-unified-margin-private-cursor.ts b/examples/deprecated/rest-unified-margin-private-cursor.ts similarity index 90% rename from examples/rest-unified-margin-private-cursor.ts rename to examples/deprecated/rest-unified-margin-private-cursor.ts index 5860424e..0bde7cbc 100644 --- a/examples/rest-unified-margin-private-cursor.ts +++ b/examples/deprecated/rest-unified-margin-private-cursor.ts @@ -1,4 +1,4 @@ -import { UnifiedMarginClient } from '../src/index'; +import { UnifiedMarginClient } from '../../src/index'; // or // import { UnifiedMarginClient } from 'bybit-api'; @@ -36,7 +36,7 @@ const client = new UnifiedMarginClient({ }); console.log( 'both to compare:', - JSON.stringify(historicOrdersBoth, null, 2) + JSON.stringify(historicOrdersBoth, null, 2), ); } catch (e) { console.error('request failed: ', e); diff --git a/examples/rest-unified-margin-public-cursor.ts b/examples/deprecated/rest-unified-margin-public-cursor.ts similarity index 94% rename from examples/rest-unified-margin-public-cursor.ts rename to examples/deprecated/rest-unified-margin-public-cursor.ts index 8d8aab68..224ed1a5 100644 --- a/examples/rest-unified-margin-public-cursor.ts +++ b/examples/deprecated/rest-unified-margin-public-cursor.ts @@ -1,4 +1,4 @@ -import { UnifiedMarginClient } from '../src/index'; +import { UnifiedMarginClient } from '../../src/index'; // or // import { UnifiedMarginClient } from 'bybit-api'; diff --git a/examples/ws-private-copytrading-v3.ts b/examples/deprecated/ws-private-copytrading-v3.ts similarity index 95% rename from examples/ws-private-copytrading-v3.ts rename to examples/deprecated/ws-private-copytrading-v3.ts index a0736a72..17e445dd 100644 --- a/examples/ws-private-copytrading-v3.ts +++ b/examples/deprecated/ws-private-copytrading-v3.ts @@ -1,7 +1,7 @@ /* eslint-disable no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-empty-function */ -import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src'; +import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../../src'; // or // import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api'; diff --git a/examples/ws-private.ts b/examples/deprecated/ws-private.ts similarity index 95% rename from examples/ws-private.ts rename to examples/deprecated/ws-private.ts index b20235dc..2ee6fafa 100644 --- a/examples/ws-private.ts +++ b/examples/deprecated/ws-private.ts @@ -1,7 +1,7 @@ /* eslint-disable no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-empty-function */ -import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src'; +import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../../src'; // or // import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api'; diff --git a/examples/ws-public.ts b/examples/deprecated/ws-public.ts similarity index 98% rename from examples/ws-public.ts rename to examples/deprecated/ws-public.ts index 5cb11eec..e1cdb0a2 100644 --- a/examples/ws-public.ts +++ b/examples/deprecated/ws-public.ts @@ -1,4 +1,4 @@ -import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src'; +import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../../src'; // or // import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api'; @@ -22,7 +22,7 @@ const wsClient = new WebsocketClient( // market: 'unifiedOption', market: 'contractUSDT', }, - logger + logger, ); wsClient.on('update', (data) => { diff --git a/examples/rest-v5-proxies.ts b/examples/rest-v5-proxies.ts new file mode 100644 index 00000000..89a2c7a1 --- /dev/null +++ b/examples/rest-v5-proxies.ts @@ -0,0 +1,66 @@ +import { RestClientV5 } from '../src/index'; + +// or +// import { RestClientV5 } from 'bybit-api'; + +const key = process.env.API_KEY_COM; +const secret = process.env.API_SECRET_COM; + +const client = new RestClientV5( + { + key: key, + secret: secret, + parseAPIRateLimits: true, + testnet: true, + // Sometimes using a proxy introduces recv timestamp errors (due to the extra latency) + // If that happens, you can try increasing the recv window (which is 5000ms by default) + // recv_window: 10000, + }, + { + proxy: { + host: 'proxyhost', + port: Number('proxyport'), + auth: { + username: 'proxyuserifneeded', + password: 'proxypassifneeded', + }, + }, + }, +); + +(async () => { + try { + const res = await client.getWalletBalance({ accountType: 'UNIFIED' }); + + console.log('response: ', JSON.stringify(res, null, 2)); + + // const orders = await client.batchSubmitOrders('linear', [ + // { + // symbol: 'ETHUSDT', + // orderType: 'Limit', + // side: 'Buy', + // qty: '1', + // orderIv: '6', + // timeInForce: 'GTC', + // orderLinkId: 'option-test-001', + // mmp: false, + // reduceOnly: false, + // }, + // { + // symbol: 'ETHUSDT', + // orderType: 'Limit', + // side: 'Sell', + // qty: '2', + // price: '700', + // timeInForce: 'GTC', + // orderLinkId: 'option-test-001', + // mmp: false, + // reduceOnly: false, + // }, + // ]); + + // console.log('orders: ', JSON.stringify(orders, null, 2)); + } catch (e) { + console.error('request failed: ', e); + } +})(); diff --git a/examples/rest-v5-public.ts b/examples/rest-v5-public.ts new file mode 100644 index 00000000..9fe8930c --- /dev/null +++ b/examples/rest-v5-public.ts @@ -0,0 +1,66 @@ +import { + APIResponseV3WithTime, + CategoryListV5, + RestClientV5, + TickerLinearInverseV5, +} from '../src/index'; + +// or +// import { RestClientV5 } from 'bybit-api'; + +/** + * If you don't plan on making any private api calls, + * you can instance the REST client without any parameters + */ +const client = new RestClientV5(); + +(async () => { + try { + // const klineResult = await client.getKline({ + // category: 'linear', + // interval: '15', + // symbol: 'BTCUSDT', + // }); + // console.log('klineResult: ', klineResult); + + // const markPriceKlineResult = await client.getMarkPriceKline({ + // category: 'linear', + // interval: '15', + // symbol: 'BTCUSDT', + // }); + // console.log('markPriceKlineResult: ', markPriceKlineResult); + + // const indexPriceKline = await client.getIndexPriceKline({ + // category: 'linear', + // interval: '15', + // symbol: 'BTCUSDT', + // }); + // console.log('indexPriceKline: ', indexPriceKline); + + // const openInterest = await client.getOpenInterest({ + // category: 'linear', + // symbol: 'BTCUSDT', + // intervalTime: '5min', + // }); + + const tickers = await client.getTickers({ category: 'linear' }); + // console.log( + // JSON.stringify( + // tickers.result.list.map((ticker) => ticker.symbol), + // null, + // 2, + // ), + // ); + + console.log('response', tickers); + // openInterest.result.list.forEach((row) => { + // console.log('int: ', { + // timestamp: row.timestamp, + // value: row.openInterest, + // }); + // }); + // console.log('openInterest: ', openInterest.result.list); + } catch (e) { + console.error('request failed: ', e); + } +})(); From 5a7337b36a51cd4d70fdf6bb589f15b1451df589 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 22 Dec 2023 11:49:56 +0000 Subject: [PATCH 3/9] chore(): readme cleaning --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ee706243..da865615 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,9 @@ The WebsocketClient can be configured to a specific API group using the market p The following API groups are still available in the WebsocketClient but are deprecated and may no longer work. They will be removed in the next major release: +
+ Click me to see the table + | API Category | Market | Description | | :------------------------------: | :-------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ~~Unified Margin - Options~~ | `market: 'unifiedOption'` | The [derivatives v3](https://bybit-exchange.github.io/docs/derivativesV3/unified_margin/#t-websocket) category for unified margin. Note: public topics only support options topics. If you need USDC/USDT perps, use `unifiedPerp` instead. | @@ -235,7 +238,11 @@ The following API groups are still available in the WebsocketClient but are depr | ~~Contract v3 USDT~~ | `market: 'contractUSDT'` | The [Contract V3](https://bybit-exchange.github.io/docs/derivativesV3/contract/#t-websocket) category (USDT perps) | | ~~Contract v3 Inverse~~ | `market: 'contractInverse'` | The [Contract V3](https://bybit-exchange.github.io/docs/derivativesV3/contract/#t-websocket) category (inverse perps) | -For more complete examples, look into the ws-\* examples in the [examples](./examples/) folder in the repo on GitHub. Here's a minimal example for using the websocket client: +
Date: Fri, 22 Dec 2023 11:54:58 +0000 Subject: [PATCH 4/9] chore(): doc updates --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index da865615..4fbc7da5 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,8 @@ Check out my related projects: Most methods accept JS objects. These can be populated using parameters specified by Bybit's API documentation, or check the type definition in each class within the github repository (see table below for convenient links to each class). -- [Bybit API Docs (choose API category from the tabs at the top)](https://bybit-exchange.github.io/docs/v5/intro). +- [Bybit API Docs](https://bybit-exchange.github.io/docs/v5/intro) +- [TSDoc Documentation (generated using typedoc via npm module)](https://tsdocs.dev/docs/bybit-api) ## Structure @@ -242,6 +243,8 @@ The following API groups are still available in the WebsocketClient but are depr --- +### WebSocket Examples + Here's a minimal example for using the websocket client. For more complete examples, look into the ws-\* examples in the [examples](./examples/) folder in the repo on GitHub. ```javascript From 2240bd4043aded3e2da42ea51e249350ea020b63 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 22 Dec 2023 11:55:46 +0000 Subject: [PATCH 5/9] chore(): disable old endpoint test --- test/account-asset/private.read.test.ts | 2 +- test/account-asset/private.v3.read.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/account-asset/private.read.test.ts b/test/account-asset/private.read.test.ts index e7f1326a..371f2c75 100644 --- a/test/account-asset/private.read.test.ts +++ b/test/account-asset/private.read.test.ts @@ -40,7 +40,7 @@ describe('Private Account Asset REST API GET Endpoints', () => { }); }); - it('getUniversalTransfers()', async () => { + it.skip('getUniversalTransfers()', async () => { expect(await api.getInternalTransfers()).toMatchObject( successResponseObject(), ); diff --git a/test/account-asset/private.v3.read.test.ts b/test/account-asset/private.v3.read.test.ts index 4dc99648..895b1fb3 100644 --- a/test/account-asset/private.v3.read.test.ts +++ b/test/account-asset/private.v3.read.test.ts @@ -49,7 +49,7 @@ describe('Private Account Asset V3 REST API Endpoints', () => { }); }); - it('getUniversalTransfers()', async () => { + it.skip('getUniversalTransfers()', async () => { expect(await api.getUniversalTransfers({ coin: coin })).toMatchObject({ ...successResponseObjectV3(), retCode: API_ERROR_CODE.INCORRECT_API_KEY_PERMISSIONS, From afc099f4aca113c43f0852ae8a1350faf4ffcaa0 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 22 Dec 2023 12:00:42 +0000 Subject: [PATCH 6/9] feat(): slight improvement around ws teardown. feat(#305): implement safe terminate for browsers --- src/util/websocket-util.ts | 14 ++++++++++++++ src/websocket-client.ts | 10 ++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/util/websocket-util.ts b/src/util/websocket-util.ts index a2d27f83..400b81f1 100644 --- a/src/util/websocket-util.ts +++ b/src/util/websocket-util.ts @@ -1,3 +1,5 @@ +import WebSocket from 'isomorphic-ws'; + import { APIMarket, CategoryV5, WsKey } from '../types'; import { DefaultLogger } from './logger'; @@ -548,3 +550,15 @@ export const WS_ERROR_ENUM = { export function neverGuard(x: never, msg: string): Error { return new Error(`Unhandled value exception "x", ${msg}`); } + +/** + * #305: ws.terminate() is undefined in browsers. + * This only works in node.js, not in browsers. + * Does nothing if `ws` is undefined. + */ +export function safeTerminateWs(ws?: WebSocket | unknown) { + // #305: ws.terminate() undefined in browsers + if (ws && typeof ws['terminate'] === 'function') { + ws.terminate(); + } +} diff --git a/src/websocket-client.ts b/src/websocket-client.ts index e8f0d5e1..595243ea 100644 --- a/src/websocket-client.ts +++ b/src/websocket-client.ts @@ -40,6 +40,7 @@ import { isTopicSubscriptionSuccess, isWsPong, neverGuard, + safeTerminateWs, serializeParams, } from './util'; import { RestClientV5 } from './rest-client-v5'; @@ -462,7 +463,7 @@ export class WebsocketClient extends EventEmitter { const ws = this.getWs(wsKey); ws?.close(); if (force) { - ws?.terminate(); + safeTerminateWs(ws); } } @@ -811,7 +812,12 @@ export class WebsocketClient extends EventEmitter { this.clearPingTimer(wsKey); this.clearPongTimer(wsKey); - this.getWs(wsKey)?.terminate(); + const ws = this.getWs(wsKey); + + if (ws) { + ws.close(); + safeTerminateWs(ws); + } if (!wasOpen) { this.logger.info( From bb023919ee8da9fc721626cc642c57067e4ec917 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Fri, 22 Dec 2023 12:03:33 +0000 Subject: [PATCH 7/9] chore(): tidying example --- examples/rest-v5-public.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/examples/rest-v5-public.ts b/examples/rest-v5-public.ts index 9fe8930c..51377c0b 100644 --- a/examples/rest-v5-public.ts +++ b/examples/rest-v5-public.ts @@ -1,9 +1,4 @@ -import { - APIResponseV3WithTime, - CategoryListV5, - RestClientV5, - TickerLinearInverseV5, -} from '../src/index'; +import { RestClientV5 } from '../src/index'; // or // import { RestClientV5 } from 'bybit-api'; From 2ba50f82e664add9bcdbd6fb8a028230c91422b0 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Wed, 3 Jan 2024 15:39:19 +0000 Subject: [PATCH 8/9] feat(#307): add new create sub parameters --- src/types/request/v5-asset.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/types/request/v5-asset.ts b/src/types/request/v5-asset.ts index 3e151427..b20402de 100644 --- a/src/types/request/v5-asset.ts +++ b/src/types/request/v5-asset.ts @@ -127,7 +127,15 @@ export interface WithdrawParamsV5 { export interface CreateSubMemberParamsV5 { username: string; + password?: string; + /** + * 1: normal, 6: custodial + */ memberType: 1 | 6; + /** + * 0: quick login disabled (default), 1: quick login enabled + */ switch?: 0 | 1; + isUta?: boolean; note?: string; } From c54d86ce3784c4acae913332c7352c06a604dea4 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Wed, 3 Jan 2024 15:44:01 +0000 Subject: [PATCH 9/9] v3.8.0: start deprecating old REST examples, update docs, minor fixes --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0fafd4eb..60c0db2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bybit-api", - "version": "3.7.6", + "version": "3.8.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "bybit-api", - "version": "3.7.6", + "version": "3.8.0", "license": "MIT", "dependencies": { "axios": "^0.21.0", diff --git a/package.json b/package.json index 13e2c41b..e5a1af9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bybit-api", - "version": "3.7.8", + "version": "3.8.0", "description": "Complete & robust Node.js SDK for Bybit's REST APIs and WebSockets, with TypeScript & strong end to end tests.", "main": "lib/index.js", "types": "lib/index.d.ts",