ccxt 4.2.43 → 4.2.45

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 (46) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +1489 -463
  3. package/dist/ccxt.browser.min.js +6 -6
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/base/Exchange.js +54 -0
  6. package/dist/cjs/src/binance.js +627 -51
  7. package/dist/cjs/src/bingx.js +46 -6
  8. package/dist/cjs/src/bitstamp.js +1 -1
  9. package/dist/cjs/src/blofin.js +2 -1
  10. package/dist/cjs/src/bybit.js +96 -43
  11. package/dist/cjs/src/coinbase.js +221 -41
  12. package/dist/cjs/src/deribit.js +1 -1
  13. package/dist/cjs/src/krakenfutures.js +3 -2
  14. package/dist/cjs/src/kucoin.js +9 -5
  15. package/dist/cjs/src/mexc.js +348 -266
  16. package/dist/cjs/src/pro/gate.js +76 -42
  17. package/dist/cjs/src/pro/hitbtc.js +1 -0
  18. package/dist/cjs/src/probit.js +3 -3
  19. package/js/ccxt.d.ts +1 -1
  20. package/js/ccxt.js +1 -1
  21. package/js/src/abstract/coinbase.d.ts +1 -0
  22. package/js/src/base/Exchange.d.ts +4 -0
  23. package/js/src/base/Exchange.js +54 -0
  24. package/js/src/binance.d.ts +1 -0
  25. package/js/src/binance.js +627 -51
  26. package/js/src/bingx.d.ts +2 -1
  27. package/js/src/bingx.js +46 -6
  28. package/js/src/bitstamp.js +1 -1
  29. package/js/src/blofin.js +2 -1
  30. package/js/src/bybit.d.ts +4 -1
  31. package/js/src/bybit.js +96 -43
  32. package/js/src/coinbase.d.ts +10 -4
  33. package/js/src/coinbase.js +221 -41
  34. package/js/src/coinbasepro.d.ts +1 -1
  35. package/js/src/deribit.js +1 -1
  36. package/js/src/krakenfutures.js +3 -2
  37. package/js/src/kucoin.js +9 -5
  38. package/js/src/mexc.d.ts +4 -5
  39. package/js/src/mexc.js +348 -266
  40. package/js/src/pro/gate.d.ts +4 -0
  41. package/js/src/pro/gate.js +76 -42
  42. package/js/src/pro/hitbtc.js +1 -0
  43. package/js/src/probit.js +3 -3
  44. package/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.d.ts +1 -1
  45. package/package.json +1 -1
  46. package/skip-tests.json +2 -0
