ccxt 4.2.89 → 4.2.91

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.
Files changed (90) hide show
  1. package/CHANGELOG.md +44 -16
  2. package/README.md +3 -3
  3. package/build.sh +1 -1
  4. package/dist/ccxt.browser.js +1167 -274
  5. package/dist/ccxt.browser.min.js +6 -4
  6. package/dist/cjs/ccxt.js +1 -1
  7. package/dist/cjs/src/ascendex.js +1 -0
  8. package/dist/cjs/src/base/Exchange.js +39 -9
  9. package/dist/cjs/src/base/functions/crypto.js +37 -0
  10. package/dist/cjs/src/base/functions/rsa.js +19 -4
  11. package/dist/cjs/src/binance.js +90 -9
  12. package/dist/cjs/src/bingx.js +101 -1
  13. package/dist/cjs/src/bitfinex2.js +1 -0
  14. package/dist/cjs/src/bitget.js +2 -0
  15. package/dist/cjs/src/bitmex.js +1 -0
  16. package/dist/cjs/src/bitrue.js +1 -0
  17. package/dist/cjs/src/bybit.js +61 -0
  18. package/dist/cjs/src/coinbase.js +51 -25
  19. package/dist/cjs/src/coinbaseinternational.js +1 -0
  20. package/dist/cjs/src/coinex.js +102 -8
  21. package/dist/cjs/src/cryptocom.js +1 -0
  22. package/dist/cjs/src/delta.js +1 -0
  23. package/dist/cjs/src/digifinex.js +1 -0
  24. package/dist/cjs/src/exmo.js +1 -0
  25. package/dist/cjs/src/gate.js +2 -0
  26. package/dist/cjs/src/gemini.js +12 -10
  27. package/dist/cjs/src/hitbtc.js +1 -0
  28. package/dist/cjs/src/htx.js +1 -0
  29. package/dist/cjs/src/hyperliquid.js +1 -0
  30. package/dist/cjs/src/kraken.js +11 -9
  31. package/dist/cjs/src/kucoin.js +1 -0
  32. package/dist/cjs/src/kucoinfutures.js +34 -3
  33. package/dist/cjs/src/mexc.js +1 -0
  34. package/dist/cjs/src/okx.js +187 -38
  35. package/dist/cjs/src/phemex.js +1 -0
  36. package/dist/cjs/src/pro/bitmex.js +39 -18
  37. package/dist/cjs/src/pro/kucoin.js +91 -0
  38. package/dist/cjs/src/pro/kucoinfutures.js +151 -82
  39. package/dist/cjs/src/static_dependencies/noble-curves/p256.js +48 -0
  40. package/dist/cjs/src/woo.js +1 -0
  41. package/js/ccxt.d.ts +1 -1
  42. package/js/ccxt.js +1 -1
  43. package/js/src/abstract/bingx.d.ts +2 -0
  44. package/js/src/abstract/bybit.d.ts +2 -0
  45. package/js/src/ascendex.js +1 -0
  46. package/js/src/base/Exchange.d.ts +5 -0
  47. package/js/src/base/Exchange.js +39 -9
  48. package/js/src/base/functions/crypto.js +37 -0
  49. package/js/src/base/functions/rsa.d.ts +1 -1
  50. package/js/src/base/functions/rsa.js +21 -5
  51. package/js/src/base/types.d.ts +1 -0
  52. package/js/src/binance.d.ts +1 -0
  53. package/js/src/binance.js +90 -9
  54. package/js/src/bingx.d.ts +1 -0
  55. package/js/src/bingx.js +101 -1
  56. package/js/src/bitfinex2.js +1 -0
  57. package/js/src/bitget.js +2 -0
  58. package/js/src/bitmex.js +1 -0
  59. package/js/src/bitrue.js +1 -0
  60. package/js/src/bybit.d.ts +2 -0
  61. package/js/src/bybit.js +61 -0
  62. package/js/src/coinbase.js +51 -25
  63. package/js/src/coinbaseinternational.js +1 -0
  64. package/js/src/coinex.d.ts +2 -0
  65. package/js/src/coinex.js +102 -8
  66. package/js/src/cryptocom.js +1 -0
  67. package/js/src/delta.js +1 -0
  68. package/js/src/digifinex.js +1 -0
  69. package/js/src/exmo.js +1 -0
  70. package/js/src/gate.js +2 -0
  71. package/js/src/gemini.js +12 -10
  72. package/js/src/hitbtc.js +1 -0
  73. package/js/src/htx.js +1 -0
  74. package/js/src/hyperliquid.js +1 -0
  75. package/js/src/kraken.js +11 -9
  76. package/js/src/kucoin.js +1 -0
  77. package/js/src/kucoinfutures.d.ts +2 -9
  78. package/js/src/kucoinfutures.js +34 -3
  79. package/js/src/mexc.js +1 -0
  80. package/js/src/okx.d.ts +1 -0
  81. package/js/src/okx.js +187 -38
  82. package/js/src/phemex.js +1 -0
  83. package/js/src/pro/bitmex.d.ts +1 -0
  84. package/js/src/pro/bitmex.js +39 -18
  85. package/js/src/pro/kucoin.d.ts +4 -0
  86. package/js/src/pro/kucoin.js +91 -0
  87. package/js/src/pro/kucoinfutures.d.ts +9 -5
  88. package/js/src/pro/kucoinfutures.js +151 -82
  89. package/js/src/woo.js +1 -0
  90. package/package.json +1 -1
