ccxt 4.2.63 → 4.2.65

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 (60) hide show
  1. package/README.md +3 -3
  2. package/build.sh +2 -2
  3. package/dist/ccxt.browser.js +565 -178
  4. package/dist/ccxt.browser.min.js +3 -3
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/base/Exchange.js +12 -0
  7. package/dist/cjs/src/binance.js +33 -12
  8. package/dist/cjs/src/bingx.js +58 -49
  9. package/dist/cjs/src/bitget.js +69 -1
  10. package/dist/cjs/src/bitmex.js +3 -1
  11. package/dist/cjs/src/blofin.js +46 -11
  12. package/dist/cjs/src/btcmarkets.js +12 -0
  13. package/dist/cjs/src/bybit.js +100 -7
  14. package/dist/cjs/src/coinbase.js +12 -2
  15. package/dist/cjs/src/delta.js +95 -1
  16. package/dist/cjs/src/gemini.js +9 -4
  17. package/dist/cjs/src/hitbtc.js +1 -1
  18. package/dist/cjs/src/krakenfutures.js +1 -0
  19. package/dist/cjs/src/kucoin.js +87 -62
  20. package/dist/cjs/src/pro/bitget.js +5 -5
  21. package/dist/cjs/src/pro/coinex.js +4 -4
  22. package/dist/cjs/src/pro/currencycom.js +1 -1
  23. package/dist/cjs/src/pro/lbank.js +1 -1
  24. package/dist/cjs/src/yobit.js +15 -15
  25. package/js/ccxt.d.ts +1 -1
  26. package/js/ccxt.js +1 -1
  27. package/js/src/abstract/blofin.d.ts +1 -0
  28. package/js/src/abstract/krakenfutures.d.ts +1 -0
  29. package/js/src/abstract/kucoin.d.ts +10 -0
  30. package/js/src/abstract/kucoinfutures.d.ts +10 -0
  31. package/js/src/base/Exchange.js +12 -0
  32. package/js/src/binance.d.ts +1 -1
  33. package/js/src/binance.js +33 -12
  34. package/js/src/bingx.js +58 -49
  35. package/js/src/bitget.d.ts +3 -1
  36. package/js/src/bitget.js +69 -1
  37. package/js/src/bitmex.js +3 -1
  38. package/js/src/blofin.d.ts +3 -1
  39. package/js/src/blofin.js +46 -11
  40. package/js/src/btcmarkets.js +12 -0
  41. package/js/src/bybit.d.ts +1 -0
  42. package/js/src/bybit.js +100 -7
  43. package/js/src/coinbase.js +12 -2
  44. package/js/src/delta.d.ts +3 -1
  45. package/js/src/delta.js +95 -1
  46. package/js/src/gate.d.ts +1 -1
  47. package/js/src/gemini.js +9 -4
  48. package/js/src/hitbtc.js +1 -1
  49. package/js/src/krakenfutures.js +1 -0
  50. package/js/src/kucoin.js +87 -62
  51. package/js/src/okx.d.ts +1 -1
  52. package/js/src/pro/bitget.js +5 -5
  53. package/js/src/pro/coinex.js +4 -4
  54. package/js/src/pro/currencycom.d.ts +1 -1
  55. package/js/src/pro/currencycom.js +1 -1
  56. package/js/src/pro/lbank.js +1 -1
  57. package/js/src/woo.d.ts +1 -1
  58. package/js/src/yobit.js +15 -15
  59. package/package.json +2 -2
  60. package/skip-tests.json +47 -22
