ccxt 4.1.38 → 4.1.40

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/cjs/ccxt.js CHANGED
@@ -180,7 +180,7 @@ var woo$1 = require('./src/pro/woo.js');
180
180
 
181
181
  //-----------------------------------------------------------------------------
182
182
  // this is updated by vss.js when building
183
- const version = '4.1.38';
183
+ const version = '4.1.40';
184
184
  Exchange["default"].ccxtVersion = version;
185
185
  const exchanges = {
186
186
  'ace': ace,
@@ -93,6 +93,7 @@ class krakenfutures extends krakenfutures$1 {
93
93
  'api': {
94
94
  'public': {
95
95
  'get': [
96
+ 'feeschedules',
96
97
  'instruments',
97
98
  'orderbook',
98
99
  'tickers',
@@ -102,6 +103,7 @@ class krakenfutures extends krakenfutures$1 {
102
103
  },
103
104
  'private': {
104
105
  'get': [
106
+ 'feeschedules/volumes',
105
107
  'openpositions',
106
108
  'notifications',
107
109
  'accounts',
@@ -142,11 +144,6 @@ class krakenfutures extends krakenfutures$1 {
142
144
  'market/{symbol}/executions',
143
145
  ],
144
146
  },
145
- 'feeschedules': {
146
- 'get': [
147
- 'volumes',
148
- ],
149
- },
150
147
  },
151
148
  'fees': {
152
149
  'trading': {
@@ -2698,16 +2698,16 @@ class mexc extends mexc$1 {
2698
2698
  await this.loadMarkets();
2699
2699
  const request = {};
2700
2700
  let market = undefined;
2701
+ let marketType = undefined;
2701
2702
  if (symbol !== undefined) {
2702
2703
  market = this.market(symbol);
2703
- request['symbol'] = market['id'];
2704
2704
  }
2705
- let marketType = undefined;
2706
2705
  [marketType, params] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
2707
2706
  if (marketType === 'spot') {
2708
2707
  if (symbol === undefined) {
2709
2708
  throw new errors.ArgumentsRequired(this.id + ' fetchOpenOrders() requires a symbol argument for spot market');
2710
2709
  }
2710
+ request['symbol'] = market['id'];
2711
2711
  let method = 'spotPrivateGetOpenOrders';
2712
2712
  const [marginMode, query] = this.handleMarginModeAndParams('fetchOpenOrders', params);
2713
2713
  if (marginMode !== undefined) {
@@ -2804,7 +2804,6 @@ class mexc extends mexc$1 {
2804
2804
  let market = undefined;
2805
2805
  if (symbol !== undefined) {
2806
2806
  market = this.market(symbol);
2807
- request['symbol'] = market['id'];
2808
2807
  }
2809
2808
  const [marketType] = this.handleMarketTypeAndParams('fetchOrdersByState', market, params);
2810
2809
  if (marketType === 'spot') {
@@ -1980,6 +1980,9 @@ class phemex extends phemex$1 {
1980
1980
  'Filled': 'closed',
1981
1981
  'Canceled': 'canceled',
1982
1982
  '1': 'open',
1983
+ '2': 'canceled',
1984
+ '3': 'closed',
1985
+ '4': 'canceled',
1983
1986
  '5': 'open',
1984
1987
  '6': 'open',
1985
1988
  '7': 'closed',
@@ -5,6 +5,9 @@ var Precise = require('../base/Precise.js');
5
5
  var errors = require('../base/errors.js');
6
6
  var Cache = require('../base/ws/Cache.js');
7
7
  var sha256 = require('../static_dependencies/noble-hashes/sha256.js');
8
+ var rsa = require('../base/functions/rsa.js');
9
+ var crypto = require('../base/functions/crypto.js');
10
+ var ed25519 = require('../static_dependencies/noble-curves/ed25519.js');
8
11
 
9
12
  // ----------------------------------------------------------------------------
10
13
  // -----------------------------------------------------------------------------
@@ -1213,7 +1216,20 @@ class binance extends binance$1 {
1213
1216
  params['recvWindow'] = recvWindow;
1214
1217
  }
1215
1218
  extendedParams = this.keysort(extendedParams);
1216
- extendedParams['signature'] = this.hmac(this.encode(this.urlencode(extendedParams)), this.encode(this.secret), sha256.sha256);
1219
+ const query = this.urlencode(extendedParams);
1220
+ let signature = undefined;
1221
+ if (this.secret.indexOf('PRIVATE KEY') > -1) {
1222
+ if (this.secret.length > 120) {
1223
+ signature = rsa.rsa(query, this.secret, sha256.sha256);
1224
+ }
1225
+ else {
1226
+ signature = crypto.eddsa(this.encode(query), this.secret, ed25519.ed25519);
1227
+ }
1228
+ }
1229
+ else {
1230
+ signature = this.hmac(this.encode(query), this.encode(this.secret), sha256.sha256);
1231
+ }
1232
+ extendedParams['signature'] = signature;
1217
1233
  return extendedParams;
1218
1234
  }
1219
1235
  async authenticate(params = {}) {
@@ -2532,6 +2548,15 @@ class binance extends binance$1 {
2532
2548
  }
2533
2549
  }
2534
2550
  handleWsError(client, message) {
2551
+ //
2552
+ // {
2553
+ // "error": {
2554
+ // "code": 2,
2555
+ // "msg": "Invalid request: invalid stream"
2556
+ // },
2557
+ // "id": 1
2558
+ // }
2559
+ //
2535
2560
  const id = this.safeString(message, 'id');
2536
2561
  let rejected = false;
2537
2562
  const error = this.safeValue(message, 'error', {});
@@ -2542,7 +2567,17 @@ class binance extends binance$1 {
2542
2567
  }
2543
2568
  catch (e) {
2544
2569
  rejected = true;
2570
+ // private endpoint uses id as messageHash
2545
2571
  client.reject(e, id);
2572
+ // public endpoint stores messageHash in subscriptios
2573
+ const subscriptionKeys = Object.keys(client.subscriptions);
2574
+ for (let i = 0; i < subscriptionKeys.length; i++) {
2575
+ const subscriptionHash = subscriptionKeys[i];
2576
+ const subscriptionId = this.safeString(client.subscriptions[subscriptionHash], 'id');
2577
+ if (id === subscriptionId) {
2578
+ client.reject(e, subscriptionHash);
2579
+ }
2580
+ }
2546
2581
  }
2547
2582
  if (!rejected) {
2548
2583
  client.reject(message, id);
@@ -2555,7 +2590,8 @@ class binance extends binance$1 {
2555
2590
  handleMessage(client, message) {
2556
2591
  // handle WebSocketAPI
2557
2592
  const status = this.safeString(message, 'status');
2558
- if (status !== undefined && status !== '200') {
2593
+ const error = this.safeValue(message, 'error');
2594
+ if ((error !== undefined) || (status !== undefined && status !== '200')) {
2559
2595
  return this.handleWsError(client, message);
2560
2596
  }
2561
2597
  const id = this.safeString(message, 'id');
@@ -1405,13 +1405,13 @@ class huobi extends huobi$1 {
1405
1405
  // }
1406
1406
  //
1407
1407
  const channel = this.safeString(message, 'ch');
1408
- const timestamp = this.safeInteger(message, 'ts');
1408
+ const data = this.safeValue(message, 'data', []);
1409
+ const timestamp = this.safeInteger(data, 'changeTime', this.safeInteger(message, 'ts'));
1409
1410
  this.balance['timestamp'] = timestamp;
1410
1411
  this.balance['datetime'] = this.iso8601(timestamp);
1411
- this.balance['info'] = this.safeValue(message, 'data');
1412
+ this.balance['info'] = data;
1412
1413
  if (channel !== undefined) {
1413
1414
  // spot balance
1414
- const data = this.safeValue(message, 'data', {});
1415
1415
  const currencyId = this.safeString(data, 'currency');
1416
1416
  const code = this.safeCurrencyCode(currencyId);
1417
1417
  const account = this.account();
@@ -1423,7 +1423,6 @@ class huobi extends huobi$1 {
1423
1423
  }
1424
1424
  else {
1425
1425
  // contract balance
1426
- const data = this.safeValue(message, 'data', []);
1427
1426
  const dataLength = data.length;
1428
1427
  if (dataLength === 0) {
1429
1428
  return;
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 { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
7
- declare const version = "4.1.37";
7
+ declare const version = "4.1.39";
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, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.1.38';
41
+ const version = '4.1.40';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -1,11 +1,13 @@
1
1
  import { implicitReturnType } from '../base/types.js';
2
2
  import { Exchange as _Exchange } from '../base/Exchange.js';
3
3
  interface Exchange {
4
+ publicGetFeeschedules(params?: {}): Promise<implicitReturnType>;
4
5
  publicGetInstruments(params?: {}): Promise<implicitReturnType>;
5
6
  publicGetOrderbook(params?: {}): Promise<implicitReturnType>;
6
7
  publicGetTickers(params?: {}): Promise<implicitReturnType>;
7
8
  publicGetHistory(params?: {}): Promise<implicitReturnType>;
8
9
  publicGetHistoricalfundingrates(params?: {}): Promise<implicitReturnType>;
10
+ privateGetFeeschedulesVolumes(params?: {}): Promise<implicitReturnType>;
9
11
  privateGetOpenpositions(params?: {}): Promise<implicitReturnType>;
10
12
  privateGetNotifications(params?: {}): Promise<implicitReturnType>;
11
13
  privateGetAccounts(params?: {}): Promise<implicitReturnType>;
@@ -32,7 +34,6 @@ interface Exchange {
32
34
  historyGetAccountlogcsv(params?: {}): Promise<implicitReturnType>;
33
35
  historyGetMarketSymbolOrders(params?: {}): Promise<implicitReturnType>;
34
36
  historyGetMarketSymbolExecutions(params?: {}): Promise<implicitReturnType>;
35
- feeschedulesGetVolumes(params?: {}): Promise<implicitReturnType>;
36
37
  }
37
38
  declare abstract class Exchange extends _Exchange {
38
39
  }
@@ -96,6 +96,7 @@ export default class krakenfutures extends Exchange {
96
96
  'api': {
97
97
  'public': {
98
98
  'get': [
99
+ 'feeschedules',
99
100
  'instruments',
100
101
  'orderbook',
101
102
  'tickers',
@@ -105,6 +106,7 @@ export default class krakenfutures extends Exchange {
105
106
  },
106
107
  'private': {
107
108
  'get': [
109
+ 'feeschedules/volumes',
108
110
  'openpositions',
109
111
  'notifications',
110
112
  'accounts',
@@ -145,11 +147,6 @@ export default class krakenfutures extends Exchange {
145
147
  'market/{symbol}/executions',
146
148
  ],
147
149
  },
148
- 'feeschedules': {
149
- 'get': [
150
- 'volumes',
151
- ],
152
- },
153
150
  },
154
151
  'fees': {
155
152
  'trading': {
package/js/src/mexc.js CHANGED
@@ -2701,16 +2701,16 @@ export default class mexc extends Exchange {
2701
2701
  await this.loadMarkets();
2702
2702
  const request = {};
2703
2703
  let market = undefined;
2704
+ let marketType = undefined;
2704
2705
  if (symbol !== undefined) {
2705
2706
  market = this.market(symbol);
2706
- request['symbol'] = market['id'];
2707
2707
  }
2708
- let marketType = undefined;
2709
2708
  [marketType, params] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
2710
2709
  if (marketType === 'spot') {
2711
2710
  if (symbol === undefined) {
2712
2711
  throw new ArgumentsRequired(this.id + ' fetchOpenOrders() requires a symbol argument for spot market');
2713
2712
  }
2713
+ request['symbol'] = market['id'];
2714
2714
  let method = 'spotPrivateGetOpenOrders';
2715
2715
  const [marginMode, query] = this.handleMarginModeAndParams('fetchOpenOrders', params);
2716
2716
  if (marginMode !== undefined) {
@@ -2807,7 +2807,6 @@ export default class mexc extends Exchange {
2807
2807
  let market = undefined;
2808
2808
  if (symbol !== undefined) {
2809
2809
  market = this.market(symbol);
2810
- request['symbol'] = market['id'];
2811
2810
  }
2812
2811
  const [marketType] = this.handleMarketTypeAndParams('fetchOrdersByState', market, params);
2813
2812
  if (marketType === 'spot') {
package/js/src/phemex.js CHANGED
@@ -1983,6 +1983,9 @@ export default class phemex extends Exchange {
1983
1983
  'Filled': 'closed',
1984
1984
  'Canceled': 'canceled',
1985
1985
  '1': 'open',
1986
+ '2': 'canceled',
1987
+ '3': 'closed',
1988
+ '4': 'canceled',
1986
1989
  '5': 'open',
1987
1990
  '6': 'open',
1988
1991
  '7': 'closed',
@@ -10,6 +10,9 @@ import { Precise } from '../base/Precise.js';
10
10
  import { ExchangeError, ArgumentsRequired, BadRequest } from '../base/errors.js';
11
11
  import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
12
12
  import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
13
+ import { rsa } from '../base/functions/rsa.js';
14
+ import { eddsa } from '../base/functions/crypto.js';
15
+ import { ed25519 } from '../static_dependencies/noble-curves/ed25519.js';
13
16
  // -----------------------------------------------------------------------------
14
17
  export default class binance extends binanceRest {
15
18
  describe() {
@@ -1216,7 +1219,20 @@ export default class binance extends binanceRest {
1216
1219
  params['recvWindow'] = recvWindow;
1217
1220
  }
1218
1221
  extendedParams = this.keysort(extendedParams);
1219
- extendedParams['signature'] = this.hmac(this.encode(this.urlencode(extendedParams)), this.encode(this.secret), sha256);
1222
+ const query = this.urlencode(extendedParams);
1223
+ let signature = undefined;
1224
+ if (this.secret.indexOf('PRIVATE KEY') > -1) {
1225
+ if (this.secret.length > 120) {
1226
+ signature = rsa(query, this.secret, sha256);
1227
+ }
1228
+ else {
1229
+ signature = eddsa(this.encode(query), this.secret, ed25519);
1230
+ }
1231
+ }
1232
+ else {
1233
+ signature = this.hmac(this.encode(query), this.encode(this.secret), sha256);
1234
+ }
1235
+ extendedParams['signature'] = signature;
1220
1236
  return extendedParams;
1221
1237
  }
1222
1238
  async authenticate(params = {}) {
@@ -2535,6 +2551,15 @@ export default class binance extends binanceRest {
2535
2551
  }
2536
2552
  }
2537
2553
  handleWsError(client, message) {
2554
+ //
2555
+ // {
2556
+ // "error": {
2557
+ // "code": 2,
2558
+ // "msg": "Invalid request: invalid stream"
2559
+ // },
2560
+ // "id": 1
2561
+ // }
2562
+ //
2538
2563
  const id = this.safeString(message, 'id');
2539
2564
  let rejected = false;
2540
2565
  const error = this.safeValue(message, 'error', {});
@@ -2545,7 +2570,17 @@ export default class binance extends binanceRest {
2545
2570
  }
2546
2571
  catch (e) {
2547
2572
  rejected = true;
2573
+ // private endpoint uses id as messageHash
2548
2574
  client.reject(e, id);
2575
+ // public endpoint stores messageHash in subscriptios
2576
+ const subscriptionKeys = Object.keys(client.subscriptions);
2577
+ for (let i = 0; i < subscriptionKeys.length; i++) {
2578
+ const subscriptionHash = subscriptionKeys[i];
2579
+ const subscriptionId = this.safeString(client.subscriptions[subscriptionHash], 'id');
2580
+ if (id === subscriptionId) {
2581
+ client.reject(e, subscriptionHash);
2582
+ }
2583
+ }
2549
2584
  }
2550
2585
  if (!rejected) {
2551
2586
  client.reject(message, id);
@@ -2558,7 +2593,8 @@ export default class binance extends binanceRest {
2558
2593
  handleMessage(client, message) {
2559
2594
  // handle WebSocketAPI
2560
2595
  const status = this.safeString(message, 'status');
2561
- if (status !== undefined && status !== '200') {
2596
+ const error = this.safeValue(message, 'error');
2597
+ if ((error !== undefined) || (status !== undefined && status !== '200')) {
2562
2598
  return this.handleWsError(client, message);
2563
2599
  }
2564
2600
  const id = this.safeString(message, 'id');
@@ -1408,13 +1408,13 @@ export default class huobi extends huobiRest {
1408
1408
  // }
1409
1409
  //
1410
1410
  const channel = this.safeString(message, 'ch');
1411
- const timestamp = this.safeInteger(message, 'ts');
1411
+ const data = this.safeValue(message, 'data', []);
1412
+ const timestamp = this.safeInteger(data, 'changeTime', this.safeInteger(message, 'ts'));
1412
1413
  this.balance['timestamp'] = timestamp;
1413
1414
  this.balance['datetime'] = this.iso8601(timestamp);
1414
- this.balance['info'] = this.safeValue(message, 'data');
1415
+ this.balance['info'] = data;
1415
1416
  if (channel !== undefined) {
1416
1417
  // spot balance
1417
- const data = this.safeValue(message, 'data', {});
1418
1418
  const currencyId = this.safeString(data, 'currency');
1419
1419
  const code = this.safeCurrencyCode(currencyId);
1420
1420
  const account = this.account();
@@ -1426,7 +1426,6 @@ export default class huobi extends huobiRest {
1426
1426
  }
1427
1427
  else {
1428
1428
  // contract balance
1429
- const data = this.safeValue(message, 'data', []);
1430
1429
  const dataLength = data.length;
1431
1430
  if (dataLength === 0) {
1432
1431
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.1.38",
3
+ "version": "4.1.40",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",
@@ -40,13 +40,13 @@
40
40
  "fast-test": "npm run commonjs-test && node run-tests --js",
41
41
  "commonjs-test": "node test-commonjs.cjs",
42
42
  "fast-test-ws": "node run-tests-ws --js",
43
- "test-js": "npm run commonjs-test && node js/src/test/static/test.ids && node run-tests --js",
43
+ "test-js": "npm run commonjs-test && node run-tests --js",
44
44
  "test-js-ws": "node run-tests-ws --js",
45
45
  "test-py": "node run-tests --python",
46
46
  "test-py-ws": "node run-tests-ws --python",
47
47
  "test-php": "node run-tests --php",
48
48
  "test-php-ws": "node run-tests-ws --php",
49
- "test-base": "npm run test-js-base && npm run test-python-base && npm run test-php-base",
49
+ "test-base": "npm run test-js-base && npm run test-python-base && npm run test-php-base && npm run id-tests && npm run static-tests",
50
50
  "test-base-ws": "npm run test-js-base-ws && npm run test-python-base-ws && npm run test-php-base-ws",
51
51
  "test-js-base": "node ./js/src/test/base/test.base.js",
52
52
  "test-js-base-ws": "npm run test-js-cache && npm run test-js-orderbook",
@@ -103,7 +103,11 @@
103
103
  "static-js": "node js/src/test/test.js --static",
104
104
  "static-py": "python python/ccxt/test/test_async.py --static",
105
105
  "static-php": "php php/test/test_async.php --static",
106
- "static-tests": "npm run static-js && npm run static-py && npm run static-php"
106
+ "static-tests": "npm run static-js && npm run static-py && npm run static-php",
107
+ "id-tests-js": "node js/src/test/test.js --idTests",
108
+ "id-tests-py": "python python/ccxt/test/test_async.py --idTests",
109
+ "id-tests-php": "php php/test/test_async.php --idTests",
110
+ "id-tests": "npm run id-tests-js && npm run id-tests-py && npm run id-tests-php"
107
111
  },
108
112
  "types": "./js/ccxt.d.ts",
109
113
  "devDependencies": {
@@ -116,7 +120,7 @@
116
120
  "as-table": "1.0.37",
117
121
  "asciichart": "^1.5.25",
118
122
  "assert": "^2.0.0",
119
- "ast-transpiler": "^0.0.24",
123
+ "ast-transpiler": "^0.0.25",
120
124
  "docsify": "^4.13.1",
121
125
  "eslint": "^8.8.0",
122
126
  "eslint-config-airbnb-base": "15.0.0",