@yuants/vendor-aster 0.11.5 → 0.11.7
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/private-api.js +29 -29
- package/dist/api/private-api.js.map +1 -1
- package/dist/api/public-api.js +19 -19
- package/dist/api/public-api.js.map +1 -1
- package/lib/api/private-api.js +28 -28
- package/lib/api/private-api.js.map +1 -1
- package/lib/api/public-api.d.ts.map +1 -1
- package/lib/api/public-api.js +18 -18
- package/lib/api/public-api.js.map +1 -1
- package/package.json +18 -18
- package/temp/build/typescript/ts_Ro1DJWVV.json +1 -1
- package/temp/package-deps.json +23 -23
- package/temp/test/jest/haste-map-0df2c1646479030bb486acc96d7e140a-62fc6fbbf847e4167de25f4822a8f953-1b0100527d0283bc2ce2729ac44cdebc +0 -0
package/dist/api/private-api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var _a;
|
|
2
|
-
import { fetch,
|
|
2
|
+
import { fetch, selectHTTPProxyIpRoundRobinAsync } from '@yuants/http-services';
|
|
3
3
|
import { encodeHex, encodePath, formatTime, HmacSHA256, newError, scopeError, tokenBucket, } from '@yuants/utils';
|
|
4
4
|
import { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';
|
|
5
5
|
import { ASTER_TOKEN_BUCKET_OPTIONS_BY_ID } from './client';
|
|
@@ -27,9 +27,9 @@ const resolveLocalPublicIp = () => {
|
|
|
27
27
|
}
|
|
28
28
|
return 'public-ip-unknown';
|
|
29
29
|
};
|
|
30
|
-
const createRequestContext = () => {
|
|
30
|
+
const createRequestContext = async () => {
|
|
31
31
|
if (shouldUseHttpProxy) {
|
|
32
|
-
const ip =
|
|
32
|
+
const ip = await selectHTTPProxyIpRoundRobinAsync(terminal);
|
|
33
33
|
return { ip };
|
|
34
34
|
}
|
|
35
35
|
return { ip: resolveLocalPublicIp() };
|
|
@@ -93,12 +93,12 @@ const SpotBaseURL = 'https://sapi.asterdex.com';
|
|
|
93
93
|
*
|
|
94
94
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data
|
|
95
95
|
*/
|
|
96
|
-
export const getFApiV4Account = (credential, params) => {
|
|
96
|
+
export const getFApiV4Account = async (credential, params) => {
|
|
97
97
|
const endpoint = '/fapi/v4/account';
|
|
98
98
|
const url = new URL(FutureBaseURL);
|
|
99
99
|
url.pathname = endpoint;
|
|
100
100
|
const weight = 5;
|
|
101
|
-
const requestContext = createRequestContext();
|
|
101
|
+
const requestContext = await createRequestContext();
|
|
102
102
|
acquireRateLimit('GET', url, endpoint, weight, requestContext);
|
|
103
103
|
return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);
|
|
104
104
|
};
|
|
@@ -109,12 +109,12 @@ export const getFApiV4Account = (credential, params) => {
|
|
|
109
109
|
*
|
|
110
110
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E7%94%A8%E6%88%B7%E6%8C%81%E4%BB%93%E9%A3%8E%E9%99%A9v2-user_data
|
|
111
111
|
*/
|
|
112
|
-
export const getFApiV2PositionRisk = (credential, params) => {
|
|
112
|
+
export const getFApiV2PositionRisk = async (credential, params) => {
|
|
113
113
|
const endpoint = '/fapi/v2/positionRisk';
|
|
114
114
|
const url = new URL(FutureBaseURL);
|
|
115
115
|
url.pathname = endpoint;
|
|
116
116
|
const weight = 5;
|
|
117
|
-
const requestContext = createRequestContext();
|
|
117
|
+
const requestContext = await createRequestContext();
|
|
118
118
|
acquireRateLimit('GET', url, endpoint, weight, requestContext);
|
|
119
119
|
return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);
|
|
120
120
|
};
|
|
@@ -123,12 +123,12 @@ export const getFApiV2PositionRisk = (credential, params) => {
|
|
|
123
123
|
*
|
|
124
124
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#L2840-L2855
|
|
125
125
|
*/
|
|
126
|
-
export const getFApiV2Balance = (credential, params) => {
|
|
126
|
+
export const getFApiV2Balance = async (credential, params) => {
|
|
127
127
|
const endpoint = '/fapi/v2/balance';
|
|
128
128
|
const url = new URL(FutureBaseURL);
|
|
129
129
|
url.pathname = endpoint;
|
|
130
130
|
const weight = 5;
|
|
131
|
-
const requestContext = createRequestContext();
|
|
131
|
+
const requestContext = await createRequestContext();
|
|
132
132
|
acquireRateLimit('GET', url, endpoint, weight, requestContext);
|
|
133
133
|
return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);
|
|
134
134
|
};
|
|
@@ -137,12 +137,12 @@ export const getFApiV2Balance = (credential, params) => {
|
|
|
137
137
|
*
|
|
138
138
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#post-fapiv1order-%E7%9A%84%E7%A4%BA%E4%BE%8B
|
|
139
139
|
*/
|
|
140
|
-
export const postFApiV1Order = (credential, params) => {
|
|
140
|
+
export const postFApiV1Order = async (credential, params) => {
|
|
141
141
|
const endpoint = '/fapi/v1/order';
|
|
142
142
|
const url = new URL(FutureBaseURL);
|
|
143
143
|
url.pathname = endpoint;
|
|
144
144
|
const weight = 1;
|
|
145
|
-
const requestContext = createRequestContext();
|
|
145
|
+
const requestContext = await createRequestContext();
|
|
146
146
|
const secondBucketKey = buildTokenBucketKey('order/future/second', requestContext.ip);
|
|
147
147
|
const minuteBucketKey = buildTokenBucketKey('order/future/minute', requestContext.ip);
|
|
148
148
|
scopeError('ASTER_FUTURE_ORDER_API_SECOND_RATE_LIMIT', { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight }, () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/future/second')).acquireSync(weight));
|
|
@@ -156,12 +156,12 @@ export const postFApiV1Order = (credential, params) => {
|
|
|
156
156
|
*
|
|
157
157
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#L2728-L2766
|
|
158
158
|
*/
|
|
159
|
-
export const getFApiV1OpenOrders = (credential, params) => {
|
|
159
|
+
export const getFApiV1OpenOrders = async (credential, params) => {
|
|
160
160
|
const endpoint = '/fapi/v1/openOrders';
|
|
161
161
|
const url = new URL(FutureBaseURL);
|
|
162
162
|
url.pathname = endpoint;
|
|
163
163
|
const weight = (params === null || params === void 0 ? void 0 : params.symbol) ? 1 : 40;
|
|
164
|
-
const requestContext = createRequestContext();
|
|
164
|
+
const requestContext = await createRequestContext();
|
|
165
165
|
scopeError('ASTER_API_RATE_LIMIT', {
|
|
166
166
|
method: 'GET',
|
|
167
167
|
endpoint,
|
|
@@ -180,12 +180,12 @@ export const getFApiV1OpenOrders = (credential, params) => {
|
|
|
180
180
|
*
|
|
181
181
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1196-L1234
|
|
182
182
|
*/
|
|
183
|
-
export const getApiV1OpenOrders = (credential, params) => {
|
|
183
|
+
export const getApiV1OpenOrders = async (credential, params) => {
|
|
184
184
|
const endpoint = '/api/v1/openOrders';
|
|
185
185
|
const url = new URL(SpotBaseURL);
|
|
186
186
|
url.pathname = endpoint;
|
|
187
187
|
const weight = (params === null || params === void 0 ? void 0 : params.symbol) ? 1 : 40;
|
|
188
|
-
const requestContext = createRequestContext();
|
|
188
|
+
const requestContext = await createRequestContext();
|
|
189
189
|
scopeError('ASTER_API_RATE_LIMIT', {
|
|
190
190
|
method: 'GET',
|
|
191
191
|
endpoint,
|
|
@@ -202,12 +202,12 @@ export const getApiV1OpenOrders = (credential, params) => {
|
|
|
202
202
|
*
|
|
203
203
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#L2498-L2516
|
|
204
204
|
*/
|
|
205
|
-
export const deleteFApiV1Order = (credential, params) => {
|
|
205
|
+
export const deleteFApiV1Order = async (credential, params) => {
|
|
206
206
|
const endpoint = '/fapi/v1/order';
|
|
207
207
|
const url = new URL(FutureBaseURL);
|
|
208
208
|
url.pathname = endpoint;
|
|
209
209
|
const weight = 1;
|
|
210
|
-
const requestContext = createRequestContext();
|
|
210
|
+
const requestContext = await createRequestContext();
|
|
211
211
|
const secondBucketKey = buildTokenBucketKey('order/future/second', requestContext.ip);
|
|
212
212
|
const minuteBucketKey = buildTokenBucketKey('order/future/minute', requestContext.ip);
|
|
213
213
|
scopeError('ASTER_FUTURE_ORDER_API_SECOND_RATE_LIMIT', { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight }, () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/future/second')).acquireSync(weight));
|
|
@@ -221,12 +221,12 @@ export const deleteFApiV1Order = (credential, params) => {
|
|
|
221
221
|
*
|
|
222
222
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AF-user_data
|
|
223
223
|
*/
|
|
224
|
-
export const getApiV1Account = (credential, params) => {
|
|
224
|
+
export const getApiV1Account = async (credential, params) => {
|
|
225
225
|
const endpoint = '/api/v1/account';
|
|
226
226
|
const url = new URL(SpotBaseURL);
|
|
227
227
|
url.pathname = endpoint;
|
|
228
228
|
const weight = 5;
|
|
229
|
-
const requestContext = createRequestContext();
|
|
229
|
+
const requestContext = await createRequestContext();
|
|
230
230
|
acquireRateLimit('GET', url, endpoint, weight, requestContext);
|
|
231
231
|
return request(credential, 'GET', SpotBaseURL, endpoint, params, requestContext);
|
|
232
232
|
};
|
|
@@ -237,12 +237,12 @@ export const getApiV1Account = (credential, params) => {
|
|
|
237
237
|
*
|
|
238
238
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC
|
|
239
239
|
*/
|
|
240
|
-
export const getApiV1TickerPrice = (credential, params) => {
|
|
240
|
+
export const getApiV1TickerPrice = async (credential, params) => {
|
|
241
241
|
const endpoint = '/api/v1/ticker/price';
|
|
242
242
|
const url = new URL(SpotBaseURL);
|
|
243
243
|
url.pathname = endpoint;
|
|
244
244
|
const weight = 2;
|
|
245
|
-
const requestContext = createRequestContext();
|
|
245
|
+
const requestContext = await createRequestContext();
|
|
246
246
|
acquireRateLimit('GET', url, endpoint, weight, requestContext);
|
|
247
247
|
return request(credential, 'GET', SpotBaseURL, endpoint, params, requestContext);
|
|
248
248
|
};
|
|
@@ -251,12 +251,12 @@ export const getApiV1TickerPrice = (credential, params) => {
|
|
|
251
251
|
*
|
|
252
252
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#post-apiv1order-%E7%9A%84%E7%A4%BA%E4%BE%8B
|
|
253
253
|
*/
|
|
254
|
-
export const postApiV1Order = (credential, params) => {
|
|
254
|
+
export const postApiV1Order = async (credential, params) => {
|
|
255
255
|
const endpoint = '/api/v1/order';
|
|
256
256
|
const url = new URL(SpotBaseURL);
|
|
257
257
|
url.pathname = endpoint;
|
|
258
258
|
const weight = 1;
|
|
259
|
-
const requestContext = createRequestContext();
|
|
259
|
+
const requestContext = await createRequestContext();
|
|
260
260
|
const secondBucketKey = buildTokenBucketKey('order/spot/second', requestContext.ip);
|
|
261
261
|
const minuteBucketKey = buildTokenBucketKey('order/spot/minute', requestContext.ip);
|
|
262
262
|
scopeError('ASTER_SPOT_ORDER_API_SECOND_RATE_LIMIT', { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight }, () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/spot/second')).acquireSync(weight));
|
|
@@ -270,12 +270,12 @@ export const postApiV1Order = (credential, params) => {
|
|
|
270
270
|
*
|
|
271
271
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1040-L1074
|
|
272
272
|
*/
|
|
273
|
-
export const deleteApiV1Order = (credential, params) => {
|
|
273
|
+
export const deleteApiV1Order = async (credential, params) => {
|
|
274
274
|
const endpoint = '/api/v1/order';
|
|
275
275
|
const url = new URL(SpotBaseURL);
|
|
276
276
|
url.pathname = endpoint;
|
|
277
277
|
const weight = 1;
|
|
278
|
-
const requestContext = createRequestContext();
|
|
278
|
+
const requestContext = await createRequestContext();
|
|
279
279
|
const secondBucketKey = buildTokenBucketKey('order/spot/second', requestContext.ip);
|
|
280
280
|
const minuteBucketKey = buildTokenBucketKey('order/spot/minute', requestContext.ip);
|
|
281
281
|
scopeError('ASTER_SPOT_ORDER_API_SECOND_RATE_LIMIT', { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight }, () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/spot/second')).acquireSync(weight));
|
|
@@ -289,12 +289,12 @@ export const deleteApiV1Order = (credential, params) => {
|
|
|
289
289
|
*
|
|
290
290
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%8E%B7%E5%8F%96%E8%B4%A6%E6%88%B7%E6%8D%9F%E7%9B%8A%E8%B5%84%E9%87%91%E6%B5%81%E6%B0%B4user_data
|
|
291
291
|
*/
|
|
292
|
-
export const getAccountIncome = (credential, params) => {
|
|
292
|
+
export const getAccountIncome = async (credential, params) => {
|
|
293
293
|
const endpoint = '/fapi/v1/income';
|
|
294
294
|
const url = new URL(FutureBaseURL);
|
|
295
295
|
url.pathname = endpoint;
|
|
296
296
|
const weight = 30;
|
|
297
|
-
const requestContext = createRequestContext();
|
|
297
|
+
const requestContext = await createRequestContext();
|
|
298
298
|
acquireRateLimit('GET', url, endpoint, weight, requestContext);
|
|
299
299
|
return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);
|
|
300
300
|
};
|
|
@@ -305,12 +305,12 @@ export const getAccountIncome = (credential, params) => {
|
|
|
305
305
|
*
|
|
306
306
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E6%88%90%E4%BA%A4%E5%8E%86%E5%8F%B2-user_data
|
|
307
307
|
*/
|
|
308
|
-
export const getAccountTradeList = (credential, params) => {
|
|
308
|
+
export const getAccountTradeList = async (credential, params) => {
|
|
309
309
|
const endpoint = '/fapi/v1/userTrades';
|
|
310
310
|
const url = new URL(FutureBaseURL);
|
|
311
311
|
url.pathname = endpoint;
|
|
312
312
|
const weight = 5;
|
|
313
|
-
const requestContext = createRequestContext();
|
|
313
|
+
const requestContext = await createRequestContext();
|
|
314
314
|
acquireRateLimit('GET', url, endpoint, weight, requestContext);
|
|
315
315
|
return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);
|
|
316
316
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"private-api.js","sourceRoot":"","sources":["../../src/api/private-api.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,UAAU,CAAC;AAE5D,MAAM,0BAA0B,GAAG,wBAAwB,CAAC,OAAO,CACjE,gBAAgB,EAChB,0BAA0B,CAC3B,CAAC;AACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AACxC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,CAAC;AACjE,MAAM,SAAS,GAAG,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAA,UAAU,CAAC,KAAK,mCAAI,KAAK,CAAC;AACzE,MAAM,8BAA8B,GAAG,OAAS,CAAC;AACjD,MAAM,gCAAgC,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEnE,IAAI,kBAAkB,EAAE,CAAC;IACvB,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC;AAC3B,CAAC;AAUD,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,EAAU,EAAU,EAAE,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAE/F,MAAM,qBAAqB,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,gCAAgC,CAAC,OAAO,CAAC,CAAC;AAE7F,MAAM,oBAAoB,GAAG,GAAW,EAAE;;IACxC,MAAM,EAAE,GAAG,MAAA,MAAA,QAAQ,CAAC,YAAY,CAAC,IAAI,0CAAE,SAAS,0CAAE,IAAI,EAAE,CAAC;IACzD,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,YAAY,GAAG,MAAA,gCAAgC,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,mCAAI,CAAC,CAAC;IACrF,IAAI,GAAG,GAAG,YAAY,GAAG,8BAA8B,EAAE,CAAC;QACxD,gCAAgC,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,+DAA+D,CAAC,CAAC;IACxG,CAAC;IACD,OAAO,mBAAmB,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,GAAmB,EAAE;IAChD,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;QACjD,OAAO,EAAE,EAAE,EAAE,CAAC;IAChB,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,CAAC;AACxC,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CACvB,MAAc,EACd,GAAQ,EACR,QAAgB,EAChB,MAAc,EACd,cAA8B,EAC9B,EAAE;IACF,MAAM,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IACnE,UAAU,CACR,sBAAsB,EACtB,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,EACrF,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAClF,CAAC;AACJ,CAAC,CAAC;AA4CF,MAAM,OAAO,GAAG,KAAK,EACnB,UAAuB,EACvB,MAAc,EACd,OAAe,EACf,QAAgB,EAChB,SAAkC,EAAE,EACpC,cAA8B,EAClB,EAAE;IACd,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;IAC7C,MAAM,SAAS,GAAG,SAAS,CACzB,MAAM,UAAU,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CACjG,CAAC;IACF,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAE7C,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxD,0BAA0B,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IACnG,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,GAAG,CAAC,QAAQ,EAAE,EACd,kBAAkB;QAChB,CAAC,CAAC;YACE,MAAM;YACN,OAAO,EAAE;gBACP,cAAc,EAAE,UAAU,CAAC,OAAO;aACnC;YACD,MAAM,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;YACjE,QAAQ;SACT;QACH,CAAC,CAAC;YACE,MAAM;YACN,OAAO,EAAE;gBACP,cAAc,EAAE,UAAU,CAAC,OAAO;aACnC;SACF,CACN,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEhC,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,OAAO,CAAC;QAChB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,QAAQ,CACZ,iBAAiB,EACjB;YACE,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO;YACP,MAAM;SACP,EACD,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAClD,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,UAAuB,EACvB,MAA6B,EAmD5B,EAAE;IACH,MAAM,QAAQ,GAAG,kBAAkB,CAAC;IACpC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACnC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACrF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,UAAuB,EACvB,MAEC,EAiBD,EAAE;IACF,MAAM,QAAQ,GAAG,uBAAuB,CAAC;IACzC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACnC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACrF,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,UAAuB,EACvB,MAA6B,EAa7B,EAAE;IACF,MAAM,QAAQ,GAAG,kBAAkB,CAAC;IACpC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACnC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACrF,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,UAAuB,EACvB,MAgBC,EAC+B,EAAE;IAClC,MAAM,QAAQ,GAAG,gBAAgB,CAAC;IAClC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACnC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,MAAM,eAAe,GAAG,mBAAmB,CAAC,qBAAqB,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IACtF,MAAM,eAAe,GAAG,mBAAmB,CAAC,qBAAqB,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IACtF,UAAU,CACR,0CAA0C,EAC1C,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,EACnG,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CACrG,CAAC;IACF,UAAU,CACR,0CAA0C,EAC1C,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,EACnG,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CACrG,CAAC;IACF,OAAO,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,UAAuB,EACvB,MAEC,EACiC,EAAE;IACpC,MAAM,QAAQ,GAAG,qBAAqB,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACnC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,UAAU,CACR,sBAAsB,EACtB;QACE,MAAM,EAAE,KAAK;QACb,QAAQ;QACR,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,QAAQ,EAAE,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;QAC1D,MAAM;QACN,SAAS,EAAE,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA;KAC5B,EACD,GAAG,EAAE,CACH,WAAW,CACT,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC,EAChD,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAChC,CAAC,WAAW,CAAC,MAAM,CAAC,CACxB,CAAC;IACF,OAAO,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACrF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,UAAuB,EACvB,MAEC,EAC+B,EAAE;IAClC,MAAM,QAAQ,GAAG,oBAAoB,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACjC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,UAAU,CACR,sBAAsB,EACtB;QACE,MAAM,EAAE,KAAK;QACb,QAAQ;QACR,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,QAAQ,EAAE,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;QAC1D,MAAM;QACN,SAAS,EAAE,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA;KAC5B,EACD,GAAG,EAAE,CACH,WAAW,CACT,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC,EAChD,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAChC,CAAC,WAAW,CAAC,MAAM,CAAC,CACxB,CAAC;IACF,OAAO,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACnF,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,UAAuB,EACvB,MAIC,EAC+B,EAAE;IAClC,MAAM,QAAQ,GAAG,gBAAgB,CAAC;IAClC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACnC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,MAAM,eAAe,GAAG,mBAAmB,CAAC,qBAAqB,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IACtF,MAAM,eAAe,GAAG,mBAAmB,CAAC,qBAAqB,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IACtF,UAAU,CACR,0CAA0C,EAC1C,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,EACrG,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CACrG,CAAC;IACF,UAAU,CACR,0CAA0C,EAC1C,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,EACrG,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CACrG,CAAC;IACF,OAAO,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACxF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,UAAuB,EACvB,MAA6B,EAa5B,EAAE;IACH,MAAM,QAAQ,GAAG,iBAAiB,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACjC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACnF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,UAAuB,EACvB,MAA6B,EAO7B,EAAE;IACF,MAAM,QAAQ,GAAG,sBAAsB,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACjC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACnF,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,UAAuB,EACvB,MAQC,EAGA,EAAE;IACH,MAAM,QAAQ,GAAG,eAAe,CAAC;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACjC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,MAAM,eAAe,GAAG,mBAAmB,CAAC,mBAAmB,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IACpF,MAAM,eAAe,GAAG,mBAAmB,CAAC,mBAAmB,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IACpF,UAAU,CACR,wCAAwC,EACxC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,EACnG,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CACnG,CAAC;IACF,UAAU,CACR,wCAAwC,EACxC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,EACnG,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CACnG,CAAC;IACF,OAAO,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACpF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,UAAuB,EACvB,MAIC,EAC+B,EAAE;IAClC,MAAM,QAAQ,GAAG,eAAe,CAAC;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACjC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,MAAM,eAAe,GAAG,mBAAmB,CAAC,mBAAmB,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IACpF,MAAM,eAAe,GAAG,mBAAmB,CAAC,mBAAmB,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IACpF,UAAU,CACR,wCAAwC,EACxC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,EACrG,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CACnG,CAAC;IACF,UAAU,CACR,wCAAwC,EACxC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,EACrG,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CACnG,CAAC;IACF,OAAO,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,UAAuB,EACvB,MAQC,EAYD,EAAE;IACF,MAAM,QAAQ,GAAG,iBAAiB,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACnC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACrF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,UAAuB,EACvB,MAQC,EAkBD,EAAE;IACF,MAAM,QAAQ,GAAG,qBAAqB,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACnC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AACrF,CAAC,CAAC","sourcesContent":["import { fetch, selectHTTPProxyIpRoundRobin } from '@yuants/http-services';\nimport {\n encodeHex,\n encodePath,\n formatTime,\n HmacSHA256,\n newError,\n scopeError,\n tokenBucket,\n} from '@yuants/utils';\n\nimport { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';\n\nimport { ASTER_TOKEN_BUCKET_OPTIONS_BY_ID } from './client';\n\nconst MetricsAsterApiCallCounter = GlobalPrometheusRegistry.counter(\n 'aster_api_call',\n 'Number of aster api call',\n);\nconst terminal = Terminal.fromNodeEnv();\nconst shouldUseHttpProxy = process.env.USE_HTTP_PROXY === 'true';\nconst fetchImpl = shouldUseHttpProxy ? fetch : globalThis.fetch ?? fetch;\nconst MISSING_PUBLIC_IP_LOG_INTERVAL = 3_600_000;\nconst missingPublicIpLogAtByTerminalId = new Map<string, number>();\n\nif (shouldUseHttpProxy) {\n globalThis.fetch = fetch;\n}\n\nexport interface ICredential {\n address: string;\n api_key: string;\n secret_key: string;\n}\n\ntype RequestContext = { ip: string };\n\nconst buildTokenBucketKey = (baseKey: string, ip: string): string => encodePath([baseKey, ip]);\n\nconst getTokenBucketOptions = (baseKey: string) => ASTER_TOKEN_BUCKET_OPTIONS_BY_ID[baseKey];\n\nconst resolveLocalPublicIp = (): string => {\n const ip = terminal.terminalInfo.tags?.public_ip?.trim();\n if (ip) return ip;\n const now = Date.now();\n const lastLoggedAt = missingPublicIpLogAtByTerminalId.get(terminal.terminal_id) ?? 0;\n if (now - lastLoggedAt > MISSING_PUBLIC_IP_LOG_INTERVAL) {\n missingPublicIpLogAtByTerminalId.set(terminal.terminal_id, now);\n console.info(formatTime(Date.now()), 'missing terminal public_ip tag, fallback to public-ip-unknown');\n }\n return 'public-ip-unknown';\n};\n\nconst createRequestContext = (): RequestContext => {\n if (shouldUseHttpProxy) {\n const ip = selectHTTPProxyIpRoundRobin(terminal);\n return { ip };\n }\n return { ip: resolveLocalPublicIp() };\n};\n\nconst acquireRateLimit = (\n method: string,\n url: URL,\n endpoint: string,\n weight: number,\n requestContext: RequestContext,\n) => {\n const bucketKey = buildTokenBucketKey(url.host, requestContext.ip);\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n { method, endpoint, host: url.host, path: url.pathname, bucketId: bucketKey, weight },\n () => tokenBucket(bucketKey, getTokenBucketOptions(url.host)).acquireSync(weight),\n );\n};\n\nexport interface IAsterFutureOpenOrder {\n orderId: number;\n clientOrderId: string;\n price: string;\n origQty: string;\n executedQty: string;\n status: string;\n timeInForce: string;\n type: string;\n side: 'BUY' | 'SELL';\n updateTime: number;\n avgPrice: string;\n reduceOnly?: boolean;\n closePosition?: boolean;\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n workingType?: string;\n priceProtect?: boolean;\n origType?: string;\n stopPrice?: string;\n symbol: string;\n}\n\nexport interface IAsterSpotOpenOrder {\n orderId: number;\n clientOrderId: string;\n price: string;\n origQty: string;\n executedQty: string;\n cummulativeQuoteQty?: string;\n status: string;\n timeInForce: string;\n type: string;\n side: 'BUY' | 'SELL';\n stopPrice?: string;\n icebergQty?: string;\n time: number;\n updateTime: number;\n isWorking?: boolean;\n avgPrice?: string;\n symbol: string;\n}\n\nconst request = async <T>(\n credential: ICredential,\n method: string,\n baseURL: string,\n endpoint: string,\n params: Record<string, unknown> = {},\n requestContext: RequestContext,\n): Promise<T> => {\n const url = new URL(baseURL);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n url.searchParams.set('timestamp', `${Date.now()}`);\n const msg = url.search.slice(1); // 去掉开头的 '?'\n const signature = encodeHex(\n await HmacSHA256(new TextEncoder().encode(msg), new TextEncoder().encode(credential.secret_key)),\n );\n url.searchParams.set('signature', signature);\n\n console.info('request', method, url.host, url.pathname);\n MetricsAsterApiCallCounter.labels({ path: url.pathname, terminal_id: terminal.terminal_id }).inc();\n const response = await fetchImpl(\n url.toString(),\n shouldUseHttpProxy\n ? {\n method,\n headers: {\n 'X-MBX-APIKEY': credential.api_key,\n },\n labels: requestContext.ip ? { ip: requestContext.ip } : undefined,\n terminal,\n }\n : {\n method,\n headers: {\n 'X-MBX-APIKEY': credential.api_key,\n },\n },\n );\n\n const resText = await response.text();\n\n try {\n const res = JSON.parse(resText);\n\n if (res.code && res.code !== 0) {\n throw resText;\n }\n return res;\n } catch (e) {\n throw newError(\n 'ASTER_API_ERROR',\n {\n status: response.status,\n statusText: response.statusText,\n resText,\n params,\n },\n e,\n );\n }\n};\n\nconst FutureBaseURL = 'https://fapi.asterdex.com';\nconst SpotBaseURL = 'https://sapi.asterdex.com';\n\n/**\n * 获取账户信息\n *\n * Weight: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data\n */\nexport const getFApiV4Account = (\n credential: ICredential,\n params: Record<string, never>,\n): Promise<{\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n updateTime: number;\n totalInitialMargin: string;\n totalMaintMargin: string;\n totalWalletBalance: string;\n totalUnrealizedProfit: string;\n totalMarginBalance: string;\n totalPositionInitialMargin: string;\n totalOpenOrderInitialMargin: string;\n totalCrossWalletBalance: string;\n totalCrossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n assets: {\n asset: string;\n walletBalance: string;\n unrealizedProfit: string;\n marginBalance: string;\n maintMargin: string;\n initialMargin: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n maxWithdrawAmount: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n marginAvailable: boolean;\n updateTime: number;\n }[];\n positions: {\n symbol: string;\n initialMargin: string;\n maintMargin: string;\n unrealizedProfit: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n leverage: string;\n isolated: boolean;\n entryPrice: string;\n maxNotional: string;\n positionSide: 'BOTH' | 'LONG' | 'SHORT';\n positionAmt: string;\n notional: string;\n isolatedWallet: string;\n updateTime: number;\n }[];\n}> => {\n const endpoint = '/fapi/v4/account';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 用户持仓风险V2 (USER_DATA)\n *\n * Weight: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E7%94%A8%E6%88%B7%E6%8C%81%E4%BB%93%E9%A3%8E%E9%99%A9v2-user_data\n */\nexport const getFApiV2PositionRisk = (\n credential: ICredential,\n params: {\n symbol?: string;\n },\n): Promise<\n {\n entryPrice: string;\n marginType: string;\n isAutoAddMargin: string;\n isolatedMargin: string;\n leverage: string;\n liquidationPrice: string;\n markPrice: string;\n maxNotionalValue: string;\n positionAmt: string;\n symbol: string;\n unRealizedProfit: string;\n positionSide: string;\n updateTime: number;\n }[]\n> => {\n const endpoint = '/fapi/v2/positionRisk';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * Weight: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#L2840-L2855\n */\nexport const getFApiV2Balance = (\n credential: ICredential,\n params: Record<string, never>,\n): Promise<\n {\n accountAlias: string;\n asset: string;\n balance: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n marginAvailable: boolean;\n updateTime: number;\n }[]\n> => {\n const endpoint = '/fapi/v2/balance';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * Weight: 1 by order\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#post-fapiv1order-%E7%9A%84%E7%A4%BA%E4%BE%8B\n */\nexport const postFApiV1Order = (\n credential: ICredential,\n params: {\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n type:\n | 'MARKET'\n | 'LIMIT'\n | 'STOP'\n | 'STOP_MARKET'\n | 'TAKE_PROFIT'\n | 'TAKE_PROFIT_MARKET'\n | 'TRAILING_STOP_MARKET';\n reduceOnly?: 'true' | 'false';\n quantity?: number;\n price?: number;\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX' | 'HIDDEN';\n },\n): Promise<Record<string, never>> => {\n const endpoint = '/fapi/v1/order';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = createRequestContext();\n const secondBucketKey = buildTokenBucketKey('order/future/second', requestContext.ip);\n const minuteBucketKey = buildTokenBucketKey('order/future/minute', requestContext.ip);\n scopeError(\n 'ASTER_FUTURE_ORDER_API_SECOND_RATE_LIMIT',\n { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight },\n () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/future/second')).acquireSync(weight),\n );\n scopeError(\n 'ASTER_FUTURE_ORDER_API_MINUTE_RATE_LIMIT',\n { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: minuteBucketKey, weight },\n () => tokenBucket(minuteBucketKey, getTokenBucketOptions('order/future/minute')).acquireSync(weight),\n );\n return request(credential, 'POST', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 查询当前挂单 (永续)\n *\n * Weight: with symbol 1, without symbol 40\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#L2728-L2766\n */\nexport const getFApiV1OpenOrders = (\n credential: ICredential,\n params: {\n symbol?: string;\n },\n): Promise<IAsterFutureOpenOrder[]> => {\n const endpoint = '/fapi/v1/openOrders';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = params?.symbol ? 1 : 40;\n const requestContext = createRequestContext();\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n {\n method: 'GET',\n endpoint,\n host: url.host,\n path: url.pathname,\n bucketId: buildTokenBucketKey(url.host, requestContext.ip),\n weight,\n hasSymbol: !!params?.symbol,\n },\n () =>\n tokenBucket(\n buildTokenBucketKey(url.host, requestContext.ip),\n getTokenBucketOptions(url.host),\n ).acquireSync(weight),\n );\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 查询当前挂单 (现货)\n *\n * Weight: with symbol 1, without symbol 40\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1196-L1234\n */\nexport const getApiV1OpenOrders = (\n credential: ICredential,\n params: {\n symbol?: string;\n },\n): Promise<IAsterSpotOpenOrder[]> => {\n const endpoint = '/api/v1/openOrders';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = params?.symbol ? 1 : 40;\n const requestContext = createRequestContext();\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n {\n method: 'GET',\n endpoint,\n host: url.host,\n path: url.pathname,\n bucketId: buildTokenBucketKey(url.host, requestContext.ip),\n weight,\n hasSymbol: !!params?.symbol,\n },\n () =>\n tokenBucket(\n buildTokenBucketKey(url.host, requestContext.ip),\n getTokenBucketOptions(url.host),\n ).acquireSync(weight),\n );\n return request(credential, 'GET', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#L2498-L2516\n */\nexport const deleteFApiV1Order = (\n credential: ICredential,\n params: {\n symbol: string;\n orderId?: string | number;\n origClientOrderId?: string;\n },\n): Promise<Record<string, never>> => {\n const endpoint = '/fapi/v1/order';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = createRequestContext();\n const secondBucketKey = buildTokenBucketKey('order/future/second', requestContext.ip);\n const minuteBucketKey = buildTokenBucketKey('order/future/minute', requestContext.ip);\n scopeError(\n 'ASTER_FUTURE_ORDER_API_SECOND_RATE_LIMIT',\n { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight },\n () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/future/second')).acquireSync(weight),\n );\n scopeError(\n 'ASTER_FUTURE_ORDER_API_MINUTE_RATE_LIMIT',\n { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: minuteBucketKey, weight },\n () => tokenBucket(minuteBucketKey, getTokenBucketOptions('order/future/minute')).acquireSync(weight),\n );\n return request(credential, 'DELETE', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取账户信息 (现货)\n *\n * Weight: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AF-user_data\n */\nexport const getApiV1Account = (\n credential: ICredential,\n params: Record<string, never>,\n): Promise<{\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n canBurnAsset: boolean;\n updateTime: number;\n balances: {\n asset: string;\n free: string;\n locked: string;\n }[];\n}> => {\n const endpoint = '/api/v1/account';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取最新价格\n *\n * Weight: without symbol 2 (current implementation)\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC\n */\nexport const getApiV1TickerPrice = (\n credential: ICredential,\n params: Record<string, never>,\n): Promise<\n {\n symbol: string;\n price: string;\n time: number;\n }[]\n> => {\n const endpoint = '/api/v1/ticker/price';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 2;\n const requestContext = createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#post-apiv1order-%E7%9A%84%E7%A4%BA%E4%BE%8B\n */\nexport const postApiV1Order = (\n credential: ICredential,\n params: {\n symbol: string;\n side: 'BUY' | 'SELL';\n type: 'MARKET' | 'LIMIT' | 'STOP' | 'STOP_MARKET' | 'TAKE_PROFIT' | 'TAKE_PROFIT_MARKET';\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX';\n quantity?: number;\n quoteOrderQty?: number;\n price?: number;\n },\n): Promise<{\n orderId: number;\n}> => {\n const endpoint = '/api/v1/order';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = createRequestContext();\n const secondBucketKey = buildTokenBucketKey('order/spot/second', requestContext.ip);\n const minuteBucketKey = buildTokenBucketKey('order/spot/minute', requestContext.ip);\n scopeError(\n 'ASTER_SPOT_ORDER_API_SECOND_RATE_LIMIT',\n { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight },\n () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/spot/second')).acquireSync(weight),\n );\n scopeError(\n 'ASTER_SPOT_ORDER_API_MINUTE_RATE_LIMIT',\n { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: minuteBucketKey, weight },\n () => tokenBucket(minuteBucketKey, getTokenBucketOptions('order/spot/minute')).acquireSync(weight),\n );\n return request(credential, 'POST', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 取消有效订单 (现货)\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1040-L1074\n */\nexport const deleteApiV1Order = (\n credential: ICredential,\n params: {\n symbol: string;\n orderId?: string | number;\n origClientOrderId?: string;\n },\n): Promise<Record<string, never>> => {\n const endpoint = '/api/v1/order';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = createRequestContext();\n const secondBucketKey = buildTokenBucketKey('order/spot/second', requestContext.ip);\n const minuteBucketKey = buildTokenBucketKey('order/spot/minute', requestContext.ip);\n scopeError(\n 'ASTER_SPOT_ORDER_API_SECOND_RATE_LIMIT',\n { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight },\n () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/spot/second')).acquireSync(weight),\n );\n scopeError(\n 'ASTER_SPOT_ORDER_API_MINUTE_RATE_LIMIT',\n { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: minuteBucketKey, weight },\n () => tokenBucket(minuteBucketKey, getTokenBucketOptions('order/spot/minute')).acquireSync(weight),\n );\n return request(credential, 'DELETE', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取账户损益资金流水(USER_DATA)\n *\n * 权重: 30\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%8E%B7%E5%8F%96%E8%B4%A6%E6%88%B7%E6%8D%9F%E7%9B%8A%E8%B5%84%E9%87%91%E6%B5%81%E6%B0%B4user_data\n */\nexport const getAccountIncome = (\n credential: ICredential,\n params: {\n symbol?: string;\n incomeType?: string;\n startTime?: number;\n endTime?: number;\n recvWindow?: number;\n limit?: number;\n timestamp: number;\n },\n): Promise<\n {\n symbol: string;\n incomeType: string;\n income: string;\n asset: string;\n info: string;\n time: number;\n tranId: string;\n tradeId: string;\n }[]\n> => {\n const endpoint = '/fapi/v1/income';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 30;\n const requestContext = createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 账户成交历史 (USER_DATA)\n *\n * 权重: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E6%88%90%E4%BA%A4%E5%8E%86%E5%8F%B2-user_data\n */\nexport const getAccountTradeList = (\n credential: ICredential,\n params: {\n symbol: string;\n timestamp: number;\n fromId?: number;\n startTime?: number;\n endTime?: number;\n limit?: number;\n recvWindow?: number;\n },\n): Promise<\n {\n symbol: string;\n id: number;\n orderId: number;\n side: string;\n price: string;\n qty: string;\n realizedPnl: string;\n quoteQty: string;\n commission: string;\n commissionAsset: string;\n time: number;\n buyer: boolean;\n maker: boolean;\n positionSide: string;\n }[]\n> => {\n const endpoint = '/fapi/v1/userTrades';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n"]}
|
|
1
|
+
{"version":3,"file":"private-api.js","sourceRoot":"","sources":["../../src/api/private-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { fetch, selectHTTPProxyIpRoundRobinAsync } from '@yuants/http-services';\nimport {\n encodeHex,\n encodePath,\n formatTime,\n HmacSHA256,\n newError,\n scopeError,\n tokenBucket,\n} from '@yuants/utils';\n\nimport { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';\n\nimport { ASTER_TOKEN_BUCKET_OPTIONS_BY_ID } from './client';\n\nconst MetricsAsterApiCallCounter = GlobalPrometheusRegistry.counter(\n 'aster_api_call',\n 'Number of aster api call',\n);\nconst terminal = Terminal.fromNodeEnv();\nconst shouldUseHttpProxy = process.env.USE_HTTP_PROXY === 'true';\nconst fetchImpl = shouldUseHttpProxy ? fetch : globalThis.fetch ?? fetch;\nconst MISSING_PUBLIC_IP_LOG_INTERVAL = 3_600_000;\nconst missingPublicIpLogAtByTerminalId = new Map<string, number>();\n\nif (shouldUseHttpProxy) {\n globalThis.fetch = fetch;\n}\n\nexport interface ICredential {\n address: string;\n api_key: string;\n secret_key: string;\n}\n\ntype RequestContext = { ip: string };\n\nconst buildTokenBucketKey = (baseKey: string, ip: string): string => encodePath([baseKey, ip]);\n\nconst getTokenBucketOptions = (baseKey: string) => ASTER_TOKEN_BUCKET_OPTIONS_BY_ID[baseKey];\n\nconst resolveLocalPublicIp = (): string => {\n const ip = terminal.terminalInfo.tags?.public_ip?.trim();\n if (ip) return ip;\n const now = Date.now();\n const lastLoggedAt = missingPublicIpLogAtByTerminalId.get(terminal.terminal_id) ?? 0;\n if (now - lastLoggedAt > MISSING_PUBLIC_IP_LOG_INTERVAL) {\n missingPublicIpLogAtByTerminalId.set(terminal.terminal_id, now);\n console.info(formatTime(Date.now()), 'missing terminal public_ip tag, fallback to public-ip-unknown');\n }\n return 'public-ip-unknown';\n};\n\nconst createRequestContext = async (): Promise<RequestContext> => {\n if (shouldUseHttpProxy) {\n const ip = await selectHTTPProxyIpRoundRobinAsync(terminal);\n return { ip };\n }\n return { ip: resolveLocalPublicIp() };\n};\n\nconst acquireRateLimit = (\n method: string,\n url: URL,\n endpoint: string,\n weight: number,\n requestContext: RequestContext,\n) => {\n const bucketKey = buildTokenBucketKey(url.host, requestContext.ip);\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n { method, endpoint, host: url.host, path: url.pathname, bucketId: bucketKey, weight },\n () => tokenBucket(bucketKey, getTokenBucketOptions(url.host)).acquireSync(weight),\n );\n};\n\nexport interface IAsterFutureOpenOrder {\n orderId: number;\n clientOrderId: string;\n price: string;\n origQty: string;\n executedQty: string;\n status: string;\n timeInForce: string;\n type: string;\n side: 'BUY' | 'SELL';\n updateTime: number;\n avgPrice: string;\n reduceOnly?: boolean;\n closePosition?: boolean;\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n workingType?: string;\n priceProtect?: boolean;\n origType?: string;\n stopPrice?: string;\n symbol: string;\n}\n\nexport interface IAsterSpotOpenOrder {\n orderId: number;\n clientOrderId: string;\n price: string;\n origQty: string;\n executedQty: string;\n cummulativeQuoteQty?: string;\n status: string;\n timeInForce: string;\n type: string;\n side: 'BUY' | 'SELL';\n stopPrice?: string;\n icebergQty?: string;\n time: number;\n updateTime: number;\n isWorking?: boolean;\n avgPrice?: string;\n symbol: string;\n}\n\nconst request = async <T>(\n credential: ICredential,\n method: string,\n baseURL: string,\n endpoint: string,\n params: Record<string, unknown> = {},\n requestContext: RequestContext,\n): Promise<T> => {\n const url = new URL(baseURL);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n url.searchParams.set('timestamp', `${Date.now()}`);\n const msg = url.search.slice(1); // 去掉开头的 '?'\n const signature = encodeHex(\n await HmacSHA256(new TextEncoder().encode(msg), new TextEncoder().encode(credential.secret_key)),\n );\n url.searchParams.set('signature', signature);\n\n console.info('request', method, url.host, url.pathname);\n MetricsAsterApiCallCounter.labels({ path: url.pathname, terminal_id: terminal.terminal_id }).inc();\n const response = await fetchImpl(\n url.toString(),\n shouldUseHttpProxy\n ? {\n method,\n headers: {\n 'X-MBX-APIKEY': credential.api_key,\n },\n labels: requestContext.ip ? { ip: requestContext.ip } : undefined,\n terminal,\n }\n : {\n method,\n headers: {\n 'X-MBX-APIKEY': credential.api_key,\n },\n },\n );\n\n const resText = await response.text();\n\n try {\n const res = JSON.parse(resText);\n\n if (res.code && res.code !== 0) {\n throw resText;\n }\n return res;\n } catch (e) {\n throw newError(\n 'ASTER_API_ERROR',\n {\n status: response.status,\n statusText: response.statusText,\n resText,\n params,\n },\n e,\n );\n }\n};\n\nconst FutureBaseURL = 'https://fapi.asterdex.com';\nconst SpotBaseURL = 'https://sapi.asterdex.com';\n\n/**\n * 获取账户信息\n *\n * Weight: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data\n */\nexport const getFApiV4Account = async (\n credential: ICredential,\n params: Record<string, never>,\n): Promise<{\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n updateTime: number;\n totalInitialMargin: string;\n totalMaintMargin: string;\n totalWalletBalance: string;\n totalUnrealizedProfit: string;\n totalMarginBalance: string;\n totalPositionInitialMargin: string;\n totalOpenOrderInitialMargin: string;\n totalCrossWalletBalance: string;\n totalCrossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n assets: {\n asset: string;\n walletBalance: string;\n unrealizedProfit: string;\n marginBalance: string;\n maintMargin: string;\n initialMargin: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n maxWithdrawAmount: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n marginAvailable: boolean;\n updateTime: number;\n }[];\n positions: {\n symbol: string;\n initialMargin: string;\n maintMargin: string;\n unrealizedProfit: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n leverage: string;\n isolated: boolean;\n entryPrice: string;\n maxNotional: string;\n positionSide: 'BOTH' | 'LONG' | 'SHORT';\n positionAmt: string;\n notional: string;\n isolatedWallet: string;\n updateTime: number;\n }[];\n}> => {\n const endpoint = '/fapi/v4/account';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = await createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 用户持仓风险V2 (USER_DATA)\n *\n * Weight: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E7%94%A8%E6%88%B7%E6%8C%81%E4%BB%93%E9%A3%8E%E9%99%A9v2-user_data\n */\nexport const getFApiV2PositionRisk = async (\n credential: ICredential,\n params: {\n symbol?: string;\n },\n): Promise<\n {\n entryPrice: string;\n marginType: string;\n isAutoAddMargin: string;\n isolatedMargin: string;\n leverage: string;\n liquidationPrice: string;\n markPrice: string;\n maxNotionalValue: string;\n positionAmt: string;\n symbol: string;\n unRealizedProfit: string;\n positionSide: string;\n updateTime: number;\n }[]\n> => {\n const endpoint = '/fapi/v2/positionRisk';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = await createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * Weight: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#L2840-L2855\n */\nexport const getFApiV2Balance = async (\n credential: ICredential,\n params: Record<string, never>,\n): Promise<\n {\n accountAlias: string;\n asset: string;\n balance: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n marginAvailable: boolean;\n updateTime: number;\n }[]\n> => {\n const endpoint = '/fapi/v2/balance';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = await createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * Weight: 1 by order\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#post-fapiv1order-%E7%9A%84%E7%A4%BA%E4%BE%8B\n */\nexport const postFApiV1Order = async (\n credential: ICredential,\n params: {\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n type:\n | 'MARKET'\n | 'LIMIT'\n | 'STOP'\n | 'STOP_MARKET'\n | 'TAKE_PROFIT'\n | 'TAKE_PROFIT_MARKET'\n | 'TRAILING_STOP_MARKET';\n reduceOnly?: 'true' | 'false';\n quantity?: number;\n price?: number;\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX' | 'HIDDEN';\n },\n): Promise<Record<string, never>> => {\n const endpoint = '/fapi/v1/order';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = await createRequestContext();\n const secondBucketKey = buildTokenBucketKey('order/future/second', requestContext.ip);\n const minuteBucketKey = buildTokenBucketKey('order/future/minute', requestContext.ip);\n scopeError(\n 'ASTER_FUTURE_ORDER_API_SECOND_RATE_LIMIT',\n { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight },\n () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/future/second')).acquireSync(weight),\n );\n scopeError(\n 'ASTER_FUTURE_ORDER_API_MINUTE_RATE_LIMIT',\n { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: minuteBucketKey, weight },\n () => tokenBucket(minuteBucketKey, getTokenBucketOptions('order/future/minute')).acquireSync(weight),\n );\n return request(credential, 'POST', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 查询当前挂单 (永续)\n *\n * Weight: with symbol 1, without symbol 40\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#L2728-L2766\n */\nexport const getFApiV1OpenOrders = async (\n credential: ICredential,\n params: {\n symbol?: string;\n },\n): Promise<IAsterFutureOpenOrder[]> => {\n const endpoint = '/fapi/v1/openOrders';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = params?.symbol ? 1 : 40;\n const requestContext = await createRequestContext();\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n {\n method: 'GET',\n endpoint,\n host: url.host,\n path: url.pathname,\n bucketId: buildTokenBucketKey(url.host, requestContext.ip),\n weight,\n hasSymbol: !!params?.symbol,\n },\n () =>\n tokenBucket(\n buildTokenBucketKey(url.host, requestContext.ip),\n getTokenBucketOptions(url.host),\n ).acquireSync(weight),\n );\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 查询当前挂单 (现货)\n *\n * Weight: with symbol 1, without symbol 40\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1196-L1234\n */\nexport const getApiV1OpenOrders = async (\n credential: ICredential,\n params: {\n symbol?: string;\n },\n): Promise<IAsterSpotOpenOrder[]> => {\n const endpoint = '/api/v1/openOrders';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = params?.symbol ? 1 : 40;\n const requestContext = await createRequestContext();\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n {\n method: 'GET',\n endpoint,\n host: url.host,\n path: url.pathname,\n bucketId: buildTokenBucketKey(url.host, requestContext.ip),\n weight,\n hasSymbol: !!params?.symbol,\n },\n () =>\n tokenBucket(\n buildTokenBucketKey(url.host, requestContext.ip),\n getTokenBucketOptions(url.host),\n ).acquireSync(weight),\n );\n return request(credential, 'GET', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#L2498-L2516\n */\nexport const deleteFApiV1Order = async (\n credential: ICredential,\n params: {\n symbol: string;\n orderId?: string | number;\n origClientOrderId?: string;\n },\n): Promise<Record<string, never>> => {\n const endpoint = '/fapi/v1/order';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = await createRequestContext();\n const secondBucketKey = buildTokenBucketKey('order/future/second', requestContext.ip);\n const minuteBucketKey = buildTokenBucketKey('order/future/minute', requestContext.ip);\n scopeError(\n 'ASTER_FUTURE_ORDER_API_SECOND_RATE_LIMIT',\n { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight },\n () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/future/second')).acquireSync(weight),\n );\n scopeError(\n 'ASTER_FUTURE_ORDER_API_MINUTE_RATE_LIMIT',\n { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: minuteBucketKey, weight },\n () => tokenBucket(minuteBucketKey, getTokenBucketOptions('order/future/minute')).acquireSync(weight),\n );\n return request(credential, 'DELETE', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取账户信息 (现货)\n *\n * Weight: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AF-user_data\n */\nexport const getApiV1Account = async (\n credential: ICredential,\n params: Record<string, never>,\n): Promise<{\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n canBurnAsset: boolean;\n updateTime: number;\n balances: {\n asset: string;\n free: string;\n locked: string;\n }[];\n}> => {\n const endpoint = '/api/v1/account';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = await createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取最新价格\n *\n * Weight: without symbol 2 (current implementation)\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC\n */\nexport const getApiV1TickerPrice = async (\n credential: ICredential,\n params: Record<string, never>,\n): Promise<\n {\n symbol: string;\n price: string;\n time: number;\n }[]\n> => {\n const endpoint = '/api/v1/ticker/price';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 2;\n const requestContext = await createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#post-apiv1order-%E7%9A%84%E7%A4%BA%E4%BE%8B\n */\nexport const postApiV1Order = async (\n credential: ICredential,\n params: {\n symbol: string;\n side: 'BUY' | 'SELL';\n type: 'MARKET' | 'LIMIT' | 'STOP' | 'STOP_MARKET' | 'TAKE_PROFIT' | 'TAKE_PROFIT_MARKET';\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX';\n quantity?: number;\n quoteOrderQty?: number;\n price?: number;\n },\n): Promise<{\n orderId: number;\n}> => {\n const endpoint = '/api/v1/order';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = await createRequestContext();\n const secondBucketKey = buildTokenBucketKey('order/spot/second', requestContext.ip);\n const minuteBucketKey = buildTokenBucketKey('order/spot/minute', requestContext.ip);\n scopeError(\n 'ASTER_SPOT_ORDER_API_SECOND_RATE_LIMIT',\n { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight },\n () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/spot/second')).acquireSync(weight),\n );\n scopeError(\n 'ASTER_SPOT_ORDER_API_MINUTE_RATE_LIMIT',\n { method: 'POST', endpoint, host: url.host, path: url.pathname, bucketId: minuteBucketKey, weight },\n () => tokenBucket(minuteBucketKey, getTokenBucketOptions('order/spot/minute')).acquireSync(weight),\n );\n return request(credential, 'POST', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 取消有效订单 (现货)\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1040-L1074\n */\nexport const deleteApiV1Order = async (\n credential: ICredential,\n params: {\n symbol: string;\n orderId?: string | number;\n origClientOrderId?: string;\n },\n): Promise<Record<string, never>> => {\n const endpoint = '/api/v1/order';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = await createRequestContext();\n const secondBucketKey = buildTokenBucketKey('order/spot/second', requestContext.ip);\n const minuteBucketKey = buildTokenBucketKey('order/spot/minute', requestContext.ip);\n scopeError(\n 'ASTER_SPOT_ORDER_API_SECOND_RATE_LIMIT',\n { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: secondBucketKey, weight },\n () => tokenBucket(secondBucketKey, getTokenBucketOptions('order/spot/second')).acquireSync(weight),\n );\n scopeError(\n 'ASTER_SPOT_ORDER_API_MINUTE_RATE_LIMIT',\n { method: 'DELETE', endpoint, host: url.host, path: url.pathname, bucketId: minuteBucketKey, weight },\n () => tokenBucket(minuteBucketKey, getTokenBucketOptions('order/spot/minute')).acquireSync(weight),\n );\n return request(credential, 'DELETE', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取账户损益资金流水(USER_DATA)\n *\n * 权重: 30\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%8E%B7%E5%8F%96%E8%B4%A6%E6%88%B7%E6%8D%9F%E7%9B%8A%E8%B5%84%E9%87%91%E6%B5%81%E6%B0%B4user_data\n */\nexport const getAccountIncome = async (\n credential: ICredential,\n params: {\n symbol?: string;\n incomeType?: string;\n startTime?: number;\n endTime?: number;\n recvWindow?: number;\n limit?: number;\n timestamp: number;\n },\n): Promise<\n {\n symbol: string;\n incomeType: string;\n income: string;\n asset: string;\n info: string;\n time: number;\n tranId: string;\n tradeId: string;\n }[]\n> => {\n const endpoint = '/fapi/v1/income';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 30;\n const requestContext = await createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 账户成交历史 (USER_DATA)\n *\n * 权重: 5\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E6%88%90%E4%BA%A4%E5%8E%86%E5%8F%B2-user_data\n */\nexport const getAccountTradeList = async (\n credential: ICredential,\n params: {\n symbol: string;\n timestamp: number;\n fromId?: number;\n startTime?: number;\n endTime?: number;\n limit?: number;\n recvWindow?: number;\n },\n): Promise<\n {\n symbol: string;\n id: number;\n orderId: number;\n side: string;\n price: string;\n qty: string;\n realizedPnl: string;\n quoteQty: string;\n commission: string;\n commissionAsset: string;\n time: number;\n buyer: boolean;\n maker: boolean;\n positionSide: string;\n }[]\n> => {\n const endpoint = '/fapi/v1/userTrades';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 5;\n const requestContext = await createRequestContext();\n acquireRateLimit('GET', url, endpoint, weight, requestContext);\n return request(credential, 'GET', FutureBaseURL, endpoint, params, requestContext);\n};\n"]}
|
package/dist/api/public-api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var _a;
|
|
2
|
-
import { fetch,
|
|
2
|
+
import { fetch, selectHTTPProxyIpRoundRobinAsync } from '@yuants/http-services';
|
|
3
3
|
import { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';
|
|
4
4
|
import { encodePath, formatTime, scopeError, tokenBucket } from '@yuants/utils';
|
|
5
5
|
import { ASTER_TOKEN_BUCKET_OPTIONS_BY_ID } from './client';
|
|
@@ -29,9 +29,9 @@ const resolveLocalPublicIp = () => {
|
|
|
29
29
|
}
|
|
30
30
|
return 'public-ip-unknown';
|
|
31
31
|
};
|
|
32
|
-
const createRequestContext = () => {
|
|
32
|
+
const createRequestContext = async () => {
|
|
33
33
|
if (shouldUseHttpProxy) {
|
|
34
|
-
const ip =
|
|
34
|
+
const ip = await selectHTTPProxyIpRoundRobinAsync(terminal);
|
|
35
35
|
return { ip };
|
|
36
36
|
}
|
|
37
37
|
return { ip: resolveLocalPublicIp() };
|
|
@@ -81,12 +81,12 @@ const request = async (method, baseUrl, endpoint, params = {}, requestContext) =
|
|
|
81
81
|
*
|
|
82
82
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9F%A5%E8%AF%A2%E8%B5%84%E9%87%91%E8%B4%B9%E7%8E%87%E5%8E%86%E5%8F%B2
|
|
83
83
|
*/
|
|
84
|
-
export const getFApiV1FundingRate = (params) => {
|
|
84
|
+
export const getFApiV1FundingRate = async (params) => {
|
|
85
85
|
const endpoint = '/fapi/v1/fundingRate';
|
|
86
86
|
const url = new URL(FutureBaseURL);
|
|
87
87
|
url.pathname = endpoint;
|
|
88
88
|
const weight = 1;
|
|
89
|
-
const requestContext = createRequestContext();
|
|
89
|
+
const requestContext = await createRequestContext();
|
|
90
90
|
acquireRateLimit(url, endpoint, weight, requestContext);
|
|
91
91
|
return request('GET', FutureBaseURL, endpoint, params, requestContext);
|
|
92
92
|
};
|
|
@@ -97,12 +97,12 @@ export const getFApiV1FundingRate = (params) => {
|
|
|
97
97
|
*
|
|
98
98
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E4%BA%A4%E6%98%93%E5%AF%B9%E4%BF%A1%E6%81%AF
|
|
99
99
|
*/
|
|
100
|
-
export const getFApiV1ExchangeInfo = (params) => {
|
|
100
|
+
export const getFApiV1ExchangeInfo = async (params) => {
|
|
101
101
|
const endpoint = '/fapi/v1/exchangeInfo';
|
|
102
102
|
const url = new URL(FutureBaseURL);
|
|
103
103
|
url.pathname = endpoint;
|
|
104
104
|
const weight = 1;
|
|
105
|
-
const requestContext = createRequestContext();
|
|
105
|
+
const requestContext = await createRequestContext();
|
|
106
106
|
acquireRateLimit(url, endpoint, weight, requestContext);
|
|
107
107
|
return request('GET', FutureBaseURL, endpoint, params, requestContext);
|
|
108
108
|
};
|
|
@@ -113,12 +113,12 @@ export const getFApiV1ExchangeInfo = (params) => {
|
|
|
113
113
|
*
|
|
114
114
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1080-L1145
|
|
115
115
|
*/
|
|
116
|
-
export const getApiV1ExchangeInfo = (params) => {
|
|
116
|
+
export const getApiV1ExchangeInfo = async (params) => {
|
|
117
117
|
const endpoint = '/api/v1/exchangeInfo';
|
|
118
118
|
const url = new URL(SpotBaseURL);
|
|
119
119
|
url.pathname = endpoint;
|
|
120
120
|
const weight = 1;
|
|
121
|
-
const requestContext = createRequestContext();
|
|
121
|
+
const requestContext = await createRequestContext();
|
|
122
122
|
acquireRateLimit(url, endpoint, weight, requestContext);
|
|
123
123
|
return request('GET', SpotBaseURL, endpoint, params, requestContext);
|
|
124
124
|
};
|
|
@@ -131,12 +131,12 @@ export const getApiV1ExchangeInfo = (params) => {
|
|
|
131
131
|
* Weight: 1
|
|
132
132
|
* https://developers.binance.com/docs/zh-CN/derivatives/usds-margined-futures/market-data/rest-api/Open-Interest
|
|
133
133
|
*/
|
|
134
|
-
export const getFApiV1OpenInterest = (params) => {
|
|
134
|
+
export const getFApiV1OpenInterest = async (params) => {
|
|
135
135
|
const endpoint = '/fapi/v1/openInterest';
|
|
136
136
|
const url = new URL(FutureBaseURL);
|
|
137
137
|
url.pathname = endpoint;
|
|
138
138
|
const weight = 1;
|
|
139
|
-
const requestContext = createRequestContext();
|
|
139
|
+
const requestContext = await createRequestContext();
|
|
140
140
|
acquireRateLimit(url, endpoint, weight, requestContext);
|
|
141
141
|
return request('GET', FutureBaseURL, endpoint, params, requestContext);
|
|
142
142
|
};
|
|
@@ -147,12 +147,12 @@ export const getFApiV1OpenInterest = (params) => {
|
|
|
147
147
|
*
|
|
148
148
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC
|
|
149
149
|
*/
|
|
150
|
-
export const getFApiV1TickerPrice = (params) => {
|
|
150
|
+
export const getFApiV1TickerPrice = async (params) => {
|
|
151
151
|
const endpoint = '/fapi/v1/ticker/price';
|
|
152
152
|
const url = new URL(FutureBaseURL);
|
|
153
153
|
url.pathname = endpoint;
|
|
154
154
|
const weight = 2;
|
|
155
|
-
const requestContext = createRequestContext();
|
|
155
|
+
const requestContext = await createRequestContext();
|
|
156
156
|
acquireRateLimit(url, endpoint, weight, requestContext);
|
|
157
157
|
return request('GET', FutureBaseURL, endpoint, params, requestContext);
|
|
158
158
|
};
|
|
@@ -163,12 +163,12 @@ export const getFApiV1TickerPrice = (params) => {
|
|
|
163
163
|
*
|
|
164
164
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md
|
|
165
165
|
*/
|
|
166
|
-
export const getFApiV1PremiumIndex = (params) => {
|
|
166
|
+
export const getFApiV1PremiumIndex = async (params) => {
|
|
167
167
|
const endpoint = '/fapi/v1/premiumIndex';
|
|
168
168
|
const url = new URL(FutureBaseURL);
|
|
169
169
|
url.pathname = endpoint;
|
|
170
170
|
const weight = 1;
|
|
171
|
-
const requestContext = createRequestContext();
|
|
171
|
+
const requestContext = await createRequestContext();
|
|
172
172
|
acquireRateLimit(url, endpoint, weight, requestContext);
|
|
173
173
|
return request('GET', FutureBaseURL, endpoint, params, requestContext);
|
|
174
174
|
};
|
|
@@ -181,12 +181,12 @@ export const getFApiV1PremiumIndex = (params) => {
|
|
|
181
181
|
*
|
|
182
182
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#k%E7%BA%BF%E6%95%B0%E6%8D%AE
|
|
183
183
|
*/
|
|
184
|
-
export const getFApiV1Klines = (params) => {
|
|
184
|
+
export const getFApiV1Klines = async (params) => {
|
|
185
185
|
const endpoint = '/fapi/v1/klines';
|
|
186
186
|
const url = new URL(FutureBaseURL);
|
|
187
187
|
url.pathname = endpoint;
|
|
188
188
|
const weight = getKlinesRequestWeight(params === null || params === void 0 ? void 0 : params.limit);
|
|
189
|
-
const requestContext = createRequestContext();
|
|
189
|
+
const requestContext = await createRequestContext();
|
|
190
190
|
scopeError('ASTER_API_RATE_LIMIT', {
|
|
191
191
|
method: 'GET',
|
|
192
192
|
endpoint,
|
|
@@ -207,12 +207,12 @@ export const getFApiV1Klines = (params) => {
|
|
|
207
207
|
*
|
|
208
208
|
* https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md
|
|
209
209
|
*/
|
|
210
|
-
export const getApiV1Klines = (params) => {
|
|
210
|
+
export const getApiV1Klines = async (params) => {
|
|
211
211
|
const endpoint = '/api/v1/klines';
|
|
212
212
|
const url = new URL(SpotBaseURL);
|
|
213
213
|
url.pathname = endpoint;
|
|
214
214
|
const weight = getKlinesRequestWeight(params === null || params === void 0 ? void 0 : params.limit);
|
|
215
|
-
const requestContext = createRequestContext();
|
|
215
|
+
const requestContext = await createRequestContext();
|
|
216
216
|
scopeError('ASTER_API_RATE_LIMIT', {
|
|
217
217
|
method: 'GET',
|
|
218
218
|
endpoint,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../src/api/public-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { fetch, selectHTTPProxyIpRoundRobin } from '@yuants/http-services';\nimport { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';\nimport { encodePath, formatTime, scopeError, tokenBucket } from '@yuants/utils';\n\nimport { ASTER_TOKEN_BUCKET_OPTIONS_BY_ID } from './client';\n\nconst MetricsAsterApiCallCounter = GlobalPrometheusRegistry.counter(\n 'aster_api_call',\n 'Number of aster api call',\n);\nconst terminal = Terminal.fromNodeEnv();\nconst shouldUseHttpProxy = process.env.USE_HTTP_PROXY === 'true';\nconst fetchImpl = shouldUseHttpProxy ? fetch : globalThis.fetch ?? fetch;\nconst MISSING_PUBLIC_IP_LOG_INTERVAL = 3_600_000;\nconst missingPublicIpLogAtByTerminalId = new Map<string, number>();\n\nif (shouldUseHttpProxy) {\n globalThis.fetch = fetch;\n}\n\nconst FutureBaseURL = 'https://fapi.asterdex.com';\nconst SpotBaseURL = 'https://sapi.asterdex.com';\n\ntype RequestContext = { ip: string };\n\nconst buildTokenBucketKey = (baseKey: string, ip: string): string => encodePath([baseKey, ip]);\n\nconst getTokenBucketOptions = (baseKey: string) => ASTER_TOKEN_BUCKET_OPTIONS_BY_ID[baseKey];\n\nconst resolveLocalPublicIp = (): string => {\n const ip = terminal.terminalInfo.tags?.public_ip?.trim();\n if (ip) return ip;\n const now = Date.now();\n const lastLoggedAt = missingPublicIpLogAtByTerminalId.get(terminal.terminal_id) ?? 0;\n if (now - lastLoggedAt > MISSING_PUBLIC_IP_LOG_INTERVAL) {\n missingPublicIpLogAtByTerminalId.set(terminal.terminal_id, now);\n console.info(formatTime(Date.now()), 'missing terminal public_ip tag, fallback to public-ip-unknown');\n }\n return 'public-ip-unknown';\n};\n\nconst createRequestContext = (): RequestContext => {\n if (shouldUseHttpProxy) {\n const ip = selectHTTPProxyIpRoundRobin(terminal);\n return { ip };\n }\n return { ip: resolveLocalPublicIp() };\n};\n\nconst acquireRateLimit = (url: URL, endpoint: string, weight: number, requestContext: RequestContext) => {\n const bucketKey = buildTokenBucketKey(url.host, requestContext.ip);\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n { method: 'GET', endpoint, host: url.host, path: url.pathname, bucketId: bucketKey, weight },\n () => tokenBucket(bucketKey, getTokenBucketOptions(url.host)).acquireSync(weight),\n );\n};\n\nconst getKlinesRequestWeight = (limit: number | undefined): number => {\n const resolvedLimit = limit ?? 500;\n if (resolvedLimit < 100) return 1;\n if (resolvedLimit < 500) return 2;\n if (resolvedLimit <= 1000) return 5;\n return 10;\n};\n\nconst request = async <T>(\n method: string,\n baseUrl: string,\n endpoint: string,\n params: Record<string, unknown> = {},\n requestContext: RequestContext,\n): Promise<T> => {\n const url = new URL(baseUrl);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n console.info(url.toString());\n MetricsAsterApiCallCounter.labels({ path: url.pathname, terminal_id: terminal.terminal_id }).inc();\n const response = (await fetchImpl(\n url.toString(),\n shouldUseHttpProxy\n ? {\n method,\n labels: requestContext.ip ? { ip: requestContext.ip } : undefined,\n terminal,\n }\n : { method },\n )) as Response;\n const res = (await response.json()) as unknown;\n\n const maybeError = res as { code?: number };\n if (typeof maybeError.code === 'number' && maybeError.code !== 0) {\n throw JSON.stringify(res);\n }\n return res as T;\n};\n\n/**\n * 获取资金费率历史\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9F%A5%E8%AF%A2%E8%B5%84%E9%87%91%E8%B4%B9%E7%8E%87%E5%8E%86%E5%8F%B2\n */\nexport const getFApiV1FundingRate = (params: {\n symbol?: string;\n startTime?: number;\n endTime?: number;\n limit?: number;\n}): Promise<\n {\n symbol: string;\n fundingRate: string;\n fundingTime: number;\n }[]\n> => {\n const endpoint = '/fapi/v1/fundingRate';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\nexport interface IAsterRateLimit {\n rateLimitType?: string;\n interval?: string;\n intervalNum?: number;\n limit?: number;\n}\n\nexport interface IAsterExchangeInfo {\n symbols: {\n symbol: string;\n status: 'TRADING' | 'BREAK' | 'HALT';\n baseAsset: string;\n quoteAsset: string;\n pricePrecision: number;\n quantityPrecision: number;\n baseAssetPrecision: number;\n quotePrecision: number;\n filters: {\n filterType: string;\n [key: string]: unknown;\n }[];\n }[];\n rateLimits?: IAsterRateLimit[];\n}\n\n/**\n * 获取交易对信息\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E4%BA%A4%E6%98%93%E5%AF%B9%E4%BF%A1%E6%81%AF\n */\nexport const getFApiV1ExchangeInfo = (params: Record<string, never>): Promise<IAsterExchangeInfo> => {\n const endpoint = '/fapi/v1/exchangeInfo';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取现货交易对信息\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1080-L1145\n */\nexport const getApiV1ExchangeInfo = (params: Record<string, never>): Promise<IAsterExchangeInfo> => {\n const endpoint = '/api/v1/exchangeInfo';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取未平仓合约数量\n *\n * 无 API 文档 (weird)\n * 参考 Binance 风格接口:/fapi/v1/openInterest\n *\n * Weight: 1\n * https://developers.binance.com/docs/zh-CN/derivatives/usds-margined-futures/market-data/rest-api/Open-Interest\n */\nexport const getFApiV1OpenInterest = (params: {\n symbol: string;\n}): Promise<{\n symbol: string;\n openInterest: string;\n time: number;\n}> => {\n const endpoint = '/fapi/v1/openInterest';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取最新价格\n *\n * Weight: without symbol 2 (current implementation)\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC\n */\nexport const getFApiV1TickerPrice = (\n params: Record<string, never>,\n): Promise<\n {\n symbol: string;\n price: string;\n time?: number;\n }[]\n> => {\n const endpoint = '/fapi/v1/ticker/price';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 2;\n const requestContext = createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取资金费率\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md\n */\nexport const getFApiV1PremiumIndex = (params: {\n symbol?: string;\n}): Promise<\n | {\n symbol: string;\n markPrice: string;\n indexPrice: string;\n estimatedSettlePrice: string;\n lastFundingRate: string;\n nextFundingTime: number;\n interestRate: string;\n time: number;\n }\n | {\n symbol: string;\n markPrice: string;\n indexPrice: string;\n estimatedSettlePrice: string;\n lastFundingRate: string;\n nextFundingTime: number;\n interestRate: string;\n time: number;\n }[]\n> => {\n const endpoint = '/fapi/v1/premiumIndex';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\nexport interface IAsterKline extends Array<string | number> {\n 0: number; // Open time\n 1: string; // Open\n 2: string; // High\n 3: string; // Low\n 4: string; // Close\n 5: string; // Volume\n 6: number; // Close time\n 7: string; // Quote asset volume\n 8: number; // Number of trades\n 9: string; // Taker buy base asset volume\n 10: string; // Taker buy quote asset volume\n 11: string; // Ignore\n}\n\n/**\n * 获取 K 线\n *\n * 参考 Binance 风格接口:/fapi/v1/klines\n *\n * Weight: by limit\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#k%E7%BA%BF%E6%95%B0%E6%8D%AE\n */\nexport const getFApiV1Klines = (params: {\n symbol: string;\n interval: string;\n startTime?: number;\n endTime?: number;\n limit?: number;\n}): Promise<IAsterKline[]> => {\n const endpoint = '/fapi/v1/klines';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = getKlinesRequestWeight(params?.limit);\n const requestContext = createRequestContext();\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n {\n method: 'GET',\n endpoint,\n host: url.host,\n path: url.pathname,\n bucketId: buildTokenBucketKey(url.host, requestContext.ip),\n weight,\n limit: params?.limit,\n },\n () =>\n tokenBucket(\n buildTokenBucketKey(url.host, requestContext.ip),\n getTokenBucketOptions(url.host),\n ).acquireSync(weight),\n );\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取现货 K 线\n *\n * 参考 Binance 风格接口:/api/v1/klines\n *\n * Weight: not documented (temporary: follow futures limit table)\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md\n */\nexport const getApiV1Klines = (params: {\n symbol: string;\n interval: string;\n startTime?: number;\n endTime?: number;\n limit?: number;\n}): Promise<IAsterKline[]> => {\n const endpoint = '/api/v1/klines';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = getKlinesRequestWeight(params?.limit);\n const requestContext = createRequestContext();\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n {\n method: 'GET',\n endpoint,\n host: url.host,\n path: url.pathname,\n bucketId: buildTokenBucketKey(url.host, requestContext.ip),\n weight,\n limit: params?.limit,\n },\n () =>\n tokenBucket(\n buildTokenBucketKey(url.host, requestContext.ip),\n getTokenBucketOptions(url.host),\n ).acquireSync(weight),\n );\n return request('GET', SpotBaseURL, endpoint, params, requestContext);\n};\n"]}
|
|
1
|
+
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../src/api/public-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { fetch, selectHTTPProxyIpRoundRobinAsync } from '@yuants/http-services';\nimport { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';\nimport { encodePath, formatTime, scopeError, tokenBucket } from '@yuants/utils';\n\nimport { ASTER_TOKEN_BUCKET_OPTIONS_BY_ID } from './client';\n\nconst MetricsAsterApiCallCounter = GlobalPrometheusRegistry.counter(\n 'aster_api_call',\n 'Number of aster api call',\n);\nconst terminal = Terminal.fromNodeEnv();\nconst shouldUseHttpProxy = process.env.USE_HTTP_PROXY === 'true';\nconst fetchImpl = shouldUseHttpProxy ? fetch : globalThis.fetch ?? fetch;\nconst MISSING_PUBLIC_IP_LOG_INTERVAL = 3_600_000;\nconst missingPublicIpLogAtByTerminalId = new Map<string, number>();\n\nif (shouldUseHttpProxy) {\n globalThis.fetch = fetch;\n}\n\nconst FutureBaseURL = 'https://fapi.asterdex.com';\nconst SpotBaseURL = 'https://sapi.asterdex.com';\n\ntype RequestContext = { ip: string };\n\nconst buildTokenBucketKey = (baseKey: string, ip: string): string => encodePath([baseKey, ip]);\n\nconst getTokenBucketOptions = (baseKey: string) => ASTER_TOKEN_BUCKET_OPTIONS_BY_ID[baseKey];\n\nconst resolveLocalPublicIp = (): string => {\n const ip = terminal.terminalInfo.tags?.public_ip?.trim();\n if (ip) return ip;\n const now = Date.now();\n const lastLoggedAt = missingPublicIpLogAtByTerminalId.get(terminal.terminal_id) ?? 0;\n if (now - lastLoggedAt > MISSING_PUBLIC_IP_LOG_INTERVAL) {\n missingPublicIpLogAtByTerminalId.set(terminal.terminal_id, now);\n console.info(formatTime(Date.now()), 'missing terminal public_ip tag, fallback to public-ip-unknown');\n }\n return 'public-ip-unknown';\n};\n\nconst createRequestContext = async (): Promise<RequestContext> => {\n if (shouldUseHttpProxy) {\n const ip = await selectHTTPProxyIpRoundRobinAsync(terminal);\n return { ip };\n }\n return { ip: resolveLocalPublicIp() };\n};\n\nconst acquireRateLimit = (url: URL, endpoint: string, weight: number, requestContext: RequestContext) => {\n const bucketKey = buildTokenBucketKey(url.host, requestContext.ip);\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n { method: 'GET', endpoint, host: url.host, path: url.pathname, bucketId: bucketKey, weight },\n () => tokenBucket(bucketKey, getTokenBucketOptions(url.host)).acquireSync(weight),\n );\n};\n\nconst getKlinesRequestWeight = (limit: number | undefined): number => {\n const resolvedLimit = limit ?? 500;\n if (resolvedLimit < 100) return 1;\n if (resolvedLimit < 500) return 2;\n if (resolvedLimit <= 1000) return 5;\n return 10;\n};\n\nconst request = async <T>(\n method: string,\n baseUrl: string,\n endpoint: string,\n params: Record<string, unknown> = {},\n requestContext: RequestContext,\n): Promise<T> => {\n const url = new URL(baseUrl);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n console.info(url.toString());\n MetricsAsterApiCallCounter.labels({ path: url.pathname, terminal_id: terminal.terminal_id }).inc();\n const response = (await fetchImpl(\n url.toString(),\n shouldUseHttpProxy\n ? {\n method,\n labels: requestContext.ip ? { ip: requestContext.ip } : undefined,\n terminal,\n }\n : { method },\n )) as Response;\n const res = (await response.json()) as unknown;\n\n const maybeError = res as { code?: number };\n if (typeof maybeError.code === 'number' && maybeError.code !== 0) {\n throw JSON.stringify(res);\n }\n return res as T;\n};\n\n/**\n * 获取资金费率历史\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9F%A5%E8%AF%A2%E8%B5%84%E9%87%91%E8%B4%B9%E7%8E%87%E5%8E%86%E5%8F%B2\n */\nexport const getFApiV1FundingRate = async (params: {\n symbol?: string;\n startTime?: number;\n endTime?: number;\n limit?: number;\n}): Promise<\n {\n symbol: string;\n fundingRate: string;\n fundingTime: number;\n }[]\n> => {\n const endpoint = '/fapi/v1/fundingRate';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = await createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\nexport interface IAsterRateLimit {\n rateLimitType?: string;\n interval?: string;\n intervalNum?: number;\n limit?: number;\n}\n\nexport interface IAsterExchangeInfo {\n symbols: {\n symbol: string;\n status: 'TRADING' | 'BREAK' | 'HALT';\n baseAsset: string;\n quoteAsset: string;\n pricePrecision: number;\n quantityPrecision: number;\n baseAssetPrecision: number;\n quotePrecision: number;\n filters: {\n filterType: string;\n [key: string]: unknown;\n }[];\n }[];\n rateLimits?: IAsterRateLimit[];\n}\n\n/**\n * 获取交易对信息\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E4%BA%A4%E6%98%93%E5%AF%B9%E4%BF%A1%E6%81%AF\n */\nexport const getFApiV1ExchangeInfo = async (params: Record<string, never>): Promise<IAsterExchangeInfo> => {\n const endpoint = '/fapi/v1/exchangeInfo';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = await createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取现货交易对信息\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1080-L1145\n */\nexport const getApiV1ExchangeInfo = async (params: Record<string, never>): Promise<IAsterExchangeInfo> => {\n const endpoint = '/api/v1/exchangeInfo';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = await createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', SpotBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取未平仓合约数量\n *\n * 无 API 文档 (weird)\n * 参考 Binance 风格接口:/fapi/v1/openInterest\n *\n * Weight: 1\n * https://developers.binance.com/docs/zh-CN/derivatives/usds-margined-futures/market-data/rest-api/Open-Interest\n */\nexport const getFApiV1OpenInterest = async (params: {\n symbol: string;\n}): Promise<{\n symbol: string;\n openInterest: string;\n time: number;\n}> => {\n const endpoint = '/fapi/v1/openInterest';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = await createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取最新价格\n *\n * Weight: without symbol 2 (current implementation)\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC\n */\nexport const getFApiV1TickerPrice = async (\n params: Record<string, never>,\n): Promise<\n {\n symbol: string;\n price: string;\n time?: number;\n }[]\n> => {\n const endpoint = '/fapi/v1/ticker/price';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 2;\n const requestContext = await createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取资金费率\n *\n * Weight: 1\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md\n */\nexport const getFApiV1PremiumIndex = async (params: {\n symbol?: string;\n}): Promise<\n | {\n symbol: string;\n markPrice: string;\n indexPrice: string;\n estimatedSettlePrice: string;\n lastFundingRate: string;\n nextFundingTime: number;\n interestRate: string;\n time: number;\n }\n | {\n symbol: string;\n markPrice: string;\n indexPrice: string;\n estimatedSettlePrice: string;\n lastFundingRate: string;\n nextFundingTime: number;\n interestRate: string;\n time: number;\n }[]\n> => {\n const endpoint = '/fapi/v1/premiumIndex';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = 1;\n const requestContext = await createRequestContext();\n acquireRateLimit(url, endpoint, weight, requestContext);\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\nexport interface IAsterKline extends Array<string | number> {\n 0: number; // Open time\n 1: string; // Open\n 2: string; // High\n 3: string; // Low\n 4: string; // Close\n 5: string; // Volume\n 6: number; // Close time\n 7: string; // Quote asset volume\n 8: number; // Number of trades\n 9: string; // Taker buy base asset volume\n 10: string; // Taker buy quote asset volume\n 11: string; // Ignore\n}\n\n/**\n * 获取 K 线\n *\n * 参考 Binance 风格接口:/fapi/v1/klines\n *\n * Weight: by limit\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#k%E7%BA%BF%E6%95%B0%E6%8D%AE\n */\nexport const getFApiV1Klines = async (params: {\n symbol: string;\n interval: string;\n startTime?: number;\n endTime?: number;\n limit?: number;\n}): Promise<IAsterKline[]> => {\n const endpoint = '/fapi/v1/klines';\n const url = new URL(FutureBaseURL);\n url.pathname = endpoint;\n const weight = getKlinesRequestWeight(params?.limit);\n const requestContext = await createRequestContext();\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n {\n method: 'GET',\n endpoint,\n host: url.host,\n path: url.pathname,\n bucketId: buildTokenBucketKey(url.host, requestContext.ip),\n weight,\n limit: params?.limit,\n },\n () =>\n tokenBucket(\n buildTokenBucketKey(url.host, requestContext.ip),\n getTokenBucketOptions(url.host),\n ).acquireSync(weight),\n );\n return request('GET', FutureBaseURL, endpoint, params, requestContext);\n};\n\n/**\n * 获取现货 K 线\n *\n * 参考 Binance 风格接口:/api/v1/klines\n *\n * Weight: not documented (temporary: follow futures limit table)\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md\n */\nexport const getApiV1Klines = async (params: {\n symbol: string;\n interval: string;\n startTime?: number;\n endTime?: number;\n limit?: number;\n}): Promise<IAsterKline[]> => {\n const endpoint = '/api/v1/klines';\n const url = new URL(SpotBaseURL);\n url.pathname = endpoint;\n const weight = getKlinesRequestWeight(params?.limit);\n const requestContext = await createRequestContext();\n scopeError(\n 'ASTER_API_RATE_LIMIT',\n {\n method: 'GET',\n endpoint,\n host: url.host,\n path: url.pathname,\n bucketId: buildTokenBucketKey(url.host, requestContext.ip),\n weight,\n limit: params?.limit,\n },\n () =>\n tokenBucket(\n buildTokenBucketKey(url.host, requestContext.ip),\n getTokenBucketOptions(url.host),\n ).acquireSync(weight),\n );\n return request('GET', SpotBaseURL, endpoint, params, requestContext);\n};\n"]}
|