ccxt 4.4.62 → 4.4.64
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/README.md +3 -3
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +10 -4
- package/dist/cjs/src/binance.js +4 -4
- package/dist/cjs/src/bingx.js +1 -1
- package/dist/cjs/src/bitmart.js +145 -54
- package/dist/cjs/src/bybit.js +5 -5
- package/dist/cjs/src/gate.js +109 -155
- package/dist/cjs/src/phemex.js +18 -12
- package/dist/cjs/src/pro/bitmart.js +67 -55
- package/dist/cjs/src/pro/bitopro.js +1 -1
- package/dist/cjs/src/pro/gate.js +5 -0
- package/dist/cjs/src/pro/vertex.js +5 -0
- package/dist/cjs/src/tradeogre.js +3 -3
- package/dist/cjs/src/whitebit.js +2 -4
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/binance.d.ts +1 -0
- package/js/src/abstract/binancecoinm.d.ts +1 -0
- package/js/src/abstract/binanceus.d.ts +1 -0
- package/js/src/abstract/binanceusdm.d.ts +1 -0
- package/js/src/abstract/bitmart.d.ts +4 -0
- package/js/src/base/Exchange.js +10 -4
- package/js/src/binance.js +4 -4
- package/js/src/bingx.js +1 -1
- package/js/src/bitmart.d.ts +36 -34
- package/js/src/bitmart.js +145 -54
- package/js/src/bybit.js +5 -5
- package/js/src/gate.d.ts +16 -0
- package/js/src/gate.js +110 -156
- package/js/src/phemex.js +18 -12
- package/js/src/pro/bitmart.js +67 -55
- package/js/src/pro/bitopro.js +1 -1
- package/js/src/pro/gate.js +5 -0
- package/js/src/pro/vertex.js +5 -0
- package/js/src/tradeogre.js +3 -3
- package/js/src/whitebit.js +2 -4
- package/package.json +1 -1
package/js/src/gate.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import Exchange from './abstract/gate.js';
|
|
9
9
|
import { Precise } from './base/Precise.js';
|
|
10
10
|
import { TICK_SIZE } from './base/functions/number.js';
|
|
11
|
-
import { ExchangeError, BadRequest, ArgumentsRequired, AuthenticationError, PermissionDenied, AccountSuspended, InsufficientFunds, RateLimitExceeded, ExchangeNotAvailable, BadSymbol, InvalidOrder, OrderNotFound, NotSupported, AccountNotEnabled, OrderImmediatelyFillable
|
|
11
|
+
import { ExchangeError, BadRequest, ArgumentsRequired, AuthenticationError, PermissionDenied, AccountSuspended, InsufficientFunds, RateLimitExceeded, ExchangeNotAvailable, BadSymbol, InvalidOrder, OrderNotFound, NotSupported, AccountNotEnabled, OrderImmediatelyFillable } from './base/errors.js';
|
|
12
12
|
import { sha512 } from './static_dependencies/noble-hashes/sha512.js';
|
|
13
13
|
/**
|
|
14
14
|
* @class gate
|
|
@@ -1829,103 +1829,83 @@ export default class gate extends Exchange {
|
|
|
1829
1829
|
}
|
|
1830
1830
|
const response = await this.publicSpotGetCurrencies(params);
|
|
1831
1831
|
//
|
|
1832
|
-
//
|
|
1833
|
-
//
|
|
1834
|
-
//
|
|
1835
|
-
//
|
|
1836
|
-
//
|
|
1837
|
-
//
|
|
1838
|
-
//
|
|
1839
|
-
//
|
|
1840
|
-
//
|
|
1841
|
-
//
|
|
1842
|
-
//
|
|
1843
|
-
//
|
|
1844
|
-
//
|
|
1845
|
-
|
|
1846
|
-
// "deposit_disabled":false,
|
|
1847
|
-
// "trade_disabled":false,
|
|
1848
|
-
// "chain":"ETH"
|
|
1849
|
-
// }
|
|
1850
|
-
//
|
|
1832
|
+
// [
|
|
1833
|
+
// {
|
|
1834
|
+
// "currency": "USDT_ETH",
|
|
1835
|
+
// "name": "Tether",
|
|
1836
|
+
// "delisted": false,
|
|
1837
|
+
// "withdraw_disabled": false,
|
|
1838
|
+
// "withdraw_delayed": false,
|
|
1839
|
+
// "deposit_disabled": false,
|
|
1840
|
+
// "trade_disabled": true,
|
|
1841
|
+
// "chain": "ETH"
|
|
1842
|
+
// },
|
|
1843
|
+
// ]
|
|
1844
|
+
//
|
|
1845
|
+
const indexedCurrencies = this.indexBy(response, 'currency');
|
|
1851
1846
|
const result = {};
|
|
1852
1847
|
for (let i = 0; i < response.length; i++) {
|
|
1853
1848
|
const entry = response[i];
|
|
1854
1849
|
const currencyId = this.safeString(entry, 'currency');
|
|
1855
|
-
const currencyIdLower = this.safeStringLower(entry, 'currency');
|
|
1856
1850
|
const parts = currencyId.split('_');
|
|
1857
|
-
const
|
|
1858
|
-
|
|
1859
|
-
const
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1851
|
+
const partFirst = this.safeString(parts, 0);
|
|
1852
|
+
// if there's an underscore then the second part is always the chain name (except the _OLD suffix)
|
|
1853
|
+
const currencyName = currencyId.endsWith('_OLD') ? currencyId : partFirst;
|
|
1854
|
+
const withdrawEnabled = !this.safeBool(entry, 'withdraw_disabled');
|
|
1855
|
+
const depositEnabled = !this.safeBool(entry, 'deposit_disabled');
|
|
1856
|
+
const tradeDisabled = !this.safeBool(entry, 'trade_disabled');
|
|
1857
|
+
const precision = this.parseNumber('0.0001'); // temporary safe default, because no value provided from API
|
|
1858
|
+
const code = this.safeCurrencyCode(currencyName);
|
|
1859
|
+
// check leveraged tokens (e.g. BTC3S, ETH5L)
|
|
1860
|
+
let isLeveragedToken = false;
|
|
1861
|
+
if (currencyId.endsWith('3S') || currencyId.endsWith('3L') || currencyId.endsWith('5S') || currencyId.endsWith('5L')) {
|
|
1862
|
+
const realCurrencyId = currencyId.slice(0, -2);
|
|
1863
|
+
if (realCurrencyId in indexedCurrencies) {
|
|
1864
|
+
isLeveragedToken = true;
|
|
1865
|
+
}
|
|
1863
1866
|
}
|
|
1864
|
-
const
|
|
1865
|
-
|
|
1866
|
-
const
|
|
1867
|
-
const
|
|
1868
|
-
const
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1867
|
+
const type = isLeveragedToken ? 'leveraged' : 'crypto';
|
|
1868
|
+
// some networks are null, they are mostly obsolete & unsupported dead tokens, so we can default their networkId to their tokenname
|
|
1869
|
+
const networkId = this.safeString(entry, 'chain', currencyId);
|
|
1870
|
+
const networkCode = this.networkIdToCode(networkId, code);
|
|
1871
|
+
const networkEntry = {
|
|
1872
|
+
'info': entry,
|
|
1873
|
+
'id': networkId,
|
|
1874
|
+
'network': networkCode,
|
|
1875
|
+
'limits': {
|
|
1876
|
+
'deposit': {
|
|
1877
|
+
'min': undefined,
|
|
1878
|
+
'max': undefined,
|
|
1879
|
+
},
|
|
1880
|
+
'withdraw': {
|
|
1881
|
+
'min': undefined,
|
|
1882
|
+
'max': undefined,
|
|
1883
|
+
},
|
|
1884
|
+
},
|
|
1885
|
+
'active': !tradeDisabled,
|
|
1886
|
+
'deposit': depositEnabled,
|
|
1887
|
+
'withdraw': withdrawEnabled,
|
|
1888
|
+
'fee': undefined,
|
|
1889
|
+
'precision': precision,
|
|
1890
|
+
};
|
|
1891
|
+
// check if first entry for the specific currency
|
|
1892
|
+
if (!(code in result)) {
|
|
1874
1893
|
result[code] = {
|
|
1875
|
-
'id':
|
|
1894
|
+
'id': currencyName,
|
|
1895
|
+
'lowerCaseId': currencyName.toLowerCase(),
|
|
1876
1896
|
'code': code,
|
|
1877
|
-
'
|
|
1878
|
-
'
|
|
1879
|
-
'active': active,
|
|
1880
|
-
'deposit': depositEnabled,
|
|
1881
|
-
'withdraw': withdrawEnabled,
|
|
1882
|
-
'fee': undefined,
|
|
1883
|
-
'fees': [],
|
|
1884
|
-
'precision': this.parseNumber('1e-4'),
|
|
1897
|
+
'type': type,
|
|
1898
|
+
'precision': precision,
|
|
1885
1899
|
'limits': this.limits,
|
|
1886
1900
|
'networks': {},
|
|
1901
|
+
'info': [], // will be filled below
|
|
1887
1902
|
};
|
|
1888
1903
|
}
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
let withdrawAvailable = this.safeValue(result[code], 'withdraw');
|
|
1892
|
-
withdrawAvailable = (withdrawEnabled) ? withdrawEnabled : withdrawAvailable;
|
|
1893
|
-
const networks = this.safeValue(result[code], 'networks', {});
|
|
1894
|
-
if (networkCode !== undefined) {
|
|
1895
|
-
networks[networkCode] = {
|
|
1896
|
-
'info': entry,
|
|
1897
|
-
'id': networkId,
|
|
1898
|
-
'network': networkCode,
|
|
1899
|
-
'currencyId': currencyId,
|
|
1900
|
-
'lowerCaseCurrencyId': currencyIdLower,
|
|
1901
|
-
'deposit': depositEnabled,
|
|
1902
|
-
'withdraw': withdrawEnabled,
|
|
1903
|
-
'active': active,
|
|
1904
|
-
'fee': undefined,
|
|
1905
|
-
'precision': this.parseNumber('1e-4'),
|
|
1906
|
-
'limits': {
|
|
1907
|
-
'amount': {
|
|
1908
|
-
'min': undefined,
|
|
1909
|
-
'max': undefined,
|
|
1910
|
-
},
|
|
1911
|
-
'withdraw': {
|
|
1912
|
-
'min': undefined,
|
|
1913
|
-
'max': undefined,
|
|
1914
|
-
},
|
|
1915
|
-
'deposit': {
|
|
1916
|
-
'min': undefined,
|
|
1917
|
-
'max': undefined,
|
|
1918
|
-
},
|
|
1919
|
-
},
|
|
1920
|
-
};
|
|
1921
|
-
}
|
|
1922
|
-
result[code]['networks'] = networks;
|
|
1923
|
-
const info = this.safeValue(result[code], 'info', []);
|
|
1904
|
+
result[code]['networks'][networkCode] = networkEntry;
|
|
1905
|
+
const info = this.safeList(result[code], 'info', []);
|
|
1924
1906
|
info.push(entry);
|
|
1925
1907
|
result[code]['info'] = info;
|
|
1926
|
-
result[code][
|
|
1927
|
-
result[code]['deposit'] = depositAvailable;
|
|
1928
|
-
result[code]['withdraw'] = withdrawAvailable;
|
|
1908
|
+
result[code] = this.safeCurrencyStructure(result[code]); // this is needed after adding network entry
|
|
1929
1909
|
}
|
|
1930
1910
|
return result;
|
|
1931
1911
|
}
|
|
@@ -2174,6 +2154,29 @@ export default class gate extends Exchange {
|
|
|
2174
2154
|
}
|
|
2175
2155
|
return result;
|
|
2176
2156
|
}
|
|
2157
|
+
/**
|
|
2158
|
+
* @method
|
|
2159
|
+
* @name gate#fetchDepositAddressesByNetwork
|
|
2160
|
+
* @description fetch a dictionary of addresses for a currency, indexed by network
|
|
2161
|
+
* @param {string} code unified currency code of the currency for the deposit address
|
|
2162
|
+
* @param {object} [params] extra parameters specific to the api endpoint
|
|
2163
|
+
* @returns {object} a dictionary of [address structures]{@link https://docs.ccxt.com/#/?id=address-structure} indexed by the network
|
|
2164
|
+
*/
|
|
2165
|
+
async fetchDepositAddressesByNetwork(code, params = {}) {
|
|
2166
|
+
await this.loadMarkets();
|
|
2167
|
+
let currency = this.currency(code);
|
|
2168
|
+
const request = {
|
|
2169
|
+
'currency': currency['id'],
|
|
2170
|
+
};
|
|
2171
|
+
const response = await this.privateWalletGetDepositAddress(this.extend(request, params));
|
|
2172
|
+
const chains = this.safeValue(response, 'multichain_addresses', []);
|
|
2173
|
+
const currencyId = this.safeString(response, 'currency');
|
|
2174
|
+
currency = this.safeCurrency(currencyId, currency);
|
|
2175
|
+
const parsed = this.parseDepositAddresses(chains, [currency['code']], false, {
|
|
2176
|
+
'currency': currency['id'],
|
|
2177
|
+
});
|
|
2178
|
+
return this.indexBy(parsed, 'network');
|
|
2179
|
+
}
|
|
2177
2180
|
/**
|
|
2178
2181
|
* @method
|
|
2179
2182
|
* @name gate#fetchDepositAddress
|
|
@@ -2186,74 +2189,30 @@ export default class gate extends Exchange {
|
|
|
2186
2189
|
*/
|
|
2187
2190
|
async fetchDepositAddress(code, params = {}) {
|
|
2188
2191
|
await this.loadMarkets();
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
const
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2192
|
+
let networkCode = undefined;
|
|
2193
|
+
[networkCode, params] = this.handleNetworkCodeAndParams(params);
|
|
2194
|
+
const chainsIndexedById = await this.fetchDepositAddressesByNetwork(code, params);
|
|
2195
|
+
const selectedNetworkId = this.selectNetworkCodeFromUnifiedNetworks(code, networkCode, chainsIndexedById);
|
|
2196
|
+
return chainsIndexedById[selectedNetworkId];
|
|
2197
|
+
}
|
|
2198
|
+
parseDepositAddress(depositAddress, currency = undefined) {
|
|
2196
2199
|
//
|
|
2197
|
-
//
|
|
2198
|
-
//
|
|
2199
|
-
//
|
|
2200
|
-
//
|
|
2201
|
-
//
|
|
2202
|
-
//
|
|
2203
|
-
//
|
|
2204
|
-
// "payment_id": "391331007",
|
|
2205
|
-
// "payment_name": "Tag",
|
|
2206
|
-
// "obtain_failed": 0
|
|
2207
|
-
// }
|
|
2208
|
-
// ]
|
|
2209
|
-
// }
|
|
2200
|
+
// {
|
|
2201
|
+
// chain: "BTC",
|
|
2202
|
+
// address: "1Nxu.......Ys",
|
|
2203
|
+
// payment_id: "",
|
|
2204
|
+
// payment_name: "",
|
|
2205
|
+
// obtain_failed: "0",
|
|
2206
|
+
// }
|
|
2210
2207
|
//
|
|
2211
|
-
const
|
|
2212
|
-
code = this.safeCurrencyCode(currencyId);
|
|
2213
|
-
const networkId = this.networkCodeToId(rawNetwork, code);
|
|
2214
|
-
let network = undefined;
|
|
2215
|
-
let tag = undefined;
|
|
2216
|
-
let address = undefined;
|
|
2217
|
-
if (networkId !== undefined) {
|
|
2218
|
-
const addresses = this.safeValue(response, 'multichain_addresses');
|
|
2219
|
-
for (let i = 0; i < addresses.length; i++) {
|
|
2220
|
-
const entry = addresses[i];
|
|
2221
|
-
const entryNetwork = this.safeString(entry, 'chain');
|
|
2222
|
-
if (networkId === entryNetwork) {
|
|
2223
|
-
const obtainFailed = this.safeInteger(entry, 'obtain_failed');
|
|
2224
|
-
if (obtainFailed) {
|
|
2225
|
-
break;
|
|
2226
|
-
}
|
|
2227
|
-
address = this.safeString(entry, 'address');
|
|
2228
|
-
tag = this.safeString(entry, 'payment_id');
|
|
2229
|
-
network = this.networkIdToCode(networkId, code);
|
|
2230
|
-
break;
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
|
-
}
|
|
2234
|
-
else {
|
|
2235
|
-
const addressField = this.safeString(response, 'address');
|
|
2236
|
-
if (addressField !== undefined) {
|
|
2237
|
-
if (addressField.indexOf('New address is being generated for you, please wait') >= 0) {
|
|
2238
|
-
throw new BadResponse(this.id + ' ' + 'New address is being generated for you, please wait a few seconds and try again to get the address.');
|
|
2239
|
-
}
|
|
2240
|
-
if (addressField.indexOf(' ') >= 0) {
|
|
2241
|
-
const splitted = addressField.split(' ');
|
|
2242
|
-
address = splitted[0];
|
|
2243
|
-
tag = splitted[1];
|
|
2244
|
-
}
|
|
2245
|
-
else {
|
|
2246
|
-
address = addressField;
|
|
2247
|
-
}
|
|
2248
|
-
}
|
|
2249
|
-
}
|
|
2208
|
+
const address = this.safeString(depositAddress, 'address');
|
|
2250
2209
|
this.checkAddress(address);
|
|
2251
2210
|
return {
|
|
2252
|
-
'info':
|
|
2253
|
-
'currency': code,
|
|
2254
|
-
'network': network,
|
|
2211
|
+
'info': depositAddress,
|
|
2212
|
+
'currency': this.safeString(currency, 'code'),
|
|
2255
2213
|
'address': address,
|
|
2256
|
-
'tag':
|
|
2214
|
+
'tag': this.safeString(depositAddress, 'payment_id'),
|
|
2215
|
+
'network': this.networkIdToCode(this.safeString(depositAddress, 'chain')),
|
|
2257
2216
|
};
|
|
2258
2217
|
}
|
|
2259
2218
|
/**
|
|
@@ -3986,15 +3945,10 @@ export default class gate extends Exchange {
|
|
|
3986
3945
|
if (tag !== undefined) {
|
|
3987
3946
|
request['memo'] = tag;
|
|
3988
3947
|
}
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
request['chain'] = network;
|
|
3994
|
-
params = this.omit(params, 'network');
|
|
3995
|
-
}
|
|
3996
|
-
else {
|
|
3997
|
-
request['chain'] = currency['id']; // todo: currencies have network-junctions
|
|
3948
|
+
let networkCode = undefined;
|
|
3949
|
+
[networkCode, params] = this.handleNetworkCodeAndParams(params);
|
|
3950
|
+
if (networkCode !== undefined) {
|
|
3951
|
+
request['chain'] = this.networkCodeToId(networkCode);
|
|
3998
3952
|
}
|
|
3999
3953
|
const response = await this.privateWithdrawalsPostWithdrawals(this.extend(request, params));
|
|
4000
3954
|
//
|
package/js/src/phemex.js
CHANGED
|
@@ -673,7 +673,8 @@ export default class phemex extends Exchange {
|
|
|
673
673
|
// }
|
|
674
674
|
//
|
|
675
675
|
const id = this.safeString(market, 'symbol');
|
|
676
|
-
const
|
|
676
|
+
const contractUnderlyingAssets = this.safeString(market, 'contractUnderlyingAssets');
|
|
677
|
+
const baseId = this.safeString(market, 'baseCurrency', contractUnderlyingAssets);
|
|
677
678
|
const quoteId = this.safeString(market, 'quoteCurrency');
|
|
678
679
|
const settleId = this.safeString(market, 'settleCurrency');
|
|
679
680
|
let base = this.safeCurrencyCode(baseId);
|
|
@@ -683,6 +684,10 @@ export default class phemex extends Exchange {
|
|
|
683
684
|
let inverse = false;
|
|
684
685
|
if (settleId !== quoteId) {
|
|
685
686
|
inverse = true;
|
|
687
|
+
// some unhandled cases
|
|
688
|
+
if (!('baseCurrency' in market) && base === quote) {
|
|
689
|
+
base = settle;
|
|
690
|
+
}
|
|
686
691
|
}
|
|
687
692
|
const priceScale = this.safeInteger(market, 'priceScale');
|
|
688
693
|
const ratioScale = this.safeInteger(market, 'ratioScale');
|
|
@@ -872,7 +877,7 @@ export default class phemex extends Exchange {
|
|
|
872
877
|
* @returns {object[]} an array of objects representing market data
|
|
873
878
|
*/
|
|
874
879
|
async fetchMarkets(params = {}) {
|
|
875
|
-
const
|
|
880
|
+
const v2ProductsPromise = this.v2GetPublicProducts(params);
|
|
876
881
|
//
|
|
877
882
|
// {
|
|
878
883
|
// "code":0,
|
|
@@ -1022,7 +1027,8 @@ export default class phemex extends Exchange {
|
|
|
1022
1027
|
// }
|
|
1023
1028
|
// }
|
|
1024
1029
|
//
|
|
1025
|
-
const
|
|
1030
|
+
const v1ProductsPromise = this.v1GetExchangePublicProducts(params);
|
|
1031
|
+
const [v2Products, v1Products] = await Promise.all([v2ProductsPromise, v1ProductsPromise]);
|
|
1026
1032
|
const v1ProductsData = this.safeValue(v1Products, 'data', []);
|
|
1027
1033
|
//
|
|
1028
1034
|
// {
|
|
@@ -1059,14 +1065,14 @@ export default class phemex extends Exchange {
|
|
|
1059
1065
|
// ]
|
|
1060
1066
|
// }
|
|
1061
1067
|
//
|
|
1062
|
-
const v2ProductsData = this.
|
|
1063
|
-
let products = this.
|
|
1064
|
-
const perpetualProductsV2 = this.
|
|
1068
|
+
const v2ProductsData = this.safeDict(v2Products, 'data', {});
|
|
1069
|
+
let products = this.safeList(v2ProductsData, 'products', []);
|
|
1070
|
+
const perpetualProductsV2 = this.safeList(v2ProductsData, 'perpProductsV2', []);
|
|
1065
1071
|
products = this.arrayConcat(products, perpetualProductsV2);
|
|
1066
|
-
let riskLimits = this.
|
|
1067
|
-
const riskLimitsV2 = this.
|
|
1072
|
+
let riskLimits = this.safeList(v2ProductsData, 'riskLimits', []);
|
|
1073
|
+
const riskLimitsV2 = this.safeList(v2ProductsData, 'riskLimitsV2', []);
|
|
1068
1074
|
riskLimits = this.arrayConcat(riskLimits, riskLimitsV2);
|
|
1069
|
-
const currencies = this.
|
|
1075
|
+
const currencies = this.safeList(v2ProductsData, 'currencies', []);
|
|
1070
1076
|
const riskLimitsById = this.indexBy(riskLimits, 'symbol');
|
|
1071
1077
|
const v1ProductsById = this.indexBy(v1ProductsData, 'symbol');
|
|
1072
1078
|
const currenciesByCode = this.indexBy(currencies, 'currency');
|
|
@@ -1076,15 +1082,15 @@ export default class phemex extends Exchange {
|
|
|
1076
1082
|
const type = this.safeStringLower(market, 'type');
|
|
1077
1083
|
if ((type === 'perpetual') || (type === 'perpetualv2') || (type === 'perpetualpilot')) {
|
|
1078
1084
|
const id = this.safeString(market, 'symbol');
|
|
1079
|
-
const riskLimitValues = this.
|
|
1085
|
+
const riskLimitValues = this.safeDict(riskLimitsById, id, {});
|
|
1080
1086
|
market = this.extend(market, riskLimitValues);
|
|
1081
|
-
const v1ProductsValues = this.
|
|
1087
|
+
const v1ProductsValues = this.safeDict(v1ProductsById, id, {});
|
|
1082
1088
|
market = this.extend(market, v1ProductsValues);
|
|
1083
1089
|
market = this.parseSwapMarket(market);
|
|
1084
1090
|
}
|
|
1085
1091
|
else {
|
|
1086
1092
|
const baseCurrency = this.safeString(market, 'baseCurrency');
|
|
1087
|
-
const currencyValues = this.
|
|
1093
|
+
const currencyValues = this.safeDict(currenciesByCode, baseCurrency, {});
|
|
1088
1094
|
const valueScale = this.safeString(currencyValues, 'valueScale', '8');
|
|
1089
1095
|
market = this.extend(market, { 'valueScale': valueScale });
|
|
1090
1096
|
market = this.parseSpotMarket(market);
|
package/js/src/pro/bitmart.js
CHANGED
|
@@ -121,7 +121,7 @@ export default class bitmart extends bitmartRest {
|
|
|
121
121
|
const url = this.implodeHostname(this.urls['api']['ws'][type]['public']);
|
|
122
122
|
const channelType = (type === 'spot') ? 'spot' : 'futures';
|
|
123
123
|
const actionType = (type === 'spot') ? 'op' : 'action';
|
|
124
|
-
|
|
124
|
+
const rawSubscriptions = [];
|
|
125
125
|
const messageHashes = [];
|
|
126
126
|
for (let i = 0; i < symbols.length; i++) {
|
|
127
127
|
const market = this.market(symbols[i]);
|
|
@@ -130,9 +130,10 @@ export default class bitmart extends bitmartRest {
|
|
|
130
130
|
messageHashes.push(channel + ':' + market['symbol']);
|
|
131
131
|
}
|
|
132
132
|
// as an exclusion, futures "tickers" need one generic request for all symbols
|
|
133
|
-
if ((type !== 'spot') && (channel === 'ticker')) {
|
|
134
|
-
|
|
135
|
-
}
|
|
133
|
+
// if ((type !== 'spot') && (channel === 'ticker')) {
|
|
134
|
+
// rawSubscriptions = [ channelType + '/' + channel ];
|
|
135
|
+
// }
|
|
136
|
+
// Exchange update from 2025-02-11 supports subscription by trading pair for swap
|
|
136
137
|
const request = {
|
|
137
138
|
'args': rawSubscriptions,
|
|
138
139
|
};
|
|
@@ -948,39 +949,44 @@ export default class bitmart extends bitmartRest {
|
|
|
948
949
|
}
|
|
949
950
|
parseWsTrade(trade, market = undefined) {
|
|
950
951
|
// spot
|
|
951
|
-
//
|
|
952
|
-
//
|
|
953
|
-
//
|
|
954
|
-
//
|
|
955
|
-
//
|
|
956
|
-
//
|
|
957
|
-
//
|
|
952
|
+
// {
|
|
953
|
+
// "ms_t": 1740320841473,
|
|
954
|
+
// "price": "2806.54",
|
|
955
|
+
// "s_t": 1740320841,
|
|
956
|
+
// "side": "sell",
|
|
957
|
+
// "size": "0.77598",
|
|
958
|
+
// "symbol": "ETH_USDT"
|
|
959
|
+
// }
|
|
960
|
+
//
|
|
958
961
|
// swap
|
|
959
|
-
//
|
|
960
|
-
//
|
|
961
|
-
//
|
|
962
|
-
//
|
|
963
|
-
//
|
|
964
|
-
//
|
|
965
|
-
//
|
|
966
|
-
//
|
|
967
|
-
//
|
|
968
|
-
// "create_time_mill":1701618503517,
|
|
969
|
-
// "created_at":"2023-12-03T15:48:23.517518538Z"
|
|
970
|
-
// }
|
|
962
|
+
// {
|
|
963
|
+
// "trade_id": "3000000245258661",
|
|
964
|
+
// "symbol": "ETHUSDT",
|
|
965
|
+
// "deal_price": "2811.1",
|
|
966
|
+
// "deal_vol": "1858",
|
|
967
|
+
// "way": 2,
|
|
968
|
+
// "m": true,
|
|
969
|
+
// "created_at": "2025-02-23T13:59:59.646490751Z"
|
|
970
|
+
// }
|
|
971
971
|
//
|
|
972
|
-
const contractId = this.safeString(trade, 'contract_id');
|
|
973
|
-
const marketType = (contractId === undefined) ? 'spot' : 'swap';
|
|
974
|
-
const marketDelimiter = (marketType === 'spot') ? '_' : '';
|
|
975
|
-
const timestamp = this.safeInteger(trade, 'create_time_mill', this.safeTimestamp(trade, 's_t'));
|
|
976
972
|
const marketId = this.safeString(trade, 'symbol');
|
|
973
|
+
market = this.safeMarket(marketId, market);
|
|
974
|
+
let timestamp = this.safeInteger(trade, 'ms_t');
|
|
975
|
+
let datetime = undefined;
|
|
976
|
+
if (timestamp === undefined) {
|
|
977
|
+
datetime = this.safeString(trade, 'created_at');
|
|
978
|
+
timestamp = this.parse8601(datetime);
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
datetime = this.iso8601(timestamp);
|
|
982
|
+
}
|
|
977
983
|
return this.safeTrade({
|
|
978
984
|
'info': trade,
|
|
979
985
|
'id': this.safeString(trade, 'trade_id'),
|
|
980
986
|
'order': undefined,
|
|
981
987
|
'timestamp': timestamp,
|
|
982
|
-
'datetime':
|
|
983
|
-
'symbol':
|
|
988
|
+
'datetime': datetime,
|
|
989
|
+
'symbol': market['symbol'],
|
|
984
990
|
'type': undefined,
|
|
985
991
|
'side': this.safeString(trade, 'side'),
|
|
986
992
|
'price': this.safeString2(trade, 'price', 'deal_price'),
|
|
@@ -1006,20 +1012,22 @@ export default class bitmart extends bitmartRest {
|
|
|
1006
1012
|
// ],
|
|
1007
1013
|
// "table": "spot/ticker"
|
|
1008
1014
|
// }
|
|
1009
|
-
//
|
|
1010
|
-
//
|
|
1011
|
-
//
|
|
1012
|
-
//
|
|
1013
|
-
//
|
|
1014
|
-
//
|
|
1015
|
-
//
|
|
1016
|
-
//
|
|
1017
|
-
//
|
|
1018
|
-
//
|
|
1019
|
-
//
|
|
1020
|
-
//
|
|
1021
|
-
//
|
|
1022
|
-
//
|
|
1015
|
+
//
|
|
1016
|
+
// {
|
|
1017
|
+
// "data": {
|
|
1018
|
+
// "symbol": "ETHUSDT",
|
|
1019
|
+
// "last_price": "2807.73",
|
|
1020
|
+
// "volume_24": "2227011952",
|
|
1021
|
+
// "range": "0.0273398194664491",
|
|
1022
|
+
// "mark_price": "2807.5",
|
|
1023
|
+
// "index_price": "2808.71047619",
|
|
1024
|
+
// "ask_price": "2808.04",
|
|
1025
|
+
// "ask_vol": "7371",
|
|
1026
|
+
// "bid_price": "2807.28",
|
|
1027
|
+
// "bid_vol": "3561"
|
|
1028
|
+
// },
|
|
1029
|
+
// "group": "futures/ticker:ETHUSDT@100ms"
|
|
1030
|
+
// }
|
|
1023
1031
|
//
|
|
1024
1032
|
this.handleBidAsk(client, message);
|
|
1025
1033
|
const table = this.safeString(message, 'table');
|
|
@@ -1044,17 +1052,19 @@ export default class bitmart extends bitmartRest {
|
|
|
1044
1052
|
}
|
|
1045
1053
|
parseWsSwapTicker(ticker, market = undefined) {
|
|
1046
1054
|
//
|
|
1047
|
-
//
|
|
1048
|
-
//
|
|
1049
|
-
//
|
|
1050
|
-
//
|
|
1051
|
-
//
|
|
1052
|
-
//
|
|
1053
|
-
//
|
|
1054
|
-
//
|
|
1055
|
-
//
|
|
1056
|
-
//
|
|
1057
|
-
//
|
|
1055
|
+
// {
|
|
1056
|
+
// "symbol": "ETHUSDT",
|
|
1057
|
+
// "last_price": "2807.73",
|
|
1058
|
+
// "volume_24": "2227011952",
|
|
1059
|
+
// "range": "0.0273398194664491",
|
|
1060
|
+
// "mark_price": "2807.5",
|
|
1061
|
+
// "index_price": "2808.71047619",
|
|
1062
|
+
// "ask_price": "2808.04",
|
|
1063
|
+
// "ask_vol": "7371",
|
|
1064
|
+
// "bid_price": "2807.28",
|
|
1065
|
+
// "bid_vol": "3561"
|
|
1066
|
+
// }
|
|
1067
|
+
//
|
|
1058
1068
|
const marketId = this.safeString(ticker, 'symbol');
|
|
1059
1069
|
return this.safeTicker({
|
|
1060
1070
|
'symbol': this.safeSymbol(marketId, market, '', 'swap'),
|
|
@@ -1073,10 +1083,12 @@ export default class bitmart extends bitmartRest {
|
|
|
1073
1083
|
'previousClose': undefined,
|
|
1074
1084
|
'change': undefined,
|
|
1075
1085
|
'percentage': undefined,
|
|
1076
|
-
'average':
|
|
1086
|
+
'average': undefined,
|
|
1077
1087
|
'baseVolume': undefined,
|
|
1078
1088
|
'quoteVolume': this.safeString(ticker, 'volume_24'),
|
|
1079
1089
|
'info': ticker,
|
|
1090
|
+
'markPrice': this.safeString(ticker, 'mark_price'),
|
|
1091
|
+
'indexPrice': this.safeString(ticker, 'index_price'),
|
|
1080
1092
|
}, market);
|
|
1081
1093
|
}
|
|
1082
1094
|
/**
|
package/js/src/pro/bitopro.js
CHANGED
|
@@ -77,7 +77,7 @@ export default class bitopro extends bitoproRest {
|
|
|
77
77
|
endPart = market['id'];
|
|
78
78
|
}
|
|
79
79
|
else {
|
|
80
|
-
endPart = market['id'] + ':' + limit;
|
|
80
|
+
endPart = market['id'] + ':' + this.numberToString(limit);
|
|
81
81
|
}
|
|
82
82
|
const orderbook = await this.watchPublic('order-books', messageHash, endPart);
|
|
83
83
|
return orderbook.limit();
|
package/js/src/pro/gate.js
CHANGED
|
@@ -2024,6 +2024,11 @@ export default class gate extends gateRest {
|
|
|
2024
2024
|
'signature': signature,
|
|
2025
2025
|
'req_param': reqParams,
|
|
2026
2026
|
};
|
|
2027
|
+
if ((channel === 'spot.order_place') || (channel === 'futures.order_place')) {
|
|
2028
|
+
payload['req_header'] = {
|
|
2029
|
+
'x-gate-channel-id': 'ccxt',
|
|
2030
|
+
};
|
|
2031
|
+
}
|
|
2027
2032
|
const request = {
|
|
2028
2033
|
'id': requestId,
|
|
2029
2034
|
'time': time,
|
package/js/src/pro/vertex.js
CHANGED
|
@@ -50,6 +50,11 @@ export default class vertex extends vertexRest {
|
|
|
50
50
|
},
|
|
51
51
|
'ws': {
|
|
52
52
|
'inflate': true,
|
|
53
|
+
'options': {
|
|
54
|
+
'headers': {
|
|
55
|
+
'Sec-WebSocket-Extensions': 'permessage-deflate', // requires permessage-deflate extension, maybe we can set this in client implementation when inflate is true
|
|
56
|
+
},
|
|
57
|
+
},
|
|
53
58
|
},
|
|
54
59
|
},
|
|
55
60
|
'streaming': {
|
package/js/src/tradeogre.js
CHANGED
|
@@ -518,12 +518,12 @@ export default class tradeogre extends Exchange {
|
|
|
518
518
|
throw new BadRequest(this.id + ' createOrder does not support market orders');
|
|
519
519
|
}
|
|
520
520
|
if (price === undefined) {
|
|
521
|
-
throw new ArgumentsRequired(this.id + ' createOrder requires a
|
|
521
|
+
throw new ArgumentsRequired(this.id + ' createOrder requires a price parameter');
|
|
522
522
|
}
|
|
523
523
|
const request = {
|
|
524
524
|
'market': market['id'],
|
|
525
|
-
'quantity': this.
|
|
526
|
-
'price': this.
|
|
525
|
+
'quantity': this.amountToPrecision(symbol, amount),
|
|
526
|
+
'price': this.priceToPrecision(symbol, price),
|
|
527
527
|
};
|
|
528
528
|
let response = undefined;
|
|
529
529
|
if (side === 'buy') {
|