@yuants/vendor-binance 0.7.8 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.js +70 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/private-api.js +162 -0
- package/dist/api/private-api.js.map +1 -0
- package/dist/api/public-api.js +52 -0
- package/dist/api/public-api.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interest_rate.js +2 -2
- package/dist/interest_rate.js.map +1 -1
- package/dist/legacy_index.js +270 -237
- package/dist/legacy_index.js.map +1 -1
- package/dist/product.js +2 -2
- package/dist/product.js.map +1 -1
- package/dist/quote.js +4 -4
- package/dist/quote.js.map +1 -1
- package/dist/services/account-actions-with-credential.js +34 -0
- package/dist/services/account-actions-with-credential.js.map +1 -0
- package/dist/services/accounts/profile.js +22 -0
- package/dist/services/accounts/profile.js.map +1 -0
- package/dist/services/accounts/spot.js +44 -0
- package/dist/services/accounts/spot.js.map +1 -0
- package/dist/services/accounts/unified.js +56 -0
- package/dist/services/accounts/unified.js.map +1 -0
- package/dist/services/order-actions-with-credential.js +19 -0
- package/dist/services/order-actions-with-credential.js.map +1 -0
- package/dist/services/orders/cancelOrder.js +39 -0
- package/dist/services/orders/cancelOrder.js.map +1 -0
- package/dist/services/orders/listOrders.js +49 -0
- package/dist/services/orders/listOrders.js.map +1 -0
- package/dist/services/orders/order-utils.js +118 -0
- package/dist/services/orders/order-utils.js.map +1 -0
- package/dist/services/orders/submitOrder.js +70 -0
- package/dist/services/orders/submitOrder.js.map +1 -0
- package/lib/api/client.d.ts +16 -0
- package/lib/api/client.d.ts.map +1 -0
- package/lib/api/client.js +80 -0
- package/lib/api/client.js.map +1 -0
- package/lib/api/private-api.d.ts +477 -0
- package/lib/api/private-api.d.ts.map +1 -0
- package/lib/api/private-api.js +183 -0
- package/lib/api/private-api.js.map +1 -0
- package/lib/api/public-api.d.ts +150 -0
- package/lib/api/public-api.d.ts.map +1 -0
- package/lib/api/public-api.js +61 -0
- package/lib/api/public-api.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/interest_rate.js +2 -2
- package/lib/interest_rate.js.map +1 -1
- package/lib/legacy_index.js +270 -237
- package/lib/legacy_index.js.map +1 -1
- package/lib/product.js +2 -2
- package/lib/product.js.map +1 -1
- package/lib/quote.js +4 -4
- package/lib/quote.js.map +1 -1
- package/lib/services/account-actions-with-credential.d.ts +2 -0
- package/lib/services/account-actions-with-credential.d.ts.map +1 -0
- package/lib/services/account-actions-with-credential.js +36 -0
- package/lib/services/account-actions-with-credential.js.map +1 -0
- package/lib/services/accounts/profile.d.ts +7 -0
- package/lib/services/accounts/profile.d.ts.map +1 -0
- package/lib/services/accounts/profile.js +26 -0
- package/lib/services/accounts/profile.js.map +1 -0
- package/lib/services/accounts/spot.d.ts +4 -0
- package/lib/services/accounts/spot.d.ts.map +1 -0
- package/lib/services/accounts/spot.js +48 -0
- package/lib/services/accounts/spot.js.map +1 -0
- package/lib/services/accounts/unified.d.ts +4 -0
- package/lib/services/accounts/unified.d.ts.map +1 -0
- package/lib/services/accounts/unified.js +60 -0
- package/lib/services/accounts/unified.js.map +1 -0
- package/lib/services/order-actions-with-credential.d.ts +2 -0
- package/lib/services/order-actions-with-credential.d.ts.map +1 -0
- package/lib/services/order-actions-with-credential.js +21 -0
- package/lib/services/order-actions-with-credential.js.map +1 -0
- package/lib/services/orders/cancelOrder.d.ts +4 -0
- package/lib/services/orders/cancelOrder.d.ts.map +1 -0
- package/lib/services/orders/cancelOrder.js +43 -0
- package/lib/services/orders/cancelOrder.js.map +1 -0
- package/lib/services/orders/listOrders.d.ts +4 -0
- package/lib/services/orders/listOrders.d.ts.map +1 -0
- package/lib/services/orders/listOrders.js +53 -0
- package/lib/services/orders/listOrders.js.map +1 -0
- package/lib/services/orders/order-utils.d.ts +12 -0
- package/lib/services/orders/order-utils.d.ts.map +1 -0
- package/lib/services/orders/order-utils.js +131 -0
- package/lib/services/orders/order-utils.js.map +1 -0
- package/lib/services/orders/submitOrder.d.ts +4 -0
- package/lib/services/orders/submitOrder.d.ts.map +1 -0
- package/lib/services/orders/submitOrder.js +74 -0
- package/lib/services/orders/submitOrder.js.map +1 -0
- package/package.json +11 -19
- package/temp/package-deps.json +32 -19
- package/dist/api.js +0 -248
- package/dist/api.js.map +0 -1
- package/lib/api.d.ts +0 -576
- package/lib/api.d.ts.map +0 -1
- package/lib/api.js +0 -256
- package/lib/api.js.map +0 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { decodePath } from '@yuants/utils';
|
|
2
|
+
import { createHash } from 'crypto';
|
|
3
|
+
export const decodeFutureSymbol = (product_id) => {
|
|
4
|
+
const [instType, symbol] = decodePath(product_id);
|
|
5
|
+
if (instType !== 'usdt-future' || !symbol) {
|
|
6
|
+
throw new Error(`Unsupported product_id for Binance futures: ${product_id}`);
|
|
7
|
+
}
|
|
8
|
+
return symbol;
|
|
9
|
+
};
|
|
10
|
+
export const decodeSpotSymbol = (product_id) => {
|
|
11
|
+
try {
|
|
12
|
+
const [instType, symbol] = decodePath(product_id);
|
|
13
|
+
if ((instType === null || instType === void 0 ? void 0 : instType.toLowerCase()) === 'spot' && symbol) {
|
|
14
|
+
return symbol;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
// ignore decode errors and fall back to raw product id
|
|
19
|
+
}
|
|
20
|
+
if (!product_id.includes('/')) {
|
|
21
|
+
return product_id;
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`Unsupported product_id for Binance spot: ${product_id}`);
|
|
24
|
+
};
|
|
25
|
+
export const mapOrderDirectionToSide = (direction) => {
|
|
26
|
+
switch (direction) {
|
|
27
|
+
case 'OPEN_LONG':
|
|
28
|
+
case 'CLOSE_SHORT':
|
|
29
|
+
return 'BUY';
|
|
30
|
+
case 'OPEN_SHORT':
|
|
31
|
+
case 'CLOSE_LONG':
|
|
32
|
+
return 'SELL';
|
|
33
|
+
default:
|
|
34
|
+
throw new Error(`Unsupported order_direction: ${direction}`);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
export const mapOrderDirectionToPositionSide = (direction) => {
|
|
38
|
+
switch (direction) {
|
|
39
|
+
case 'OPEN_LONG':
|
|
40
|
+
case 'CLOSE_LONG':
|
|
41
|
+
return 'LONG';
|
|
42
|
+
case 'OPEN_SHORT':
|
|
43
|
+
case 'CLOSE_SHORT':
|
|
44
|
+
return 'SHORT';
|
|
45
|
+
default:
|
|
46
|
+
throw new Error(`Unsupported order_direction for positionSide: ${direction}`);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
export const mapOrderTypeToOrdType = (order_type) => {
|
|
50
|
+
switch (order_type) {
|
|
51
|
+
case 'LIMIT':
|
|
52
|
+
case 'MAKER':
|
|
53
|
+
return 'LIMIT';
|
|
54
|
+
case 'MARKET':
|
|
55
|
+
return 'MARKET';
|
|
56
|
+
default:
|
|
57
|
+
throw new Error(`Unsupported order_type: ${order_type}`);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
export const mapBinanceOrderTypeToYuants = (binanceType) => {
|
|
61
|
+
switch (binanceType) {
|
|
62
|
+
case 'LIMIT':
|
|
63
|
+
return 'LIMIT';
|
|
64
|
+
case 'MARKET':
|
|
65
|
+
return 'MARKET';
|
|
66
|
+
default:
|
|
67
|
+
return 'LIMIT';
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
export const mapBinanceSideToYuantsDirection = (side, positionSide) => {
|
|
71
|
+
if (!side || !positionSide) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
if (positionSide === 'LONG') {
|
|
75
|
+
return side === 'BUY' ? 'OPEN_LONG' : 'CLOSE_LONG';
|
|
76
|
+
}
|
|
77
|
+
if (positionSide === 'SHORT') {
|
|
78
|
+
return side === 'SELL' ? 'OPEN_SHORT' : 'CLOSE_SHORT';
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
};
|
|
82
|
+
export const mapSpotSideToOrderDirection = (side) => {
|
|
83
|
+
if (side === 'SELL') {
|
|
84
|
+
return 'CLOSE_LONG';
|
|
85
|
+
}
|
|
86
|
+
return 'OPEN_LONG';
|
|
87
|
+
};
|
|
88
|
+
export const deriveClientOrderId = (order) => {
|
|
89
|
+
if (order.order_id)
|
|
90
|
+
return `${order.order_id}`;
|
|
91
|
+
const payload = JSON.stringify({
|
|
92
|
+
account_id: order.account_id,
|
|
93
|
+
product_id: order.product_id,
|
|
94
|
+
order_direction: order.order_direction,
|
|
95
|
+
order_type: order.order_type,
|
|
96
|
+
price: order.price,
|
|
97
|
+
volume: order.volume,
|
|
98
|
+
});
|
|
99
|
+
return `YUANTS${createHash('sha256').update(payload).digest('hex').slice(0, 24)}`;
|
|
100
|
+
};
|
|
101
|
+
const BinanceOrderStatusMap = {
|
|
102
|
+
NEW: 'ACCEPTED',
|
|
103
|
+
PARTIALLY_FILLED: 'TRADED',
|
|
104
|
+
FILLED: 'TRADED',
|
|
105
|
+
PENDING_NEW: 'ACCEPTED',
|
|
106
|
+
PENDING_CANCEL: 'CANCELLED',
|
|
107
|
+
CANCELED: 'CANCELLED',
|
|
108
|
+
CANCELLED: 'CANCELLED',
|
|
109
|
+
REJECTED: 'CANCELLED',
|
|
110
|
+
EXPIRED: 'CANCELLED',
|
|
111
|
+
};
|
|
112
|
+
export const mapBinanceOrderStatus = (status) => {
|
|
113
|
+
var _a;
|
|
114
|
+
if (!status)
|
|
115
|
+
return 'ACCEPTED';
|
|
116
|
+
return (_a = BinanceOrderStatusMap[status]) !== null && _a !== void 0 ? _a : 'ACCEPTED';
|
|
117
|
+
};
|
|
118
|
+
//# sourceMappingURL=order-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order-utils.js","sourceRoot":"","sources":["../../../src/services/orders/order-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { decodePath } from '@yuants/utils';\nimport { createHash } from 'crypto';\n\nexport const decodeFutureSymbol = (product_id: string) => {\n const [instType, symbol] = decodePath(product_id);\n if (instType !== 'usdt-future' || !symbol) {\n throw new Error(`Unsupported product_id for Binance futures: ${product_id}`);\n }\n return symbol;\n};\n\nexport const decodeSpotSymbol = (product_id: string) => {\n try {\n const [instType, symbol] = decodePath(product_id);\n if (instType?.toLowerCase() === 'spot' && symbol) {\n return symbol;\n }\n } catch (err) {\n // ignore decode errors and fall back to raw product id\n }\n if (!product_id.includes('/')) {\n return product_id;\n }\n throw new Error(`Unsupported product_id for Binance spot: ${product_id}`);\n};\n\nexport const mapOrderDirectionToSide = (direction?: IOrder['order_direction']) => {\n switch (direction) {\n case 'OPEN_LONG':\n case 'CLOSE_SHORT':\n return 'BUY';\n case 'OPEN_SHORT':\n case 'CLOSE_LONG':\n return 'SELL';\n default:\n throw new Error(`Unsupported order_direction: ${direction}`);\n }\n};\n\nexport const mapOrderDirectionToPositionSide = (direction?: IOrder['order_direction']) => {\n switch (direction) {\n case 'OPEN_LONG':\n case 'CLOSE_LONG':\n return 'LONG';\n case 'OPEN_SHORT':\n case 'CLOSE_SHORT':\n return 'SHORT';\n default:\n throw new Error(`Unsupported order_direction for positionSide: ${direction}`);\n }\n};\n\nexport const mapOrderTypeToOrdType = (order_type?: IOrder['order_type']) => {\n switch (order_type) {\n case 'LIMIT':\n case 'MAKER':\n return 'LIMIT';\n case 'MARKET':\n return 'MARKET';\n default:\n throw new Error(`Unsupported order_type: ${order_type}`);\n }\n};\n\nexport const mapBinanceOrderTypeToYuants = (binanceType?: string): IOrder['order_type'] => {\n switch (binanceType) {\n case 'LIMIT':\n return 'LIMIT';\n case 'MARKET':\n return 'MARKET';\n default:\n return 'LIMIT';\n }\n};\n\nexport const mapBinanceSideToYuantsDirection = (\n side?: string,\n positionSide?: string,\n): IOrder['order_direction'] | undefined => {\n if (!side || !positionSide) {\n return undefined;\n }\n if (positionSide === 'LONG') {\n return side === 'BUY' ? 'OPEN_LONG' : 'CLOSE_LONG';\n }\n if (positionSide === 'SHORT') {\n return side === 'SELL' ? 'OPEN_SHORT' : 'CLOSE_SHORT';\n }\n return undefined;\n};\n\nexport const mapSpotSideToOrderDirection = (side?: string): IOrder['order_direction'] => {\n if (side === 'SELL') {\n return 'CLOSE_LONG';\n }\n return 'OPEN_LONG';\n};\n\nexport const deriveClientOrderId = (order: IOrder) => {\n if (order.order_id) return `${order.order_id}`;\n const payload = JSON.stringify({\n account_id: order.account_id,\n product_id: order.product_id,\n order_direction: order.order_direction,\n order_type: order.order_type,\n price: order.price,\n volume: order.volume,\n });\n return `YUANTS${createHash('sha256').update(payload).digest('hex').slice(0, 24)}`;\n};\n\nconst BinanceOrderStatusMap: Record<string, IOrder['order_status']> = {\n NEW: 'ACCEPTED',\n PARTIALLY_FILLED: 'TRADED',\n FILLED: 'TRADED',\n PENDING_NEW: 'ACCEPTED',\n PENDING_CANCEL: 'CANCELLED',\n CANCELED: 'CANCELLED',\n CANCELLED: 'CANCELLED',\n REJECTED: 'CANCELLED',\n EXPIRED: 'CANCELLED',\n};\n\nexport const mapBinanceOrderStatus = (status?: string): IOrder['order_status'] => {\n if (!status) return 'ACCEPTED';\n return BinanceOrderStatusMap[status] ?? 'ACCEPTED';\n};\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { isApiError } from '../../api/client';
|
|
2
|
+
import { postSpotOrder, postUmOrder } from '../../api/private-api';
|
|
3
|
+
import { decodeFutureSymbol, decodeSpotSymbol, deriveClientOrderId, mapOrderDirectionToPositionSide, mapOrderDirectionToSide, mapOrderTypeToOrdType, } from './order-utils';
|
|
4
|
+
const submitUnifiedOrder = async (credential, order) => {
|
|
5
|
+
const symbol = decodeFutureSymbol(order.product_id);
|
|
6
|
+
if (!order.volume) {
|
|
7
|
+
throw new Error('Binance submitOrder requires order.volume to be set');
|
|
8
|
+
}
|
|
9
|
+
const side = mapOrderDirectionToSide(order.order_direction);
|
|
10
|
+
const positionSide = mapOrderDirectionToPositionSide(order.order_direction);
|
|
11
|
+
const type = mapOrderTypeToOrdType(order.order_type);
|
|
12
|
+
const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
|
|
13
|
+
const reduceOnly = order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;
|
|
14
|
+
const res = await postUmOrder(credential, {
|
|
15
|
+
symbol,
|
|
16
|
+
side,
|
|
17
|
+
positionSide,
|
|
18
|
+
type,
|
|
19
|
+
quantity: order.volume,
|
|
20
|
+
price: order.price,
|
|
21
|
+
timeInForce,
|
|
22
|
+
reduceOnly,
|
|
23
|
+
newClientOrderId: deriveClientOrderId(order),
|
|
24
|
+
});
|
|
25
|
+
if (isApiError(res)) {
|
|
26
|
+
throw new Error(`Binance submit unified order failed: ${res.code} ${res.msg}`);
|
|
27
|
+
}
|
|
28
|
+
return { order_id: `${res.orderId}` };
|
|
29
|
+
};
|
|
30
|
+
const submitSpotOrder = async (credential, order) => {
|
|
31
|
+
const symbol = decodeSpotSymbol(order.product_id);
|
|
32
|
+
if (!order.volume) {
|
|
33
|
+
throw new Error('Binance submitOrder requires order.volume to be set');
|
|
34
|
+
}
|
|
35
|
+
const side = mapOrderDirectionToSide(order.order_direction);
|
|
36
|
+
const type = mapOrderTypeToOrdType(order.order_type);
|
|
37
|
+
const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
|
|
38
|
+
const params = {
|
|
39
|
+
symbol,
|
|
40
|
+
side,
|
|
41
|
+
type,
|
|
42
|
+
quantity: order.volume,
|
|
43
|
+
newClientOrderId: deriveClientOrderId(order),
|
|
44
|
+
};
|
|
45
|
+
if (type === 'LIMIT') {
|
|
46
|
+
if (order.price === undefined) {
|
|
47
|
+
throw new Error('Binance spot LIMIT order requires price');
|
|
48
|
+
}
|
|
49
|
+
params.price = order.price;
|
|
50
|
+
params.timeInForce = timeInForce;
|
|
51
|
+
}
|
|
52
|
+
if (order.price !== undefined && type === 'MARKET') {
|
|
53
|
+
params.price = order.price;
|
|
54
|
+
}
|
|
55
|
+
const res = await postSpotOrder(credential, params);
|
|
56
|
+
if (isApiError(res)) {
|
|
57
|
+
throw new Error(`Binance submit spot order failed: ${res.code} ${res.msg}`);
|
|
58
|
+
}
|
|
59
|
+
return { order_id: `${res.orderId}` };
|
|
60
|
+
};
|
|
61
|
+
export const submitOrder = async (credential, order) => {
|
|
62
|
+
if (order.account_id.includes('/unified/')) {
|
|
63
|
+
return submitUnifiedOrder(credential, order);
|
|
64
|
+
}
|
|
65
|
+
if (order.account_id.includes('/spot/')) {
|
|
66
|
+
return submitSpotOrder(credential, order);
|
|
67
|
+
}
|
|
68
|
+
throw new Error(`Unsupported account_id for submitOrder: ${order.account_id}`);
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=submitOrder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submitOrder.js","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"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","sourcesContent":["import { IActionHandlerOfSubmitOrder } from '@yuants/data-order';\nimport { isApiError } from '../../api/client';\nimport { ICredential, postSpotOrder, postUmOrder } from '../../api/private-api';\nimport {\n decodeFutureSymbol,\n decodeSpotSymbol,\n deriveClientOrderId,\n mapOrderDirectionToPositionSide,\n mapOrderDirectionToSide,\n mapOrderTypeToOrdType,\n} from './order-utils';\n\nconst submitUnifiedOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeFutureSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n const side = mapOrderDirectionToSide(order.order_direction);\n const positionSide = mapOrderDirectionToPositionSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const reduceOnly =\n order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;\n\n const res = await postUmOrder(credential, {\n symbol,\n side,\n positionSide,\n type,\n quantity: order.volume,\n price: order.price,\n timeInForce,\n reduceOnly,\n newClientOrderId: deriveClientOrderId(order),\n });\n if (isApiError(res)) {\n throw new Error(`Binance submit unified order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nconst submitSpotOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeSpotSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n const side = mapOrderDirectionToSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const params: Parameters<typeof postSpotOrder>[1] = {\n symbol,\n side,\n type,\n quantity: order.volume,\n newClientOrderId: deriveClientOrderId(order),\n };\n if (type === 'LIMIT') {\n if (order.price === undefined) {\n throw new Error('Binance spot LIMIT order requires price');\n }\n params.price = order.price;\n params.timeInForce = timeInForce;\n }\n if (order.price !== undefined && type === 'MARKET') {\n params.price = order.price;\n }\n const res = await postSpotOrder(credential, params);\n if (isApiError(res)) {\n throw new Error(`Binance submit spot order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nexport const submitOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n if (order.account_id.includes('/unified/')) {\n return submitUnifiedOrder(credential, order);\n }\n if (order.account_id.includes('/spot/')) {\n return submitSpotOrder(credential, order);\n }\n throw new Error(`Unsupported account_id for submitOrder: ${order.account_id}`);\n};\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare type HttpMethod = 'GET' | 'POST' | 'DELETE' | 'PUT';
|
|
2
|
+
declare type RequestParams = Record<string, string | number | boolean | undefined>;
|
|
3
|
+
export interface ICredential {
|
|
4
|
+
access_key: string;
|
|
5
|
+
secret_key: string;
|
|
6
|
+
}
|
|
7
|
+
export interface IApiError {
|
|
8
|
+
code: number;
|
|
9
|
+
msg: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const isApiError: <T>(value: IApiError | T) => value is IApiError;
|
|
12
|
+
export declare const requestPublic: <T>(method: HttpMethod, endpoint: string, params?: RequestParams) => Promise<T>;
|
|
13
|
+
export declare const requestPrivate: <T>(credential: ICredential, method: HttpMethod, endpoint: string, params?: RequestParams) => Promise<T>;
|
|
14
|
+
export declare const getDefaultCredential: () => ICredential;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAOA,aAAK,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEpD,aAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;AAE3E,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,UAAU,iDAC0E,CAAC;AA4ElG,eAAO,MAAM,aAAa,cAAe,UAAU,YAAY,MAAM,WAAW,aAAa,eACvD,CAAC;AAEvC,eAAO,MAAM,cAAc,kBACb,WAAW,UACf,UAAU,YACR,MAAM,WACP,aAAa,eAC6B,CAAC;AAEtD,eAAO,MAAM,oBAAoB,QAAO,WAOvC,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getDefaultCredential = exports.requestPrivate = exports.requestPublic = exports.isApiError = void 0;
|
|
7
|
+
const protocol_1 = require("@yuants/protocol");
|
|
8
|
+
const utils_1 = require("@yuants/utils");
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
11
|
+
const MetricBinanceApiUsedWeight = protocol_1.GlobalPrometheusRegistry.gauge('binance_api_used_weight', '');
|
|
12
|
+
const isApiError = (value) => typeof (value === null || value === void 0 ? void 0 : value.code) === 'number' && typeof (value === null || value === void 0 ? void 0 : value.msg) === 'string';
|
|
13
|
+
exports.isApiError = isApiError;
|
|
14
|
+
const appendParams = (url, params) => {
|
|
15
|
+
if (!params)
|
|
16
|
+
return;
|
|
17
|
+
const entries = Object.entries(params).filter(([, value]) => value !== undefined);
|
|
18
|
+
const timestampEntry = entries.find(([key]) => key === 'timestamp');
|
|
19
|
+
const restEntries = entries.filter(([key]) => key !== 'timestamp');
|
|
20
|
+
restEntries
|
|
21
|
+
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
|
|
22
|
+
.forEach(([key, value]) => {
|
|
23
|
+
url.searchParams.set(key, String(value));
|
|
24
|
+
});
|
|
25
|
+
if (timestampEntry) {
|
|
26
|
+
url.searchParams.set(timestampEntry[0], String(timestampEntry[1]));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const callApi = async (method, endpoint, params, credential) => {
|
|
30
|
+
const url = new URL(endpoint);
|
|
31
|
+
const normalizedParams = Object.assign({}, params);
|
|
32
|
+
if (credential) {
|
|
33
|
+
if (normalizedParams.recvWindow === undefined) {
|
|
34
|
+
// FYI https://developers.binance.com/docs/derivatives/usds-margined-futures/general-info#timing-security
|
|
35
|
+
normalizedParams.recvWindow = 5000;
|
|
36
|
+
}
|
|
37
|
+
if (normalizedParams.timestamp === undefined) {
|
|
38
|
+
normalizedParams.timestamp = Date.now();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
appendParams(url, normalizedParams);
|
|
42
|
+
let headers;
|
|
43
|
+
if (credential) {
|
|
44
|
+
const signData = url.search.slice(1);
|
|
45
|
+
const signature = crypto_js_1.default.enc.Hex.stringify(crypto_js_1.default.HmacSHA256(signData, credential.secret_key));
|
|
46
|
+
url.searchParams.set('signature', signature);
|
|
47
|
+
headers = {
|
|
48
|
+
'Content-Type': 'application/json;charset=utf-8',
|
|
49
|
+
'X-MBX-APIKEY': credential.access_key,
|
|
50
|
+
};
|
|
51
|
+
console.info((0, utils_1.formatTime)(Date.now()), method, url.href, JSON.stringify(headers), url.searchParams.toString(), signData);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.info((0, utils_1.formatTime)(Date.now()), method, url.href);
|
|
55
|
+
}
|
|
56
|
+
const res = await fetch(url.href, {
|
|
57
|
+
method,
|
|
58
|
+
headers,
|
|
59
|
+
});
|
|
60
|
+
const usedWeight1M = res.headers.get('x-mbx-used-weight-1m');
|
|
61
|
+
console.info((0, utils_1.formatTime)(Date.now()), 'response', method, url.href, res.status, `usedWeight1M=${usedWeight1M !== null && usedWeight1M !== void 0 ? usedWeight1M : 'N/A'}`);
|
|
62
|
+
if (usedWeight1M) {
|
|
63
|
+
MetricBinanceApiUsedWeight.set(+usedWeight1M);
|
|
64
|
+
}
|
|
65
|
+
return res.json();
|
|
66
|
+
};
|
|
67
|
+
const requestPublic = (method, endpoint, params) => callApi(method, endpoint, params);
|
|
68
|
+
exports.requestPublic = requestPublic;
|
|
69
|
+
const requestPrivate = (credential, method, endpoint, params) => callApi(method, endpoint, params, credential);
|
|
70
|
+
exports.requestPrivate = requestPrivate;
|
|
71
|
+
const getDefaultCredential = () => {
|
|
72
|
+
const access_key = process.env.ACCESS_KEY;
|
|
73
|
+
const secret_key = process.env.SECRET_KEY;
|
|
74
|
+
if (!access_key || !secret_key) {
|
|
75
|
+
throw new Error('Missing Binance credential: ACCESS_KEY and SECRET_KEY must be set');
|
|
76
|
+
}
|
|
77
|
+
return { access_key, secret_key };
|
|
78
|
+
};
|
|
79
|
+
exports.getDefaultCredential = getDefaultCredential;
|
|
80
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { GlobalPrometheusRegistry } from '@yuants/protocol';\nimport { formatTime } from '@yuants/utils';\n// @ts-ignore\nimport CryptoJS from 'crypto-js';\n\nconst MetricBinanceApiUsedWeight = GlobalPrometheusRegistry.gauge('binance_api_used_weight', '');\n\ntype HttpMethod = 'GET' | 'POST' | 'DELETE' | 'PUT';\n\ntype RequestParams = Record<string, string | number | boolean | undefined>;\n\nexport interface ICredential {\n access_key: string;\n secret_key: string;\n}\n\nexport interface IApiError {\n code: number;\n msg: string;\n}\n\nexport const isApiError = <T>(value: T | IApiError): value is IApiError =>\n typeof (value as IApiError)?.code === 'number' && typeof (value as IApiError)?.msg === 'string';\n\nconst appendParams = (url: URL, params?: RequestParams) => {\n if (!params) return;\n const entries = Object.entries(params).filter(([, value]) => value !== undefined);\n const timestampEntry = entries.find(([key]) => key === 'timestamp');\n const restEntries = entries.filter(([key]) => key !== 'timestamp');\n restEntries\n .sort(([keyA], [keyB]) => keyA.localeCompare(keyB))\n .forEach(([key, value]) => {\n url.searchParams.set(key, String(value));\n });\n if (timestampEntry) {\n url.searchParams.set(timestampEntry[0], String(timestampEntry[1]));\n }\n};\n\nconst callApi = async <T>(\n method: HttpMethod,\n endpoint: string,\n params?: RequestParams,\n credential?: ICredential,\n): Promise<T> => {\n const url = new URL(endpoint);\n const normalizedParams: RequestParams = { ...params };\n if (credential) {\n if (normalizedParams.recvWindow === undefined) {\n // FYI https://developers.binance.com/docs/derivatives/usds-margined-futures/general-info#timing-security\n normalizedParams.recvWindow = 5000;\n }\n if (normalizedParams.timestamp === undefined) {\n normalizedParams.timestamp = Date.now();\n }\n }\n appendParams(url, normalizedParams);\n\n let headers: Record<string, string> | undefined;\n if (credential) {\n const signData = url.search.slice(1);\n const signature = CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA256(signData, credential.secret_key));\n url.searchParams.set('signature', signature);\n headers = {\n 'Content-Type': 'application/json;charset=utf-8',\n 'X-MBX-APIKEY': credential.access_key,\n };\n console.info(\n formatTime(Date.now()),\n method,\n url.href,\n JSON.stringify(headers),\n url.searchParams.toString(),\n signData,\n );\n } else {\n console.info(formatTime(Date.now()), method, url.href);\n }\n\n const res = await fetch(url.href, {\n method,\n headers,\n });\n const usedWeight1M = res.headers.get('x-mbx-used-weight-1m');\n console.info(\n formatTime(Date.now()),\n 'response',\n method,\n url.href,\n res.status,\n `usedWeight1M=${usedWeight1M ?? 'N/A'}`,\n );\n if (usedWeight1M) {\n MetricBinanceApiUsedWeight.set(+usedWeight1M);\n }\n return res.json() as Promise<T>;\n};\n\nexport const requestPublic = <T>(method: HttpMethod, endpoint: string, params?: RequestParams) =>\n callApi<T>(method, endpoint, params);\n\nexport const requestPrivate = <T>(\n credential: ICredential,\n method: HttpMethod,\n endpoint: string,\n params?: RequestParams,\n) => callApi<T>(method, endpoint, params, credential);\n\nexport const getDefaultCredential = (): ICredential => {\n const access_key = process.env.ACCESS_KEY;\n const secret_key = process.env.SECRET_KEY;\n if (!access_key || !secret_key) {\n throw new Error('Missing Binance credential: ACCESS_KEY and SECRET_KEY must be set');\n }\n return { access_key, secret_key };\n};\n"]}
|