ccxt 4.2.89 → 4.2.90

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 (78) hide show
  1. package/README.md +3 -3
  2. package/build.sh +1 -1
  3. package/dist/ccxt.browser.js +829 -114
  4. package/dist/ccxt.browser.min.js +6 -4
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/ascendex.js +1 -0
  7. package/dist/cjs/src/base/Exchange.js +38 -0
  8. package/dist/cjs/src/base/functions/crypto.js +37 -0
  9. package/dist/cjs/src/base/functions/rsa.js +19 -4
  10. package/dist/cjs/src/binance.js +90 -9
  11. package/dist/cjs/src/bingx.js +101 -1
  12. package/dist/cjs/src/bitfinex2.js +1 -0
  13. package/dist/cjs/src/bitget.js +2 -0
  14. package/dist/cjs/src/bitmex.js +1 -0
  15. package/dist/cjs/src/bitrue.js +1 -0
  16. package/dist/cjs/src/bybit.js +61 -0
  17. package/dist/cjs/src/coinbase.js +48 -24
  18. package/dist/cjs/src/coinbaseinternational.js +1 -0
  19. package/dist/cjs/src/coinex.js +102 -8
  20. package/dist/cjs/src/cryptocom.js +1 -0
  21. package/dist/cjs/src/delta.js +1 -0
  22. package/dist/cjs/src/digifinex.js +1 -0
  23. package/dist/cjs/src/exmo.js +1 -0
  24. package/dist/cjs/src/gate.js +2 -0
  25. package/dist/cjs/src/gemini.js +10 -9
  26. package/dist/cjs/src/hitbtc.js +1 -0
  27. package/dist/cjs/src/htx.js +1 -0
  28. package/dist/cjs/src/hyperliquid.js +1 -0
  29. package/dist/cjs/src/kucoin.js +1 -0
  30. package/dist/cjs/src/kucoinfutures.js +34 -3
  31. package/dist/cjs/src/mexc.js +1 -0
  32. package/dist/cjs/src/okx.js +157 -8
  33. package/dist/cjs/src/phemex.js +1 -0
  34. package/dist/cjs/src/static_dependencies/noble-curves/p256.js +48 -0
  35. package/dist/cjs/src/woo.js +1 -0
  36. package/js/ccxt.d.ts +1 -1
  37. package/js/ccxt.js +1 -1
  38. package/js/src/abstract/bingx.d.ts +2 -0
  39. package/js/src/abstract/bybit.d.ts +2 -0
  40. package/js/src/ascendex.js +1 -0
  41. package/js/src/base/Exchange.d.ts +5 -0
  42. package/js/src/base/Exchange.js +38 -0
  43. package/js/src/base/functions/crypto.js +37 -0
  44. package/js/src/base/functions/rsa.d.ts +1 -1
  45. package/js/src/base/functions/rsa.js +21 -5
  46. package/js/src/base/types.d.ts +1 -0
  47. package/js/src/binance.d.ts +1 -0
  48. package/js/src/binance.js +90 -9
  49. package/js/src/bingx.d.ts +1 -0
  50. package/js/src/bingx.js +101 -1
  51. package/js/src/bitfinex2.js +1 -0
  52. package/js/src/bitget.js +2 -0
  53. package/js/src/bitmex.js +1 -0
  54. package/js/src/bitrue.js +1 -0
  55. package/js/src/bybit.d.ts +2 -0
  56. package/js/src/bybit.js +61 -0
  57. package/js/src/coinbase.js +48 -24
  58. package/js/src/coinbaseinternational.js +1 -0
  59. package/js/src/coinex.d.ts +2 -0
  60. package/js/src/coinex.js +102 -8
  61. package/js/src/cryptocom.js +1 -0
  62. package/js/src/delta.js +1 -0
  63. package/js/src/digifinex.js +1 -0
  64. package/js/src/exmo.js +1 -0
  65. package/js/src/gate.js +2 -0
  66. package/js/src/gemini.js +10 -9
  67. package/js/src/hitbtc.js +1 -0
  68. package/js/src/htx.js +1 -0
  69. package/js/src/hyperliquid.js +1 -0
  70. package/js/src/kucoin.js +1 -0
  71. package/js/src/kucoinfutures.d.ts +2 -9
  72. package/js/src/kucoinfutures.js +34 -3
  73. package/js/src/mexc.js +1 -0
  74. package/js/src/okx.d.ts +1 -0
  75. package/js/src/okx.js +157 -8
  76. package/js/src/phemex.js +1 -0
  77. package/js/src/woo.js +1 -0
  78. package/package.json +1 -1
