ccxt 4.4.93 → 4.4.94

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.
@@ -345,6 +345,9 @@ export default class hyperliquid extends Exchange {
345
345
  * @returns {object} an associative dictionary of currencies
346
346
  */
347
347
  async fetchCurrencies(params = {}) {
348
+ if (this.checkRequiredCredentials(false)) {
349
+ await this.handleBuilderFeeApproval();
350
+ }
348
351
  const request = {
349
352
  'type': 'meta',
350
353
  };
@@ -625,6 +628,7 @@ export default class hyperliquid extends Exchange {
625
628
  'quote': quote,
626
629
  'settle': undefined,
627
630
  'baseId': baseId,
631
+ 'baseName': baseName,
628
632
  'quoteId': quoteId,
629
633
  'settleId': undefined,
630
634
  'type': 'spot',
@@ -732,6 +736,7 @@ export default class hyperliquid extends Exchange {
732
736
  'quote': quote,
733
737
  'settle': settle,
734
738
  'baseId': baseId,
739
+ 'baseName': baseName,
735
740
  'quoteId': quoteId,
736
741
  'settleId': settleId,
737
742
  'type': 'swap',
@@ -787,6 +792,7 @@ export default class hyperliquid extends Exchange {
787
792
  * @param {string} [params.user] user address, will default to this.walletAddress if not provided
788
793
  * @param {string} [params.type] wallet type, ['spot', 'swap'], defaults to swap
789
794
  * @param {string} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null
795
+ * @param {string} [params.subAccountAddress] sub account user address
790
796
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
791
797
  */
792
798
  async fetchBalance(params = {}) {
@@ -797,9 +803,8 @@ export default class hyperliquid extends Exchange {
797
803
  let marginMode = undefined;
798
804
  [marginMode, params] = this.handleMarginModeAndParams('fetchBalance', params);
799
805
  const isSpot = (type === 'spot');
800
- const reqType = (isSpot) ? 'spotClearinghouseState' : 'clearinghouseState';
801
806
  const request = {
802
- 'type': reqType,
807
+ 'type': (isSpot) ? 'spotClearinghouseState' : 'clearinghouseState',
803
808
  'user': userAddress,
804
809
  };
805
810
  const response = await this.publicPostInfo(this.extend(request, params));
@@ -887,7 +892,7 @@ export default class hyperliquid extends Exchange {
887
892
  const market = this.market(symbol);
888
893
  const request = {
889
894
  'type': 'l2Book',
890
- 'coin': market['swap'] ? market['base'] : market['id'],
895
+ 'coin': market['swap'] ? market['baseName'] : market['id'],
891
896
  };
892
897
  const response = await this.publicPostInfo(this.extend(request, params));
893
898
  //
@@ -1125,7 +1130,7 @@ export default class hyperliquid extends Exchange {
1125
1130
  const request = {
1126
1131
  'type': 'candleSnapshot',
1127
1132
  'req': {
1128
- 'coin': market['swap'] ? market['base'] : market['id'],
1133
+ 'coin': market['swap'] ? market['baseName'] : market['id'],
1129
1134
  'interval': this.safeString(this.timeframes, timeframe, timeframe),
1130
1135
  'startTime': since,
1131
1136
  'endTime': until,
@@ -1187,6 +1192,7 @@ export default class hyperliquid extends Exchange {
1187
1192
  * @param {int} [params.until] timestamp in ms of the latest trade
1188
1193
  * @param {string} [params.address] wallet address that made trades
1189
1194
  * @param {string} [params.user] wallet address that made trades
1195
+ * @param {string} [params.subAccountAddress] sub account user address
1190
1196
  * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1191
1197
  */
1192
1198
  async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
@@ -1371,6 +1377,71 @@ export default class hyperliquid extends Exchange {
1371
1377
  };
1372
1378
  return this.signUserSignedAction(messageTypes, message);
1373
1379
  }
1380
+ buildApproveBuilderFeeSig(message) {
1381
+ const messageTypes = {
1382
+ 'HyperliquidTransaction:ApproveBuilderFee': [
1383
+ { 'name': 'hyperliquidChain', 'type': 'string' },
1384
+ { 'name': 'maxFeeRate', 'type': 'string' },
1385
+ { 'name': 'builder', 'type': 'address' },
1386
+ { 'name': 'nonce', 'type': 'uint64' },
1387
+ ],
1388
+ };
1389
+ return this.signUserSignedAction(messageTypes, message);
1390
+ }
1391
+ async approveBuilderFee(builder, maxFeeRate) {
1392
+ const nonce = this.milliseconds();
1393
+ const isSandboxMode = this.safeBool(this.options, 'sandboxMode', false);
1394
+ const payload = {
1395
+ 'hyperliquidChain': isSandboxMode ? 'Testnet' : 'Mainnet',
1396
+ 'maxFeeRate': maxFeeRate,
1397
+ 'builder': builder,
1398
+ 'nonce': nonce,
1399
+ };
1400
+ const sig = this.buildApproveBuilderFeeSig(payload);
1401
+ const action = {
1402
+ 'hyperliquidChain': payload['hyperliquidChain'],
1403
+ 'signatureChainId': '0x66eee',
1404
+ 'maxFeeRate': payload['maxFeeRate'],
1405
+ 'builder': payload['builder'],
1406
+ 'nonce': nonce,
1407
+ 'type': 'approveBuilderFee',
1408
+ };
1409
+ const request = {
1410
+ 'action': action,
1411
+ 'nonce': nonce,
1412
+ 'signature': sig,
1413
+ 'vaultAddress': undefined,
1414
+ };
1415
+ //
1416
+ // {
1417
+ // "status": "ok",
1418
+ // "response": {
1419
+ // "type": "default"
1420
+ // }
1421
+ // }
1422
+ //
1423
+ return await this.privatePostExchange(request);
1424
+ }
1425
+ async handleBuilderFeeApproval() {
1426
+ const buildFee = this.safeBool(this.options, 'builderFee', true);
1427
+ if (!buildFee) {
1428
+ return false; // skip if builder fee is not enabled
1429
+ }
1430
+ const approvedBuilderFee = this.safeBool(this.options, 'approvedBuilderFee', false);
1431
+ if (approvedBuilderFee) {
1432
+ return true; // skip if builder fee is already approved
1433
+ }
1434
+ try {
1435
+ const builder = this.safeString(this.options, 'builder', '0x6530512A6c89C7cfCEbC3BA7fcD9aDa5f30827a6');
1436
+ const maxFeeRate = this.safeString(this.options, 'feeRate', '0.01%');
1437
+ await this.approveBuilderFee(builder, maxFeeRate);
1438
+ this.options['approvedBuilderFee'] = true;
1439
+ }
1440
+ catch (e) {
1441
+ this.options['builderFee'] = false; // disable builder fee if an error occurs
1442
+ }
1443
+ return true;
1444
+ }
1374
1445
  /**
1375
1446
  * @method
1376
1447
  * @name hyperliquid#createOrder
@@ -1389,6 +1460,7 @@ export default class hyperliquid extends Exchange {
1389
1460
  * @param {string} [params.clientOrderId] client order id, (optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
1390
1461
  * @param {string} [params.slippage] the slippage for market order
1391
1462
  * @param {string} [params.vaultAddress] the vault address for order
1463
+ * @param {string} [params.subAccountAddress] sub account user address
1392
1464
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1393
1465
  */
1394
1466
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
@@ -1408,6 +1480,7 @@ export default class hyperliquid extends Exchange {
1408
1480
  */
1409
1481
  async createOrders(orders, params = {}) {
1410
1482
  await this.loadMarkets();
1483
+ await this.handleBuilderFeeApproval();
1411
1484
  const request = this.createOrdersRequest(orders, params);
1412
1485
  const response = await this.privatePostExchange(request);
1413
1486
  //
@@ -1593,10 +1666,10 @@ export default class hyperliquid extends Exchange {
1593
1666
  'type': 'order',
1594
1667
  'orders': orderReq,
1595
1668
  'grouping': grouping,
1596
- // 'brokerCode': 1, // cant
1597
1669
  };
1598
- if (vaultAddress === undefined) {
1599
- orderAction['brokerCode'] = 1;
1670
+ if (this.safeBool(this.options, 'approvedBuilderFee', false)) {
1671
+ const wallet = this.safeStringLower(this.options, 'builder', '0x6530512A6c89C7cfCEbC3BA7fcD9aDa5f30827a6');
1672
+ orderAction['builder'] = { 'b': wallet, 'f': this.safeInteger(this.options, 'feeInt', 10) };
1600
1673
  }
1601
1674
  const signature = this.signL1Action(orderAction, nonce, vaultAddress);
1602
1675
  const request = {
@@ -1622,6 +1695,7 @@ export default class hyperliquid extends Exchange {
1622
1695
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1623
1696
  * @param {string} [params.clientOrderId] client order id, (optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
1624
1697
  * @param {string} [params.vaultAddress] the vault address for order
1698
+ * @param {string} [params.subAccountAddress] sub account user address
1625
1699
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1626
1700
  */
1627
1701
  async cancelOrder(id, symbol = undefined, params = {}) {
@@ -1639,6 +1713,7 @@ export default class hyperliquid extends Exchange {
1639
1713
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1640
1714
  * @param {string|string[]} [params.clientOrderId] client order ids, (optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
1641
1715
  * @param {string} [params.vaultAddress] the vault address
1716
+ * @param {string} [params.subAccountAddress] sub account user address
1642
1717
  * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1643
1718
  */
1644
1719
  async cancelOrders(ids, symbol = undefined, params = {}) {
@@ -1684,7 +1759,7 @@ export default class hyperliquid extends Exchange {
1684
1759
  }
1685
1760
  cancelAction['cancels'] = cancelReq;
1686
1761
  let vaultAddress = undefined;
1687
- [vaultAddress, params] = this.handleOptionAndParams(params, 'cancelOrders', 'vaultAddress');
1762
+ [vaultAddress, params] = this.handleOptionAndParams2(params, 'cancelOrders', 'vaultAddress', 'subAccountAddress');
1688
1763
  vaultAddress = this.formatVaultAddress(vaultAddress);
1689
1764
  const signature = this.signL1Action(cancelAction, nonce, vaultAddress);
1690
1765
  request['action'] = cancelAction;
@@ -1729,6 +1804,7 @@ export default class hyperliquid extends Exchange {
1729
1804
  * @param {CancellationRequest[]} orders each order should contain the parameters required by cancelOrder namely id and symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
1730
1805
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1731
1806
  * @param {string} [params.vaultAddress] the vault address
1807
+ * @param {string} [params.subAccountAddress] sub account user address
1732
1808
  * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1733
1809
  */
1734
1810
  async cancelOrdersForSymbols(orders, params = {}) {
@@ -1770,7 +1846,7 @@ export default class hyperliquid extends Exchange {
1770
1846
  cancelAction['type'] = cancelByCloid ? 'cancelByCloid' : 'cancel';
1771
1847
  cancelAction['cancels'] = cancelReq;
1772
1848
  let vaultAddress = undefined;
1773
- [vaultAddress, params] = this.handleOptionAndParams(params, 'cancelOrdersForSymbols', 'vaultAddress');
1849
+ [vaultAddress, params] = this.handleOptionAndParams2(params, 'cancelOrdersForSymbols', 'vaultAddress', 'subAccountAddress');
1774
1850
  vaultAddress = this.formatVaultAddress(vaultAddress);
1775
1851
  const signature = this.signL1Action(cancelAction, nonce, vaultAddress);
1776
1852
  request['action'] = cancelAction;
@@ -1802,6 +1878,7 @@ export default class hyperliquid extends Exchange {
1802
1878
  * @param {number} timeout time in milliseconds, 0 represents cancel the timer
1803
1879
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1804
1880
  * @param {string} [params.vaultAddress] the vault address
1881
+ * @param {string} [params.subAccountAddress] sub account user address
1805
1882
  * @returns {object} the api result
1806
1883
  */
1807
1884
  async cancelAllOrdersAfter(timeout, params = {}) {
@@ -1818,7 +1895,7 @@ export default class hyperliquid extends Exchange {
1818
1895
  'time': nonce + timeout,
1819
1896
  };
1820
1897
  let vaultAddress = undefined;
1821
- [vaultAddress, params] = this.handleOptionAndParams(params, 'cancelAllOrdersAfter', 'vaultAddress');
1898
+ [vaultAddress, params] = this.handleOptionAndParams2(params, 'cancelAllOrdersAfter', 'vaultAddress', 'subAccountAddress');
1822
1899
  vaultAddress = this.formatVaultAddress(vaultAddress);
1823
1900
  const signature = this.signL1Action(cancelAction, nonce, vaultAddress);
1824
1901
  request['action'] = cancelAction;
@@ -1977,6 +2054,7 @@ export default class hyperliquid extends Exchange {
1977
2054
  * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
1978
2055
  * @param {string} [params.clientOrderId] client order id, (optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
1979
2056
  * @param {string} [params.vaultAddress] the vault address for order
2057
+ * @param {string} [params.subAccountAddress] sub account user address
1980
2058
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1981
2059
  */
1982
2060
  async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
@@ -2101,7 +2179,7 @@ export default class hyperliquid extends Exchange {
2101
2179
  const market = this.market(symbol);
2102
2180
  const request = {
2103
2181
  'type': 'fundingHistory',
2104
- 'coin': market['base'],
2182
+ 'coin': market['baseName'],
2105
2183
  };
2106
2184
  if (since !== undefined) {
2107
2185
  request['startTime'] = since;
@@ -2152,6 +2230,7 @@ export default class hyperliquid extends Exchange {
2152
2230
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2153
2231
  * @param {string} [params.user] user address, will default to this.walletAddress if not provided
2154
2232
  * @param {string} [params.method] 'openOrders' or 'frontendOpenOrders' default is 'frontendOpenOrders'
2233
+ * @param {string} [params.subAccountAddress] sub account user address
2155
2234
  * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2156
2235
  */
2157
2236
  async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -2250,6 +2329,7 @@ export default class hyperliquid extends Exchange {
2250
2329
  * @param {int} [limit] the maximum number of open orders structures to retrieve
2251
2330
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2252
2331
  * @param {string} [params.user] user address, will default to this.walletAddress if not provided
2332
+ * @param {string} [params.subAccountAddress] sub account user address
2253
2333
  * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2254
2334
  */
2255
2335
  async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -2286,6 +2366,7 @@ export default class hyperliquid extends Exchange {
2286
2366
  * @param {string} symbol unified symbol of the market the order was made in
2287
2367
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2288
2368
  * @param {string} [params.user] user address, will default to this.walletAddress if not provided
2369
+ * @param {string} [params.subAccountAddress] sub account user address
2289
2370
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2290
2371
  */
2291
2372
  async fetchOrder(id, symbol = undefined, params = {}) {
@@ -2518,6 +2599,7 @@ export default class hyperliquid extends Exchange {
2518
2599
  * @param {int} [limit] the maximum number of trades structures to retrieve
2519
2600
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2520
2601
  * @param {int} [params.until] timestamp in ms of the latest trade
2602
+ * @param {string} [params.subAccountAddress] sub account user address
2521
2603
  * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
2522
2604
  */
2523
2605
  async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -2643,6 +2725,7 @@ export default class hyperliquid extends Exchange {
2643
2725
  * @param {string[]} [symbols] list of unified market symbols
2644
2726
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2645
2727
  * @param {string} [params.user] user address, will default to this.walletAddress if not provided
2728
+ * @param {string} [params.subAccountAddress] sub account user address
2646
2729
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
2647
2730
  */
2648
2731
  async fetchPositions(symbols = undefined, params = {}) {
@@ -2787,6 +2870,8 @@ export default class hyperliquid extends Exchange {
2787
2870
  * @param {string} symbol unified market symbol of the market the position is held in, default is undefined
2788
2871
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2789
2872
  * @param {string} [params.leverage] the rate of leverage, is required if setting trade mode (symbol)
2873
+ * @param {string} [params.vaultAddress] the vault address
2874
+ * @param {string} [params.subAccountAddress] sub account user address
2790
2875
  * @returns {object} response from the exchange
2791
2876
  */
2792
2877
  async setMarginMode(marginMode, symbol = undefined, params = {}) {
@@ -2810,7 +2895,7 @@ export default class hyperliquid extends Exchange {
2810
2895
  'leverage': leverage,
2811
2896
  };
2812
2897
  let vaultAddress = undefined;
2813
- [vaultAddress, params] = this.handleOptionAndParams(params, 'setMarginMode', 'vaultAddress');
2898
+ [vaultAddress, params] = this.handleOptionAndParams2(params, 'setMarginMode', 'vaultAddress', 'subAccountAddress');
2814
2899
  if (vaultAddress !== undefined) {
2815
2900
  if (vaultAddress.startsWith('0x')) {
2816
2901
  vaultAddress = vaultAddress.replace('0x', '');
@@ -2865,7 +2950,7 @@ export default class hyperliquid extends Exchange {
2865
2950
  'leverage': leverage,
2866
2951
  };
2867
2952
  let vaultAddress = undefined;
2868
- [vaultAddress, params] = this.handleOptionAndParams(params, 'setLeverage', 'vaultAddress');
2953
+ [vaultAddress, params] = this.handleOptionAndParams2(params, 'setLeverage', 'vaultAddress', 'subAccountAddress');
2869
2954
  vaultAddress = this.formatVaultAddress(vaultAddress);
2870
2955
  const signature = this.signL1Action(updateAction, nonce, vaultAddress);
2871
2956
  const request = {
@@ -2897,6 +2982,8 @@ export default class hyperliquid extends Exchange {
2897
2982
  * @param {string} symbol unified market symbol
2898
2983
  * @param {float} amount amount of margin to add
2899
2984
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2985
+ * @param {string} [params.vaultAddress] the vault address
2986
+ * @param {string} [params.subAccountAddress] sub account user address
2900
2987
  * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure}
2901
2988
  */
2902
2989
  async addMargin(symbol, amount, params = {}) {
@@ -2910,6 +2997,8 @@ export default class hyperliquid extends Exchange {
2910
2997
  * @param {string} symbol unified market symbol
2911
2998
  * @param {float} amount the amount of margin to remove
2912
2999
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3000
+ * @param {string} [params.vaultAddress] the vault address
3001
+ * @param {string} [params.subAccountAddress] sub account user address
2913
3002
  * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=reduce-margin-structure}
2914
3003
  */
2915
3004
  async reduceMargin(symbol, amount, params = {}) {
@@ -2931,7 +3020,7 @@ export default class hyperliquid extends Exchange {
2931
3020
  'ntli': sz,
2932
3021
  };
2933
3022
  let vaultAddress = undefined;
2934
- [vaultAddress, params] = this.handleOptionAndParams(params, 'modifyMargin', 'vaultAddress');
3023
+ [vaultAddress, params] = this.handleOptionAndParams2(params, 'modifyMargin', 'vaultAddress', 'subAccountAddress');
2935
3024
  vaultAddress = this.formatVaultAddress(vaultAddress);
2936
3025
  const signature = this.signL1Action(updateAction, nonce, vaultAddress);
2937
3026
  const request = {
@@ -3031,30 +3120,36 @@ export default class hyperliquid extends Exchange {
3031
3120
  const transferResponse = await this.privatePostExchange(transferRequest);
3032
3121
  return transferResponse;
3033
3122
  }
3034
- // handle sub-account/different account transfer
3035
- this.checkAddress(toAccount);
3123
+ // transfer between main account and subaccount
3036
3124
  if (code !== undefined) {
3037
3125
  code = code.toUpperCase();
3038
3126
  if (code !== 'USDC') {
3039
3127
  throw new NotSupported(this.id + ' transfer() only support USDC');
3040
3128
  }
3041
3129
  }
3042
- const payload = {
3043
- 'hyperliquidChain': isSandboxMode ? 'Testnet' : 'Mainnet',
3044
- 'destination': toAccount,
3045
- 'amount': this.numberToString(amount),
3046
- 'time': nonce,
3130
+ let isDeposit = false;
3131
+ let subAccountAddress = undefined;
3132
+ if (fromAccount === 'main') {
3133
+ subAccountAddress = toAccount;
3134
+ isDeposit = true;
3135
+ }
3136
+ else if (toAccount === 'main') {
3137
+ subAccountAddress = fromAccount;
3138
+ }
3139
+ else {
3140
+ throw new NotSupported(this.id + ' transfer() only support main <> subaccount transfer');
3141
+ }
3142
+ this.checkAddress(subAccountAddress);
3143
+ const usd = this.parseToInt(Precise.stringMul(this.numberToString(amount), '1000000'));
3144
+ const action = {
3145
+ 'type': 'subAccountTransfer',
3146
+ 'subAccountUser': subAccountAddress,
3147
+ 'isDeposit': isDeposit,
3148
+ 'usd': usd,
3047
3149
  };
3048
- const sig = this.buildUsdSendSig(payload);
3150
+ const sig = this.signL1Action(action, nonce);
3049
3151
  const request = {
3050
- 'action': {
3051
- 'hyperliquidChain': payload['hyperliquidChain'],
3052
- 'signatureChainId': '0x66eee',
3053
- 'destination': toAccount,
3054
- 'amount': amount.toString(),
3055
- 'time': nonce,
3056
- 'type': 'usdSend',
3057
- },
3152
+ 'action': action,
3058
3153
  'nonce': nonce,
3059
3154
  'signature': sig,
3060
3155
  };
@@ -3206,6 +3301,7 @@ export default class hyperliquid extends Exchange {
3206
3301
  * @param {string} symbol unified market symbol
3207
3302
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3208
3303
  * @param {string} [params.user] user address, will default to this.walletAddress if not provided
3304
+ * @param {string} [params.subAccountAddress] sub account user address
3209
3305
  * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
3210
3306
  */
3211
3307
  async fetchTradingFee(symbol, params = {}) {
@@ -3314,6 +3410,7 @@ export default class hyperliquid extends Exchange {
3314
3410
  * @param {int} [limit] max number of ledger entries to return
3315
3411
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3316
3412
  * @param {int} [params.until] timestamp in ms of the latest ledger entry
3413
+ * @param {string} [params.subAccountAddress] sub account user address
3317
3414
  * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
3318
3415
  */
3319
3416
  async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
@@ -3406,6 +3503,7 @@ export default class hyperliquid extends Exchange {
3406
3503
  * @param {int} [limit] the maximum number of deposits structures to retrieve
3407
3504
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3408
3505
  * @param {int} [params.until] the latest time in ms to fetch withdrawals for
3506
+ * @param {string} [params.subAccountAddress] sub account user address
3409
3507
  * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
3410
3508
  */
3411
3509
  async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
@@ -3451,6 +3549,7 @@ export default class hyperliquid extends Exchange {
3451
3549
  * @param {int} [limit] the maximum number of withdrawals structures to retrieve
3452
3550
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3453
3551
  * @param {int} [params.until] the latest time in ms to fetch withdrawals for
3552
+ * @param {string} [params.subAccountAddress] sub account user address
3454
3553
  * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
3455
3554
  */
3456
3555
  async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
@@ -3557,6 +3656,7 @@ export default class hyperliquid extends Exchange {
3557
3656
  * @param {int} [since] the earliest time in ms to fetch funding history for
3558
3657
  * @param {int} [limit] the maximum number of funding history structures to retrieve
3559
3658
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3659
+ * @param {string} [params.subAccountAddress] sub account user address
3560
3660
  * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure}
3561
3661
  */
3562
3662
  async fetchFundingHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -3654,7 +3754,7 @@ export default class hyperliquid extends Exchange {
3654
3754
  }
3655
3755
  handlePublicAddress(methodName, params) {
3656
3756
  let userAux = undefined;
3657
- [userAux, params] = this.handleOptionAndParams(params, methodName, 'user');
3757
+ [userAux, params] = this.handleOptionAndParams2(params, methodName, 'user', 'subAccountAddress');
3658
3758
  let user = userAux;
3659
3759
  [user, params] = this.handleOptionAndParams(params, methodName, 'address', userAux);
3660
3760
  if ((user !== undefined) && (user !== '')) {
@@ -3733,7 +3833,7 @@ export default class hyperliquid extends Exchange {
3733
3833
  parseCreateEditOrderArgs(id, symbol, type, side, amount, price = undefined, params = {}) {
3734
3834
  const market = this.market(symbol);
3735
3835
  let vaultAddress = undefined;
3736
- [vaultAddress, params] = this.handleOptionAndParams(params, 'createOrder', 'vaultAddress');
3836
+ [vaultAddress, params] = this.handleOptionAndParams2(params, 'createOrder', 'vaultAddress', 'subAccountAddress');
3737
3837
  vaultAddress = this.formatVaultAddress(vaultAddress);
3738
3838
  symbol = market['symbol'];
3739
3839
  const order = {
package/js/src/okx.js CHANGED
@@ -2604,12 +2604,12 @@ export default class okx extends Exchange {
2604
2604
  // it may be incorrect to use total, free and used for swap accounts
2605
2605
  const eq = this.safeString(balance, 'eq');
2606
2606
  const availEq = this.safeString(balance, 'availEq');
2607
- if ((eq === undefined) || (availEq === undefined)) {
2607
+ account['total'] = eq;
2608
+ if (availEq === undefined) {
2608
2609
  account['free'] = this.safeString(balance, 'availBal');
2609
2610
  account['used'] = this.safeString(balance, 'frozenBal');
2610
2611
  }
2611
2612
  else {
2612
- account['total'] = eq;
2613
2613
  account['free'] = availEq;
2614
2614
  }
2615
2615
  result[code] = account;
@@ -2881,7 +2881,7 @@ export default class okx extends Exchange {
2881
2881
  }
2882
2882
  createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
2883
2883
  const market = this.market(symbol);
2884
- const request = {
2884
+ let request = {
2885
2885
  'instId': market['id'],
2886
2886
  // 'ccy': currency['id'], // only applicable to cross MARGIN orders in single-currency margin
2887
2887
  // 'clOrdId': clientOrderId, // up to 32 characters, must be unique
@@ -3046,7 +3046,8 @@ export default class okx extends Exchange {
3046
3046
  if (stopLossTriggerPrice === undefined) {
3047
3047
  throw new InvalidOrder(this.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"], or params["stopLoss"]["stopPrice"], or params["stopLoss"]["slTriggerPx"] for a stop loss order');
3048
3048
  }
3049
- request['slTriggerPx'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
3049
+ const slTriggerPx = this.priceToPrecision(symbol, stopLossTriggerPrice);
3050
+ request['slTriggerPx'] = slTriggerPx;
3050
3051
  const stopLossLimitPrice = this.safeValueN(stopLoss, ['price', 'stopLossPrice', 'slOrdPx']);
3051
3052
  const stopLossOrderType = this.safeString(stopLoss, 'type');
3052
3053
  if (stopLossOrderType !== undefined) {
@@ -3138,6 +3139,14 @@ export default class okx extends Exchange {
3138
3139
  if (twoWayCondition) {
3139
3140
  request['ordType'] = 'oco';
3140
3141
  }
3142
+ if (side === 'sell') {
3143
+ request = this.omit(request, 'tgtCcy');
3144
+ }
3145
+ if (this.safeString(request, 'tdMode') === 'cash') {
3146
+ // for some reason tdMode = cash throws
3147
+ // {"code":"1","data":[{"algoClOrdId":"","algoId":"","clOrdId":"","sCode":"51000","sMsg":"Parameter tdMode error ","tag":""}],"msg":""}
3148
+ request['tdMode'] = marginMode;
3149
+ }
3141
3150
  if (takeProfitPrice !== undefined) {
3142
3151
  request['tpTriggerPx'] = this.priceToPrecision(symbol, takeProfitPrice);
3143
3152
  let tpOrdPxReq = '-1';
package/js/src/paradex.js CHANGED
@@ -57,6 +57,7 @@ export default class paradex extends Exchange {
57
57
  'createTriggerOrder': true,
58
58
  'editOrder': false,
59
59
  'fetchAccounts': false,
60
+ 'fetchAllGreeks': true,
60
61
  'fetchBalance': true,
61
62
  'fetchBorrowInterest': false,
62
63
  'fetchBorrowRateHistories': false,
@@ -76,7 +77,6 @@ export default class paradex extends Exchange {
76
77
  'fetchFundingRateHistory': false,
77
78
  'fetchFundingRates': false,
78
79
  'fetchGreeks': true,
79
- 'fetchAllGreeks': true,
80
80
  'fetchIndexOHLCV': false,
81
81
  'fetchIsolatedBorrowRate': false,
82
82
  'fetchIsolatedBorrowRates': false,
@@ -2322,13 +2322,26 @@ export default class wavesexchange extends Exchange {
2322
2322
  const order1 = this.safeValue(data, 'order1');
2323
2323
  const order2 = this.safeValue(data, 'order2');
2324
2324
  let order = undefined;
2325
- // order2 arrived after order1
2325
+ // at first, detect if response is from `fetch_my_trades`
2326
2326
  if (this.safeString(order1, 'senderPublicKey') === this.apiKey) {
2327
2327
  order = order1;
2328
2328
  }
2329
- else {
2329
+ else if (this.safeString(order2, 'senderPublicKey') === this.apiKey) {
2330
2330
  order = order2;
2331
2331
  }
2332
+ else {
2333
+ // response is from `fetch_trades`, so find only taker order
2334
+ const date1 = this.safeString(order1, 'timestamp');
2335
+ const date2 = this.safeString(order2, 'timestamp');
2336
+ const ts1 = this.parse8601(date1);
2337
+ const ts2 = this.parse8601(date2);
2338
+ if (ts1 > ts2) {
2339
+ order = order1;
2340
+ }
2341
+ else {
2342
+ order = order2;
2343
+ }
2344
+ }
2332
2345
  let symbol = undefined;
2333
2346
  const assetPair = this.safeValue(order, 'assetPair');
2334
2347
  if (assetPair !== undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.4.93",
3
+ "version": "4.4.94",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.min.js",
6
6
  "type": "module",