feat(): examples for v5 websockets with and without auth

This commit is contained in:
tiagosiebler
2023-02-27 11:37:49 +00:00
parent d6534a438c
commit a0dc9c811d
4 changed files with 424 additions and 209 deletions

103
examples/ws-private-v5.ts Normal file
View File

@@ -0,0 +1,103 @@
/* eslint-disable @typescript-eslint/no-empty-function */
import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src';
// or
// import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api';
// Create & inject a custom logger to disable the silly logging level (empty function)
const logger = {
...DefaultLogger,
silly: () => {},
};
const key = process.env.API_KEY;
const secret = process.env.API_SECRET;
/**
* Prepare an instance of the WebSocket client. This client handles all aspects of connectivity for you:
* - Connections are opened when you subscribe to topics
* - If key & secret are provided, authentication is handled automatically
* - If you subscribe to topics from different v5 products (e.g. spot and linear perps),
* subscription events are automatically routed to the different ws endpoints on bybit's side
* - Heartbeats/ping/pong/reconnects are all handled automatically.
* If a connection drops, the client will clean it up, respawn a fresh connection and resubscribe for you.
*/
const wsClient = new WebsocketClient(
{
key: key,
secret: secret,
market: 'v5',
testnet: true,
},
logger
);
wsClient.on('update', (data) => {
console.log('raw message received ', JSON.stringify(data));
// console.log('raw message received ', JSON.stringify(data, null, 2));
});
wsClient.on('open', (data) => {
console.log('connection opened open:', data.wsKey);
});
wsClient.on('response', (data) => {
console.log('log response: ', JSON.stringify(data, null, 2));
});
wsClient.on('reconnect', ({ wsKey }) => {
console.log('ws automatically reconnecting.... ', wsKey);
});
wsClient.on('reconnected', (data) => {
console.log('ws has reconnected ', data?.wsKey);
});
// wsClient.on('error', (data) => {
// console.error('ws exception: ', data);
// });
/**
* For private V5 topics, us the subscribeV5() method on the ws client or use the original subscribe() method.
*
* Note: for private endpoints the "category" field is ignored since there is only one private endpoint
* (compared to one public one per category).
* The "category" is only needed for public topics since bybit has one endpoint for public events per category.
*/
wsClient.subscribeV5('position', 'linear');
wsClient.subscribeV5('execution', 'linear');
wsClient.subscribeV5(['order', 'wallet', 'greek'], 'linear');
/**
* The following has the same effect as above, since there's only one private endpoint for V5 account topics:
*/
// wsClient.subscribe('position');
// wsClient.subscribe('execution');
// wsClient.subscribe(['order', 'wallet', 'greek']);
// To unsubscribe from topics (after a 5 second delay, in this example):
// setTimeout(() => {
// console.log('unsubscribing');
// wsClient.unsubscribeV5('execution', 'linear');
// }, 5 * 1000);
// Topics are tracked per websocket type
// Get a list of subscribed topics (e.g. for public v3 spot topics) (after a 5 second delay)
setTimeout(() => {
const activePrivateTopics = wsClient
.getWsStore()
.getTopics(WS_KEY_MAP.v5Private);
console.log('Active private v5 topics: ', activePrivateTopics);
const activePublicLinearTopics = wsClient
.getWsStore()
.getTopics(WS_KEY_MAP.v5LinearPublic);
console.log('Active public linear v5 topics: ', activePublicLinearTopics);
const activePublicSpotTopis = wsClient
.getWsStore()
.getTopics(WS_KEY_MAP.v5SpotPublic);
console.log('Active public spot v5 topics: ', activePublicSpotTopis);
const activePublicOptionsTopics = wsClient
.getWsStore()
.getTopics(WS_KEY_MAP.v5OptionPublic);
console.log('Active public option v5 topics: ', activePublicOptionsTopics);
}, 5 * 1000);

View File