@@ -84,6 +84,7 @@ class okx extends okx$1 {
84
84
  'fetchLedgerEntry': undefined,
85
85
  'fetchLeverage': true,
86
86
  'fetchLeverageTiers': false,
87
+ 'fetchMarginAdjustmentHistory': true,
87
88
  'fetchMarketLeverageTiers': true,
88
89
  'fetchMarkets': true,
89
90
  'fetchMarkOHLCV': true,
@@ -6463,9 +6464,9 @@ class okx extends okx$1 {
6463
6464
  // }
6464
6465
  //
6465
6466
  const data = this.safeList(response, 'data', []);
6467
+ const entry = this.safeDict(data, 0, {});
6466
6468
  const errorCode = this.safeString(response, 'code');
6467
- const item = this.safeDict(data, 0, {});
6468
- return this.extend(this.parseMarginModification(item, market), {
6469
+ return this.extend(this.parseMarginModification(entry, market), {
6469
6470
  'status': (errorCode === '0') ? 'ok' : 'failed',
6470
6471
  });
6471
6472
  }
@@ -6480,22 +6481,68 @@ class okx extends okx$1 {
6480
6481
  // "type": "reduce"
6481
6482
  // }
6482
6483
  //
6483
- const amountRaw = this.safeNumber(data, 'amt');
6484
+ // fetchMarginAdjustmentHistory
6485
+ //
6486
+ // {
6487
+ // bal: '67621.4325135010619812',
6488
+ // balChg: '-10.0000000000000000',
6489
+ // billId: '691293628710342659',
6490
+ // ccy: 'USDT',
6491
+ // clOrdId: '',
6492
+ // execType: '',
6493
+ // fee: '0',
6494
+ // fillFwdPx: '',
6495
+ // fillIdxPx: '',
6496
+ // fillMarkPx: '',
6497
+ // fillMarkVol: '',
6498
+ // fillPxUsd: '',
6499
+ // fillPxVol: '',
6500
+ // fillTime: '1711089244850',
6501
+ // from: '',
6502
+ // instId: 'XRP-USDT-SWAP',
6503
+ // instType: 'SWAP',
6504
+ // interest: '0',
6505
+ // mgnMode: 'isolated',
6506
+ // notes: '',
6507
+ // ordId: '',
6508
+ // pnl: '0',
6509
+ // posBal: '73.12',
6510
+ // posBalChg: '10.00',
6511
+ // px: '',
6512
+ // subType: '160',
6513
+ // sz: '10',
6514
+ // tag: '',
6515
+ // to: '',
6516
+ // tradeId: '0',
6517
+ // ts: '1711089244699',
6518
+ // type: '6'
6519
+ // }
6520
+ //
6521
+ const amountRaw = this.safeString2(data, 'amt', 'posBalChg');
6484
6522
  const typeRaw = this.safeString(data, 'type');
6485
- const type = (typeRaw === 'reduce') ? 'reduce' : 'add';
6523
+ let type = undefined;
6524
+ if (typeRaw === '6') {
6525
+ type = Precise["default"].stringGt(amountRaw, '0') ? 'add' : 'reduce';
6526
+ }
6527
+ else {
6528
+ type = typeRaw;
6529
+ }
6530
+ const amount = Precise["default"].stringAbs(amountRaw);
6486
6531
  const marketId = this.safeString(data, 'instId');
6487
6532
  const responseMarket = this.safeMarket(marketId, market);
6488
6533
  const code = responseMarket['inverse'] ? responseMarket['base'] : responseMarket['quote'];
6534
+ const timestamp = this.safeInteger(data, 'ts');
6489
6535
  return {
6490
6536
  'info': data,
6491
6537
  'symbol': responseMarket['symbol'],
6492
6538
  'type': type,
6493
- 'amount': amountRaw,
6494
- 'total': undefined,
6539
+ 'marginMode': 'isolated',
6540
+ 'amount': this.parseNumber(amount),
6495
6541
  'code': code,
6542
+ 'total': undefined,
6496
6543
  'status': undefined,
6497
- 'timestamp': undefined,
6498
- 'datetime': undefined,
6544
+ 'timestamp': timestamp,
6545
+ 'datetime': this.iso8601(timestamp),
6499
6546
  };
6500
6547
  }
6501
6548
  async reduceMargin(symbol, amount, params = {}) {
@@ -7597,6 +7644,108 @@ class okx extends okx$1 {
7597
7644
  }
7598
7645
  return undefined;
7599
7646
  }
7647
+ async fetchMarginAdjustmentHistory(symbol = undefined, type = undefined, since = undefined, limit = undefined, params = {}) {
7648
+ /**
7649
+ * @method
7650
+ * @name okx#fetchMarginAdjustmentHistory
7651
+ * @description fetches the history of margin added or reduced from contract isolated positions
7652
+ * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-7-days
7653
+ * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
7654
+ * @param {string} [symbol] not used by okx fetchMarginAdjustmentHistory
7655
+ * @param {string} [type] "add" or "reduce"
7656
+ * @param {object} params extra parameters specific to the exchange api endpoint
7657
+ * @param {boolean} [params.auto] true if fetching auto margin increases
7658
+ * @returns {object[]} a list of [margin structures]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
7659
+ */
7660
+ await this.loadMarkets();
7661
+ const auto = this.safeBool(params, 'auto');
7662
+ if (type === undefined) {
7663
+ throw new errors.ArgumentsRequired(this.id + ' fetchMarginAdjustmentHistory () requires a type argument');
7664
+ }
7665
+ const isAdd = type === 'add';
7666
+ let subType = isAdd ? '160' : '161';
7667
+ if (auto) {
7668
+ if (isAdd) {
7669
+ subType = '162';
7670
+ }
7671
+ else {
7672
+ throw new errors.BadRequest(this.id + ' cannot fetch margin adjustments for type ' + type);
7673
+ }
7674
+ }
7675
+ const request = {
7676
+ 'subType': subType,
7677
+ 'mgnMode': 'isolated',
7678
+ };
7679
+ const until = this.safeInteger(params, 'until');
7680
+ params = this.omit(params, 'until');
7681
+ if (since !== undefined) {
7682
+ request['startTime'] = since;
7683
+ }
7684
+ if (limit !== undefined) {
7685
+ request['limit'] = limit;
7686
+ }
7687
+ if (until !== undefined) {
7688
+ request['endTime'] = until;
7689
+ }
7690
+ let response = undefined;
7691
+ const now = this.milliseconds();
7692
+ const oneWeekAgo = now - 604800000;
7693
+ const threeMonthsAgo = now - 7776000000;
7694
+ if ((since === undefined) || (since > oneWeekAgo)) {
7695
+ response = await this.privateGetAccountBills(this.extend(request, params));
7696
+ }
7697
+ else if (since > threeMonthsAgo) {
7698
+ response = await this.privateGetAccountBillsArchive(this.extend(request, params));
7699
+ }
7700
+ else {
7701
+ throw new errors.BadRequest(this.id + ' fetchMarginAdjustmentHistory () cannot fetch margin adjustments older than 3 months');
7702
+ }
7703
+ //
7704
+ // {
7705
+ // code: '0',
7706
+ // data: [
7707
+ // {
7708
+ // bal: '67621.4325135010619812',
7709
+ // balChg: '-10.0000000000000000',
7710
+ // billId: '691293628710342659',
7711
+ // ccy: 'USDT',
7712
+ // clOrdId: '',
7713
+ // execType: '',
7714
+ // fee: '0',
7715
+ // fillFwdPx: '',
7716
+ // fillIdxPx: '',
7717
+ // fillMarkPx: '',
7718
+ // fillMarkVol: '',
7719
+ // fillPxUsd: '',
7720
+ // fillPxVol: '',
7721
+ // fillTime: '1711089244850',
7722
+ // from: '',
7723
+ // instId: 'XRP-USDT-SWAP',
7724
+ // instType: 'SWAP',
7725
+ // interest: '0',
7726
+ // mgnMode: 'isolated',
7727
+ // notes: '',
7728
+ // ordId: '',
7729
+ // pnl: '0',
7730
+ // posBal: '73.12',
7731
+ // posBalChg: '10.00',
7732
+ // px: '',
7733
+ // subType: '160',
7734
+ // sz: '10',
7735
+ // tag: '',
7736
+ // to: '',
7737
+ // tradeId: '0',
7738
+ // ts: '1711089244699',
7739
+ // type: '6'
7740
+ // }
7741
+ // ],
7742
+ // msg: ''
7743
+ // }
7744
+ //
7745
+ const data = this.safeList(response, 'data');
7746
+ const modifications = this.parseMarginModifications(data);
7747
+ return this.filterBySymbolSinceLimit(modifications, symbol, since, limit);
7748
+ }
7600
7749
  }
7601
7750
 
7602
7751
  module.exports = okx;
@@ -4062,6 +4062,7 @@ class phemex extends phemex$1 {
4062
4062
  'info': data,
4063
4063
  'symbol': this.safeSymbol(undefined, market),
4064
4064
  'type': 'set',
4065
+ 'marginMode': 'isolated',
4065
4066
  'amount': undefined,
4066
4067
  'total': undefined,
4067
4068
  'code': market[codeCurrency],
@@ -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.89";
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.90';
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
  }
@@ -5801,5 +5824,20 @@ export default class Exchange {
5801
5824
  const reconstructedDate = day + month + year;
5802
5825
  return reconstructedDate;
5803
5826
  }
5827
+ parseMarginModification(data, market = undefined) {
5828
+ throw new NotSupported(this.id + ' parseMarginModification() is not supported yet');
5829
+ }
5830
+ parseMarginModifications(response, symbols = undefined, symbolKey = undefined, marketType = undefined) {
5831
+ const marginModifications = [];
5832
+ for (let i = 0; i < response.length; i++) {
5833
+ const info = response[i];
5834
+ const marketId = this.safeString(info, symbolKey);
5835
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
5836
+ if ((symbols === undefined) || this.inArray(market['symbol'], symbols)) {
5837
+ marginModifications.push(this.parseMarginModification(info, market));
5838
+ }
5839
+ }
5840
+ return marginModifications;
5841
+ }
5804
5842
  }
5805
5843
  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),