@@ -12,6 +12,8 @@ class kucoinfutures extends kucoinfutures$1 {
12
12
  'has': {
13
13
  'ws': true,
14
14
  'watchTicker': true,
15
+ 'watchTickers': true,
16
+ 'watchBidsAsks': true,
15
17
  'watchTrades': true,
16
18
  'watchOrderBook': true,
17
19
  'watchOrders': true,
@@ -41,9 +43,6 @@ class kucoinfutures extends kucoinfutures$1 {
41
43
  'snapshotDelay': 20,
42
44
  'snapshotMaxRetries': 3,
43
45
  },
44
- 'watchTicker': {
45
- 'name': 'contractMarket/tickerV2', // market/ticker
46
- },
47
46
  'watchPosition': {
48
47
  'fetchPositionSnapshot': true,
49
48
  'awaitPositionSnapshot': true, // whether to wait for the position snapshot before providing updates
@@ -146,7 +145,7 @@ class kucoinfutures extends kucoinfutures$1 {
146
145
  }
147
146
  return await this.watch(url, messageHash, message, subscriptionHash, subscription);
148
147
  }
149
- async subscribeMultiple(url, messageHashes, topic, subscriptionHashes, subscription, params = {}) {
148
+ async subscribeMultiple(url, messageHashes, topic, subscriptionHashes, subscriptionArgs, params = {}) {
150
149
  const requestId = this.requestId().toString();
151
150
  const request = {
152
151
  'id': requestId,
@@ -154,24 +153,14 @@ class kucoinfutures extends kucoinfutures$1 {
154
153
  'topic': topic,
155
154
  'response': true,
156
155
  };
157
- const message = this.extend(request, params);
158
- const subscriptionRequest = {
159
- 'id': requestId,
160
- };
161
- if (subscription === undefined) {
162
- subscription = subscriptionRequest;
163
- }
164
- else {
165
- subscription = this.extend(subscriptionRequest, subscription);
166
- }
167
- return await this.watchMultiple(url, messageHashes, message, subscriptionHashes, subscription);
156
+ return await this.watchMultiple(url, messageHashes, this.extend(request, params), subscriptionHashes, subscriptionArgs);
168
157
  }
169
158
  async watchTicker(symbol, params = {}) {
170
159
  /**
171
160
  * @method
172
161
  * @name kucoinfutures#watchTicker
173
162
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
174
- * @see https://docs.kucoin.com/futures/#get-real-time-symbol-ticker-v2
163
+ * @see https://www.kucoin.com/docs/websocket/futures-trading/public-channels/get-ticker
175
164
  * @param {string} symbol unified symbol of the market to fetch the ticker for
176
165
  * @param {object} [params] extra parameters specific to the exchange API endpoint
177
166
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
@@ -179,30 +168,48 @@ class kucoinfutures extends kucoinfutures$1 {
179
168
  await this.loadMarkets();
180
169
  const market = this.market(symbol);
181
170
  symbol = market['symbol'];
182
- const url = await this.negotiate(false);
183
- const options = this.safeValue(this.options, 'watchTicker', {});
184
- const channel = this.safeString(options, 'name', 'contractMarket/tickerV2');
185
- const topic = '/' + channel + ':' + market['id'];
186
- const messageHash = 'ticker:' + symbol;
187
- return await this.subscribe(url, messageHash, topic, undefined, params);
171
+ params['callerMethodName'] = 'watchTicker';
172
+ const tickers = await this.watchTickers([symbol], params);
173
+ return tickers[symbol];
174
+ }
175
+ async watchTickers(symbols = undefined, params = {}) {
176
+ /**
177
+ * @method
178
+ * @name kucoinfutures#watchTickers
179
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
180
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
181
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
182
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
183
+ */
184
+ await this.loadMarkets();
185
+ const ticker = await this.watchMultiRequest('watchTickers', '/contractMarket/ticker:', symbols, params);
186
+ if (this.newUpdates) {
187
+ const tickers = {};
188
+ tickers[ticker['symbol']] = ticker;
189
+ return tickers;
190
+ }
191
+ return this.filterByArray(this.tickers, 'symbol', symbols);
188
192
  }
189
193
  handleTicker(client, message) {
190
194
  //
191
- // market/tickerV2
195
+ // ticker (v1)
192
196
  //
193
197
  // {
194
- // "type": "message",
195
- // "topic": "/contractMarket/tickerV2:ADAUSDTM",
196
- // "subject": "tickerV2",
197
- // "data": {
198
- // "symbol": "ADAUSDTM",
199
- // "sequence": 1668007800439,
200
- // "bestBidSize": 178,
201
- // "bestBidPrice": "0.35959",
202
- // "bestAskPrice": "0.35981",
203
- // "ts": "1668141430037124460",
204
- // "bestAskSize": 134
205
- // }
198
+ // "subject": "ticker",
199
+ // "topic": "/contractMarket/ticker:XBTUSDM",
200
+ // "data": {
201
+ // "symbol": "XBTUSDM", //Market of the symbol
202
+ // "sequence": 45, //Sequence number which is used to judge the continuity of the pushed messages
203
+ // "side": "sell", //Transaction side of the last traded taker order
204
+ // "price": "3600.0", //Filled price
205
+ // "size": 16, //Filled quantity
206
+ // "tradeId": "5c9dcf4170744d6f5a3d32fb", //Order ID
207
+ // "bestBidSize": 795, //Best bid size
208
+ // "bestBidPrice": "3200.0", //Best bid
209
+ // "bestAskPrice": "3600.0", //Best ask size
210
+ // "bestAskSize": 284, //Best ask
211
+ // "ts": 1553846081210004941 //Filled time - nanosecond
212
+ // }
206
213
  // }
207
214
  //
208
215
  const data = this.safeValue(message, 'data', {});
@@ -210,9 +217,95 @@ class kucoinfutures extends kucoinfutures$1 {
210
217
  const market = this.safeMarket(marketId, undefined, '-');
211
218
  const ticker = this.parseTicker(data, market);
212
219
  this.tickers[market['symbol']] = ticker;
213
- const messageHash = 'ticker:' + market['symbol'];
214
- client.resolve(ticker, messageHash);
215
- return message;
220
+ client.resolve(ticker, this.getMessageHash('ticker', market['symbol']));
221
+ }
222
+ async watchBidsAsks(symbols = undefined, params = {}) {
223
+ /**
224
+ * @method
225
+ * @name kucoinfutures#watchBidsAsks
226
+ * @see https://www.kucoin.com/docs/websocket/futures-trading/public-channels/get-ticker-v2
227
+ * @description watches best bid & ask for symbols
228
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
229
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
230
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
231
+ */
232
+ const ticker = await this.watchMultiRequest('watchBidsAsks', '/contractMarket/tickerV2:', symbols, params);
233
+ if (this.newUpdates) {
234
+ const tickers = {};
235
+ tickers[ticker['symbol']] = ticker;
236
+ return tickers;
237
+ }
238
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
239
+ }
240
+ async watchMultiRequest(methodName, channelName, symbols = undefined, params = {}) {
241
+ await this.loadMarkets();
242
+ [methodName, params] = this.handleParamString(params, 'callerMethodName', methodName);
243
+ const isBidsAsks = (methodName === 'watchBidsAsks');
244
+ symbols = this.marketSymbols(symbols, undefined, false, true, false);
245
+ const length = symbols.length;
246
+ if (length > 100) {
247
+ throw new errors.ArgumentsRequired(this.id + ' ' + methodName + '() accepts a maximum of 100 symbols');
248
+ }
249
+ const messageHashes = [];
250
+ for (let i = 0; i < symbols.length; i++) {
251
+ const symbol = symbols[i];
252
+ const market = this.market(symbol);
253
+ const prefix = isBidsAsks ? 'bidask' : 'ticker';
254
+ messageHashes.push(this.getMessageHash(prefix, market['symbol']));
255
+ }
256
+ const url = await this.negotiate(false);
257
+ const marketIds = this.marketIds(symbols);
258
+ const joined = marketIds.join(',');
259
+ const requestId = this.requestId().toString();
260
+ const request = {
261
+ 'id': requestId,
262
+ 'type': 'subscribe',
263
+ 'topic': channelName + joined,
264
+ 'response': true,
265
+ };
266
+ const subscription = {
267
+ 'id': requestId,
268
+ };
269
+ return await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscription);
270
+ }
271
+ handleBidAsk(client, message) {
272
+ //
273
+ // arrives one symbol dict
274
+ //
275
+ // {
276
+ // "subject": "tickerV2",
277
+ // "topic": "/contractMarket/tickerV2:XBTUSDM",
278
+ // "data": {
279
+ // "symbol": "XBTUSDM", //Market of the symbol
280
+ // "bestBidSize": 795, // Best bid size
281
+ // "bestBidPrice": 3200.0, // Best bid
282
+ // "bestAskPrice": 3600.0, // Best ask
283
+ // "bestAskSize": 284, // Best ask size
284
+ // "ts": 1553846081210004941 // Filled time - nanosecond
285
+ // }
286
+ // }
287
+ //
288
+ const parsedTicker = this.parseWsBidAsk(message);
289
+ const symbol = parsedTicker['symbol'];
290
+ this.bidsasks[symbol] = parsedTicker;
291
+ client.resolve(parsedTicker, this.getMessageHash('bidask', symbol));
292
+ }
293
+ parseWsBidAsk(ticker, market = undefined) {
294
+ const data = this.safeDict(ticker, 'data', {});
295
+ const marketId = this.safeString(data, 'symbol');
296
+ market = this.safeMarket(marketId, market);
297
+ const symbol = this.safeString(market, 'symbol');
298
+ const timestamp = this.safeIntegerProduct(data, 'ts', 0.000001);
299
+ return this.safeTicker({
300
+ 'symbol': symbol,
301
+ 'timestamp': timestamp,
302
+ 'datetime': this.iso8601(timestamp),
303
+ 'ask': this.safeNumber(data, 'bestAskPrice'),
304
+ 'askVolume': this.safeNumber(data, 'bestAskSize'),
305
+ 'bid': this.safeNumber(data, 'bestBidPrice'),
306
+ 'bidVolume': this.safeNumber(data, 'bestBidSize'),
307
+ 'info': ticker,
308
+ }, market);
216
309
  }
217
310
  async watchPosition(symbol = undefined, params = {}) {
218
311
  /**
@@ -431,7 +524,7 @@ class kucoinfutures extends kucoinfutures$1 {
431
524
  messageHashes.push('trades:' + symbol);
432
525
  subscriptionHashes.push('/contractMarket/execution:' + marketId);
433
526
  }
434
- const trades = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, params);
527
+ const trades = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, undefined, params);
435
528
  if (this.newUpdates) {
436
529
  const first = this.safeValue(trades, 0);
437
530
  const tradeSymbol = this.safeString(first, 'symbol');
@@ -517,9 +610,7 @@ class kucoinfutures extends kucoinfutures$1 {
517
610
  const marketIds = this.marketIds(symbols);
518
611
  const url = await this.negotiate(false);
519
612
  const topic = '/contractMarket/level2:' + marketIds.join(',');
520
- const subscription = {
521
- 'method': this.handleOrderBookSubscription,
522
- 'symbols': symbols,
613
+ const subscriptionArgs = {
523
614
  'limit': limit,
524
615
  };
525
616
  const subscriptionHashes = [];
@@ -530,7 +621,7 @@ class kucoinfutures extends kucoinfutures$1 {
530
621
  messageHashes.push('orderbook:' + symbol);
531
622
  subscriptionHashes.push('/contractMarket/level2:' + marketId);
532
623
  }
533
- const orderbook = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, subscription, params);
624
+ const orderbook = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, subscriptionArgs, params);
534
625
  return orderbook.limit();
535
626
  }
536
627
  handleDelta(orderbook, delta) {
@@ -581,11 +672,13 @@ class kucoinfutures extends kucoinfutures$1 {
581
672
  const marketId = this.safeString(topicParts, 1);
582
673
  const symbol = this.safeSymbol(marketId, undefined, '-');
583
674
  const messageHash = 'orderbook:' + symbol;
584
- const storedOrderBook = this.safeValue(this.orderbooks, symbol);
585
- const nonce = this.safeInteger(storedOrderBook, 'nonce');
586
- if (storedOrderBook === undefined) {
587
- return; // this shouldn't be needed, but for some reason sometimes this runs before handleOrderBookSubscription in c#
675
+ if (!(symbol in this.orderbooks)) {
676
+ const subscriptionArgs = this.safeDict(client.subscriptions, topic, {});
677
+ const limit = this.safeInteger(subscriptionArgs, 'limit');
678
+ this.orderbooks[symbol] = this.orderBook({}, limit);
588
679
  }
680
+ const storedOrderBook = this.orderbooks[symbol];
681
+ const nonce = this.safeInteger(storedOrderBook, 'nonce');
589
682
  const deltaEnd = this.safeInteger(data, 'sequence');
590
683
  if (nonce === undefined) {
591
684
  const cacheLength = storedOrderBook.cache.length;
@@ -631,39 +724,6 @@ class kucoinfutures extends kucoinfutures$1 {
631
724
  }
632
725
  return cache.length;
633
726
  }
634
- handleOrderBookSubscription(client, message, subscription) {
635
- const limit = this.safeInteger(subscription, 'limit');
636
- const symbols = this.safeValue(subscription, 'symbols');
637
- if (symbols === undefined) {
638
- const symbol = this.safeString(subscription, 'symbol');
639
- this.orderbooks[symbol] = this.orderBook({}, limit);
640
- }
641
- else {
642
- for (let i = 0; i < symbols.length; i++) {
643
- const symbol = symbols[i];
644
- this.orderbooks[symbol] = this.orderBook({}, limit);
645
- }
646
- }
647
- // moved snapshot initialization to handleOrderBook to fix
648
- // https://github.com/ccxt/ccxt/issues/6820
649
- // the general idea is to fetch the snapshot after the first delta
650
- // but not before, because otherwise we cannot synchronize the feed
651
- }
652
- handleSubscriptionStatus(client, message) {
653
- //
654
- // {
655
- // "id": "1578090438322",
656
- // "type": "ack"
657
- // }
658
- //
659
- const id = this.safeString(message, 'id');
660
- const subscriptionsById = this.indexBy(client.subscriptions, 'id');
661
- const subscription = this.safeValue(subscriptionsById, id, {});
662
- const method = this.safeValue(subscription, 'method');
663
- if (method !== undefined) {
664
- method.call(this, client, message, subscription);
665
- }
666
- }
667
727
  handleSystemStatus(client, message) {
668
728
  //
669
729
  // todo: answer the question whether handleSystemStatus should be renamed
@@ -922,7 +982,8 @@ class kucoinfutures extends kucoinfutures$1 {
922
982
  const subject = this.safeString(message, 'subject');
923
983
  const methods = {
924
984
  'level2': this.handleOrderBook,
925
- 'tickerV2': this.handleTicker,
985
+ 'ticker': this.handleTicker,
986
+ 'tickerV2': this.handleBidAsk,
926
987
  'availableBalance.change': this.handleBalance,
927
988
  'match': this.handleTrade,
928
989
  'orderChange': this.handleOrder,
@@ -936,6 +997,15 @@ class kucoinfutures extends kucoinfutures$1 {
936
997
  method.call(this, client, message);
937
998
  }
938
999
  }
1000
+ getMessageHash(elementName, symbol = undefined) {
1001
+ // elementName can be 'ticker', 'bidask', ...
1002
+ if (symbol !== undefined) {
1003
+ return elementName + '@' + symbol;
1004
+ }
1005
+ else {
1006
+ return elementName + 's@all';
1007
+ }
1008
+ }
939
1009
  ping(client) {
940
1010
  // kucoin does not support built-in ws protocol-level ping-pong
941
1011
  // instead it requires a custom json-based text ping-pong
@@ -975,7 +1045,6 @@ class kucoinfutures extends kucoinfutures$1 {
975
1045
  const methods = {
976
1046
  // 'heartbeat': this.handleHeartbeat,
977
1047
  'welcome': this.handleSystemStatus,
978
- 'ack': this.handleSubscriptionStatus,
979
1048
  'message': this.handleSubject,
980
1049
  'pong': this.handlePong,
981
1050
  'error': this.handleErrorMessage,
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _shortw_utils = require('./_shortw_utils.js');
6
+ var sha256 = require('../noble-hashes/sha256.js');
7
+ var modular = require('./abstract/modular.js');
8
+ var weierstrass = require('./abstract/weierstrass.js');
9
+ var hashToCurve = require('./abstract/hash-to-curve.js');
10
+
11
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
12
+ // NIST secp256r1 aka P256
13
+ // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-256
14
+ // Field over which we'll do calculations; 2n**224n * (2n**32n-1n) + 2n**192n + 2n**96n-1n
15
+ const Fp = modular.Fp(BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff'));
16
+ const CURVE_A = Fp.create(BigInt('-3'));
17
+ const CURVE_B = BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b');
18
+ const mapSWU = weierstrass.mapToCurveSimpleSWU(Fp, {
19
+ A: CURVE_A,
20
+ B: CURVE_B,
21
+ Z: Fp.create(BigInt('-10')),
22
+ });
23
+ const P256 = _shortw_utils.createCurve({
24
+ // Params: a, b
25
+ a: CURVE_A,
26
+ b: CURVE_B,
27
+ Fp,
28
+ // Curve order, total count of valid points in the field
29
+ n: BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551'),
30
+ // Base point (x, y) aka generator point
31
+ Gx: BigInt('0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296'),
32
+ Gy: BigInt('0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5'),
33
+ h: BigInt(1),
34
+ lowS: false,
35
+ }, sha256.sha256);
36
+ const secp256r1 = P256;
37
+ hashToCurve.createHasher(secp256r1.ProjectivePoint, (scalars) => mapSWU(scalars[0]), {
38
+ DST: 'P256_XMD:SHA-256_SSWU_RO_',
39
+ encodeDST: 'P256_XMD:SHA-256_SSWU_NU_',
40
+ p: Fp.ORDER,
41
+ m: 1,
42
+ k: 128,
43
+ expand: 'xmd',
44
+ hash: sha256.sha256,
45
+ });
46
+
47
+ exports.P256 = P256;
48
+ exports.secp256r1 = secp256r1;
@@ -68,6 +68,7 @@ class woo extends woo$1 {
68
68
  'fetchIndexOHLCV': false,
69
69
  'fetchLedger': true,
70
70
  'fetchLeverage': true,
71
+ 'fetchMarginAdjustmentHistory': false,
71
72
  'fetchMarginMode': false,
72
73
  'fetchMarkets': true,
73
74
  'fetchMarkOHLCV': false,
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import type { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks, Leverage, Leverages, Option, OptionChain } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, ProxyError, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, ExchangeClosedByUser } from './src/base/errors.js';
7
- declare const version = "4.2.88";
7
+ declare const version = "4.2.90";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, ProxyError, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, ExchangeClosedByUser } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.2.89';
41
+ const version = '4.2.91';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -29,6 +29,7 @@ interface Exchange {
29
29
  swapV1PrivateGetPositionSideDual(params?: {}): Promise<implicitReturnType>;
30
30
  swapV1PrivateGetMarketMarkPriceKlines(params?: {}): Promise<implicitReturnType>;
31
31
  swapV1PrivateGetTradeBatchCancelReplace(params?: {}): Promise<implicitReturnType>;
32
+ swapV1PrivateGetTradeFullOrder(params?: {}): Promise<implicitReturnType>;
32
33
  swapV1PrivatePostTradeCancelReplace(params?: {}): Promise<implicitReturnType>;
33
34
  swapV1PrivatePostPositionSideDual(params?: {}): Promise<implicitReturnType>;
34
35
  swapV1PrivatePostTradeClosePosition(params?: {}): Promise<implicitReturnType>;
@@ -96,6 +97,7 @@ interface Exchange {
96
97
  copyTradingV1PrivateGetSwapTraceCurrentTrack(params?: {}): Promise<implicitReturnType>;
97
98
  copyTradingV1PrivatePostSwapTraceCloseTrackOrder(params?: {}): Promise<implicitReturnType>;
98
99
  copyTradingV1PrivatePostSwapTraceSetTPSL(params?: {}): Promise<implicitReturnType>;
100
+ copyTradingV1PrivatePostSpotTraderSellOrder(params?: {}): Promise<implicitReturnType>;
99
101
  apiV3PrivateGetAssetTransfer(params?: {}): Promise<implicitReturnType>;
100
102
  apiV3PrivateGetCapitalDepositHisrec(params?: {}): Promise<implicitReturnType>;
101
103
  apiV3PrivateGetCapitalWithdrawHistory(params?: {}): Promise<implicitReturnType>;
@@ -154,6 +154,7 @@ interface Exchange {
154
154
  privateGetV5UserGetMemberType(params?: {}): Promise<implicitReturnType>;
155
155
  privateGetV5UserAffCustomerInfo(params?: {}): Promise<implicitReturnType>;
156
156
  privateGetV5UserDelSubmember(params?: {}): Promise<implicitReturnType>;
157
+ privateGetV5UserSubmembers(params?: {}): Promise<implicitReturnType>;
157
158
  privateGetV5SpotLeverTokenOrderRecord(params?: {}): Promise<implicitReturnType>;
158
159
  privateGetV5SpotMarginTradeState(params?: {}): Promise<implicitReturnType>;
159
160
  privateGetV5SpotCrossMarginTradeLoanInfo(params?: {}): Promise<implicitReturnType>;
@@ -290,6 +291,7 @@ interface Exchange {
290
291
  privatePostV5LendingRedeemCancel(params?: {}): Promise<implicitReturnType>;
291
292
  privatePostV5AccountSetCollateralSwitch(params?: {}): Promise<implicitReturnType>;
292
293
  privatePostV5AccountSetCollateralSwitchBatch(params?: {}): Promise<implicitReturnType>;
294
+ privatePostV5AccountDemoApplyMoney(params?: {}): Promise<implicitReturnType>;
293
295
  }
294
296
  declare abstract class Exchange extends _Exchange {
295
297
  }
@@ -2891,6 +2891,7 @@ export default class ascendex extends Exchange {
2891
2891
  'info': data,
2892
2892
  'symbol': market['symbol'],
2893
2893
  'type': undefined,
2894
+ 'marginMode': 'isolated',
2894
2895
  'amount': undefined,
2895
2896
  'total': undefined,
2896
2897
  'code': market['quote'],
@@ -369,6 +369,7 @@ export default class Exchange {
369
369
  fetchIndexOHLCV: any;
370
370
  fetchIsolatedBorrowRate: any;
371
371
  fetchIsolatedBorrowRates: any;
372
+ fetchMarginAdjustmentHistory: any;
372
373
  fetchIsolatedPositions: any;
373
374
  fetchL2OrderBook: boolean;
374
375
  fetchL3OrderBook: any;
@@ -625,6 +626,7 @@ export default class Exchange {
625
626
  intToBase16(elem: any): string;
626
627
  extendExchangeOptions(newOptions: any): void;
627
628
  createSafeDictionary(): {};
629
+ randomBytes(length: any): string;
628
630
  safeBoolN(dictionaryOrList: any, keys: IndexType[], defaultValue?: boolean): boolean | undefined;
629
631
  safeBool2(dictionary: any, key1: IndexType, key2: IndexType, defaultValue?: boolean): boolean | undefined;
630
632
  safeBool(dictionary: any, key: IndexType, defaultValue?: boolean): boolean | undefined;
@@ -700,6 +702,7 @@ export default class Exchange {
700
702
  addMargin(symbol: string, amount: number, params?: {}): Promise<MarginModification>;
701
703
  reduceMargin(symbol: string, amount: number, params?: {}): Promise<MarginModification>;
702
704
  setMargin(symbol: string, amount: number, params?: {}): Promise<{}>;
705
+ fetchMarginAdjustmentHistory(symbol?: Str, type?: Str, since?: Num, limit?: Num, params?: {}): Promise<MarginModification[]>;
703
706
  setMarginMode(marginMode: string, symbol?: Str, params?: {}): Promise<{}>;
704
707
  fetchDepositAddressesByNetwork(code: string, params?: {}): Promise<{}>;
705
708
  fetchOpenInterestHistory(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OpenInterest[]>;
@@ -1015,5 +1018,7 @@ export default class Exchange {
1015
1018
  convertExpireDate(date: string): string;
1016
1019
  convertExpireDateToMarketIdDate(date: string): string;
1017
1020
  convertMarketIdExpireDate(date: string): string;
1021
+ parseMarginModification(data: any, market?: Market): MarginModification;
1022
+ parseMarginModifications(response: object[], symbols?: string[], symbolKey?: Str, marketType?: MarketType): MarginModification[];
1018
1023
  }
1019
1024
  export { Exchange, };
@@ -23,6 +23,7 @@ import { axolotl } from './functions/crypto.js';
23
23
  import totp from './functions/totp.js';
24
24
  import ethers from '../static_dependencies/ethers/index.js';
25
25
  import { TypedDataEncoder } from '../static_dependencies/ethers/hash/index.js';
26
+ import { SecureRandom } from "../static_dependencies/jsencrypt/lib/jsbn/rng.js";
26
27
  // ----------------------------------------------------------------------------
27
28
  /**
28
29
  * @class Exchange
@@ -426,6 +427,7 @@ export default class Exchange {
426
427
  'fetchIndexOHLCV': undefined,
427
428
  'fetchIsolatedBorrowRate': undefined,
428
429
  'fetchIsolatedBorrowRates': undefined,
430
+ 'fetchMarginAdjustmentHistory': undefined,
429
431
  'fetchIsolatedPositions': undefined,
430
432
  'fetchL2OrderBook': true,
431
433
  'fetchL3OrderBook': undefined,
@@ -1432,6 +1434,13 @@ export default class Exchange {
1432
1434
  createSafeDictionary() {
1433
1435
  return {};
1434
1436
  }
1437
+ randomBytes(length) {
1438
+ const rng = new SecureRandom();
1439
+ const x = [];
1440
+ x.length = length;
1441
+ rng.nextBytes(x);
1442
+ return Buffer.from(x).toString('hex');
1443
+ }
1435
1444
  /* eslint-enable */
1436
1445
  // ------------------------------------------------------------------------
1437
1446
  // ########################################################################
@@ -2038,6 +2047,20 @@ export default class Exchange {
2038
2047
  async setMargin(symbol, amount, params = {}) {
2039
2048
  throw new NotSupported(this.id + ' setMargin() is not supported yet');
2040
2049
  }
2050
+ async fetchMarginAdjustmentHistory(symbol = undefined, type = undefined, since = undefined, limit = undefined, params = {}) {
2051
+ /**
2052
+ * @method
2053
+ * @name exchange#fetchMarginAdjustmentHistory
2054
+ * @description fetches the history of margin added or reduced from contract isolated positions
2055
+ * @param {string} [symbol] unified market symbol
2056
+ * @param {string} [type] "add" or "reduce"
2057
+ * @param {int} [since] timestamp in ms of the earliest change to fetch
2058
+ * @param {int} [limit] the maximum amount of changes to fetch
2059
+ * @param {object} params extra parameters specific to the exchange api endpoint
2060
+ * @returns {object[]} a list of [margin structures]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
2061
+ */
2062
+ throw new NotSupported(this.id + ' fetchMarginAdjustmentHistory() is not supported yet');
2063
+ }
2041
2064
  async setMarginMode(marginMode, symbol = undefined, params = {}) {
2042
2065
  throw new NotSupported(this.id + ' setMarginMode() is not supported yet');
2043
2066
  }
@@ -2059,7 +2082,7 @@ export default class Exchange {
2059
2082
  parseToInt(number) {
2060
2083
  // Solve Common parseInt misuse ex: parseInt ((since / 1000).toString ())
2061
2084
  // using a number as parameter which is not valid in ts
2062
- const stringifiedNumber = number.toString();
2085
+ const stringifiedNumber = this.numberToString(number);
2063
2086
  const convertedNumber = parseFloat(stringifiedNumber);
2064
2087
  return parseInt(convertedNumber);
2065
2088
  }
@@ -4552,13 +4575,6 @@ export default class Exchange {
4552
4575
  if (!this.substituteCommonCurrencyCodes) {
4553
4576
  return code;
4554
4577
  }
4555
- // if the provided code already exists as a value in commonCurrencies dict, then we should not again transform it
4556
- // more details at: https://github.com/ccxt/ccxt/issues/21112#issuecomment-2031293691
4557
- const commonCurrencies = Object.values(this.commonCurrencies);
4558
- const exists = this.inArray(code, commonCurrencies);
4559
- if (exists) {
4560
- return code;
4561
- }
4562
4578
  return this.safeString(this.commonCurrencies, code, code);
4563
4579
  }
4564
4580
  currency(code) {
@@ -5209,7 +5225,6 @@ export default class Exchange {
5209
5225
  * @returns {object} objects with withdraw and deposit fees, indexed by currency codes
5210
5226
  */
5211
5227
  const depositWithdrawFees = {};
5212
- codes = this.marketCodes(codes);
5213
5228
  const isArray = Array.isArray(response);
5214
5229
  let responseKeys = response;
5215
5230
  if (!isArray) {
@@ -5801,5 +5816,20 @@ export default class Exchange {
5801
5816
  const reconstructedDate = day + month + year;
5802
5817
  return reconstructedDate;
5803
5818
  }
5819
+ parseMarginModification(data, market = undefined) {
5820
+ throw new NotSupported(this.id + ' parseMarginModification() is not supported yet');
5821
+ }
5822
+ parseMarginModifications(response, symbols = undefined, symbolKey = undefined, marketType = undefined) {
5823
+ const marginModifications = [];
5824
+ for (let i = 0; i < response.length; i++) {
5825
+ const info = response[i];
5826
+ const marketId = this.safeString(info, symbolKey);
5827
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
5828
+ if ((symbols === undefined) || this.inArray(market['symbol'], symbols)) {
5829
+ marginModifications.push(this.parseMarginModification(info, market));
5830
+ }
5831
+ }
5832
+ return marginModifications;
5833
+ }
5804
5834
  }
5805
5835
  export { Exchange, };
@@ -8,12 +8,19 @@
8
8
  import { hmac as _hmac } from '../../static_dependencies/noble-hashes/hmac.js';
9
9
  import { base16, base64, base58 } from '../../static_dependencies/scure-base/index.js';
10
10
  import { Base64 } from '../../static_dependencies/jsencrypt/lib/asn1js/base64.js';
11
+ import { ASN1 } from "../../static_dependencies/jsencrypt/lib/asn1js/asn1.js";
12
+ import { secp256k1 } from '../../static_dependencies/noble-curves/secp256k1.js';
13
+ import { P256 } from '../../static_dependencies/noble-curves/p256.js';
11
14
  /* ------------------------------------------------------------------------ */
12
15
  const encoders = {
13
16
  binary: x => x,
14
17
  hex: base16.encode,
15
18
  base64: base64.encode,
16
19
  };
20
+ const supportedCurve = {
21
+ '1.3.132.0.10': secp256k1,
22
+ '1.2.840.10045.3.1.7': P256,
23
+ };
17
24
  /* ............................................. */
18
25
  const hash = (request, hash, digest = 'hex') => {
19
26
  const binary = hash(request);
@@ -29,6 +36,36 @@ function ecdsa(request, secret, curve, prehash = null) {
29
36
  if (prehash) {
30
37
  request = hash(request, prehash, 'hex');
31
38
  }
39
+ if (typeof secret === 'string' && secret.length > 64) {
40
+ // decode pem key
41
+ if (secret.startsWith('-----BEGIN EC PRIVATE KEY-----')) {
42
+ const der = Base64.unarmor(secret);
43
+ let asn1 = ASN1.decode(der);
44
+ if (asn1.sub.length === 4) {
45
+ // ECPrivateKey ::= SEQUENCE {
46
+ // version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
47
+ // privateKey OCTET STRING,
48
+ // parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
49
+ // publicKey [1] BIT STRING OPTIONAL
50
+ // }
51
+ if (typeof asn1.sub[2].sub !== null && asn1.sub[2].sub.length > 0) {
52
+ const oid = asn1.sub[2].sub[0].content(undefined);
53
+ if (supportedCurve[oid] === undefined)
54
+ throw new Error('Unsupported curve');
55
+ curve = supportedCurve[oid];
56
+ }
57
+ secret = asn1.sub[1].getHexStringValue();
58
+ }
59
+ else {
60
+ // maybe return false
61
+ throw new Error('Unsupported key format');
62
+ }
63
+ }
64
+ else {
65
+ // maybe return false
66
+ throw new Error('Unsupported key format');
67
+ }
68
+ }
32
69
  const signature = curve.sign(request, secret);
33
70
  return {
34
71
  'r': signature.r.toString(16),