fix(#187): signature fails sometimes for spot v3 with param GET requests. add example for query spot tpsl orders
This commit is contained in:
42
examples/rest-spot-tpsl.ts
Normal file
42
examples/rest-spot-tpsl.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { SpotClientV3 } from '../src/index';
|
||||||
|
|
||||||
|
// or
|
||||||
|
// import { SpotClientV3 } from 'bybit-api';
|
||||||
|
|
||||||
|
const symbol = 'BTCUSDT';
|
||||||
|
const key = process.env.API_KEY_COM;
|
||||||
|
const secret = process.env.API_SECRET_COM;
|
||||||
|
|
||||||
|
const client = new SpotClientV3({
|
||||||
|
key,
|
||||||
|
secret,
|
||||||
|
strict_param_validation: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const orderId = undefined;
|
||||||
|
const ordersPerPage = undefined;
|
||||||
|
|
||||||
|
const orders = await client.getOpenOrders(symbol);
|
||||||
|
console.log('orders 1:', orders);
|
||||||
|
|
||||||
|
const normalOrders = await client.getOpenOrders(
|
||||||
|
symbol,
|
||||||
|
orderId,
|
||||||
|
ordersPerPage,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
console.log('normal orders:', normalOrders);
|
||||||
|
|
||||||
|
const tpSlOrders = await client.getOpenOrders(
|
||||||
|
symbol,
|
||||||
|
orderId,
|
||||||
|
ordersPerPage,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
console.log('tpSlOrders:', tpSlOrders);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('request failed: ', e);
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -17,6 +17,7 @@ export const API_ERROR_CODE = {
|
|||||||
/** This could mean bad request, incorrect value types or even incorrect/missing values */
|
/** This could mean bad request, incorrect value types or even incorrect/missing values */
|
||||||
PARAMS_MISSING_OR_WRONG: 10001,
|
PARAMS_MISSING_OR_WRONG: 10001,
|
||||||
INVALID_API_KEY_OR_PERMISSIONS: 10003,
|
INVALID_API_KEY_OR_PERMISSIONS: 10003,
|
||||||
|
SIGNATURE_NOT_VALID: 10004,
|
||||||
INCORRECT_API_KEY_PERMISSIONS: 10005,
|
INCORRECT_API_KEY_PERMISSIONS: 10005,
|
||||||
INCORRECT_PRIVATE_OPERATIONS: 3303001,
|
INCORRECT_PRIVATE_OPERATIONS: 3303001,
|
||||||
/** Account not unified margin, update required */
|
/** Account not unified margin, update required */
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export default abstract class BaseRestClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private isSpotClient() {
|
private isSpotV1Client() {
|
||||||
return this.clientType === REST_CLIENT_TYPE_ENUM.spot;
|
return this.clientType === REST_CLIENT_TYPE_ENUM.spot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ export default abstract class BaseRestClient {
|
|||||||
isPublicApi
|
isPublicApi
|
||||||
);
|
);
|
||||||
|
|
||||||
if (method === 'GET' || this.isSpotClient()) {
|
if (method === 'GET' || this.isSpotV1Client()) {
|
||||||
return {
|
return {
|
||||||
...options,
|
...options,
|
||||||
params: signResult.paramsWithSign,
|
params: signResult.paramsWithSign,
|
||||||
@@ -343,13 +343,20 @@ export default abstract class BaseRestClient {
|
|||||||
|
|
||||||
// usdc is different for some reason
|
// usdc is different for some reason
|
||||||
if (signMethod === 'usdc') {
|
if (signMethod === 'usdc') {
|
||||||
|
const sortProperties = false;
|
||||||
const signRequestParams =
|
const signRequestParams =
|
||||||
method === 'GET'
|
method === 'GET'
|
||||||
? serializeParams(res.originalParams, strictParamValidation)
|
? serializeParams(
|
||||||
|
res.originalParams,
|
||||||
|
strictParamValidation,
|
||||||
|
sortProperties
|
||||||
|
)
|
||||||
: JSON.stringify(res.originalParams);
|
: JSON.stringify(res.originalParams);
|
||||||
|
|
||||||
const paramsStr = timestamp + key + recvWindow + signRequestParams;
|
const paramsStr = timestamp + key + recvWindow + signRequestParams;
|
||||||
res.sign = await signMessage(paramsStr, this.secret);
|
res.sign = await signMessage(paramsStr, this.secret);
|
||||||
|
|
||||||
|
// console.log('sign req: ', paramsStr);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,16 +367,18 @@ export default abstract class BaseRestClient {
|
|||||||
|
|
||||||
// Optional, set to 5000 by default. Increase if timestamp/recv_window errors are seen.
|
// Optional, set to 5000 by default. Increase if timestamp/recv_window errors are seen.
|
||||||
if (recvWindow) {
|
if (recvWindow) {
|
||||||
if (this.isSpotClient()) {
|
if (this.isSpotV1Client()) {
|
||||||
res.originalParams.recvWindow = recvWindow;
|
res.originalParams.recvWindow = recvWindow;
|
||||||
} else {
|
} else {
|
||||||
res.originalParams.recv_window = recvWindow;
|
res.originalParams.recv_window = recvWindow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const sortProperties = true;
|
||||||
|
|
||||||
res.serializedParams = serializeParams(
|
res.serializedParams = serializeParams(
|
||||||
res.originalParams,
|
res.originalParams,
|
||||||
strictParamValidation
|
strictParamValidation,
|
||||||
|
sortProperties
|
||||||
);
|
);
|
||||||
res.sign = await signMessage(res.serializedParams, this.secret);
|
res.sign = await signMessage(res.serializedParams, this.secret);
|
||||||
res.paramsWithSign = {
|
res.paramsWithSign = {
|
||||||
|
|||||||
@@ -30,12 +30,23 @@ export interface RestClientOptions {
|
|||||||
parse_exceptions?: boolean;
|
parse_exceptions?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialise a (flat) object into a query string
|
||||||
|
* @param params the object to serialise
|
||||||
|
* @param strict_validation throw if any properties are undefined
|
||||||
|
* @param sortProperties sort properties alphabetically before building a query string
|
||||||
|
* @returns the params object as a serialised string key1=value1&key2=value2&etc
|
||||||
|
*/
|
||||||
export function serializeParams(
|
export function serializeParams(
|
||||||
params: object = {},
|
params: object = {},
|
||||||
strict_validation = false
|
strict_validation = false,
|
||||||
|
sortProperties = true
|
||||||
): string {
|
): string {
|
||||||
return Object.keys(params)
|
const properties = sortProperties
|
||||||
.sort()
|
? Object.keys(params).sort()
|
||||||
|
: Object.keys(params);
|
||||||
|
|
||||||
|
return properties
|
||||||
.map((key) => {
|
.map((key) => {
|
||||||
const value = params[key];
|
const value = params[key];
|
||||||
if (strict_validation === true && typeof value === 'undefined') {
|
if (strict_validation === true && typeof value === 'undefined') {
|
||||||
|
|||||||
Reference in New Issue
Block a user