@@ -6,26 +6,25 @@ import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src';
// or // or
// import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api'; // import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api';
(async () => { const logger = {
const logger = {
...DefaultLogger, ...DefaultLogger,
silly: () => {}, silly: () => {},
}; };
const key = process.env.API_KEY; const key = process.env.API_KEY;
const secret = process.env.API_SECRET; const secret = process.env.API_SECRET;
// USDT Perps: // USDT Perps:
// const market = 'linear'; // const market = 'linear';
// Inverse Perp // Inverse Perp
// const market = 'inverse'; // const market = 'inverse';
// const market = 'spotv3'; // const market = 'spotv3';
// Contract v3 // Contract v3
const market = 'contractUSDT'; const market = 'contractUSDT';
// const market = 'contractInverse'; // const market = 'contractInverse';
// Note: the WebsocketClient defaults to testnet. Set `livenet: true` to use live markets. // Note: the WebsocketClient defaults to testnet. Set `livenet: true` to use live markets.
const wsClient = new WebsocketClient( const wsClient = new WebsocketClient(
{ {
key: key, key: key,
secret: secret, secret: secret,
@@ -36,37 +35,36 @@ import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src';
}, },
}, },
logger logger
); );
wsClient.on('update', (data) => { wsClient.on('update', (data) => {
console.log('raw message received ', JSON.stringify(data, null, 2)); console.log('raw message received ', JSON.stringify(data, null, 2));
}); });
wsClient.on('open', (data) => { wsClient.on('open', (data) => {
console.log('connection opened open:', data.wsKey); console.log('connection opened open:', data.wsKey);
}); });
wsClient.on('response', (data) => { wsClient.on('response', (data) => {
console.log('ws response: ', JSON.stringify(data, null, 2)); console.log('ws response: ', JSON.stringify(data, null, 2));
}); });
wsClient.on('reconnect', ({ wsKey }) => { wsClient.on('reconnect', ({ wsKey }) => {
console.log('ws automatically reconnecting.... ', wsKey); console.log('ws automatically reconnecting.... ', wsKey);
}); });
wsClient.on('reconnected', (data) => { wsClient.on('reconnected', (data) => {
console.log('ws has reconnected ', data?.wsKey); console.log('ws has reconnected ', data?.wsKey);
}); });
wsClient.on('error', (data) => { wsClient.on('error', (data) => {
console.error('ws exception: ', data); console.error('ws exception: ', data);
}); });
// subscribe to private endpoints // subscribe to private endpoints
// check the api docs in your api category to see the available topics // check the api docs in your api category to see the available topics
// wsClient.subscribe(['position', 'execution', 'order', 'wallet']); // wsClient.subscribe(['position', 'execution', 'order', 'wallet']);
// Contract v3 // Contract v3
wsClient.subscribe([ wsClient.subscribe([
'user.position.contractAccount', 'user.position.contractAccount',
'user.execution.contractAccount', 'user.execution.contractAccount',
'user.order.contractAccount', 'user.order.contractAccount',
'user.wallet.contractAccount', 'user.wallet.contractAccount',
]); ]);
})();

116
examples/ws-public-v5.ts Normal file
View File

@@ -0,0 +1,116 @@
import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src';
// or
// import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api';
const logger = {
...DefaultLogger,
silly: (...params) => console.log('silly', ...params),
};
/**
* Prepare an instance of the WebSocket client. This client handles all aspects of connectivity for you:
* - Connections are opened when you subscribe to topics
* - If key & secret are provided, authentication is handled automatically
* - If you subscribe to topics from different v5 products (e.g. spot and linear perps),
* subscription events are automatically routed to the different ws endpoints on bybit's side
* - Heartbeats/ping/pong/reconnects are all handled automatically.
* If a connection drops, the client will clean it up, respawn a fresh connection and resubscribe for you.
*/
const wsClient = new WebsocketClient(
{
// key: key,
// secret: secret,
market: 'v5',
},
logger
);
wsClient.on('update', (data) => {
console.log('raw message received ', JSON.stringify(data));
// console.log('raw message received ', JSON.stringify(data, null, 2));
});
wsClient.on('open', (data) => {
console.log('connection opened open:', data.wsKey);
});
wsClient.on('response', (data) => {
console.log('log response: ', JSON.stringify(data, null, 2));
});
wsClient.on('reconnect', ({ wsKey }) => {
console.log('ws automatically reconnecting.... ', wsKey);
});
wsClient.on('reconnected', (data) => {
console.log('ws has reconnected ', data?.wsKey);
});
// wsClient.on('error', (data) => {
// console.error('ws exception: ', data);
// });
/**
* For public V5 topics, use the subscribeV5 method and include the API category this topic is for.
* Category is required, since each category has a different websocket endpoint.
*/
// Linear v5
// -> Just one topic per call
// wsClient.subscribeV5('orderbook.50.BTCUSDT', 'linear');
// -> Or multiple topics in one call
// wsClient.subscribeV5(
// ['orderbook.50.BTCUSDT', 'orderbook.50.ETHUSDT'],
// 'linear'
// );
// Inverse v5
// wsClient.subscribeV5('orderbook.50.BTCUSD', 'inverse');
// Spot v5
// wsClient.subscribeV5('orderbook.50.BTCUSDT', 'spot');
// Option v5
// wsClient.subscribeV5('publicTrade.BTC', 'option');
/**
* For private V5 topics, just call the same subscribeV5() method on the ws client or use the original subscribe() method.
*
* Note: for private endpoints the "category" field is ignored since there is only one private endpoint
* (compared to one public one per category)
*/
wsClient.subscribeV5('position', 'linear');
wsClient.subscribeV5('execution', 'linear');
wsClient.subscribeV5(['order', 'wallet', 'greek'], 'linear');
// Other example topics
// To unsubscribe from topics (after a 5 second delay, in this example):
// setTimeout(() => {
// console.log('unsubscribing');
// wsClient.unsubscribeV5('orderbook.50.BTCUSDT', 'linear);
// }, 5 * 1000);
// Topics are tracked per websocket type
// Get a list of subscribed topics (e.g. for public v3 spot topics) (after a 5 second delay)
setTimeout(() => {
const activePrivateTopics = wsClient
.getWsStore()
.getTopics(WS_KEY_MAP.v5Private);
console.log('Active private v5 topics: ', activePrivateTopics);
const activePublicLinearTopics = wsClient
.getWsStore()
.getTopics(WS_KEY_MAP.v5LinearPublic);
console.log('Active public linear v5 topics: ', activePublicLinearTopics);
const activePublicSpotTopis = wsClient
.getWsStore()
.getTopics(WS_KEY_MAP.v5SpotPublic);
console.log('Active public spot v5 topics: ', activePublicSpotTopis);
const activePublicOptionsTopics = wsClient
.getWsStore()
.getTopics(WS_KEY_MAP.v5OptionPublic);
console.log('Active public option v5 topics: ', activePublicOptionsTopics);
}, 5 * 1000);