@@ -84,7 +84,7 @@ class bitget extends bitget$1 {
84
84
  'fetchLeverage': true,
85
85
  'fetchLeverageTiers': false,
86
86
  'fetchLiquidations': false,
87
- 'fetchMarginMode': false,
87
+ 'fetchMarginMode': true,
88
88
  'fetchMarketLeverageTiers': true,
89
89
  'fetchMarkets': true,
90
90
  'fetchMarkOHLCV': true,
@@ -8304,6 +8304,74 @@ class bitget extends bitget$1 {
8304
8304
  const orderInfo = this.safeValue(data, 'successList', []);
8305
8305
  return this.parsePositions(orderInfo, undefined, params);
8306
8306
  }
8307
+ async fetchMarginMode(symbol, params = {}) {
8308
+ /**
8309
+ * @method
8310
+ * @name bitget#fetchMarginMode
8311
+ * @description fetches the margin mode of a trading pair
8312
+ * @see https://www.bitget.com/api-doc/contract/account/Get-Single-Account
8313
+ * @param {string} symbol unified symbol of the market to fetch the margin mode for
8314
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
8315
+ * @returns {object} a [margin mode structure]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
8316
+ */
8317
+ await this.loadMarkets();
8318
+ const sandboxMode = this.safeBool(this.options, 'sandboxMode', false);
8319
+ let market = undefined;
8320
+ if (sandboxMode) {
8321
+ const sandboxSymbol = this.convertSymbolForSandbox(symbol);
8322
+ market = this.market(sandboxSymbol);
8323
+ }
8324
+ else {
8325
+ market = this.market(symbol);
8326
+ }
8327
+ let productType = undefined;
8328
+ [productType, params] = this.handleProductTypeAndParams(market, params);
8329
+ const request = {
8330
+ 'symbol': market['id'],
8331
+ 'marginCoin': market['settleId'],
8332
+ 'productType': productType,
8333
+ };
8334
+ const response = await this.privateMixGetV2MixAccountAccount(this.extend(request, params));
8335
+ //
8336
+ // {
8337
+ // "code": "00000",
8338
+ // "msg": "success",
8339
+ // "requestTime": 1709791216652,
8340
+ // "data": {
8341
+ // "marginCoin": "USDT",
8342
+ // "locked": "0",
8343
+ // "available": "19.88811074",
8344
+ // "crossedMaxAvailable": "19.88811074",
8345
+ // "isolatedMaxAvailable": "19.88811074",
8346
+ // "maxTransferOut": "19.88811074",
8347
+ // "accountEquity": "19.88811074",
8348
+ // "usdtEquity": "19.888110749166",
8349
+ // "btcEquity": "0.000302183391",
8350
+ // "crossedRiskRate": "0",
8351
+ // "crossedMarginLeverage": 20,
8352
+ // "isolatedLongLever": 20,
8353
+ // "isolatedShortLever": 20,
8354
+ // "marginMode": "crossed",
8355
+ // "posMode": "hedge_mode",
8356
+ // "unrealizedPL": "0",
8357
+ // "coupon": "0",
8358
+ // "crossedUnrealizedPL": "0",
8359
+ // "isolatedUnrealizedPL": ""
8360
+ // }
8361
+ // }
8362
+ //
8363
+ const data = this.safeDict(response, 'data', {});
8364
+ return this.parseMarginMode(data, market);
8365
+ }
8366
+ parseMarginMode(marginMode, market = undefined) {
8367
+ let marginType = this.safeString(marginMode, 'marginMode');
8368
+ marginType = (marginType === 'crossed') ? 'cross' : marginType;
8369
+ return {
8370
+ 'info': marginMode,
8371
+ 'symbol': market['symbol'],
8372
+ 'marginMode': marginType,
8373
+ };
8374
+ }
8307
8375
  handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
8308
8376
  if (!response) {
8309
8377
  return undefined; // fallback to default error handler
@@ -2547,7 +2547,9 @@ class bitmex extends bitmex$1 {
2547
2547
  if (until !== undefined) {
2548
2548
  request['endTime'] = this.iso8601(until);
2549
2549
  }
2550
- request['reverse'] = true;
2550
+ if ((since === undefined) && (until === undefined)) {
2551
+ request['reverse'] = true;
2552
+ }
2551
2553
  const response = await this.publicGetFunding(this.extend(request, params));
2552
2554
  //
2553
2555
  // [
@@ -82,6 +82,8 @@ class blofin extends blofin$1 {
82
82
  'fetchLeverage': true,
83
83
  'fetchLeverages': true,
84
84
  'fetchLeverageTiers': false,
85
+ 'fetchMarginMode': true,
86
+ 'fetchMarginModes': false,
85
87
  'fetchMarketLeverageTiers': false,
86
88
  'fetchMarkets': true,
87
89
  'fetchMarkOHLCV': false,
@@ -185,6 +187,7 @@ class blofin extends blofin$1 {
185
187
  'account/balance': 1,
186
188
  'account/positions': 1,
187
189
  'account/leverage-info': 1,
190
+ 'account/margin-mode': 1,
188
191
  'account/batch-leverage-info': 1,
189
192
  'trade/orders-tpsl-pending': 1,
190
193
  'trade/orders-history': 1,
@@ -378,7 +381,7 @@ class blofin extends blofin$1 {
378
381
  const strikePrice = undefined;
379
382
  const optionType = undefined;
380
383
  const tickSize = this.safeString(market, 'tickSize');
381
- const fees = this.safeValue2(this.fees, type, 'trading', {});
384
+ const fees = this.safeDict2(this.fees, type, 'trading', {});
382
385
  const taker = this.safeNumber(fees, 'taker');
383
386
  const maker = this.safeNumber(fees, 'maker');
384
387
  let maxLeverage = this.safeString(market, 'maxLeverage', '100');
@@ -479,7 +482,7 @@ class blofin extends blofin$1 {
479
482
  // }
480
483
  //
481
484
  const data = this.safeList(response, 'data', []);
482
- const first = this.safeValue(data, 0, {});
485
+ const first = this.safeDict(data, 0, {});
483
486
  const timestamp = this.safeInteger(first, 'ts');
484
487
  return this.parseOrderBook(first, symbol, timestamp);
485
488
  }
@@ -535,7 +538,7 @@ class blofin extends blofin$1 {
535
538
  };
536
539
  const response = await this.publicGetMarketTickers(this.extend(request, params));
537
540
  const data = this.safeList(response, 'data', []);
538
- const first = this.safeValue(data, 0, {});
541
+ const first = this.safeDict(data, 0, {});
539
542
  return this.parseTicker(first, market);
540
543
  }
541
544
  async fetchTickers(symbols = undefined, params = {}) {
@@ -995,8 +998,8 @@ class blofin extends blofin$1 {
995
998
  if (postOnly) {
996
999
  request['type'] = 'post_only';
997
1000
  }
998
- const stopLoss = this.safeValue(params, 'stopLoss');
999
- const takeProfit = this.safeValue(params, 'takeProfit');
1001
+ const stopLoss = this.safeDict(params, 'stopLoss');
1002
+ const takeProfit = this.safeDict(params, 'takeProfit');
1000
1003
  params = this.omit(params, ['stopLoss', 'takeProfit']);
1001
1004
  const isStopLoss = stopLoss !== undefined;
1002
1005
  const isTakeProfit = takeProfit !== undefined;
@@ -1289,7 +1292,7 @@ class blofin extends blofin$1 {
1289
1292
  const side = this.safeString(rawOrder, 'side');
1290
1293
  const amount = this.safeValue(rawOrder, 'amount');
1291
1294
  const price = this.safeValue(rawOrder, 'price');
1292
- const orderParams = this.safeValue(rawOrder, 'params', {});
1295
+ const orderParams = this.safeDict(rawOrder, 'params', {});
1293
1296
  const extendedParams = this.extend(orderParams, params); // the request does not accept extra params since it's a list, so we're extending each order with the common params
1294
1297
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, extendedParams);
1295
1298
  ordersRequests.push(orderRequest);
@@ -1328,7 +1331,7 @@ class blofin extends blofin$1 {
1328
1331
  if (limit !== undefined) {
1329
1332
  request['limit'] = limit; // default 100, max 100
1330
1333
  }
1331
- const isStop = this.safeValueN(params, ['stop', 'trigger', 'tpsl', 'TPSL'], false);
1334
+ const isStop = this.safeBoolN(params, ['stop', 'trigger', 'tpsl', 'TPSL'], false);
1332
1335
  let method = undefined;
1333
1336
  [method, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'method', 'privateGetTradeOrdersPending');
1334
1337
  const query = this.omit(params, ['method', 'stop', 'trigger', 'tpsl', 'TPSL']);
@@ -1656,7 +1659,7 @@ class blofin extends blofin$1 {
1656
1659
  await this.loadMarkets();
1657
1660
  const market = this.market(symbol);
1658
1661
  const request = [];
1659
- const options = this.safeValue(this.options, 'cancelOrders', {});
1662
+ const options = this.safeDict(this.options, 'cancelOrders', {});
1660
1663
  const defaultMethod = this.safeString(options, 'method', 'privatePostTradeCancelBatchOrders');
1661
1664
  let method = this.safeString(params, 'method', defaultMethod);
1662
1665
  const clientOrderIds = this.parseIds(this.safeValue(params, 'clientOrderId'));
@@ -1723,7 +1726,7 @@ class blofin extends blofin$1 {
1723
1726
  */
1724
1727
  await this.loadMarkets();
1725
1728
  const currency = this.currency(code);
1726
- const accountsByType = this.safeValue(this.options, 'accountsByType', {});
1729
+ const accountsByType = this.safeDict(this.options, 'accountsByType', {});
1727
1730
  const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
1728
1731
  const toId = this.safeString(accountsByType, toAccount, toAccount);
1729
1732
  const request = {
@@ -2056,7 +2059,7 @@ class blofin extends blofin$1 {
2056
2059
  request['clientOrderId'] = clientOrderId;
2057
2060
  }
2058
2061
  const response = await this.privatePostTradeClosePosition(this.extend(request, params));
2059
- return this.safeValue(response, 'data');
2062
+ return this.safeDict(response, 'data');
2060
2063
  }
2061
2064
  async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2062
2065
  /**
@@ -2091,7 +2094,7 @@ class blofin extends blofin$1 {
2091
2094
  if (since !== undefined) {
2092
2095
  request['begin'] = since;
2093
2096
  }
2094
- const isStop = this.safeValueN(params, ['stop', 'trigger', 'tpsl', 'TPSL'], false);
2097
+ const isStop = this.safeBoolN(params, ['stop', 'trigger', 'tpsl', 'TPSL'], false);
2095
2098
  let method = undefined;
2096
2099
  [method, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'method', 'privateGetTradeOrdersHistory');
2097
2100
  const query = this.omit(params, ['method', 'stop', 'trigger', 'tpsl', 'TPSL']);
@@ -2105,6 +2108,38 @@ class blofin extends blofin$1 {
2105
2108
  const data = this.safeList(response, 'data', []);
2106
2109
  return this.parseOrders(data, market, since, limit);
2107
2110
  }
2111
+ async fetchMarginMode(symbol, params = {}) {
2112
+ /**
2113
+ * @method
2114
+ * @name blofin#fetchMarginMode
2115
+ * @description fetches the margin mode of a trading pair
2116
+ * @see https://docs.blofin.com/index.html#get-margin-mode
2117
+ * @param {string} symbol unified symbol of the market to fetch the margin mode for
2118
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2119
+ * @returns {object} a [margin mode structure]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
2120
+ */
2121
+ await this.loadMarkets();
2122
+ const market = this.market(symbol);
2123
+ const response = await this.privateGetAccountMarginMode(params);
2124
+ //
2125
+ // {
2126
+ // "code": "0",
2127
+ // "msg": "success",
2128
+ // "data": {
2129
+ // "marginMode": "cross"
2130
+ // }
2131
+ // }
2132
+ //
2133
+ const data = this.safeDict(response, 'data', {});
2134
+ return this.parseMarginMode(data, market);
2135
+ }
2136
+ parseMarginMode(marginMode, market = undefined) {
2137
+ return {
2138
+ 'info': marginMode,
2139
+ 'symbol': market['symbol'],
2140
+ 'marginMode': this.safeString(marginMode, 'marginMode'),
2141
+ };
2142
+ }
2108
2143
  handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
2109
2144
  if (response === undefined) {
2110
2145
  return undefined; // fallback to default error handler
@@ -914,6 +914,18 @@ class btcmarkets extends btcmarkets$1 {
914
914
  return await this.privateDeleteOrdersId(this.extend(request, params));
915
915
  }
916
916
  calculateFee(symbol, type, side, amount, price, takerOrMaker = 'taker', params = {}) {
917
+ /**
918
+ * @method
919
+ * @description calculates the presumptive fee that would be charged for an order
920
+ * @param {string} symbol unified market symbol
921
+ * @param {string} type not used by btcmarkets.calculateFee
922
+ * @param {string} side not used by btcmarkets.calculateFee
923
+ * @param {float} amount how much you want to trade, in units of the base currency on most exchanges, or number of contracts
924
+ * @param {float} price the price for the order to be filled at, in units of the quote currency
925
+ * @param {string} takerOrMaker 'taker' or 'maker'
926
+ * @param {object} params
927
+ * @returns {object} contains the rate, the percentage multiplied to the order amount to obtain the fee amount, and cost, the total value of the fee in units of the quote currency, for the order
928
+ */
917
929
  const market = this.markets[symbol];
918
930
  let currency = undefined;
919
931
  let cost = undefined;
@@ -3784,8 +3784,8 @@ class bybit extends bybit$1 {
3784
3784
  const market = this.market(symbols[0]);
3785
3785
  let category = undefined;
3786
3786
  [category, params] = this.getBybitType('createOrders', market, params);
3787
- if ((category === 'spot') || (category === 'inverse')) {
3788
- throw new errors.NotSupported(this.id + ' createOrders does not allow spot or inverse orders');
3787
+ if (category === 'inverse') {
3788
+ throw new errors.NotSupported(this.id + ' createOrders does not allow inverse orders');
3789
3789
  }
3790
3790
  const request = {
3791
3791
  'category': category,
@@ -4265,6 +4265,87 @@ class bybit extends bybit$1 {
4265
4265
  const result = this.safeValue(response, 'result', {});
4266
4266
  return this.parseOrder(result, market);
4267
4267
  }
4268
+ async cancelOrders(ids, symbol = undefined, params = {}) {
4269
+ /**
4270
+ * @method
4271
+ * @name bybit#cancelOrders
4272
+ * @description cancel multiple orders
4273
+ * @see https://bybit-exchange.github.io/docs/v5/order/batch-cancel
4274
+ * @param {string[]} ids order ids
4275
+ * @param {string} symbol unified symbol of the market the order was made in
4276
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
4277
+ * @param {string[]} [params.clientOrderIds] client order ids
4278
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
4279
+ */
4280
+ if (symbol === undefined) {
4281
+ throw new errors.ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
4282
+ }
4283
+ await this.loadMarkets();
4284
+ const market = this.market(symbol);
4285
+ let category = undefined;
4286
+ [category, params] = this.getBybitType('cancelOrders', market, params);
4287
+ if (category === 'inverse') {
4288
+ throw new errors.NotSupported(this.id + ' cancelOrders does not allow inverse orders');
4289
+ }
4290
+ const ordersRequests = [];
4291
+ const clientOrderIds = this.safeList2(params, 'clientOrderIds', 'clientOids', []);
4292
+ params = this.omit(params, ['clientOrderIds', 'clientOids']);
4293
+ for (let i = 0; i < clientOrderIds.length; i++) {
4294
+ ordersRequests.push({
4295
+ 'symbol': market['id'],
4296
+ 'orderLinkId': this.safeString(clientOrderIds, i),
4297
+ });
4298
+ }
4299
+ for (let i = 0; i < ids.length; i++) {
4300
+ ordersRequests.push({
4301
+ 'symbol': market['id'],
4302
+ 'orderId': this.safeString(ids, i),
4303
+ });
4304
+ }
4305
+ const request = {
4306
+ 'category': category,
4307
+ 'request': ordersRequests,
4308
+ };
4309
+ const response = await this.privatePostV5OrderCancelBatch(this.extend(request, params));
4310
+ //
4311
+ // {
4312
+ // "retCode": "0",
4313
+ // "retMsg": "OK",
4314
+ // "result": {
4315
+ // "list": [
4316
+ // {
4317
+ // "category": "spot",
4318
+ // "symbol": "BTCUSDT",
4319
+ // "orderId": "1636282505818800896",
4320
+ // "orderLinkId": "1636282505818800897"
4321
+ // },
4322
+ // {
4323
+ // "category": "spot",
4324
+ // "symbol": "BTCUSDT",
4325
+ // "orderId": "1636282505818800898",
4326
+ // "orderLinkId": "1636282505818800899"
4327
+ // }
4328
+ // ]
4329
+ // },
4330
+ // "retExtInfo": {
4331
+ // "list": [
4332
+ // {
4333
+ // "code": "0",
4334
+ // "msg": "OK"
4335
+ // },
4336
+ // {
4337
+ // "code": "0",
4338
+ // "msg": "OK"
4339
+ // }
4340
+ // ]
4341
+ // },
4342
+ // "time": "1709796158501"
4343
+ // }
4344
+ //
4345
+ const result = this.safeDict(response, 'result', {});
4346
+ const row = this.safeList(result, 'list', []);
4347
+ return this.parseOrders(row, market);
4348
+ }
4268
4349
  async cancelAllUsdcOrders(symbol = undefined, params = {}) {
4269
4350
  if (symbol === undefined) {
4270
4351
  throw new errors.ArgumentsRequired(this.id + ' cancelAllUsdcOrders() requires a symbol argument');
@@ -7223,7 +7304,8 @@ class bybit extends bybit$1 {
7223
7304
  // }
7224
7305
  //
7225
7306
  const marketId = this.safeString(fee, 'symbol');
7226
- const symbol = this.safeSymbol(marketId, undefined, undefined, 'contract');
7307
+ const defaultType = (market !== undefined) ? market['type'] : 'contract';
7308
+ const symbol = this.safeSymbol(marketId, market, undefined, defaultType);
7227
7309
  return {
7228
7310
  'info': fee,
7229
7311
  'symbol': symbol,
@@ -7243,12 +7325,23 @@ class bybit extends bybit$1 {
7243
7325
  */
7244
7326
  await this.loadMarkets();
7245
7327
  const market = this.market(symbol);
7246
- if (market['spot']) {
7247
- throw new errors.NotSupported(this.id + ' fetchTradingFee() is not supported for spot market');
7248
- }
7249
7328
  const request = {
7250
7329
  'symbol': market['id'],
7251
7330
  };
7331
+ let category = undefined;
7332
+ if (market['linear']) {
7333
+ category = 'linear';
7334
+ }
7335
+ else if (market['inverse']) {
7336
+ category = 'inverse';
7337
+ }
7338
+ else if (market['spot']) {
7339
+ category = 'spot';
7340
+ }
7341
+ else {
7342
+ category = 'option';
7343
+ }
7344
+ request['category'] = category;
7252
7345
  const response = await this.privateGetV5AccountFeeRate(this.extend(request, params));
7253
7346
  //
7254
7347
  // {
@@ -7270,7 +7363,7 @@ class bybit extends bybit$1 {
7270
7363
  const result = this.safeValue(response, 'result', {});
7271
7364
  const fees = this.safeValue(result, 'list', []);
7272
7365
  const first = this.safeValue(fees, 0, {});
7273
- return this.parseTradingFee(first);
7366
+ return this.parseTradingFee(first, market);
7274
7367
  }
7275
7368
  async fetchTradingFees(params = {}) {
7276
7369
  /**
@@ -3721,7 +3721,8 @@ class coinbase extends coinbase$1 {
3721
3721
  sign(path, api = [], method = 'GET', params = {}, headers = undefined, body = undefined) {
3722
3722
  const version = api[0];
3723
3723
  const signed = api[1] === 'private';
3724
- const pathPart = (version === 'v3') ? 'api/v3' : 'v2';
3724
+ const isV3 = version === 'v3';
3725
+ const pathPart = (isV3) ? 'api/v3' : 'v2';
3725
3726
  let fullPath = '/' + pathPart + '/' + this.implodeParams(path, params);
3726
3727
  const query = this.omit(params, this.extractParams(path));
3727
3728
  const savedPath = fullPath;
@@ -3765,8 +3766,17 @@ class coinbase extends coinbase$1 {
3765
3766
  payload = body;
3766
3767
  }
3767
3768
  }
3768
- // 'GET' doesn't need payload in the signature. inside url is enough
3769
+ else {
3770
+ if (!isV3) {
3771
+ if (Object.keys(query).length) {
3772
+ payload += '?' + this.urlencode(query);
3773
+ }
3774
+ }
3775
+ }
3776
+ // v3: 'GET' doesn't need payload in the signature. inside url is enough
3769
3777
  // https://docs.cloud.coinbase.com/advanced-trade-api/docs/auth#example-request
3778
+ // v2: 'GET' require payload in the signature
3779
+ // https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-key-authentication
3770
3780
  const auth = timestampString + method + savedPath + payload;
3771
3781
  const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256.sha256);
3772
3782
  headers = {
@@ -51,7 +51,8 @@ class delta extends delta$1 {
51
51
  'fetchLedger': true,
52
52
  'fetchLeverage': true,
53
53
  'fetchLeverageTiers': false,
54
- 'fetchMarginMode': false,
54
+ 'fetchMarginMode': true,
55
+ 'fetchMarginModes': false,
55
56
  'fetchMarketLeverageTiers': false,
56
57
  'fetchMarkets': true,
57
58
  'fetchMarkOHLCV': true,
@@ -3201,6 +3202,99 @@ class delta extends delta$1 {
3201
3202
  const position = this.parsePosition(this.safeValue(response, 'result', {}));
3202
3203
  return [position];
3203
3204
  }
3205
+ async fetchMarginMode(symbol, params = {}) {
3206
+ /**
3207
+ * @method
3208
+ * @name delta#fetchMarginMode
3209
+ * @description fetches the margin mode of a trading pair
3210
+ * @see https://docs.delta.exchange/#get-user
3211
+ * @param {string} symbol unified symbol of the market to fetch the margin mode for
3212
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3213
+ * @returns {object} a [margin mode structure]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
3214
+ */
3215
+ await this.loadMarkets();
3216
+ let market = undefined;
3217
+ if (symbol !== undefined) {
3218
+ market = this.market(symbol);
3219
+ }
3220
+ const response = await this.privateGetProfile(params);
3221
+ //
3222
+ // {
3223
+ // "result": {
3224
+ // "is_password_set": true,
3225
+ // "kyc_expiry_date": null,
3226
+ // "phishing_code": "12345",
3227
+ // "preferences": {
3228
+ // "favorites": []
3229
+ // },
3230
+ // "is_kyc_provisioned": false,
3231
+ // "country": "Canada",
3232
+ // "margin_mode": "isolated",
3233
+ // "mfa_updated_at": "2023-07-19T01:04:43Z",
3234
+ // "last_name": "",
3235
+ // "oauth_apple_active": false,
3236
+ // "pf_index_symbol": null,
3237
+ // "proof_of_identity_status": "approved",
3238
+ // "dob": null,
3239
+ // "email": "abc_123@gmail.com",
3240
+ // "force_change_password": false,
3241
+ // "nick_name": "still-breeze-123",
3242
+ // "oauth_google_active": false,
3243
+ // "phone_verification_status": "verified",
3244
+ // "id": 12345678,
3245
+ // "last_seen": null,
3246
+ // "is_withdrawal_enabled": true,
3247
+ // "force_change_mfa": false,
3248
+ // "enable_bots": false,
3249
+ // "kyc_verified_on": null,
3250
+ // "created_at": "2023-07-19T01:02:32Z",
3251
+ // "withdrawal_blocked_till": null,
3252
+ // "proof_of_address_status": "approved",
3253
+ // "is_password_change_blocked": false,
3254
+ // "is_mfa_enabled": true,
3255
+ // "is_kyc_done": true,
3256
+ // "oauth": null,
3257
+ // "account_name": "Main",
3258
+ // "sub_account_permissions": null,
3259
+ // "phone_number": null,
3260
+ // "tracking_info": {
3261
+ // "ga_cid": "1234.4321",
3262
+ // "is_kyc_gtm_tracked": true,
3263
+ // "sub_account_config": {
3264
+ // "cross": 2,
3265
+ // "isolated": 2,
3266
+ // "portfolio": 2
3267
+ // }
3268
+ // },
3269
+ // "first_name": "",
3270
+ // "phone_verified_on": null,
3271
+ // "seen_intro": false,
3272
+ // "password_updated_at": null,
3273
+ // "is_login_enabled": true,
3274
+ // "registration_date": "2023-07-19T01:02:32Z",
3275
+ // "permissions": {},
3276
+ // "max_sub_accounts_limit": 2,
3277
+ // "country_calling_code": null,
3278
+ // "is_sub_account": false,
3279
+ // "is_kyc_refresh_required": false
3280
+ // },
3281
+ // "success": true
3282
+ // }
3283
+ //
3284
+ const result = this.safeDict(response, 'result', {});
3285
+ return this.parseMarginMode(result, market);
3286
+ }
3287
+ parseMarginMode(marginMode, market = undefined) {
3288
+ let symbol = undefined;
3289
+ if (market !== undefined) {
3290
+ symbol = market['symbol'];
3291
+ }
3292
+ return {
3293
+ 'info': marginMode,
3294
+ 'symbol': symbol,
3295
+ 'marginMode': this.safeString(marginMode, 'margin_mode'),
3296
+ };
3297
+ }
3204
3298
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3205
3299
  const requestPath = '/' + this.version + '/' + this.implodeParams(path, params);
3206
3300
  let url = this.urls['api'][api] + requestPath;
@@ -262,12 +262,12 @@ class gemini extends gemini$1 {
262
262
  'webApiEnable': true,
263
263
  'webApiRetries': 10,
264
264
  },
265
+ 'fetchUsdtMarkets': ['btcusdt', 'ethusdt'],
265
266
  'fetchCurrencies': {
266
267
  'webApiEnable': true,
267
268
  'webApiRetries': 5,
268
269
  'webApiMuteFailure': true,
269
270
  },
270
- 'fetchUsdtMarkets': ['btcusdt', 'ethusdt'],
271
271
  'fetchTickerMethod': 'fetchTickerV1',
272
272
  'networks': {
273
273
  'BTC': 'bitcoin',
@@ -406,9 +406,11 @@ class gemini extends gemini$1 {
406
406
  */
407
407
  const method = this.safeValue(this.options, 'fetchMarketsMethod', 'fetch_markets_from_api');
408
408
  if (method === 'fetch_markets_from_web') {
409
- const usdMarkets = await this.fetchMarketsFromWeb(params); // get usd markets
410
- const usdtMarkets = await this.fetchUSDTMarkets(params); // get usdt markets
411
- return this.arrayConcat(usdMarkets, usdtMarkets);
409
+ const promises = [];
410
+ promises.push(this.fetchMarketsFromWeb(params)); // get usd markets
411
+ promises.push(this.fetchUSDTMarkets(params)); // get usdt markets
412
+ const promisesResult = await Promise.all(promises);
413
+ return this.arrayConcat(promisesResult[0], promisesResult[1]);
412
414
  }
413
415
  return await this.fetchMarketsFromAPI(params);
414
416
  }
@@ -516,6 +518,9 @@ class gemini extends gemini$1 {
516
518
  'post_only': true,
517
519
  'limit_only': true,
518
520
  };
521
+ if (status === undefined) {
522
+ return true; // as defaulted below
523
+ }
519
524
  return this.safeBool(statuses, status, true);
520
525
  }
521
526
  async fetchUSDTMarkets(params = {}) {
@@ -2517,7 +2517,7 @@ class hitbtc extends hitbtc$1 {
2517
2517
  * @see https://api.hitbtc.com/#get-futures-position-parameters
2518
2518
  * @param {string} symbol unified symbol of the market the order was made in
2519
2519
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2520
- * @returns {object} Struct of MarginMode
2520
+ * @returns {object} a list of [margin mode structures]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
2521
2521
  */
2522
2522
  await this.loadMarkets();
2523
2523
  let market = undefined;
@@ -146,6 +146,7 @@ class krakenfutures extends krakenfutures$1 {
146
146
  'executions',
147
147
  'triggers',
148
148
  'accountlogcsv',
149
+ 'account-log',
149
150
  'market/{symbol}/orders',
150
151
  'market/{symbol}/executions',
151
152
  ],