@yuants/vendor-coinex 0.2.40 → 0.2.41
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.js +2 -4
- package/dist/api.js.map +1 -1
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +1 -6
- package/lib/api.js.map +1 -1
- package/package.json +10 -11
- package/temp/package-deps.json +13 -14
- package/dist/cli.js +0 -3
- package/dist/cli.js.map +0 -1
- package/lib/cli.d.ts +0 -3
- package/lib/cli.d.ts.map +0 -1
- package/lib/cli.js +0 -5
- package/lib/cli.js.map +0 -1
package/dist/api.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { UUID, formatTime } from '@yuants/utils';
|
|
2
|
-
// @ts-ignore
|
|
3
|
-
import CryptoJS from 'crypto-js';
|
|
1
|
+
import { HmacSHA256, UUID, encodeBase64, formatTime } from '@yuants/utils';
|
|
4
2
|
import { Subject, filter, firstValueFrom, mergeMap, of, shareReplay, throwError, timeout, timer } from 'rxjs';
|
|
5
3
|
/**
|
|
6
4
|
* API: https://www.bitget.com/zh-CN/api-doc/common/intro
|
|
@@ -56,7 +54,7 @@ export class CoinExClient {
|
|
|
56
54
|
const secret_key = this.config.auth.secret_key;
|
|
57
55
|
const body = method === 'GET' ? '' : JSON.stringify(params);
|
|
58
56
|
const signData = method + url.pathname + url.search + body + timestamp;
|
|
59
|
-
const str =
|
|
57
|
+
const str = encodeBase64(await HmacSHA256(new TextEncoder().encode(signData), new TextEncoder().encode(secret_key)));
|
|
60
58
|
const headers = {
|
|
61
59
|
'Content-Type': 'application/json',
|
|
62
60
|
'X-COINEX-KEY': this.config.auth.access_key,
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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","sourcesContent":["import { UUID, formatTime } from '@yuants/utils';\n// @ts-ignore\nimport CryptoJS from 'crypto-js';\nimport { Subject, filter, firstValueFrom, mergeMap, of, shareReplay, throwError, timeout, timer } from 'rxjs';\n\n/**\n * API: https://www.bitget.com/zh-CN/api-doc/common/intro\n */\nexport class CoinExClient {\n noAuth = true;\n constructor(\n public config: {\n auth: {\n access_key: string;\n secret_key: string;\n };\n },\n ) {\n if (config.auth.access_key && config.auth.secret_key) {\n this.noAuth = false;\n }\n }\n\n async request(method: string, path: string, params?: any) {\n const url = new URL('https://api.coinex.com');\n url.pathname = path;\n if (method === 'GET' && params !== undefined) {\n const sortedParams = Object.entries(params).sort(([a], [b]) => a.localeCompare(b));\n for (const [k, v] of sortedParams) {\n url.searchParams.set(k, '' + v);\n }\n }\n if (this.noAuth) {\n console.info(formatTime(Date.now()), method, url.href);\n const res = await fetch(url.href, { method });\n return res.json();\n }\n const timestamp = '' + Date.now();\n const secret_key = this.config.auth.secret_key;\n const body = method === 'GET' ? '' : JSON.stringify(params);\n const signData = method + url.pathname + url.search + body + timestamp;\n const str = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(signData, secret_key));\n\n const headers = {\n 'Content-Type': 'application/json',\n 'X-COINEX-KEY': this.config.auth.access_key!,\n 'X-COINEX-SIGN': str,\n 'X-COINEX-TIMESTAMP': timestamp,\n };\n\n console.info(formatTime(Date.now()), method, url.href, JSON.stringify(headers), body, signData);\n const res = await fetch(url.href, {\n method,\n headers,\n body: body || undefined,\n });\n\n return res.json();\n }\n\n mapPathToRequestChannel: Record<\n string,\n {\n requestQueue: Array<{\n trace_id: string;\n method: string;\n path: string;\n params?: any;\n }>;\n responseChannel: Subject<{ trace_id: string; response?: any; error?: Error }>;\n }\n > = {};\n\n setupChannel(path: string, period: number, limit: number) {\n this.mapPathToRequestChannel[path] = {\n requestQueue: [],\n responseChannel: new Subject(),\n };\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n timer(0, period)\n .pipe(\n filter(() => requestQueue.length > 0),\n mergeMap(() => requestQueue.splice(0, limit)),\n mergeMap(async (request) => {\n try {\n const res = await this.request(request.method, request.path, request.params);\n return { trace_id: request.trace_id, response: res };\n } catch (error) {\n return { trace_id: request.trace_id, error };\n }\n }),\n )\n .subscribe(responseChannel);\n }\n\n /**\n * @param method - GET, POST, PUT, DELETE\n * @param path - api path\n * @param flowControl - period in ms, limit in count\n * @param params - request params/body\n * @returns\n */\n async requestWithFlowControl(\n method: string,\n path: string,\n flowControl: { period: number; limit: number } = { period: 10, limit: Infinity },\n params?: any,\n ) {\n const { period, limit } = flowControl;\n if (!this.mapPathToRequestChannel[path]) {\n this.setupChannel(path, period, limit);\n }\n const uuid = UUID();\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n const res$ = responseChannel.pipe(\n //\n filter((response) => response.trace_id === uuid),\n mergeMap((response) => (response.error ? throwError(() => response.error) : of(response))),\n timeout(30_000),\n shareReplay(1),\n );\n requestQueue.push({ trace_id: uuid, method, path, params });\n return (await firstValueFrom(res$)).response;\n }\n\n /**\n * 获取市场资金费率\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate\n */\n getFuturesFundingRate = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n mark_price: string;\n latest_funding_rate: string;\n next_funding_rate: string;\n max_funding_time: string;\n min_funding_time: string;\n latest_funding_time: number;\n next_funding_time: number;\n }[];\n }> => this.requestWithFlowControl('GET', '/v2/futures/funding-rate', { period: 1000, limit: 400 }, params);\n\n /**\n * 获取市场资金费率历史记录\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate-history\n */\n getFuturesFundingRateHistory = async (params: {\n market: string;\n start_time?: number;\n end_time?: number;\n page?: number;\n limit?: number;\n }): Promise<{\n code: number;\n message: string;\n pagination: {\n has_next: boolean;\n };\n data: {\n market: string;\n funding_time: number;\n theoretical_funding_rate: string;\n actual_funding_rate: string;\n }[];\n }> =>\n this.requestWithFlowControl(\n 'GET',\n '/v2/futures/funding-rate-history',\n { period: 1000, limit: 400 },\n params,\n );\n\n /**\n * 获取市场状态\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market\n */\n getFuturesMarket = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n contract_type: string;\n maker_fee_rate: string;\n taker_fee_rate: string;\n min_amount: string;\n base_ccy: string;\n quote_ccy: string;\n base_ccy_precision: number;\n quote_ccy_precision: number;\n leverage: number[];\n open_interest_volume: string;\n }[];\n }> => this.request('GET', '/v2/futures/market', params);\n\n /**\n * 获取市场行情\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-ticker\n */\n getFuturesTicker = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n last: string;\n open: string;\n close: string;\n high: string;\n low: string;\n volume: string;\n value: string;\n volume_sell: string;\n volume_buy: string;\n index_price: string;\n mark_price: string;\n period: number;\n }[];\n }> => this.request('GET', '/v2/futures/ticker', params);\n}\n\nexport const client = new CoinExClient({\n auth: {\n access_key: process.env.ACCESS_KEY!,\n secret_key: process.env.SECRET_KEY!,\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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","sourcesContent":["import { HmacSHA256, UUID, encodeBase64, formatTime } from '@yuants/utils';\nimport { Subject, filter, firstValueFrom, mergeMap, of, shareReplay, throwError, timeout, timer } from 'rxjs';\n\n/**\n * API: https://www.bitget.com/zh-CN/api-doc/common/intro\n */\nexport class CoinExClient {\n noAuth = true;\n constructor(\n public config: {\n auth: {\n access_key: string;\n secret_key: string;\n };\n },\n ) {\n if (config.auth.access_key && config.auth.secret_key) {\n this.noAuth = false;\n }\n }\n\n async request(method: string, path: string, params?: any) {\n const url = new URL('https://api.coinex.com');\n url.pathname = path;\n if (method === 'GET' && params !== undefined) {\n const sortedParams = Object.entries(params).sort(([a], [b]) => a.localeCompare(b));\n for (const [k, v] of sortedParams) {\n url.searchParams.set(k, '' + v);\n }\n }\n if (this.noAuth) {\n console.info(formatTime(Date.now()), method, url.href);\n const res = await fetch(url.href, { method });\n return res.json();\n }\n const timestamp = '' + Date.now();\n const secret_key = this.config.auth.secret_key;\n const body = method === 'GET' ? '' : JSON.stringify(params);\n const signData = method + url.pathname + url.search + body + timestamp;\n const str = encodeBase64(\n await HmacSHA256(new TextEncoder().encode(signData), new TextEncoder().encode(secret_key)),\n );\n\n const headers = {\n 'Content-Type': 'application/json',\n 'X-COINEX-KEY': this.config.auth.access_key!,\n 'X-COINEX-SIGN': str,\n 'X-COINEX-TIMESTAMP': timestamp,\n };\n\n console.info(formatTime(Date.now()), method, url.href, JSON.stringify(headers), body, signData);\n const res = await fetch(url.href, {\n method,\n headers,\n body: body || undefined,\n });\n\n return res.json();\n }\n\n mapPathToRequestChannel: Record<\n string,\n {\n requestQueue: Array<{\n trace_id: string;\n method: string;\n path: string;\n params?: any;\n }>;\n responseChannel: Subject<{ trace_id: string; response?: any; error?: Error }>;\n }\n > = {};\n\n setupChannel(path: string, period: number, limit: number) {\n this.mapPathToRequestChannel[path] = {\n requestQueue: [],\n responseChannel: new Subject(),\n };\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n timer(0, period)\n .pipe(\n filter(() => requestQueue.length > 0),\n mergeMap(() => requestQueue.splice(0, limit)),\n mergeMap(async (request) => {\n try {\n const res = await this.request(request.method, request.path, request.params);\n return { trace_id: request.trace_id, response: res };\n } catch (error) {\n return { trace_id: request.trace_id, error };\n }\n }),\n )\n .subscribe(responseChannel);\n }\n\n /**\n * @param method - GET, POST, PUT, DELETE\n * @param path - api path\n * @param flowControl - period in ms, limit in count\n * @param params - request params/body\n * @returns\n */\n async requestWithFlowControl(\n method: string,\n path: string,\n flowControl: { period: number; limit: number } = { period: 10, limit: Infinity },\n params?: any,\n ) {\n const { period, limit } = flowControl;\n if (!this.mapPathToRequestChannel[path]) {\n this.setupChannel(path, period, limit);\n }\n const uuid = UUID();\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n const res$ = responseChannel.pipe(\n //\n filter((response) => response.trace_id === uuid),\n mergeMap((response) => (response.error ? throwError(() => response.error) : of(response))),\n timeout(30_000),\n shareReplay(1),\n );\n requestQueue.push({ trace_id: uuid, method, path, params });\n return (await firstValueFrom(res$)).response;\n }\n\n /**\n * 获取市场资金费率\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate\n */\n getFuturesFundingRate = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n mark_price: string;\n latest_funding_rate: string;\n next_funding_rate: string;\n max_funding_time: string;\n min_funding_time: string;\n latest_funding_time: number;\n next_funding_time: number;\n }[];\n }> => this.requestWithFlowControl('GET', '/v2/futures/funding-rate', { period: 1000, limit: 400 }, params);\n\n /**\n * 获取市场资金费率历史记录\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate-history\n */\n getFuturesFundingRateHistory = async (params: {\n market: string;\n start_time?: number;\n end_time?: number;\n page?: number;\n limit?: number;\n }): Promise<{\n code: number;\n message: string;\n pagination: {\n has_next: boolean;\n };\n data: {\n market: string;\n funding_time: number;\n theoretical_funding_rate: string;\n actual_funding_rate: string;\n }[];\n }> =>\n this.requestWithFlowControl(\n 'GET',\n '/v2/futures/funding-rate-history',\n { period: 1000, limit: 400 },\n params,\n );\n\n /**\n * 获取市场状态\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market\n */\n getFuturesMarket = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n contract_type: string;\n maker_fee_rate: string;\n taker_fee_rate: string;\n min_amount: string;\n base_ccy: string;\n quote_ccy: string;\n base_ccy_precision: number;\n quote_ccy_precision: number;\n leverage: number[];\n open_interest_volume: string;\n }[];\n }> => this.request('GET', '/v2/futures/market', params);\n\n /**\n * 获取市场行情\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-ticker\n */\n getFuturesTicker = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n last: string;\n open: string;\n close: string;\n high: string;\n low: string;\n volume: string;\n value: string;\n volume_sell: string;\n volume_buy: string;\n index_price: string;\n mark_price: string;\n period: number;\n }[];\n }> => this.request('GET', '/v2/futures/ticker', params);\n}\n\nexport const client = new CoinExClient({\n auth: {\n access_key: process.env.ACCESS_KEY!,\n secret_key: process.env.SECRET_KEY!,\n },\n});\n"]}
|
package/lib/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAiF,MAAM,MAAM,CAAC;AAE9G;;GAEG;AACH,qBAAa,YAAY;IAGd,MAAM,EAAE;QACb,IAAI,EAAE;YACJ,UAAU,EAAE,MAAM,CAAC;YACnB,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;KACH;IAPH,MAAM,UAAQ;gBAEL,MAAM,EAAE;QACb,IAAI,EAAE;YACJ,UAAU,EAAE,MAAM,CAAC;YACnB,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;KACH;IAOG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG;IAuCxD,uBAAuB,EAAE,MAAM,CAC7B,MAAM,EACN;QACE,YAAY,EAAE,KAAK,CAAC;YAClB,QAAQ,EAAE,MAAM,CAAC;YACjB,MAAM,EAAE,MAAM,CAAC;YACf,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,CAAC,EAAE,GAAG,CAAC;SACd,CAAC,CAAC;QACH,eAAe,EAAE,OAAO,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,GAAG,CAAC;YAAC,KAAK,CAAC,EAAE,KAAK,CAAA;SAAE,CAAC,CAAC;KAC/E,CACF,CAAM;IAEP,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAuBxD;;;;;;OAMG;IACG,sBAAsB,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,WAAW,GAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAoC,EAChF,MAAM,CAAC,EAAE,GAAG;IAoBd;;;;OAIG;IACH,qBAAqB,YAAmB;QACtC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,KAAG,QAAQ;QACV,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE;YACJ,MAAM,EAAE,MAAM,CAAC;YACf,UAAU,EAAE,MAAM,CAAC;YACnB,mBAAmB,EAAE,MAAM,CAAC;YAC5B,iBAAiB,EAAE,MAAM,CAAC;YAC1B,gBAAgB,EAAE,MAAM,CAAC;YACzB,gBAAgB,EAAE,MAAM,CAAC;YACzB,mBAAmB,EAAE,MAAM,CAAC;YAC5B,iBAAiB,EAAE,MAAM,CAAC;SAC3B,EAAE,CAAC;KACL,CAAC,CAAyG;IAE3G;;;;OAIG;IACH,4BAA4B,WAAkB;QAC5C,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,KAAG,QAAQ;QACV,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE;YACV,QAAQ,EAAE,OAAO,CAAC;SACnB,CAAC;QACF,IAAI,EAAE;YACJ,MAAM,EAAE,MAAM,CAAC;YACf,YAAY,EAAE,MAAM,CAAC;YACrB,wBAAwB,EAAE,MAAM,CAAC;YACjC,mBAAmB,EAAE,MAAM,CAAC;SAC7B,EAAE,CAAC;KACL,CAAC,CAME;IAEJ;;;;OAIG;IACH,gBAAgB,YAAmB;QACjC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,KAAG,QAAQ;QACV,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE;YACJ,MAAM,EAAE,MAAM,CAAC;YACf,aAAa,EAAE,MAAM,CAAC;YACtB,cAAc,EAAE,MAAM,CAAC;YACvB,cAAc,EAAE,MAAM,CAAC;YACvB,UAAU,EAAE,MAAM,CAAC;YACnB,QAAQ,EAAE,MAAM,CAAC;YACjB,SAAS,EAAE,MAAM,CAAC;YAClB,kBAAkB,EAAE,MAAM,CAAC;YAC3B,mBAAmB,EAAE,MAAM,CAAC;YAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;YACnB,oBAAoB,EAAE,MAAM,CAAC;SAC9B,EAAE,CAAC;KACL,CAAC,CAAsD;IAExD;;;;OAIG;IACH,gBAAgB,YAAmB;QACjC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,KAAG,QAAQ;QACV,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE;YACJ,MAAM,EAAE,MAAM,CAAC;YACf,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,MAAM,CAAC;YACb,OAAO,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;YACZ,MAAM,EAAE,MAAM,CAAC;YACf,KAAK,EAAE,MAAM,CAAC;YACd,WAAW,EAAE,MAAM,CAAC;YACpB,UAAU,EAAE,MAAM,CAAC;YACnB,WAAW,EAAE,MAAM,CAAC;YACpB,UAAU,EAAE,MAAM,CAAC;YACnB,MAAM,EAAE,MAAM,CAAC;SAChB,EAAE,CAAC;KACL,CAAC,CAAsD;CACzD;AAED,eAAO,MAAM,MAAM,cAKjB,CAAC"}
|
package/lib/api.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.client = exports.CoinExClient = void 0;
|
|
7
4
|
const utils_1 = require("@yuants/utils");
|
|
8
|
-
// @ts-ignore
|
|
9
|
-
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
10
5
|
const rxjs_1 = require("rxjs");
|
|
11
6
|
/**
|
|
12
7
|
* API: https://www.bitget.com/zh-CN/api-doc/common/intro
|
|
@@ -62,7 +57,7 @@ class CoinExClient {
|
|
|
62
57
|
const secret_key = this.config.auth.secret_key;
|
|
63
58
|
const body = method === 'GET' ? '' : JSON.stringify(params);
|
|
64
59
|
const signData = method + url.pathname + url.search + body + timestamp;
|
|
65
|
-
const str =
|
|
60
|
+
const str = (0, utils_1.encodeBase64)(await (0, utils_1.HmacSHA256)(new TextEncoder().encode(signData), new TextEncoder().encode(secret_key)));
|
|
66
61
|
const headers = {
|
|
67
62
|
'Content-Type': 'application/json',
|
|
68
63
|
'X-COINEX-KEY': this.config.auth.access_key,
|
package/lib/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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","sourcesContent":["import { UUID, formatTime } from '@yuants/utils';\n// @ts-ignore\nimport CryptoJS from 'crypto-js';\nimport { Subject, filter, firstValueFrom, mergeMap, of, shareReplay, throwError, timeout, timer } from 'rxjs';\n\n/**\n * API: https://www.bitget.com/zh-CN/api-doc/common/intro\n */\nexport class CoinExClient {\n noAuth = true;\n constructor(\n public config: {\n auth: {\n access_key: string;\n secret_key: string;\n };\n },\n ) {\n if (config.auth.access_key && config.auth.secret_key) {\n this.noAuth = false;\n }\n }\n\n async request(method: string, path: string, params?: any) {\n const url = new URL('https://api.coinex.com');\n url.pathname = path;\n if (method === 'GET' && params !== undefined) {\n const sortedParams = Object.entries(params).sort(([a], [b]) => a.localeCompare(b));\n for (const [k, v] of sortedParams) {\n url.searchParams.set(k, '' + v);\n }\n }\n if (this.noAuth) {\n console.info(formatTime(Date.now()), method, url.href);\n const res = await fetch(url.href, { method });\n return res.json();\n }\n const timestamp = '' + Date.now();\n const secret_key = this.config.auth.secret_key;\n const body = method === 'GET' ? '' : JSON.stringify(params);\n const signData = method + url.pathname + url.search + body + timestamp;\n const str = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(signData, secret_key));\n\n const headers = {\n 'Content-Type': 'application/json',\n 'X-COINEX-KEY': this.config.auth.access_key!,\n 'X-COINEX-SIGN': str,\n 'X-COINEX-TIMESTAMP': timestamp,\n };\n\n console.info(formatTime(Date.now()), method, url.href, JSON.stringify(headers), body, signData);\n const res = await fetch(url.href, {\n method,\n headers,\n body: body || undefined,\n });\n\n return res.json();\n }\n\n mapPathToRequestChannel: Record<\n string,\n {\n requestQueue: Array<{\n trace_id: string;\n method: string;\n path: string;\n params?: any;\n }>;\n responseChannel: Subject<{ trace_id: string; response?: any; error?: Error }>;\n }\n > = {};\n\n setupChannel(path: string, period: number, limit: number) {\n this.mapPathToRequestChannel[path] = {\n requestQueue: [],\n responseChannel: new Subject(),\n };\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n timer(0, period)\n .pipe(\n filter(() => requestQueue.length > 0),\n mergeMap(() => requestQueue.splice(0, limit)),\n mergeMap(async (request) => {\n try {\n const res = await this.request(request.method, request.path, request.params);\n return { trace_id: request.trace_id, response: res };\n } catch (error) {\n return { trace_id: request.trace_id, error };\n }\n }),\n )\n .subscribe(responseChannel);\n }\n\n /**\n * @param method - GET, POST, PUT, DELETE\n * @param path - api path\n * @param flowControl - period in ms, limit in count\n * @param params - request params/body\n * @returns\n */\n async requestWithFlowControl(\n method: string,\n path: string,\n flowControl: { period: number; limit: number } = { period: 10, limit: Infinity },\n params?: any,\n ) {\n const { period, limit } = flowControl;\n if (!this.mapPathToRequestChannel[path]) {\n this.setupChannel(path, period, limit);\n }\n const uuid = UUID();\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n const res$ = responseChannel.pipe(\n //\n filter((response) => response.trace_id === uuid),\n mergeMap((response) => (response.error ? throwError(() => response.error) : of(response))),\n timeout(30_000),\n shareReplay(1),\n );\n requestQueue.push({ trace_id: uuid, method, path, params });\n return (await firstValueFrom(res$)).response;\n }\n\n /**\n * 获取市场资金费率\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate\n */\n getFuturesFundingRate = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n mark_price: string;\n latest_funding_rate: string;\n next_funding_rate: string;\n max_funding_time: string;\n min_funding_time: string;\n latest_funding_time: number;\n next_funding_time: number;\n }[];\n }> => this.requestWithFlowControl('GET', '/v2/futures/funding-rate', { period: 1000, limit: 400 }, params);\n\n /**\n * 获取市场资金费率历史记录\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate-history\n */\n getFuturesFundingRateHistory = async (params: {\n market: string;\n start_time?: number;\n end_time?: number;\n page?: number;\n limit?: number;\n }): Promise<{\n code: number;\n message: string;\n pagination: {\n has_next: boolean;\n };\n data: {\n market: string;\n funding_time: number;\n theoretical_funding_rate: string;\n actual_funding_rate: string;\n }[];\n }> =>\n this.requestWithFlowControl(\n 'GET',\n '/v2/futures/funding-rate-history',\n { period: 1000, limit: 400 },\n params,\n );\n\n /**\n * 获取市场状态\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market\n */\n getFuturesMarket = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n contract_type: string;\n maker_fee_rate: string;\n taker_fee_rate: string;\n min_amount: string;\n base_ccy: string;\n quote_ccy: string;\n base_ccy_precision: number;\n quote_ccy_precision: number;\n leverage: number[];\n open_interest_volume: string;\n }[];\n }> => this.request('GET', '/v2/futures/market', params);\n\n /**\n * 获取市场行情\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-ticker\n */\n getFuturesTicker = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n last: string;\n open: string;\n close: string;\n high: string;\n low: string;\n volume: string;\n value: string;\n volume_sell: string;\n volume_buy: string;\n index_price: string;\n mark_price: string;\n period: number;\n }[];\n }> => this.request('GET', '/v2/futures/ticker', params);\n}\n\nexport const client = new CoinExClient({\n auth: {\n access_key: process.env.ACCESS_KEY!,\n secret_key: process.env.SECRET_KEY!,\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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","sourcesContent":["import { HmacSHA256, UUID, encodeBase64, formatTime } from '@yuants/utils';\nimport { Subject, filter, firstValueFrom, mergeMap, of, shareReplay, throwError, timeout, timer } from 'rxjs';\n\n/**\n * API: https://www.bitget.com/zh-CN/api-doc/common/intro\n */\nexport class CoinExClient {\n noAuth = true;\n constructor(\n public config: {\n auth: {\n access_key: string;\n secret_key: string;\n };\n },\n ) {\n if (config.auth.access_key && config.auth.secret_key) {\n this.noAuth = false;\n }\n }\n\n async request(method: string, path: string, params?: any) {\n const url = new URL('https://api.coinex.com');\n url.pathname = path;\n if (method === 'GET' && params !== undefined) {\n const sortedParams = Object.entries(params).sort(([a], [b]) => a.localeCompare(b));\n for (const [k, v] of sortedParams) {\n url.searchParams.set(k, '' + v);\n }\n }\n if (this.noAuth) {\n console.info(formatTime(Date.now()), method, url.href);\n const res = await fetch(url.href, { method });\n return res.json();\n }\n const timestamp = '' + Date.now();\n const secret_key = this.config.auth.secret_key;\n const body = method === 'GET' ? '' : JSON.stringify(params);\n const signData = method + url.pathname + url.search + body + timestamp;\n const str = encodeBase64(\n await HmacSHA256(new TextEncoder().encode(signData), new TextEncoder().encode(secret_key)),\n );\n\n const headers = {\n 'Content-Type': 'application/json',\n 'X-COINEX-KEY': this.config.auth.access_key!,\n 'X-COINEX-SIGN': str,\n 'X-COINEX-TIMESTAMP': timestamp,\n };\n\n console.info(formatTime(Date.now()), method, url.href, JSON.stringify(headers), body, signData);\n const res = await fetch(url.href, {\n method,\n headers,\n body: body || undefined,\n });\n\n return res.json();\n }\n\n mapPathToRequestChannel: Record<\n string,\n {\n requestQueue: Array<{\n trace_id: string;\n method: string;\n path: string;\n params?: any;\n }>;\n responseChannel: Subject<{ trace_id: string; response?: any; error?: Error }>;\n }\n > = {};\n\n setupChannel(path: string, period: number, limit: number) {\n this.mapPathToRequestChannel[path] = {\n requestQueue: [],\n responseChannel: new Subject(),\n };\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n timer(0, period)\n .pipe(\n filter(() => requestQueue.length > 0),\n mergeMap(() => requestQueue.splice(0, limit)),\n mergeMap(async (request) => {\n try {\n const res = await this.request(request.method, request.path, request.params);\n return { trace_id: request.trace_id, response: res };\n } catch (error) {\n return { trace_id: request.trace_id, error };\n }\n }),\n )\n .subscribe(responseChannel);\n }\n\n /**\n * @param method - GET, POST, PUT, DELETE\n * @param path - api path\n * @param flowControl - period in ms, limit in count\n * @param params - request params/body\n * @returns\n */\n async requestWithFlowControl(\n method: string,\n path: string,\n flowControl: { period: number; limit: number } = { period: 10, limit: Infinity },\n params?: any,\n ) {\n const { period, limit } = flowControl;\n if (!this.mapPathToRequestChannel[path]) {\n this.setupChannel(path, period, limit);\n }\n const uuid = UUID();\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n const res$ = responseChannel.pipe(\n //\n filter((response) => response.trace_id === uuid),\n mergeMap((response) => (response.error ? throwError(() => response.error) : of(response))),\n timeout(30_000),\n shareReplay(1),\n );\n requestQueue.push({ trace_id: uuid, method, path, params });\n return (await firstValueFrom(res$)).response;\n }\n\n /**\n * 获取市场资金费率\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate\n */\n getFuturesFundingRate = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n mark_price: string;\n latest_funding_rate: string;\n next_funding_rate: string;\n max_funding_time: string;\n min_funding_time: string;\n latest_funding_time: number;\n next_funding_time: number;\n }[];\n }> => this.requestWithFlowControl('GET', '/v2/futures/funding-rate', { period: 1000, limit: 400 }, params);\n\n /**\n * 获取市场资金费率历史记录\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate-history\n */\n getFuturesFundingRateHistory = async (params: {\n market: string;\n start_time?: number;\n end_time?: number;\n page?: number;\n limit?: number;\n }): Promise<{\n code: number;\n message: string;\n pagination: {\n has_next: boolean;\n };\n data: {\n market: string;\n funding_time: number;\n theoretical_funding_rate: string;\n actual_funding_rate: string;\n }[];\n }> =>\n this.requestWithFlowControl(\n 'GET',\n '/v2/futures/funding-rate-history',\n { period: 1000, limit: 400 },\n params,\n );\n\n /**\n * 获取市场状态\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market\n */\n getFuturesMarket = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n contract_type: string;\n maker_fee_rate: string;\n taker_fee_rate: string;\n min_amount: string;\n base_ccy: string;\n quote_ccy: string;\n base_ccy_precision: number;\n quote_ccy_precision: number;\n leverage: number[];\n open_interest_volume: string;\n }[];\n }> => this.request('GET', '/v2/futures/market', params);\n\n /**\n * 获取市场行情\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-ticker\n */\n getFuturesTicker = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n last: string;\n open: string;\n close: string;\n high: string;\n low: string;\n volume: string;\n value: string;\n volume_sell: string;\n volume_buy: string;\n index_price: string;\n mark_price: string;\n period: number;\n }[];\n }> => this.request('GET', '/v2/futures/ticker', params);\n}\n\nexport const client = new CoinExClient({\n auth: {\n access_key: process.env.ACCESS_KEY!,\n secret_key: process.env.SECRET_KEY!,\n },\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuants/vendor-coinex",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.41",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -9,15 +9,14 @@
|
|
|
9
9
|
"temp"
|
|
10
10
|
],
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@yuants/protocol": "0.53.
|
|
13
|
-
"@yuants/transfer": "0.2.
|
|
14
|
-
"@yuants/utils": "0.
|
|
15
|
-
"@yuants/sql": "0.9.
|
|
16
|
-
"@yuants/data-series": "0.3.
|
|
17
|
-
"@yuants/data-product": "0.4.
|
|
18
|
-
"@yuants/data-interest-rate": "0.1.
|
|
19
|
-
"rxjs": "~7.5.6"
|
|
20
|
-
"crypto-js": "^4.2.0"
|
|
12
|
+
"@yuants/protocol": "0.53.1",
|
|
13
|
+
"@yuants/transfer": "0.2.38",
|
|
14
|
+
"@yuants/utils": "0.14.0",
|
|
15
|
+
"@yuants/sql": "0.9.29",
|
|
16
|
+
"@yuants/data-series": "0.3.50",
|
|
17
|
+
"@yuants/data-product": "0.4.20",
|
|
18
|
+
"@yuants/data-interest-rate": "0.1.47",
|
|
19
|
+
"rxjs": "~7.5.6"
|
|
21
20
|
},
|
|
22
21
|
"devDependencies": {
|
|
23
22
|
"@microsoft/api-extractor": "~7.30.0",
|
|
@@ -26,7 +25,7 @@
|
|
|
26
25
|
"@rushstack/heft-node-rig": "~1.10.7",
|
|
27
26
|
"@types/heft-jest": "1.0.3",
|
|
28
27
|
"@types/node": "22",
|
|
29
|
-
"@yuants/extension": "0.2.
|
|
28
|
+
"@yuants/extension": "0.2.31",
|
|
30
29
|
"@yuants/tool-kit": "0.2.1",
|
|
31
30
|
"typescript": "~4.7.4",
|
|
32
31
|
"ts-node": "~10.9.2"
|
package/temp/package-deps.json
CHANGED
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
"apps/vendor-coinex/CHANGELOG.json": "
|
|
3
|
-
"apps/vendor-coinex/CHANGELOG.md": "
|
|
2
|
+
"apps/vendor-coinex/CHANGELOG.json": "0dd3e635ac3af5147d8ac6b0aa7f835f94273aaa",
|
|
3
|
+
"apps/vendor-coinex/CHANGELOG.md": "b6d89c827959d80c9dd08cff23fe0f75e984d888",
|
|
4
4
|
"apps/vendor-coinex/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
|
|
5
5
|
"apps/vendor-coinex/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
|
|
6
6
|
"apps/vendor-coinex/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
|
|
7
7
|
"apps/vendor-coinex/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
|
|
8
8
|
"apps/vendor-coinex/etc/vendor-coinex.api.md": "33941b70ac7469421ff8fb8c157181014a0ea655",
|
|
9
|
-
"apps/vendor-coinex/package.json": "
|
|
10
|
-
"apps/vendor-coinex/src/api.ts": "
|
|
11
|
-
"apps/vendor-coinex/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
|
|
9
|
+
"apps/vendor-coinex/package.json": "a117f2a732e78025a796825af9648a70b42ffb8c",
|
|
10
|
+
"apps/vendor-coinex/src/api.ts": "2c912b4fcb8e849cef573c6cd7c26489a6ab0b70",
|
|
12
11
|
"apps/vendor-coinex/src/index.ts": "1839b7a344b0f693f8e835f048a0bf6a69f5ff60",
|
|
13
12
|
"apps/vendor-coinex/src/interest_rate.ts": "a4c7e8f7302c9efe2dd28f6553641d85f45af45c",
|
|
14
13
|
"apps/vendor-coinex/src/product.ts": "c11fafeac162c0037299b79d4ce9594a931d7a96",
|
|
15
14
|
"apps/vendor-coinex/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
|
|
16
|
-
"apps/vendor-coinex/.rush/temp/shrinkwrap-deps.json": "
|
|
17
|
-
"libraries/protocol/temp/package-deps.json": "
|
|
18
|
-
"libraries/transfer/temp/package-deps.json": "
|
|
19
|
-
"libraries/utils/temp/package-deps.json": "
|
|
20
|
-
"libraries/sql/temp/package-deps.json": "
|
|
21
|
-
"libraries/data-series/temp/package-deps.json": "
|
|
22
|
-
"libraries/data-product/temp/package-deps.json": "
|
|
23
|
-
"libraries/data-interest-rate/temp/package-deps.json": "
|
|
24
|
-
"libraries/extension/temp/package-deps.json": "
|
|
15
|
+
"apps/vendor-coinex/.rush/temp/shrinkwrap-deps.json": "537a943cdb48a6dab24c8bb450baed0c66b8c244",
|
|
16
|
+
"libraries/protocol/temp/package-deps.json": "14095036ed251977cb3fb362a7e23d8786aaa4c9",
|
|
17
|
+
"libraries/transfer/temp/package-deps.json": "0be7967706065779def1ef1e7f68a9794690599a",
|
|
18
|
+
"libraries/utils/temp/package-deps.json": "6d58e9b325e8d16de8a878c32010f626b12a01da",
|
|
19
|
+
"libraries/sql/temp/package-deps.json": "95cd7209bf6002d530eb37960bac77c793afadd0",
|
|
20
|
+
"libraries/data-series/temp/package-deps.json": "d70ec6d1ca7342204a35a1c3619481e226239e73",
|
|
21
|
+
"libraries/data-product/temp/package-deps.json": "60b8abf6f95edc29268f10f0d64331e2f034a3e5",
|
|
22
|
+
"libraries/data-interest-rate/temp/package-deps.json": "92396227ed3aab2f407bf93c515cf340ac796932",
|
|
23
|
+
"libraries/extension/temp/package-deps.json": "9569c553c2f9a7d50b70d8f101fc2d3825aaccb9",
|
|
25
24
|
"tools/toolkit/temp/package-deps.json": "23e053490eb8feade23e4d45de4e54883e322711"
|
|
26
25
|
}
|
package/dist/cli.js
DELETED
package/dist/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,SAAS,CAAC","sourcesContent":["#!/usr/bin/env node\nimport './index';\n"]}
|
package/lib/cli.d.ts
DELETED
package/lib/cli.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,SAAS,CAAC"}
|
package/lib/cli.js
DELETED
package/lib/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,mBAAiB","sourcesContent":["#!/usr/bin/env node\nimport './index';\n"]}
|