View File

@@ -3,13 +3,12 @@ import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src';
// or // or
// import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api'; // import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from 'bybit-api';
(async () => { const logger = {
const logger = {
...DefaultLogger, ...DefaultLogger,
silly: (...params) => console.log('silly', ...params), silly: (...params) => console.log('silly', ...params),
}; };
const wsClient = new WebsocketClient( const wsClient = new WebsocketClient(
{ {
// key: key, // key: key,
// secret: secret, // secret: secret,
@@ -23,14 +22,14 @@ import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src';
// market: 'unifiedOption', // market: 'unifiedOption',
}, },
logger logger
); );
wsClient.on('update', (data) => { wsClient.on('update', (data) => {
console.log('raw message received ', JSON.stringify(data)); console.log('raw message received ', JSON.stringify(data));
// console.log('raw message received ', JSON.stringify(data, null, 2)); // console.log('raw message received ', JSON.stringify(data, null, 2));
}); });
wsClient.on('open', (data) => { wsClient.on('open', (data) => {
console.log('connection opened open:', data.wsKey); console.log('connection opened open:', data.wsKey);
// if (data.wsKey === WS_KEY_MAP.spotPublic) { // if (data.wsKey === WS_KEY_MAP.spotPublic) {
@@ -41,124 +40,124 @@ import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src';
// // wsClient.subscribePublicSpotV1Kline('BTCUSDT', '1m'); // // wsClient.subscribePublicSpotV1Kline('BTCUSDT', '1m');
// // wsClient.subscribePublicSpotOrderbook('BTCUSDT', 'full'); // // wsClient.subscribePublicSpotOrderbook('BTCUSDT', 'full');
// } // }
}); });
wsClient.on('response', (data) => { wsClient.on('response', (data) => {
console.log('log response: ', JSON.stringify(data, null, 2)); console.log('log response: ', JSON.stringify(data, null, 2));
}); });
wsClient.on('reconnect', ({ wsKey }) => { wsClient.on('reconnect', ({ wsKey }) => {
console.log('ws automatically reconnecting.... ', wsKey); console.log('ws automatically reconnecting.... ', wsKey);
}); });
wsClient.on('reconnected', (data) => { wsClient.on('reconnected', (data) => {
console.log('ws has reconnected ', data?.wsKey); console.log('ws has reconnected ', data?.wsKey);
}); });
// wsClient.on('error', (data) => { // wsClient.on('error', (data) => {
// console.error('ws exception: ', data); // console.error('ws exception: ', data);
// }); // });
// Inverse // Inverse
// wsClient.subscribe('trade'); // wsClient.subscribe('trade');
// Linear // Linear
// wsClient.subscribe('trade.BTCUSDT'); // wsClient.subscribe('trade.BTCUSDT');
// Spot V3 // Spot V3
// wsClient.subscribe('trade.BTCUSDT'); // wsClient.subscribe('trade.BTCUSDT');
// Or an array of topics // Or an array of topics
// wsClient.subscribe([ // wsClient.subscribe([
// 'orderbook.40.BTCUSDT', // 'orderbook.40.BTCUSDT',
// 'orderbook.40.BTCUSDC', // 'orderbook.40.BTCUSDC',
// 'orderbook.40.USDCUSDT', // 'orderbook.40.USDCUSDT',
// 'orderbook.40.BTCDAI', // 'orderbook.40.BTCDAI',
// 'orderbook.40.DAIUSDT', // 'orderbook.40.DAIUSDT',
// 'orderbook.40.ETHUSDT', // 'orderbook.40.ETHUSDT',
// 'orderbook.40.ETHUSDC', // 'orderbook.40.ETHUSDC',
// 'orderbook.40.ETHDAI', // 'orderbook.40.ETHDAI',
// 'orderbook.40.XRPUSDT', // 'orderbook.40.XRPUSDT',
// 'orderbook.40.XRPUSDC', // 'orderbook.40.XRPUSDC',
// 'orderbook.40.EOSUSDT', // 'orderbook.40.EOSUSDT',
// 'orderbook.40.EOSUSDC', // 'orderbook.40.EOSUSDC',
// 'orderbook.40.DOTUSDT', // 'orderbook.40.DOTUSDT',
// 'orderbook.40.DOTUSDC', // 'orderbook.40.DOTUSDC',
// 'orderbook.40.XLMUSDT', // 'orderbook.40.XLMUSDT',
// 'orderbook.40.XLMUSDC', // 'orderbook.40.XLMUSDC',
// 'orderbook.40.LTCUSDT', // 'orderbook.40.LTCUSDT',
// 'orderbook.40.LTCUSDC', // 'orderbook.40.LTCUSDC',
// 'orderbook.40.DOGEUSDT', // 'orderbook.40.DOGEUSDT',
// 'orderbook.40.DOGEUSDC', // 'orderbook.40.DOGEUSDC',
// 'orderbook.40.BITUSDT', // 'orderbook.40.BITUSDT',
// 'orderbook.40.BITUSDC', // 'orderbook.40.BITUSDC',
// 'orderbook.40.BITDAI', // 'orderbook.40.BITDAI',
// 'orderbook.40.CHZUSDT', // 'orderbook.40.CHZUSDT',
// 'orderbook.40.CHZUSDC', // 'orderbook.40.CHZUSDC',
// 'orderbook.40.MANAUSDT', // 'orderbook.40.MANAUSDT',
// 'orderbook.40.MANAUSDC', // 'orderbook.40.MANAUSDC',
// 'orderbook.40.LINKUSDT', // 'orderbook.40.LINKUSDT',
// 'orderbook.40.LINKUSDC', // 'orderbook.40.LINKUSDC',
// 'orderbook.40.ICPUSDT', // 'orderbook.40.ICPUSDT',
// 'orderbook.40.ICPUSDC', // 'orderbook.40.ICPUSDC',
// 'orderbook.40.ADAUSDT', // 'orderbook.40.ADAUSDT',
// 'orderbook.40.ADAUSDC', // 'orderbook.40.ADAUSDC',
// 'orderbook.40.SOLUSDC', // 'orderbook.40.SOLUSDC',
// 'orderbook.40.SOLUSDT', // 'orderbook.40.SOLUSDT',
// 'orderbook.40.MATICUSDC', // 'orderbook.40.MATICUSDC',
// 'orderbook.40.MATICUSDT', // 'orderbook.40.MATICUSDT',
// 'orderbook.40.SANDUSDC', // 'orderbook.40.SANDUSDC',
// 'orderbook.40.SANDUSDT', // 'orderbook.40.SANDUSDT',
// 'orderbook.40.LUNCUSDC', // 'orderbook.40.LUNCUSDC',
// 'orderbook.40.LUNCUSDT', // 'orderbook.40.LUNCUSDT',
// 'orderbook.40.SLGUSDC', // 'orderbook.40.SLGUSDC',
// 'orderbook.40.SLGUSDT', // 'orderbook.40.SLGUSDT',
// 'orderbook.40.AVAXUSDC', // 'orderbook.40.AVAXUSDC',
// 'orderbook.40.AVAXUSDT', // 'orderbook.40.AVAXUSDT',
// 'orderbook.40.OPUSDC', // 'orderbook.40.OPUSDC',
// 'orderbook.40.OPUSDT', // 'orderbook.40.OPUSDT',
// 'orderbook.40.OKSEUSDC', // 'orderbook.40.OKSEUSDC',
// 'orderbook.40.OKSEUSDT', // 'orderbook.40.OKSEUSDT',
// 'orderbook.40.APEXUSDC', // 'orderbook.40.APEXUSDC',
// 'orderbook.40.APEXUSDT', // 'orderbook.40.APEXUSDT',
// 'orderbook.40.TRXUSDC', // 'orderbook.40.TRXUSDC',
// 'orderbook.40.TRXUSDT', // 'orderbook.40.TRXUSDT',
// 'orderbook.40.GMTUSDC', // 'orderbook.40.GMTUSDC',
// 'orderbook.40.GMTUSDT', // 'orderbook.40.GMTUSDT',
// 'orderbook.40.SHIBUSDC', // 'orderbook.40.SHIBUSDC',
// 'orderbook.40.SHIBUSDT', // 'orderbook.40.SHIBUSDT',
// 'orderbook.40.LDOUSDC', // 'orderbook.40.LDOUSDC',
// 'orderbook.40.LDOUSDT', // 'orderbook.40.LDOUSDT',
// 'orderbook.40.APEUSDC', // 'orderbook.40.APEUSDC',
// 'orderbook.40.APEUSDT', // 'orderbook.40.APEUSDT',
// 'orderbook.40.FILUSDC', // 'orderbook.40.FILUSDC',
// 'orderbook.40.FILUSDT', // 'orderbook.40.FILUSDT',
// ]); // ]);
// usdc options // usdc options
// wsClient.subscribe([ // wsClient.subscribe([
// `recenttrades.BTC`, // `recenttrades.BTC`,
// `recenttrades.ETH`, // `recenttrades.ETH`,
// `recenttrades.SOL`, // `recenttrades.SOL`,
// ]); // ]);
// usdc perps (note: the syntax is different for the unified perp market) // usdc perps (note: the syntax is different for the unified perp market)
// (market: 'usdcPerp') // (market: 'usdcPerp')
// wsClient.subscribe('trade.BTCUSDC'); // wsClient.subscribe('trade.BTCUSDC');
wsClient.subscribe('instrument_info.100ms.BTCPERP'); wsClient.subscribe('instrument_info.100ms.BTCPERP');
// unified perps // unified perps
// wsClient.subscribe('publicTrade.BTCUSDT'); // wsClient.subscribe('publicTrade.BTCUSDT');
// wsClient.subscribe('publicTrade.BTCPERP'); // wsClient.subscribe('publicTrade.BTCPERP');
// For spot v1 (the old, deprecated client), request public connection first then send required topics on 'open' // For spot v1 (the old, deprecated client), request public connection first then send required topics on 'open'
// Not necessary for spot v3 // Not necessary for spot v3
// wsClient.connectPublic(); // wsClient.connectPublic();
// To unsubscribe from topics (after a 5 second delay, in this example): // To unsubscribe from topics (after a 5 second delay, in this example):
// setTimeout(() => { // setTimeout(() => {
// console.log('unsubscribing'); // console.log('unsubscribing');
// wsClient.unsubscribe('trade.BTCUSDT'); // wsClient.unsubscribe('trade.BTCUSDT');
// }, 5 * 1000); // }, 5 * 1000);
// Topics are tracked per websocket type // Topics are tracked per websocket type
// Get a list of subscribed topics (e.g. for public v3 spot topics) (after a 5 second delay) // Get a list of subscribed topics (e.g. for public v3 spot topics) (after a 5 second delay)
setTimeout(() => { setTimeout(() => {
const publicSpotTopics = wsClient const publicSpotTopics = wsClient
.getWsStore() .getWsStore()
.getTopics(WS_KEY_MAP.spotV3Public); .getTopics(WS_KEY_MAP.spotV3Public);
@@ -169,5 +168,4 @@ import { DefaultLogger, WS_KEY_MAP, WebsocketClient } from '../src';
.getWsStore() .getWsStore()
.getTopics(WS_KEY_MAP.spotV3Private); .getTopics(WS_KEY_MAP.spotV3Private);
console.log('private spot topics: ', privateSpotTopics); console.log('private spot topics: ', privateSpotTopics);
}, 5 * 1000); }, 5 * 1000);
})();