v1.1.0: feat() enable uri encode for GET requests by default. add env var for tracing http requests.
This commit is contained in:
51
README.md
51
README.md
@@ -4,12 +4,12 @@
|
|||||||
[][1]
|
[][1]
|
||||||
[](https://www.codefactor.io/repository/github/tiagosiebler/bitget-api) [](https://t.me/nodetraders)
|
[](https://www.codefactor.io/repository/github/tiagosiebler/bitget-api) [](https://t.me/nodetraders)
|
||||||
|
|
||||||
|
|
||||||
[][1]
|
[][1]
|
||||||
|
|
||||||
[1]: https://www.npmjs.com/package/bitget-api
|
[1]: https://www.npmjs.com/package/bitget-api
|
||||||
|
|
||||||
Node.js connector for the Bitget APIs and WebSockets:
|
Node.js connector for the Bitget APIs and WebSockets:
|
||||||
|
|
||||||
- Complete integration with all Bitget APIs.
|
- Complete integration with all Bitget APIs.
|
||||||
- TypeScript support (with type declarations for most API requests & responses).
|
- TypeScript support (with type declarations for most API requests & responses).
|
||||||
- Over 100 integration tests making real API calls & WebSocket connections, validating any changes before they reach npm.
|
- Over 100 integration tests making real API calls & WebSocket connections, validating any changes before they reach npm.
|
||||||
@@ -18,14 +18,18 @@ Node.js connector for the Bitget APIs and WebSockets:
|
|||||||
- Browser support (via webpack bundle - see "Browser Usage" below).
|
- Browser support (via webpack bundle - see "Browser Usage" below).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
`npm install --save bitget-api`
|
`npm install --save bitget-api`
|
||||||
|
|
||||||
## Issues & Discussion
|
## Issues & Discussion
|
||||||
|
|
||||||
- Issues? Check the [issues tab](https://github.com/tiagosiebler/bitget-api/issues).
|
- Issues? Check the [issues tab](https://github.com/tiagosiebler/bitget-api/issues).
|
||||||
- Discuss & collaborate with other node devs? Join our [Node.js Algo Traders](https://t.me/nodetraders) engineering community on telegram.
|
- Discuss & collaborate with other node devs? Join our [Node.js Algo Traders](https://t.me/nodetraders) engineering community on telegram.
|
||||||
|
|
||||||
## Related projects
|
## Related projects
|
||||||
|
|
||||||
Check out my related projects:
|
Check out my related projects:
|
||||||
|
|
||||||
- Try my connectors:
|
- Try my connectors:
|
||||||
- [binance](https://www.npmjs.com/package/binance)
|
- [binance](https://www.npmjs.com/package/binance)
|
||||||
- [bybit-api](https://www.npmjs.com/package/bybit-api)
|
- [bybit-api](https://www.npmjs.com/package/bybit-api)
|
||||||
@@ -38,13 +42,17 @@ Check out my related projects:
|
|||||||
- [awesome-crypto-examples](https://github.com/tiagosiebler/awesome-crypto-examples)
|
- [awesome-crypto-examples](https://github.com/tiagosiebler/awesome-crypto-examples)
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Most methods pass values as-is into HTTP requests. These can be populated using parameters specified by Bitget's API documentation, or check the type definition in each class within this repository (see table below for convenient links to each class).
|
Most methods pass values as-is into HTTP requests. These can be populated using parameters specified by Bitget's API documentation, or check the type definition in each class within this repository (see table below for convenient links to each class).
|
||||||
|
|
||||||
- [Bitget API Documentation](https://www.bitget.com/docs-v5/en/#rest-api).
|
- [Bitget API Documentation](https://www.bitget.com/docs-v5/en/#rest-api).
|
||||||
|
|
||||||
## Structure
|
## Structure
|
||||||
|
|
||||||
This connector is fully compatible with both TypeScript and pure JavaScript projects, while the connector is written in TypeScript. A pure JavaScript version can be built using `npm run build`, which is also the version published to [npm](https://www.npmjs.com/package/bitget-api).
|
This connector is fully compatible with both TypeScript and pure JavaScript projects, while the connector is written in TypeScript. A pure JavaScript version can be built using `npm run build`, which is also the version published to [npm](https://www.npmjs.com/package/bitget-api).
|
||||||
|
|
||||||
The version on npm is the output from the `build` command and can be used in projects without TypeScript (although TypeScript is definitely recommended).
|
The version on npm is the output from the `build` command and can be used in projects without TypeScript (although TypeScript is definitely recommended).
|
||||||
|
|
||||||
- [src](./src) - the whole connector written in TypeScript
|
- [src](./src) - the whole connector written in TypeScript
|
||||||
- [lib](./lib) - the JavaScript version of the project (built from TypeScript). This should not be edited directly, as it will be overwritten with each release.
|
- [lib](./lib) - the JavaScript version of the project (built from TypeScript). This should not be edited directly, as it will be overwritten with each release.
|
||||||
- [dist](./dist) - the webpack bundle of the project for use in browser environments (see guidance on webpack below).
|
- [dist](./dist) - the webpack bundle of the project for use in browser environments (see guidance on webpack below).
|
||||||
@@ -53,22 +61,24 @@ The version on npm is the output from the `build` command and can be used in pro
|
|||||||
---
|
---
|
||||||
|
|
||||||
## REST API Clients
|
## REST API Clients
|
||||||
|
|
||||||
Each REST API group has a dedicated REST client. To avoid confusion, here are the available REST clients and the corresponding API groups:
|
Each REST API group has a dedicated REST client. To avoid confusion, here are the available REST clients and the corresponding API groups:
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
|:------------------------------------: |:---------------------------------------------------------------------------------------------: |
|
|:------------------------------------: |:---------------------------------------------------------------------------------------------: |
|
||||||
| [SpotClient](src/spot-client.ts) | [Spot APIs](https://bitgetlimited.github.io/apidoc/en/spot/#introduction) |
|
| [SpotClient](src/spot-client.ts) | [Spot APIs](https://bitgetlimited.github.io/apidoc/en/spot/#introduction) |
|
||||||
| [FuturesClient](src/futures-client.ts) | [Futures APIs](https://bitgetlimited.github.io/apidoc/en/mix/#introduction) |
|
| [FuturesClient](src/futures-client.ts) | [Futures APIs](https://bitgetlimited.github.io/apidoc/en/mix/#introduction) |
|
||||||
| [BrokerClient](src/broker-client.ts) | [Broker APIs](https://bitgetlimited.github.io/apidoc/en/broker/#introduction) |
|
| [BrokerClient](src/broker-client.ts) | [Broker APIs](https://bitgetlimited.github.io/apidoc/en/broker/#introduction) |
|
||||||
| [WebsocketClient](src/websocket-client.ts) | Universal client for all Bitget's Websockets |
|
| [WebsocketClient](src/websocket-client.ts) | Universal client for all Bitget's Websockets |
|
||||||
|
|
||||||
Examples for using each client can be found in:
|
Examples for using each client can be found in:
|
||||||
|
|
||||||
- the [examples](./examples) folder.
|
- the [examples](./examples) folder.
|
||||||
- the [awesome-crypto-examples](https://github.com/tiagosiebler/awesome-crypto-examples) repository.
|
- the [awesome-crypto-examples](https://github.com/tiagosiebler/awesome-crypto-examples) repository.
|
||||||
|
|
||||||
If you're missing an example, you're welcome to request one. Priority will be given to [github sponsors](https://github.com/sponsors/tiagosiebler).
|
If you're missing an example, you're welcome to request one. Priority will be given to [github sponsors](https://github.com/sponsors/tiagosiebler).
|
||||||
|
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
First, create API credentials on Bitget's website.
|
First, create API credentials on Bitget's website.
|
||||||
|
|
||||||
All REST clients have can be used in a similar way. However, method names, parameters and responses may vary depending on the API category you're using!
|
All REST clients have can be used in a similar way. However, method names, parameters and responses may vary depending on the API category you're using!
|
||||||
@@ -122,7 +132,10 @@ For more examples, including how to use websockets with bitget, check the [examp
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Customise Logging
|
## Logging
|
||||||
|
|
||||||
|
### Customise logging
|
||||||
|
|
||||||
Pass a custom logger which supports the log methods `silly`, `debug`, `notice`, `info`, `warning` and `error`, or override methods from the default logger as desired.
|
Pass a custom logger which supports the log methods `silly`, `debug`, `notice`, `info`, `warning` and `error`, or override methods from the default logger as desired.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@@ -133,16 +146,22 @@ DefaultLogger.silly = () => {};
|
|||||||
|
|
||||||
const ws = new WebsocketClient(
|
const ws = new WebsocketClient(
|
||||||
{
|
{
|
||||||
apiKey: 'API_KEY',
|
apiKey: 'API_KEY',
|
||||||
apiSecret: 'API_SECRET',
|
apiSecret: 'API_SECRET',
|
||||||
apiPass: 'API_PASS',
|
apiPass: 'API_PASS',
|
||||||
},
|
},
|
||||||
DefaultLogger
|
DefaultLogger,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Debug HTTP requests
|
||||||
|
|
||||||
|
In rare situations, you may want to see the raw HTTP requets being built as well as the API response. These can be enabled by setting the `BITGETTRACE` env var to `true`.
|
||||||
|
|
||||||
## Browser Usage
|
## Browser Usage
|
||||||
|
|
||||||
Build a bundle using webpack:
|
Build a bundle using webpack:
|
||||||
|
|
||||||
- `npm install`
|
- `npm install`
|
||||||
- `npm build`
|
- `npm build`
|
||||||
- `npm pack`
|
- `npm pack`
|
||||||
@@ -152,9 +171,13 @@ The bundle can be found in `dist/`. Altough usage should be largely consistent,
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Contributions & Thanks
|
## Contributions & Thanks
|
||||||
|
|
||||||
### Donations
|
### Donations
|
||||||
|
|
||||||
#### tiagosiebler
|
#### tiagosiebler
|
||||||
|
|
||||||
Support my efforts to make algo trading accessible to all - register with my referral links:
|
Support my efforts to make algo trading accessible to all - register with my referral links:
|
||||||
|
|
||||||
- [Bybit](https://www.bybit.com/en-US/register?affiliate_id=9410&language=en-US&group_id=0&group_type=1)
|
- [Bybit](https://www.bybit.com/en-US/register?affiliate_id=9410&language=en-US&group_id=0&group_type=1)
|
||||||
- [Binance](https://www.binance.com/en/register?ref=20983262)
|
- [Binance](https://www.binance.com/en/register?ref=20983262)
|
||||||
- [Bitget](https://partner.bitget.com/bg/ZNM295)
|
- [Bitget](https://partner.bitget.com/bg/ZNM295)
|
||||||
@@ -162,10 +185,12 @@ Support my efforts to make algo trading accessible to all - register with my ref
|
|||||||
- [FTX](https://ftx.com/referrals#a=ftxapigithub)
|
- [FTX](https://ftx.com/referrals#a=ftxapigithub)
|
||||||
|
|
||||||
Or buy me a coffee using any of these:
|
Or buy me a coffee using any of these:
|
||||||
|
|
||||||
- BTC: `1C6GWZL1XW3jrjpPTS863XtZiXL1aTK7Jk`
|
- BTC: `1C6GWZL1XW3jrjpPTS863XtZiXL1aTK7Jk`
|
||||||
- ETH (ERC20): `0xd773d8e6a50758e1ada699bb6c4f98bb4abf82da`
|
- ETH (ERC20): `0xd773d8e6a50758e1ada699bb6c4f98bb4abf82da`
|
||||||
|
|
||||||
### Contributions & Pull Requests
|
### Contributions & Pull Requests
|
||||||
|
|
||||||
Contributions are encouraged, I will review any incoming pull requests. See the issues tab for todo items.
|
Contributions are encouraged, I will review any incoming pull requests. See the issues tab for todo items.
|
||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|||||||
38
examples/rest-private-futures.ts
Normal file
38
examples/rest-private-futures.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { FuturesClient, WebsocketClient } from '../src/index';
|
||||||
|
|
||||||
|
// or
|
||||||
|
// import { SpotClient } from 'bitget-api';
|
||||||
|
|
||||||
|
// read from environmental variables
|
||||||
|
const API_KEY = process.env.API_KEY_COM;
|
||||||
|
const API_SECRET = process.env.API_SECRET_COM;
|
||||||
|
const API_PASS = process.env.API_PASS_COM;
|
||||||
|
|
||||||
|
const client = new FuturesClient({
|
||||||
|
apiKey: API_KEY,
|
||||||
|
apiSecret: API_SECRET,
|
||||||
|
apiPass: API_PASS,
|
||||||
|
// apiKey: 'apiKeyHere',
|
||||||
|
// apiSecret: 'apiSecretHere',
|
||||||
|
// apiPass: 'apiPassHere',
|
||||||
|
});
|
||||||
|
|
||||||
|
/** This is a simple script wrapped in a immediately invoked function expression, designed to check for any available BTC balance and immediately sell the full amount for USDT */
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const now = new Date();
|
||||||
|
const toTime = new Date(now.getTime() - 24 * 60 * 60 * 1000);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
await client.getAccountBill({
|
||||||
|
symbol: 'BTCUSDT_UMCBL',
|
||||||
|
marginCoin: 'USDT',
|
||||||
|
startTime: now.getTime() + '', // should be sent as a string
|
||||||
|
endTime: toTime.getTime() + '', // should be sent as a string
|
||||||
|
pageSize: 100,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('request failed: ', e);
|
||||||
|
}
|
||||||
|
})();
|
||||||
27
examples/rest-private-spot.ts
Normal file
27
examples/rest-private-spot.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { SpotClient, WebsocketClient } from '../src/index';
|
||||||
|
|
||||||
|
// or
|
||||||
|
// import { SpotClient } from 'bitget-api';
|
||||||
|
|
||||||
|
// read from environmental variables
|
||||||
|
const API_KEY = process.env.API_KEY_COM;
|
||||||
|
const API_SECRET = process.env.API_SECRET_COM;
|
||||||
|
const API_PASS = process.env.API_PASS_COM;
|
||||||
|
|
||||||
|
const client = new SpotClient({
|
||||||
|
apiKey: API_KEY,
|
||||||
|
apiSecret: API_SECRET,
|
||||||
|
apiPass: API_PASS,
|
||||||
|
// apiKey: 'apiKeyHere',
|
||||||
|
// apiSecret: 'apiSecretHere',
|
||||||
|
// apiPass: 'apiPassHere',
|
||||||
|
});
|
||||||
|
|
||||||
|
/** This is a simple script wrapped in a immediately invoked function expression, designed to check for any available BTC balance and immediately sell the full amount for USDT */
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
console.log(await client.getApiKeyInfo());
|
||||||
|
} catch (e) {
|
||||||
|
console.error('request failed: ', e);
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "bitget-api",
|
"name": "bitget-api",
|
||||||
"version": "1.0.6",
|
"version": "1.1.0",
|
||||||
"description": "Node.js connector for Bitget REST APIs and WebSockets, with TypeScript & end-to-end tests.",
|
"description": "Node.js connector for Bitget REST APIs and WebSockets, with TypeScript & end-to-end tests.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
|
|||||||
@@ -26,11 +26,12 @@ interface UnsignedRequest<T extends object | undefined = {}> {
|
|||||||
|
|
||||||
type SignMethod = 'bitget';
|
type SignMethod = 'bitget';
|
||||||
|
|
||||||
if (
|
const ENABLE_HTTP_TRACE =
|
||||||
typeof process === 'object' &&
|
typeof process === 'object' &&
|
||||||
typeof process.env === 'object' &&
|
typeof process.env === 'object' &&
|
||||||
process.env.BITGETTRACE
|
process.env.BITGETTRACE;
|
||||||
) {
|
|
||||||
|
if (ENABLE_HTTP_TRACE) {
|
||||||
axios.interceptors.request.use((request) => {
|
axios.interceptors.request.use((request) => {
|
||||||
console.log(
|
console.log(
|
||||||
new Date(),
|
new Date(),
|
||||||
@@ -91,6 +92,7 @@ export default abstract class BaseRestClient {
|
|||||||
recvWindow: 5000,
|
recvWindow: 5000,
|
||||||
/** Throw errors if any request params are empty */
|
/** Throw errors if any request params are empty */
|
||||||
strictParamValidation: false,
|
strictParamValidation: false,
|
||||||
|
encodeQueryStringValues: true,
|
||||||
...restOptions,
|
...restOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,7 +168,9 @@ export default abstract class BaseRestClient {
|
|||||||
isPublicApi,
|
isPublicApi,
|
||||||
);
|
);
|
||||||
|
|
||||||
// console.log('full request: ', options);
|
if (ENABLE_HTTP_TRACE) {
|
||||||
|
console.log('full request: ', options);
|
||||||
|
}
|
||||||
|
|
||||||
// Dispatch request
|
// Dispatch request
|
||||||
return axios(options)
|
return axios(options)
|
||||||
@@ -250,11 +254,17 @@ export default abstract class BaseRestClient {
|
|||||||
|
|
||||||
// It's possible to override the recv window on a per rquest level
|
// It's possible to override the recv window on a per rquest level
|
||||||
const strictParamValidation = this.options.strictParamValidation;
|
const strictParamValidation = this.options.strictParamValidation;
|
||||||
|
const encodeQueryStringValues = this.options.encodeQueryStringValues;
|
||||||
|
|
||||||
if (signMethod === 'bitget') {
|
if (signMethod === 'bitget') {
|
||||||
const signRequestParams =
|
const signRequestParams =
|
||||||
method === 'GET'
|
method === 'GET'
|
||||||
? serializeParams(data, strictParamValidation, '?')
|
? serializeParams(
|
||||||
|
data,
|
||||||
|
strictParamValidation,
|
||||||
|
encodeQueryStringValues,
|
||||||
|
'?',
|
||||||
|
)
|
||||||
: JSON.stringify(data) || '';
|
: JSON.stringify(data) || '';
|
||||||
|
|
||||||
const paramsStr =
|
const paramsStr =
|
||||||
|
|||||||
@@ -17,6 +17,13 @@ export interface RestClientOptions {
|
|||||||
/** Default: false. If true, we'll throw errors if any params are undefined */
|
/** Default: false. If true, we'll throw errors if any params are undefined */
|
||||||
strictParamValidation?: boolean;
|
strictParamValidation?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default: true.
|
||||||
|
* If true, query string values will be URI Encoded (encodeURIComponent).
|
||||||
|
* This prevents sign errors with GET requests containing unusual parameters (spaces, symbols, etc).
|
||||||
|
*/
|
||||||
|
encodeQueryStringValues?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionally override API protocol + domain
|
* Optionally override API protocol + domain
|
||||||
* e.g baseUrl: 'https://api.bitget.com'
|
* e.g baseUrl: 'https://api.bitget.com'
|
||||||
@@ -30,6 +37,7 @@ export interface RestClientOptions {
|
|||||||
export function serializeParams<T extends object | undefined = {}>(
|
export function serializeParams<T extends object | undefined = {}>(
|
||||||
params: T,
|
params: T,
|
||||||
strict_validation = false,
|
strict_validation = false,
|
||||||
|
encodeValues: boolean = true,
|
||||||
prefixWith: string = '',
|
prefixWith: string = '',
|
||||||
): string {
|
): string {
|
||||||
if (!params) {
|
if (!params) {
|
||||||
@@ -45,7 +53,8 @@ export function serializeParams<T extends object | undefined = {}>(
|
|||||||
'Failed to sign API request due to undefined parameter',
|
'Failed to sign API request due to undefined parameter',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return `${key}=${value}`;
|
const encodedValue = encodeValues ? encodeURIComponent(value) : value;
|
||||||
|
return `${key}=${encodedValue}`;
|
||||||
})
|
})
|
||||||
.join('&');
|
.join('&');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user