@@ -1,4 +1,4 @@
1
1
  import { CHash } from '../../static_dependencies/noble-hashes/utils.js';
2
2
  declare function rsa(request: string, secret: string, hash: CHash): string | false;
3
- declare function jwt(request: {}, secret: Uint8Array, hash: CHash, isRSA?: boolean): string;
3
+ declare function jwt(request: {}, secret: Uint8Array, hash: CHash, isRSA?: boolean, opts?: {}): string;
4
4
  export { rsa, jwt };
@@ -6,8 +6,10 @@
6
6
 
7
7
  import { JSEncrypt } from "../../static_dependencies/jsencrypt/JSEncrypt.js";
8
8
  import { base16, utf8 } from '../../static_dependencies/scure-base/index.js';
9
- import { urlencodeBase64, stringToBase64 } from './encode.js';
9
+ import { urlencodeBase64, stringToBase64, base16ToBinary, binaryToBase64 } from './encode.js';
10
10
  import { hmac } from './crypto.js';
11
+ import { P256 } from '../../static_dependencies/noble-curves/p256.js';
12
+ import { ecdsa } from '../../base/functions/crypto.js';
11
13
  function rsa(request, secret, hash) {
12
14
  const RSA = new JSEncrypt();
13
15
  const digester = (input) => base16.encode(hash(input));
@@ -15,9 +17,17 @@ function rsa(request, secret, hash) {
15
17
  const name = (hash.create()).constructor.name.toLowerCase();
16
18
  return RSA.sign(request, digester, name);
17
19
  }
18
- function jwt(request, secret, hash, isRSA = false) {
19
- const alg = (isRSA ? 'RS' : 'HS') + (hash.outputLen * 8);
20
- const encodedHeader = urlencodeBase64(stringToBase64(JSON.stringify({ 'alg': alg, 'typ': 'JWT' })));
20
+ function jwt(request, secret, hash, isRSA = false, opts = {}) {
21
+ let alg = (isRSA ? 'RS' : 'HS') + (hash.outputLen * 8);
22
+ if (opts['alg']) {
23
+ alg = opts['alg'].toUpperCase();
24
+ }
25
+ const header = Object.assign({ 'alg': alg, 'typ': 'JWT' }, opts);
26
+ if (header['iat'] !== undefined) {
27
+ request['iat'] = header['iat'];
28
+ delete header['iat'];
29
+ }
30
+ const encodedHeader = urlencodeBase64(stringToBase64(JSON.stringify(header)));
21
31
  const encodedData = urlencodeBase64(stringToBase64(JSON.stringify(request)));
22
32
  const token = [encodedHeader, encodedData].join('.');
23
33
  const algoType = alg.slice(0, 2);
@@ -25,9 +35,15 @@ function jwt(request, secret, hash, isRSA = false) {
25
35
  if (algoType === 'HS') {
26
36
  signature = urlencodeBase64(hmac(token, secret, hash, 'base64'));
27
37
  }
28
- else if (algoType === 'RS') {
38
+ else if (isRSA || algoType === 'RS') {
29
39
  signature = urlencodeBase64(rsa(token, utf8.encode(secret), hash));
30
40
  }
41
+ else if (algoType === 'ES') {
42
+ const signedHash = ecdsa(token, utf8.encode(secret), P256, hash);
43
+ const r = (signedHash.r.length === 64) ? signedHash.r : '0' + signedHash.r;
44
+ const s = (signedHash.s.length === 64) ? signedHash.s : '0' + signedHash.s;
45
+ signature = urlencodeBase64(binaryToBase64(base16ToBinary(r + s)));
46
+ }
31
47
  return [token, signature].join('.');
32
48
  }
33
49
  export { rsa, jwt };
@@ -465,6 +465,7 @@ export interface MarginModification {
465
465
  'info': any;
466
466
  'symbol': string;
467
467
  'type': 'add' | 'reduce' | 'set' | undefined;
468
+ 'marginMode': 'cross' | 'isolated' | undefined;
468
469
  'amount': Num;
469
470
  'total': Num;
470
471
  'code': Str;
@@ -438,4 +438,5 @@ export default class binance extends Exchange {
438
438
  baseVolume: number;
439
439
  quoteVolume: any;
440
440
  };
441
+ fetchMarginAdjustmentHistory(symbol?: Str, type?: Str, since?: Num, limit?: Num, params?: {}): Promise<MarginModification[]>;
441
442
  }