@@ -62,6 +62,7 @@ class coinbase extends coinbase$1 {
62
62
  'fetchCrossBorrowRate': false,
63
63
  'fetchCrossBorrowRates': false,
64
64
  'fetchCurrencies': true,
65
+ 'fetchDepositAddressesByNetwork': true,
65
66
  'fetchDeposits': true,
66
67
  'fetchFundingHistory': false,
67
68
  'fetchFundingRate': false,
@@ -129,6 +130,7 @@ class coinbase extends coinbase$1 {
129
130
  'public': {
130
131
  'get': [
131
132
  'currencies',
133
+ 'currencies/crypto',
132
134
  'time',
133
135
  'exchange-rates',
134
136
  'users/{user_id}',
@@ -323,6 +325,10 @@ class coinbase extends coinbase$1 {
323
325
  'ACCOUNT_TYPE_CRYPTO',
324
326
  'ACCOUNT_TYPE_FIAT',
325
327
  ],
328
+ 'networks': {
329
+ 'ERC20': 'ethereum',
330
+ 'XLM': 'stellar',
331
+ },
326
332
  'createMarketBuyOrderRequiresPrice': true,
327
333
  'advanced': true,
328
334
  'fetchMarkets': 'fetchMarketsV3',
@@ -678,10 +684,10 @@ class coinbase extends coinbase$1 {
678
684
  return this.parseTrades(buys['data'], undefined, since, limit);
679
685
  }
680
686
  async fetchTransactionsWithMethod(method, code = undefined, since = undefined, limit = undefined, params = {}) {
681
- const request = await this.prepareAccountRequestWithCurrencyCode(code, limit, params);
687
+ let request = undefined;
688
+ [request, params] = await this.prepareAccountRequestWithCurrencyCode(code, limit, params);
682
689
  await this.loadMarkets();
683
- const query = this.omit(params, ['account_id', 'accountId']);
684
- const response = await this[method](this.extend(request, query));
690
+ const response = await this[method](this.extend(request, params));
685
691
  return this.parseTransactions(response['data'], undefined, since, limit);
686
692
  }
687
693
  async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
@@ -1233,15 +1239,45 @@ class coinbase extends coinbase$1 {
1233
1239
  const expires = this.safeInteger(options, 'expires', 1000);
1234
1240
  const now = this.milliseconds();
1235
1241
  if ((timestamp === undefined) || ((now - timestamp) > expires)) {
1236
- const currencies = await this.v2PublicGetCurrencies(params);
1242
+ const promises = [
1243
+ this.v2PublicGetCurrencies(params),
1244
+ this.v2PublicGetCurrenciesCrypto(params),
1245
+ ];
1246
+ const promisesResult = await Promise.all(promises);
1247
+ const fiatResponse = this.safeDict(promisesResult, 0, {});
1248
+ //
1249
+ // [
1250
+ // "data": {
1251
+ // id: 'IMP',
1252
+ // name: 'Isle of Man Pound',
1253
+ // min_size: '0.01'
1254
+ // },
1255
+ // ...
1256
+ // ]
1257
+ //
1258
+ const cryptoResponse = this.safeDict(promisesResult, 1, {});
1259
+ //
1260
+ // {
1261
+ // asset_id: '9476e3be-b731-47fa-82be-347fabc573d9',
1262
+ // code: 'AERO',
1263
+ // name: 'Aerodrome Finance',
1264
+ // color: '#0433FF',
1265
+ // sort_index: '340',
1266
+ // exponent: '8',
1267
+ // type: 'crypto',
1268
+ // address_regex: '^(?:0x)?[0-9a-fA-F]{40}$'
1269
+ // }
1270
+ //
1271
+ const fiatData = this.safeList(fiatResponse, 'data', []);
1272
+ const cryptoData = this.safeList(cryptoResponse, 'data', []);
1237
1273
  const exchangeRates = await this.v2PublicGetExchangeRates(params);
1238
1274
  this.options['fetchCurrencies'] = this.extend(options, {
1239
- 'currencies': currencies,
1275
+ 'currencies': this.arrayConcat(fiatData, cryptoData),
1240
1276
  'exchangeRates': exchangeRates,
1241
1277
  'timestamp': now,
1242
1278
  });
1243
1279
  }
1244
- return this.safeValue(this.options, 'fetchCurrencies', {});
1280
+ return this.safeDict(this.options, 'fetchCurrencies', {});
1245
1281
  }
1246
1282
  async fetchCurrencies(params = {}) {
1247
1283
  /**
@@ -1256,18 +1292,27 @@ class coinbase extends coinbase$1 {
1256
1292
  const response = await this.fetchCurrenciesFromCache(params);
1257
1293
  const currencies = this.safeValue(response, 'currencies', {});
1258
1294
  //
1259
- // {
1260
- // "data":[
1261
- // {"id":"AED","name":"United Arab Emirates Dirham","min_size":"0.01000000"},
1262
- // {"id":"AFN","name":"Afghan Afghani","min_size":"0.01000000"},
1263
- // {"id":"ALL","name":"Albanian Lek","min_size":"0.01000000"},
1264
- // {"id":"AMD","name":"Armenian Dram","min_size":"0.01000000"},
1265
- // {"id":"ANG","name":"Netherlands Antillean Gulden","min_size":"0.01000000"},
1266
- // ...
1267
- // ],
1268
- // }
1295
+ // fiat
1296
+ //
1297
+ // {
1298
+ // id: 'IMP',
1299
+ // name: 'Isle of Man Pound',
1300
+ // min_size: '0.01'
1301
+ // },
1302
+ //
1303
+ // crypto
1304
+ //
1305
+ // {
1306
+ // asset_id: '9476e3be-b731-47fa-82be-347fabc573d9',
1307
+ // code: 'AERO',
1308
+ // name: 'Aerodrome Finance',
1309
+ // color: '#0433FF',
1310
+ // sort_index: '340',
1311
+ // exponent: '8',
1312
+ // type: 'crypto',
1313
+ // address_regex: '^(?:0x)?[0-9a-fA-F]{40}$'
1314
+ // }
1269
1315
  //
1270
- const exchangeRates = this.safeValue(response, 'exchangeRates', {});
1271
1316
  //
1272
1317
  // {
1273
1318
  // "data":{
@@ -1283,24 +1328,23 @@ class coinbase extends coinbase$1 {
1283
1328
  // }
1284
1329
  // }
1285
1330
  //
1286
- const data = this.safeValue(currencies, 'data', []);
1287
- const dataById = this.indexBy(data, 'id');
1288
- const rates = this.safeValue(this.safeValue(exchangeRates, 'data', {}), 'rates', {});
1289
- const keys = Object.keys(rates);
1290
1331
  const result = {};
1291
- for (let i = 0; i < keys.length; i++) {
1292
- const key = keys[i];
1293
- const type = (key in dataById) ? 'fiat' : 'crypto';
1294
- const currency = this.safeValue(dataById, key, {});
1295
- const id = this.safeString(currency, 'id', key);
1296
- const name = this.safeString(currency, 'name');
1332
+ const networks = {};
1333
+ const networksById = {};
1334
+ for (let i = 0; i < currencies.length; i++) {
1335
+ const currency = currencies[i];
1336
+ const assetId = this.safeString(currency, 'asset_id');
1337
+ const id = this.safeString2(currency, 'id', 'code');
1297
1338
  const code = this.safeCurrencyCode(id);
1339
+ const name = this.safeString(currency, 'name');
1340
+ this.options['networks'][code] = name.toLowerCase();
1341
+ this.options['networksById'][code] = name.toLowerCase();
1298
1342
  result[code] = {
1343
+ 'info': currency,
1299
1344
  'id': id,
1300
1345
  'code': code,
1301
- 'info': currency,
1302
- 'type': type,
1303
- 'name': name,
1346
+ 'type': (assetId !== undefined) ? 'crypto' : 'fiat',
1347
+ 'name': this.safeString(currency, 'name'),
1304
1348
  'active': true,
1305
1349
  'deposit': undefined,
1306
1350
  'withdraw': undefined,
@@ -1317,7 +1361,14 @@ class coinbase extends coinbase$1 {
1317
1361
  },
1318
1362
  },
1319
1363
  };
1364
+ if (assetId !== undefined) {
1365
+ const lowerCaseName = name.toLowerCase();
1366
+ networks[code] = lowerCaseName;
1367
+ networksById[lowerCaseName] = code;
1368
+ }
1320
1369
  }
1370
+ this.options['networks'] = this.extend(networks, this.options['networks']);
1371
+ this.options['networksById'] = this.extend(networksById, this.options['networksById']);
1321
1372
  return result;
1322
1373
  }
1323
1374
  async fetchTickers(symbols = undefined, params = {}) {
@@ -1795,12 +1846,12 @@ class coinbase extends coinbase$1 {
1795
1846
  if (code !== undefined) {
1796
1847
  currency = this.currency(code);
1797
1848
  }
1798
- const request = await this.prepareAccountRequestWithCurrencyCode(code, limit, params);
1799
- const query = this.omit(params, ['account_id', 'accountId']);
1849
+ let request = undefined;
1850
+ [request, params] = await this.prepareAccountRequestWithCurrencyCode(code, limit, params);
1800
1851
  // for pagination use parameter 'starting_after'
1801
1852
  // the value for the next page can be obtained from the result of the previous call in the 'pagination' field
1802
1853
  // eg: instance.last_json_response.pagination.next_starting_after
1803
- const response = await this.v2PrivateGetAccountsAccountIdTransactions(this.extend(request, query));
1854
+ const response = await this.v2PrivateGetAccountsAccountIdTransactions(this.extend(request, params));
1804
1855
  return this.parseLedger(response['data'], currency, since, limit);
1805
1856
  }
1806
1857
  parseLedgerEntryStatus(status) {
@@ -2158,6 +2209,7 @@ class coinbase extends coinbase$1 {
2158
2209
  }
2159
2210
  async prepareAccountRequestWithCurrencyCode(code = undefined, limit = undefined, params = {}) {
2160
2211
  let accountId = this.safeString2(params, 'account_id', 'accountId');
2212
+ params = this.omit(params, ['account_id', 'accountId']);
2161
2213
  if (accountId === undefined) {
2162
2214
  if (code === undefined) {
2163
2215
  throw new errors.ArgumentsRequired(this.id + ' prepareAccountRequestWithCurrencyCode() method requires an account_id (or accountId) parameter OR a currency code argument');
@@ -2173,7 +2225,7 @@ class coinbase extends coinbase$1 {
2173
2225
  if (limit !== undefined) {
2174
2226
  request['limit'] = limit;
2175
2227
  }
2176
- return request;
2228
+ return [request, params];
2177
2229
  }
2178
2230
  async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
2179
2231
  /**
@@ -3346,6 +3398,140 @@ class coinbase extends coinbase$1 {
3346
3398
  const data = this.safeValue(response, 'data', {});
3347
3399
  return this.parseTransaction(data, currency);
3348
3400
  }
3401
+ async fetchDepositAddressesByNetwork(code, params = {}) {
3402
+ /**
3403
+ * @method
3404
+ * @name ascendex#fetchDepositAddress
3405
+ * @description fetch the deposit address for a currency associated with this account
3406
+ * @see https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_postcoinbaseaccountaddresses
3407
+ * @param {string} code unified currency code
3408
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3409
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
3410
+ */
3411
+ await this.loadMarkets();
3412
+ const currency = this.currency(code);
3413
+ let request = undefined;
3414
+ [request, params] = await this.prepareAccountRequestWithCurrencyCode(currency['code']);
3415
+ const response = await this.v2PrivateGetAccountsAccountIdAddresses(this.extend(request, params));
3416
+ //
3417
+ // {
3418
+ // pagination: {
3419
+ // ending_before: null,
3420
+ // starting_after: null,
3421
+ // previous_ending_before: null,
3422
+ // next_starting_after: null,
3423
+ // limit: '25',
3424
+ // order: 'desc',
3425
+ // previous_uri: null,
3426
+ // next_uri: null
3427
+ // },
3428
+ // data: [
3429
+ // {
3430
+ // id: '64ceb5f1-5fa2-5310-a4ff-9fd46271003d',
3431
+ // address: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk',
3432
+ // address_info: { address: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk' },
3433
+ // name: null,
3434
+ // created_at: '2023-05-29T21:12:12Z',
3435
+ // updated_at: '2023-05-29T21:12:12Z',
3436
+ // network: 'solana',
3437
+ // uri_scheme: 'solana',
3438
+ // resource: 'address',
3439
+ // resource_path: '/v2/accounts/a7b3d387-bfb8-5ce7-b8da-1f507e81cf25/addresses/64ceb5f1-5fa2-5310-a4ff-9fd46271003d',
3440
+ // warnings: [
3441
+ // {
3442
+ // type: 'correct_address_warning',
3443
+ // title: 'This is an ERC20 USDC address.',
3444
+ // details: 'Only send ERC20 USD Coin (USDC) to this address.',
3445
+ // image_url: 'https://www.coinbase.com/assets/addresses/global-receive-warning-a3d91807e61c717e5a38d270965003dcc025ca8a3cea40ec3d7835b7c86087fa.png',
3446
+ // options: [ { text: 'I understand', style: 'primary', id: 'dismiss' } ]
3447
+ // }
3448
+ // ],
3449
+ // qr_code_image_url: 'https://static-assets.coinbase.com/p2p/l2/asset_network_combinations/v5/usdc-solana.png',
3450
+ // address_label: 'USDC address (Solana)',
3451
+ // default_receive: true,
3452
+ // deposit_uri: 'solana:5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk?spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
3453
+ // callback_url: null,
3454
+ // share_address_copy: {
3455
+ // line1: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk',
3456
+ // line2: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.'
3457
+ // },
3458
+ // receive_subtitle: 'ERC-20',
3459
+ // inline_warning: {
3460
+ // text: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.',
3461
+ // tooltip: {
3462
+ // title: 'USDC (Solana)',
3463
+ // subtitle: 'This address can only receive USDC-SPL from Solana network.'
3464
+ // }
3465
+ // }
3466
+ // },
3467
+ // ...
3468
+ // ]
3469
+ // }
3470
+ //
3471
+ const data = this.safeList(response, 'data', []);
3472
+ const addressStructures = this.parseDepositAddresses(data, undefined, false);
3473
+ return this.indexBy(addressStructures, 'network');
3474
+ }
3475
+ parseDepositAddress(depositAddress, currency = undefined) {
3476
+ //
3477
+ // {
3478
+ // id: '64ceb5f1-5fa2-5310-a4ff-9fd46271003d',
3479
+ // address: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk',
3480
+ // address_info: {
3481
+ // address: 'GCF74576I7AQ56SLMKBQAP255EGUOWCRVII3S44KEXVNJEOIFVBDMXVL',
3482
+ // destination_tag: '3722061866'
3483
+ // },
3484
+ // name: null,
3485
+ // created_at: '2023-05-29T21:12:12Z',
3486
+ // updated_at: '2023-05-29T21:12:12Z',
3487
+ // network: 'solana',
3488
+ // uri_scheme: 'solana',
3489
+ // resource: 'address',
3490
+ // resource_path: '/v2/accounts/a7b3d387-bfb8-5ce7-b8da-1f507e81cf25/addresses/64ceb5f1-5fa2-5310-a4ff-9fd46271003d',
3491
+ // warnings: [
3492
+ // {
3493
+ // type: 'correct_address_warning',
3494
+ // title: 'This is an ERC20 USDC address.',
3495
+ // details: 'Only send ERC20 USD Coin (USDC) to this address.',
3496
+ // image_url: 'https://www.coinbase.com/assets/addresses/global-receive-warning-a3d91807e61c717e5a38d270965003dcc025ca8a3cea40ec3d7835b7c86087fa.png',
3497
+ // options: [ { text: 'I understand', style: 'primary', id: 'dismiss' } ]
3498
+ // }
3499
+ // ],
3500
+ // qr_code_image_url: 'https://static-assets.coinbase.com/p2p/l2/asset_network_combinations/v5/usdc-solana.png',
3501
+ // address_label: 'USDC address (Solana)',
3502
+ // default_receive: true,
3503
+ // deposit_uri: 'solana:5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk?spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
3504
+ // callback_url: null,
3505
+ // share_address_copy: {
3506
+ // line1: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk',
3507
+ // line2: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.'
3508
+ // },
3509
+ // receive_subtitle: 'ERC-20',
3510
+ // inline_warning: {
3511
+ // text: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.',
3512
+ // tooltip: {
3513
+ // title: 'USDC (Solana)',
3514
+ // subtitle: 'This address can only receive USDC-SPL from Solana network.'
3515
+ // }
3516
+ // }
3517
+ // }
3518
+ //
3519
+ const address = this.safeString(depositAddress, 'address');
3520
+ this.checkAddress(address);
3521
+ const networkId = this.safeString(depositAddress, 'network');
3522
+ const code = this.safeCurrencyCode(undefined, currency);
3523
+ const addressLabel = this.safeString(depositAddress, 'address_label');
3524
+ const splitAddressLabel = addressLabel.split(' ');
3525
+ const marketId = this.safeString(splitAddressLabel, 0);
3526
+ const addressInfo = this.safeDict(depositAddress, 'address_info');
3527
+ return {
3528
+ 'info': depositAddress,
3529
+ 'currency': this.safeCurrencyCode(marketId, currency),
3530
+ 'address': address,
3531
+ 'tag': this.safeString(addressInfo, 'destination_tag'),
3532
+ 'network': this.networkIdToCode(networkId, code),
3533
+ };
3534
+ }
3349
3535
  sign(path, api = [], method = 'GET', params = {}, headers = undefined, body = undefined) {
3350
3536
  const version = api[0];
3351
3537
  const signed = api[1] === 'private';
@@ -3388,13 +3574,7 @@ class coinbase extends coinbase$1 {
3388
3574
  payload = body;
3389
3575
  }
3390
3576
  }
3391
- let auth = undefined;
3392
- if (version === 'v3') {
3393
- auth = nonce + method + savedPath + payload;
3394
- }
3395
- else {
3396
- auth = nonce + method + fullPath + payload;
3397
- }
3577
+ const auth = nonce + method + savedPath + payload;
3398
3578
  const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256.sha256);
3399
3579
  headers = {
3400
3580
  'CB-ACCESS-KEY': this.apiKey,
@@ -1781,7 +1781,7 @@ class deribit extends deribit$1 {
1781
1781
  const amount = this.safeString(order, 'amount');
1782
1782
  let cost = Precise["default"].stringMul(filledString, averageString);
1783
1783
  if (market['inverse']) {
1784
- if (this.parseNumber(averageString) !== 0) {
1784
+ if (averageString !== '0') {
1785
1785
  cost = Precise["default"].stringDiv(amount, averageString);
1786
1786
  }
1787
1787
  }
@@ -861,6 +861,7 @@ class krakenfutures extends krakenfutures$1 {
861
861
  }
862
862
  createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
863
863
  const market = this.market(symbol);
864
+ symbol = market['symbol'];
864
865
  type = this.safeString(params, 'orderType', type);
865
866
  const timeInForce = this.safeString(params, 'timeInForce');
866
867
  let postOnly = false;
@@ -880,7 +881,7 @@ class krakenfutures extends krakenfutures$1 {
880
881
  const request = {
881
882
  'symbol': market['id'],
882
883
  'side': side,
883
- 'size': amount,
884
+ 'size': this.amountToPrecision(symbol, amount),
884
885
  };
885
886
  const clientOrderId = this.safeString2(params, 'clientOrderId', 'cliOrdId');
886
887
  if (clientOrderId !== undefined) {
@@ -918,7 +919,7 @@ class krakenfutures extends krakenfutures$1 {
918
919
  }
919
920
  request['orderType'] = type;
920
921
  if (price !== undefined) {
921
- request['limitPrice'] = price;
922
+ request['limitPrice'] = this.priceToPrecision(symbol, price);
922
923
  }
923
924
  params = this.omit(params, ['clientOrderId', 'timeInForce', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']);
924
925
  return this.extend(request, params);
@@ -3857,11 +3857,11 @@ class kucoin extends kucoin$1 {
3857
3857
  }
3858
3858
  }
3859
3859
  let fee = undefined;
3860
- const feeCost = this.safeNumber(item, 'fee');
3860
+ const feeCost = this.safeString(item, 'fee');
3861
3861
  let feeCurrency = undefined;
3862
- if (feeCost !== 0) {
3862
+ if (feeCost !== '0') {
3863
3863
  feeCurrency = code;
3864
- fee = { 'cost': feeCost, 'currency': feeCurrency };
3864
+ fee = { 'cost': this.parseNumber(feeCost), 'currency': feeCurrency };
3865
3865
  }
3866
3866
  return {
3867
3867
  'id': id,
@@ -3975,8 +3975,12 @@ class kucoin extends kucoin$1 {
3975
3975
  // }
3976
3976
  // }
3977
3977
  //
3978
- const data = this.safeValue(response, 'data');
3979
- const items = this.safeValue(data, 'items', data);
3978
+ const dataList = this.safeList(response, 'data');
3979
+ if (dataList !== undefined) {
3980
+ return this.parseLedger(dataList, currency, since, limit);
3981
+ }
3982
+ const data = this.safeDict(response, 'data');
3983
+ const items = this.safeList(data, 'items', []);
3980
3984
  return this.parseLedger(items, currency, since, limit);
3981
3985
  }
3982
3986
  calculateRateLimiterCost(api, method, path, params, config = {}) {